libpcap报文解析: ipv4、ipv6(待优化)

来源:互联网 发布:机房网络维护 编辑:程序博客网 时间:2024/06/05 05:18
  1 #include <string.h>  2 #include <stdlib.h>  3 #include <pcap.h>  4 #include <netinet/in.h>  5 #include "packet_header.h"  6   7 #define MAXBYTE2CAPTURE 2048  8   9 int isprint(char c) 10 { 11     return 0; 12 } 13  14 void print_buf(u_char* pBuf, u_int32 len) 15 { 16     if (!pBuf) 17     { 18         return; 19     } 20  21     for(int i=0; i<len; i++) 22     { 23         printf("%02x ",  (u_char*)pBuf[i]); 24  25         if ((i%16 == 0 && i!=0) || i == len-1) 26         { 27             printf("\r\n"); 28         } 29     } 30 } 31  32 void parse_ethII(u_char* pData, u_int32 len) 33 { 34     if (!pData || len <14) 35     { 36         return; 37     } 38  39     printf("eth II frame: \r\n"); 40     print_buf(pData, 14); 41  42     /* parse src mac and dst mac */ 43     EthHeader_t* pEth = (EthHeader_t*)pData; 44     printf("destination: %02x:%02x:%02x:%02x:%02x:%02x ", 45         pEth->dest_hwaddr[0], 46         pEth->dest_hwaddr[1], 47         pEth->dest_hwaddr[2], 48         pEth->dest_hwaddr[3], 49         pEth->dest_hwaddr[4], 50         pEth->dest_hwaddr[5]); 51  52     printf("source : %02x:%02x:%02x:%02x:%02x:%02x", 53         pEth->source_hwaddr[0], 54         pEth->source_hwaddr[1], 55         pEth->source_hwaddr[2], 56         pEth->source_hwaddr[3], 57         pEth->source_hwaddr[4], 58         pEth->source_hwaddr[5]); 59  60     /* parse frame type */ 61     printf("\r\nframe type: 0x%x\r\n", ntohs(pEth->frame_type)); 62 } 63  64  65 void parse_ipheader(u_char* pData, u_int32 len) 66 { 67     if (!pData || len <14) 68     { 69         return; 70     } 71  72     printf("ip header: \r\n"); 73     print_buf(pData, 20); 74  75     /* parse ip header */ 76     IPHeader_t* pIpHeader = (IPHeader_t*)pData; 77     printf("\tversion     : %02x\r\n" 78            "\ttos         : %02x\r\n" 79            "\ttotal length: %d(0x%02x)\r\n" 80            "\tid          : %d(0x%02x)\r\n" 81            "\tsegment flag: %d(0x%02x)\r\n" 82            "\tttl         : %02x\r\n" 83            "\tprotocol    : %02x\r\n" 84            "\tchecksum    : %d(0x%02x)\r\n" 85            "\tsrc ip      : %d.%d.%d.%d\r\n" 86            "\tdst ip      : %d.%d.%d.%d\r\n", 87         pIpHeader->Ver_HLen, 88         pIpHeader->TOS, 89         ntohs(pIpHeader->TotalLen), ntohs(pIpHeader->TotalLen), 90         ntohs(pIpHeader->ID), ntohs(pIpHeader->ID), 91         ntohs(pIpHeader->Flag_Segment), ntohs(pIpHeader->Flag_Segment), 92         pIpHeader->TTL, 93         pIpHeader->Protocol, 94         ntohs(pIpHeader->Checksum), ntohs(pIpHeader->Checksum), 95         pIpHeader->SrcIP[0],pIpHeader->SrcIP[1],pIpHeader->SrcIP[2],pIpHeader->SrcIP[3], 96         pIpHeader->DstIP[0],pIpHeader->DstIP[1],pIpHeader->DstIP[2],pIpHeader->DstIP[3]); 97 } 98  99 void parse_ip6header(u_char* pData, u_int32 len)100 {101     if (!pData || len <14)102     {103         return;104     }105 106     printf("ipv6 header: \r\n");107     print_buf(pData, 40);108 109     /* parse ipv6 header */110     IPv6Header_t* pIpv6Header = (IPv6Header_t*)pData;111     printf("\tversion           : %x\r\n"112            "\ttraffic class     : %x\r\n"113            "\tflow label        : %x\r\n"114            "\tpayload length    : %x\r\n"115            "\tnext header       : %x\r\n"116            "\thop limit         : %x\r\n"117            "\tsource            : %x\r\n"118            "\tdestination       : %x\r\n",119            pIpv6Header->ip6_ctlun.ip6_un2_vfc,120            pIpv6Header->ip6_ctlun.ip6_unl.ip6_unl_flow,121            pIpv6Header->ip6_ctlun.ip6_unl.ip6_unl_flow,122            pIpv6Header->ip6_ctlun.ip6_unl.ip6_unl_plen,123            pIpv6Header->ip6_ctlun.ip6_unl.ip6_unl_nxt,124            pIpv6Header->ip6_ctlun.ip6_unl.ip6_unl_hlim,125            pIpv6Header->ip6_src,126            pIpv6Header->ip6_dst);127 }128 129 130 void parse_packet(const u_char* packet, u_int32 len)131 {132     u_short ftype = 0;133 134     if (!packet)135     {136         return ;137     }138 139     u_char* pMbuf = (u_char*)packet;140     parse_ethII(pMbuf, len);141 142     ftype = ntohs(((EthHeader_t*)pMbuf)->frame_type);143     switch(ftype)144     {145         case 0x0800:  /* ipv4 */146             pMbuf = (u_char*)packet + 14;147             parse_ipheader(pMbuf, len-14);148             break;149         case 0x86dd: /* ipv6 */150             pMbuf = (u_char*)packet + 14;151             parse_ip6header(pMbuf, len-14);152             break;153         default:154             printf("frame type : 0x%x\r\n", ftype);155             break;156     }157 158     printf("\r\n");159 }160 161 void processPacket(u_char *arg, const struct pcap_pkthdr *pkthdr, const u_char *packet)162 {163     int i = 0, *counter = (int *)arg;164 165     printf("--------------------------------------------\r\n");166     printf("Packet Count: %d\n", ++(*counter));167     printf("Received Packet Size: %d\n", pkthdr->len);168     printf("Payload:\n");169 170 #if 1171     for (i = 0; i < pkthdr->len; i++)172     {173         if (isprint(packet[i]))174         {175             printf("%02d ", packet[i]);176         }177         else178         {179             printf("%02x ", packet[i]);180         }181 182         if ((i % 16 == 0 && i != 0) || i == pkthdr->len-1)183         {184             printf("\n");185         }186 187     }188 #endif189 190     parse_packet(packet, pkthdr->len);191 192     return;193 }194 195 int main()196 {197 198     int i = 0, count = 0;199     pcap_t *descr = NULL;200     char errbuf[PCAP_ERRBUF_SIZE], *device = NULL;201     memset(errbuf, 0, PCAP_ERRBUF_SIZE);202 203     /* Get the name of the first device suitable for capture */204     device = pcap_lookupdev(errbuf);205     if (!device)206     {207         printf("Open device failed.");208         return -1;209     }210 211     printf("Opening device %s\n", device);212 213     /* Open device in promiscuous mode */214     descr = pcap_open_live(device, MAXBYTE2CAPTURE, 1, 512, errbuf);215 216     /* Loop forever & call processPacket() for every received packet */217     pcap_loop(descr, -1, processPacket, (u_char *)&count);218 219     return 0;
