IP包解析

#include "pcap.h"
#include "stdio.h"

/*下边是以太网的协议格式 */
struct ethernet_header
 {
 
  u_int8_t ether_dhost[6];  /*目的以太地址*/
  u_int8_t ether_shost[6];  /*源以太网地址*/
  u_int16_t ether_type;  /*以太网类型*/
 };

/*ip地址格式*/
typedef u_int32_t in_addr_t;
//struct in_addr
//{
// in_addr_t s_addr;
//};
struct ip_header
 {
 #ifdef WORKS_BIGENDIAN
  u_int8_t ip_version:4,  /*version:4*/
       ip_header_length:4; /*IP协议首部长度*/
 #else
 u_int8_t ip_header_length:4,
       ip_version:4;
 #endif
 u_int8_t ip_tos;   /*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_source_address; /*源IP*/
        struct in_addr  ip_destination_address; /*目的IP*/
 };

/*关于tcp头部的定义*/
struct tcp_header
 {
  u_int16_t tcp_source_port;
 
  u_int16_t tcp_destination_port;
 
  u_int32_t tcp_acknowledgement;
 
  u_int32_t tcp_ack;
 #ifdef WORDS_BIGENDIAN
  u_int8_t tcp_offset:4 ,
     tcp_reserved:4;
 #else
  u_int8_t tcp_reserved:4,
     tcp_offset:4;
 #endif
  u_int8_t tcp_flags;
 
  u_int16_t tcp_windows;
 
  u_int16_t tcp_checksum;
 
  u_int16_t tcp_urgent_pointer;
};

/*下边实现tcp数据包分析的函数定义tcp_protocol_packet_callback*/
void tcp_protocol_packet_callback(u_char *argument,const struct pcap_pkthdr*
packet_header,const u_char* packet_content)
{
 struct tcp_header *tcp_protocol ;     /*tcp协议变量*/
 u_char flags;    /*标记*/
 int header_length;   /*头长度*/
 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);  /*获得tcp首部内容*/
 source_port =ntohs(tcp_protocol->tcp_source_port); /*获得源端口号*/
 destination_port =ntohs(tcp_protocol->tcp_destination_port); /*获得目的端口号*/
 header_length =tcp_protocol->tcp_offset *4;   /*获得首部长度*/
 sequence =ntohl(tcp_protocol->tcp_acknowledgement);     
  /*获得序列号*/
 acknowledgement =ntohl(tcp_protocol->tcp_ack);
 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 (Transprot Layer )***************\n");
 printf("Source Port %d\n",source_port);
 printf("Destination Port %d\n",destination_port);
 
    switch (destination_port)
   {
  case 80:printf("Protocol is http ");break;
 
  case 21:printf("Protocol is ftp");break;
 
  case 23:printf("Protocol is telnet ");break;
 
  case 25:printf("Protocol is smtp");break;
 
  case 110:printf("Protocol is pop3");break;
  default :break;
   }
 

 printf("Sequence Number %u \n",sequence);
 printf("Acknowledgement Number %u \n",acknowledgement);
 printf("Header Length %d \n",header_length);
 printf("Reserved  %d \n",tcp_protocol->tcp_reserved);
 printf("Flags:");
 if (flags & 0x08)  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("Windows Size :%d \n",windows);
 printf("Checksum :%d\n",checksum);
 printf("Urgent pointer :%d\n",urgent_pointer);
}

/*下边实现IP数据包分析的函数定义ip_protocol_packet_callback*/
void ip_protocol_packet_callback(u_char *argument,const struct pcap_pkthdr*
packet_header,const u_char* packet_content)
 {
  struct ip_header *ip_protocol;   /*ip协议变量*/
  u_int  header_length;    /*长度*/
  u_int  offset;     /*偏移*/
  u_char  tos;     /*服务质量*/
  u_int16_t checksum;    /*校验和*/
  ip_protocol=(struct ip_header*) (packet_content+14);
       /*获得ip数据包的内容去掉以太头部*/
 
  checksum=ntohs(ip_protocol->ip_checksum);  /*获得校验和*/
  header_length=ip_protocol->ip_header_length*4; /*获得长度*/
  tos=ip_protocol->ip_tos;    /*获得tos*/
  offset=ntohs(ip_protocol->ip_off);   /*获得偏移量*/
 printf("***************IP Protocol network layer***************\n \n");
 printf("IP Version :%d\n",ip_protocol->ip_version);
 printf("Header length :%d\n",header_length);
 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);     /*获得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_source_address));          /*
获得源ip地址*/
 printf("Destinastion address :%s\n",inet_ntoa(ip_protocol->ip_destination_address));
