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

  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 1

171     for (i = 0; i < pkthdr->len; i++)

172     {

173         if (isprint(packet[i]))

174         {

175             printf("%02d ", packet[i]);

176         }

177         else

178         {

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 #endif

189 

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 0

typedef 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;



#endif





typedef 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

 

你可能感兴趣的:(ipv4)