linux下使用libcpcap的简单代码

#include <stdio.h>

#include <stdlib.h>

#include <pcap.h>
#include <arpa/inet.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <string.h>
struct arp_header
{
  u_int16_t arp_hardware_type;    /*硬件类型 */
  u_int16_t arp_protocol_type;    /*协议类型 */
  u_int8_t arp_hardware_length;    /*硬件地址长度 */
  u_int8_t arp_protocol_length;    /*协议地址长度 */
  u_int16_t arp_operation_code;    /*ARP操作码 */
  u_int8_t arp_source_ethernet_address[6];    /*源以太网地址 */
  u_int8_t arp_source_ip_address[4];    /*源IP地址 */
  u_int8_t arp_destination_ethernet_address[6];    /*目的以太网地址 */
  u_int8_t arp_destination_ip_address[4];    /*目的IP地址 */
};
/*ip协议格式的定义*/
struct ip_header
{
#ifdef WORDS_BIGENDIAN
  u_int8_t ip_version:4, ip_header_length:4;
#else
  u_int8_t ip_header_length:4, ip_version:4;
#endif
  u_int8_t ip_tos;        //服务质量
  u_int16_t ip_length;        //总长度
  u_int16_t ip_id;        //标识
  u_int16_t ip_off;        //偏移
  u_int8_t ip_ttl;        //生存时间
  u_int8_t ip_protocol;        //协议类型
  u_int16_t ip_checksum;    //校验和
  struct in_addr ip_souce_address;    //源ip地址
  struct in_addr ip_destination_address;    //目的ip地址
};
/*tcp协议格式的定义*/
struct tcp_header
{
#ifdef WORDS_BIGENDIAN
  u_int8_t tcp_offset:4, tcp_reserved:4;
#else
  u_int8_t tcp_reserved:4, tcp_offset:4;
#endif
  u_int16_t tcp_source_port;    //源端口号
  u_int16_t tcp_destination_port;    //目的端口号
  u_int32_t tcp_acknowledgement;    //序列号
  u_int32_t tcp_ack;        //确认号
  u_int8_t tcp_flags;        //标记
  u_int16_t tcp_windows;    //窗口大小
  u_int16_t tcp_checksum;    //校验和
  u_int16_t tcp_urgent_pointer;    //紧急指针
};
/*udp些一个是的定义*/
struct udp_header
{
  u_int16_t udp_source_port;    /*源端口号 */
  u_int16_t udp_destination_port;    /*目的端口号 */
  u_int16_t udp_length;        /*长度 */
  u_int16_t udp_checksum;    /*校验和 */
};
/*icmp协议格式的定义*/
struct icmp_header
{
  u_int8_t icmp_type;        /*ICMP类型 */
  u_int8_t icmp_code;        /*ICMP代码 */
  u_int16_t icmp_checksum;    /*校验和 */
  u_int16_t icmp_id;        /*标识 */
  u_int16_t icmp_sequence;    /*序列号 */
};
/*分析tcp协议的回调函数*/
void
tcp_protocol_callback (u_char * argument,
               const struct pcap_pkthdr *packet_header,
               const u_char * packet_content)
{
  struct tcp_header *tcp_protocol;
  u_char flags;
  u_int header_len;
  u_short source_port;
  u_short destination_port;
  u_short windows;
  u_short urgent_pointer;
  u_int sequence;
  u_int acknowledgement;
  u_int16_t checksum;
  tcp_protocol = (struct tcp_header *) (packet_content + 14 + 20);
  source_port = ntohs (tcp_protocol->tcp_source_port);
  destination_port = ntohs (tcp_protocol->tcp_destination_port);
  header_len = tcp_protocol->tcp_offset * 4;
  sequence = ntohl (tcp_protocol->tcp_acknowledgement);
  windows = ntohs (tcp_protocol->tcp_windows);
  urgent_pointer = ntohs (tcp_protocol->tcp_urgent_pointer);
  flags = tcp_protocol->tcp_flags;
  checksum = ntohs (tcp_protocol->tcp_checksum);
  printf ("-------------------TCP Protocol--------------/n");
  printf ("Source Port:%d/n", source_port);
  printf ("Destination port:%d/n", destination_port);
  switch (destination_port)
    {
    case 80:
      printf ("HTTP protocol/n");
      break;            //端口80,表示上层协议是HTTP
    case 21:
      printf ("FTP protocol/n");
      break;            //端口21,表示上层协议是FTP
    case 23:
      printf ("TELNET protocol/n");
      break;            //端口23,表示上层协议是TELNET
    case 25:
      printf ("SMTP protocol/n");
      break;            //端口25,表示上层协议是SMTP
    case 110:
      printf ("POP3 protocol/n");
      break;            //端口110,表示上层协议是POP3
    default:
      break;
    }
  printf ("Sequence Number:%u/n", sequence);
  printf ("Acknowledgement Number:%u/n", acknowledgement);
  printf ("Header Length:%d/n", header_len);
  printf ("Reserved:%d/n", tcp_protocol->tcp_reserved);
  printf ("flags:");
  if (flags & 0x80)
    printf ("PSH");
  if (flags & 0x10)
    printf ("ACK");
  if (flags & 0x02)
    printf ("SYN");
  if (flags & 0x20)
    printf ("URG");
  if (flags & 0x01)
    printf ("FIN");
  if (flags & 0x04)
    printf ("RST");
  printf ("/n");
  printf ("Window size:%d/n", windows);
  printf ("Checksum:%d/n", checksum);
  printf ("Urgent pointer:%d/n", urgent_pointer);
}
/*分析udp协议的回调函数*/
void
udp_protocol_callback (u_char * argument,
               const struct pcap_pkthdr *packet_header,
               const u_char * packet_content)
{
  struct udp_header *udp_protocol;
  u_short source_port;
  u_short destination_port;
  u_short length;
  udp_protocol = (struct udp_header *) (packet_content + 14 + 20);
  source_port = ntohs (udp_protocol->udp_source_port);
  destination_port = ntohs (udp_protocol->udp_destination_port);
  length = ntohs (udp_protocol->udp_length);
  printf ("---------------------UDP PROTOCOL---------------------/n");
  printf ("Source port is:%d/n", source_port);
  printf ("Destination port is:%d/n", destination_port);
  switch (destination_port)
    {
    case 138:
      printf ("NETBIOS Datagram Service./n");
      break;
    case 137:
      printf ("NETBIOS Name Service./n");
      break;
    case 139:
      printf ("NETBIOS Session Service./n");
      break;
    case 53:
      printf ("name-domain server./n");
      break;
    default:
      break;
    }
  printf ("Length is:%d/n", length);
  printf ("checksum is:%d/n", ntohs (udp_protocol->udp_checksum));
}
/*分析ICMP协议的回调函数*/
void
icmp_protocol_callback (u_char * argument,
            const struct pcap_pkthdr *packet_header,
            const u_char * packet_content)
{
  struct icmp_header *icmp_protocol;
  icmp_protocol = (struct icmp_header *) (packet_content + 14 + 20);
  printf ("---------------------ICMP PROTOCOL-------------------------/n");
  printf ("ICMP type is:%d/n", icmp_protocol->icmp_type);
  switch (icmp_protocol->icmp_type)
    {
    case 8:
      printf ("ICMP Echo Request Protocol/n");
      printf ("ICMP Code:%d/n", icmp_protocol->icmp_code);
      printf ("Idetifier:%d/n", icmp_protocol->icmp_id);
      printf ("Sequence Number:%d/n", icmp_protocol->icmp_sequence);
      break;
    case 0:
      printf ("ICMP Echo Reply Protocol/n");
      printf ("ICMP Code:%d/n", icmp_protocol->icmp_code);
      printf ("Idetifier:%d/n", icmp_protocol->icmp_id);
      printf ("Sequence Number:%d/n", icmp_protocol->icmp_sequence);
      break;
    default:
      break;
    }
  printf ("ICMP Checksum is:%d/n", ntohs (icmp_protocol->icmp_checksum));
}
/*分析ARP协议的回调函数*/
void
arp_protocol_callback (u_char * argument,
               const struct pcap_pkthdr *packet_header,
               const u_char * packet_content)
{
  struct arp_header *arp_protocol;
  u_short protocol_type;
  u_short hardware_type;
  u_short operation_code;
  u_char *mac_string;
  struct in_addr addr;
  u_char hardware_len;
  u_char protocol_len;
  printf ("--------------------ARP Protocol --------------------------/n");
  arp_protocol = (struct arp_header *) (packet_content + 14);
  hardware_type = ntohs (arp_protocol->arp_hardware_type);
  protocol_type = ntohs (arp_protocol->arp_protocol_type);
  operation_code = ntohs (arp_protocol->arp_operation_code);
  hardware_len = arp_protocol->arp_hardware_length;
  protocol_len = arp_protocol->arp_protocol_length;
  printf ("ARP Hardware Type:%d/n", hardware_type);
  printf ("ARP Protocol Type:%d/n", protocol_type);
  printf ("ARP Hardware Length:%d/n", hardware_len);
  printf ("ARP Protocol Length:%d/n", protocol_len);
  switch (operation_code)
    {
    case 1:
      printf ("ARP Request Protocol/n");
      break;
    case 2:
      printf ("ARP Reply Protocol/n");
      break;
    case 3:
      printf ("RARP Request Protocol/n");
      break;
    case 4:
      printf ("RARP Reply Protocol/n");
      break;
    default:
      break;
    }
  printf ("Ethernet Source Address is:/n");
  mac_string = arp_protocol->arp_source_ethernet_address;
  printf ("%02x:%02x:%02x:%02x:%02x:%02x/n", *mac_string, *(mac_string + 1),
      *(mac_string + 2), *(mac_string + 3), *(mac_string + 4),
      *(mac_string + 5));
  memcpy ((void *) &addr, (void *) &arp_protocol->arp_source_ip_address,
      sizeof (struct in_addr));
  printf ("Source IP Address is:%s/n", inet_ntoa (addr));
  printf ("Ethernet Destination Address is:/n");
  mac_string = arp_protocol->arp_destination_ethernet_address;
  printf ("%02x:%02x:%02x:%02x:%02x:%02x/n", *mac_string, *(mac_string + 1),
      *(mac_string + 2), *(mac_string + 3), *(mac_string + 4),
      *(mac_string + 5));
  memcpy ((void *) &addr, (void *) &arp_protocol->arp_destination_ip_address,
      sizeof (struct in_addr));
  printf ("Source IP Address is:%s/n", inet_ntoa (addr));
}
/*分析ip协议的回调函数*/
void
ip_protocol_callback (u_char * argument,
              const struct pcap_pkthdr *packet_header,
              const u_char * packet_content)
{
  struct ip_header *ip_protocol;
  //struct iphdr *ip_protocol;
  u_int header_len;
  u_int offset;
  u_char tos;
  u_int16_t checksum;
  ip_protocol = (struct ip_header *) (packet_content + 14);
  checksum = ntohs (ip_protocol->ip_checksum);
  header_len = (ip_protocol->ip_header_length) * 4;
  tos = ip_protocol->ip_tos;
  offset = ntohs (ip_protocol->ip_off);
  printf ("------------IP Protocol --------------------/n");
  printf ("IP Version:%d/n", ip_protocol->ip_version);
  printf ("Header length:%d/n", header_len);
  printf ("TOS:%d/n", tos);
  printf ("Total length:%d/n", ntohs (ip_protocol->ip_length));
  printf ("Identification:%d/n", ntohs (ip_protocol->ip_id));
  printf ("Offset:%d/n", (offset & 0x1fff) * 8);
  printf ("TTL:%d/n", ip_protocol->ip_ttl);
  printf ("Protocol:%d/n", ip_protocol->ip_protocol);
  printf ("Header checksum:%d/n", checksum);
  printf ("Source address:%s/n", inet_ntoa (ip_protocol->ip_souce_address));
  printf ("Destination address:%s/n",
      inet_ntoa (ip_protocol->ip_destination_address));
  switch (ip_protocol->ip_protocol)
    {
    case 6://上层是TCP协议
      printf ("The Transport Layer Protocol is TCP/n");
      tcp_protocol_callback (argument, packet_header, packet_content);
      break;
    case 17://上层是UDP协议
      printf ("The Transport Layer Protocol is UDP/n");
      udp_protocol_callback (argument, packet_header, packet_content);
      break;
    case 1://上层是ICMP协议
      printf ("The Transport Layer Protocol is ICMP/n");
      icmp_protocol_callback (argument, packet_header, packet_content);
      break;
    default:
      break;
    }
}
/*分析以太网协议的回调函数*/
void
ether_protocol_callback (u_char * argument,
             const struct pcap_pkthdr *packet_header,
             const u_char * packet_content)
{
  static int number = 0;
  struct ether_header *ethernet_protocol;
  u_short ethernet_type;
  u_char *mac_string;
  printf
    ("---------------------------------------------------------------------/n");
  printf ("The %d packet is captured./n", ++number);
  printf ("---------------------ETHER PROTOCOL----------------------/n");
  ethernet_protocol = (struct ether_header *) packet_content;
  printf ("Ether type is:/n");
  ethernet_type = ntohs (ethernet_protocol->ether_type);
  printf ("%04x/n", ethernet_type);
  printf ("MAC Source Address is:/n");
  int i = ETHER_ADDR_LEN;
  mac_string = ethernet_protocol->ether_shost;
  do
    {
      printf ("%s%02x", (i == ETHER_ADDR_LEN) ? "" : ":", *mac_string++);
    }
  while (--i > 0);
  printf ("/nMac Destination Address is:/n");
  i = ETHER_ADDR_LEN;
  mac_string = ethernet_protocol->ether_dhost;
  do
    {
      printf ("%s%02x", (i == ETHER_ADDR_LEN) ? "" : ":", *mac_string++);
    }
  while (--i > 0);
  printf("/n");
  switch (ethernet_type)
    {
    case 0x0800://上层是IP协议
      printf ("the network layer is IP protocol/n");
      ip_protocol_callback (argument, packet_header, packet_content);//调用分析ip协议函数
      break;
    case 0x0806://上层是ARP协议
      printf ("the network layer is ARP protocol/n");
      arp_protocol_callback (argument, packet_header, packet_content);//调用分析ARP协议函数
      break;
    case 0x8035://上层是RARP协议
      printf ("the network layer is RARP protocol/n");
      break;
    default:
      break;
    }
  printf
    ("-------------------------------------------------------------------------------/n");
}

int
main (char *argv, char *argc[])
{
  char *dev;//网络接口
  char errbuf[PCAP_ERRBUF_SIZE];
  u_int32_t net_ip;
  u_int32_t net_mask;
  char bpf_filter_string[] = "";//过滤规则字符串
  pcap_t *packet_handle;//libpcap句柄
  struct bpf_program bpf_filter;//BPF过滤规则
  dev = pcap_lookupdev (errbuf);//获得网络接口
  if (dev == NULL)
    exit (1);
  int ret = pcap_lookupnet (dev, &net_ip, &net_mask, errbuf);//获得网络地址和网络掩码
  if (ret == -1)
    exit (1);
  packet_handle = pcap_open_live (dev, 1000, 1, 0, errbuf);//打开网络接口
  pcap_compile (packet_handle, &bpf_filter, bpf_filter_string, 0, net_ip);//编译过滤规则
  pcap_setfilter (packet_handle, &bpf_filter);//设置过滤规则
  if (pcap_datalink (packet_handle) != DLT_EN10MB)
    return;
  pcap_loop (packet_handle, -1, ether_protocol_callback, NULL);//进行抓包,然后用回掉函数进行数据包的分析
  pcap_close (packet_handle);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值