/*获得目的ip地址*/
 switch(ip_protocol->ip_protocol)
 {
   case 6 :printf("The Transport Layer Protocol is TCP#####################################\n");
        tcp_protocol_packet_callback(argument,packet_header,packet_content);
       
     break; /*协议类型是6代表TCP*/
   case 17:printf("The Transport Layer Protocol is  UDP\n");break;/*17代表UDP*/
    case 1:printf("The Transport Layer Protocol is ICMP\n");break;/*代表ICMP*/
   case 2:printf("The Transport Layer Protocol is IGMP\n");break;/*代表IGMP*/
  default :break;
 }

 }

/*下边实现以太网帧分析的函数定义ethernet_protocol_packet_callback*/
void ethernet_protocol_packet_callback(u_char *argument,const struct pcap_pkthdr *packet_header,const u_char* packet_content)
 {
 u_short ethernet_type;     /*以太网协议类型*/
 struct ethernet_header *ethernet_protocol;  /*以太网协议变量*/
 u_char *mac_string;
 static int packet_number=1;
 
 printf("*******************************************************************************\n");
 printf("The %d ip packet is captured,\n",packet_number);
 printf("**********ethernet protocol (link Layer)*******************\n");
 ethernet_protocol =(struct ethernet_header *) packet_content;  /*获得一太网协议数据内容*/
 printf("Ethernet type is :\n");
 ethernet_type=ntohs(ethernet_protocol->ether_type);
       /*获得以太网类型*/
  printf("%04x\n",ethernet_type);
  switch(ethernet_type)            /*判断以太网类型的值*/
      {
  case 0x0800 :  printf("The network layer is ip protocol\n");break;
        case 0x0806 :  printf("The network layer is ARP protocol\n");break;
  case 0x8035 :  printf("The network layer is RARP protocol\n");break;
  default: break;
      }
printf("Mac souce address is :\n");
mac_string=ethernet_protocol->ether_shost;
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));

/*获得以太网地址*/
 
printf("Mac Destination Address is :\n");
mac_string=ethernet_protocol->ether_dhost;
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));
 
/*获得目的端口地址*/
 
  switch (ethernet_type)
 {case 0x0800:   ip_protocol_packet_callback(argument,packet_header,packet_content);break;
  /*如果上层是ip协议,就调用分析ip协议的函数对ip包进行贩治*/
  default :break;
        }
 
  packet_number++;
}
 
main()
{
  pcap_if_t  *alldevs;
  pcap_if_t *d;
  int inum=0;
  int i=0;
  pcap_t *adhandle;
  char errbuf[PCAP_ERRBUF_SIZE];
 
  /* 获得网卡的列表 */
  if (pcap_findalldevs(&alldevs, errbuf) == -1)
  {
    fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);
    exit(1);
  }
 
  /* 打印网卡信息 */
  for(d=alldevs; d; d=d->next)
  {
    printf("%d. %s", ++i, d->name);
    if (d->description)
        printf(" (%s)\n", d->description);
    else
        printf(" (No description available)\n");
  }
 
  if(i==0)
  {
    printf("\nNo interfaces found! Make sure LibPcap is installed.\n");
    return -1;
  }
 
  printf("Enter the interface number (1-%d):",i);
  scanf("%d", &inum);               //输入要选择打开的网卡号
 
  if(inum < 1 || inum > i) //判断号的合法性
  {
    printf("\nInterface number out of range.\n");
    /* Free the device list */
    pcap_freealldevs(alldevs);
    return -1;
  }
 
  /* 找到要选择的网卡结构 */
  for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++);
 
  /* 打开选择的网卡 */
  if ( (adhandle= pcap_open_live(d->name, /* 设备名称*/
                  65536,   /* portion of the packet to capture.*/
                  /* 65536 grants that the whole packet will be captured on allthe MACs.*/
                  1,       /* 混杂模式*/
                  1000,     /* 读超时为1秒*/
                  errbuf   /* error buffer*/
                  ) ) == NULL)
  {
    fprintf(stderr,"\nUnable to open the adapter. %s is not supported by LibPcap\n");
    /* Free the device list */
    pcap_freealldevs(alldevs);
    return -1;
  }
 
  printf("\nlistening on %s...\n", d->description);
 
  /* At this point, we don't need any more the device list. Free it */
  pcap_freealldevs(alldevs);
 
  /* 开始捕获包 */
  pcap_loop(adhandle, 0, ethernet_protocol_packet_callback, NULL);
 
  return 0;
}
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值