220 }
#ifndef PACKET_HEADER_H#define PACKET_HEADER_H#ifndef u_char#define u_char unsigned char#endif#ifndef u_int8#define u_int8 unsigned char#endif#ifndef u_int16#define u_int16 unsigned short#endif#ifndef u_int32#define u_int32 unsigned int#endif#ifndef u_int64#define u_int64 unsigned long long#endif#ifndef u_short#define u_short unsigned short#endif/* 以太帧头 */typedef struct tagEthHeader_t{    //Pcap捕获的数据帧头    u_int8 dest_hwaddr[6];   //目的MAC地址    u_int8 source_hwaddr[6]; //源MAC地址    u_short frame_type;      //帧类型}EthHeader_t;//IP数据报头typedef struct tagIPHeader_t{    //IP数据报头    u_int8  Ver_HLen; //版本+报头长度    u_int8  TOS;      //服务类型    u_int16 TotalLen;//总长度    u_int16 ID;      //标识    u_int16 Flag_Segment; //标志+片偏移    u_int8  TTL;      //生存周期    u_int8  Protocol; //协议类型    u_int16 Checksum;//头部校验和    u_int8 SrcIP[4];   //源IP地址    u_int8 DstIP[4];   //目的IP地址} IPHeader_t;//IPv6基本首部#if 0typedef struct tagIPv6Header_t{    u_char    version:4;      // 4-bit版本号    u_char  traffic_class:8;  // 8-bit流量等级    u_int32 label:20;       // 20-bit流标签    u_short    payload_len;    // 16-bit 载荷长度    u_char    next_header;    // 8-bit 下一首部    u_char    hop_limit;        // 8-bit 跳数限制    struct    {        u_int64 prefix_subnetid;        u_char interface_id[8];    } src_ip;                // 128-bit 源地址    struct    {        u_int64 prefix_subnetid;        u_char interface_id[8];    } dst_ip;                // 128-bit 目的地址} IPv6Header_t;typedef struct in6_addr {  union {    u_char  Byte[16];    u_short Word[8];  } u;} IN6_ADDR, *PIN6_ADDR, FAR *LPIN6_ADDR;#endiftypedef struct tagIPv6Header_t{    union    {        struct ip6_hdrctl        {            u_int32_t ip6_unl_flow;/* 4位的版本,8位的传输与分类,20位的流标识符 */            u_int16_t ip6_unl_plen;/* 报头长度 */            u_int8_t ip6_unl_nxt;  /* 下一个报头 */            u_int8_t ip6_unl_hlim; /* 跨度限制 */        }ip6_unl ;        u_int8_t ip6_un2_vfc;/* 4位的版本号,跨度为4位的传输分类 */    }ip6_ctlun ;#define ip6_vfc              ip6_ctlun.ip6_un2_vfc#define ip6_flow             ip6_ctlun.ip6_unl.ip6_unl_flow#define ip6_plen             ip6_ctlun.ip6_unl.ip6_unl_plen#define ip6_nxt              ip6_ctlun.ip6_unl.ip6_unl_nxt#define ip6_hlim             ip6_ctlun.ip6_unl.ip6_unl_hlim#define ip6_hops             ip6_ctlun.ip6_unl.ip6_unl_hops    struct in6_addr ip6_src;/* 发送端地址 */    struct in6_addr ip6_dst;/* 接收端地址 */}IPv6Header_t;//TCP数据报头typedef struct tagTCPHeader_t{    //TCP数据报头    u_int16 SrcPort; //源端口    u_int16 DstPort; //目的端口    u_int32 SeqNO;   //序号    u_int32 AckNO;   //确认号} TCPHeader_t;#endif

 

0 0
原创粉丝点击