libpcap报文解析: ipv4、ipv6 @ 2014.7.2

  1 #include <string.h>

  2 #include <stdlib.h>

  3 #include <pcap.h>

  4 #include <stdio.h>

  5 #include <sys/time.h>

  6 #include <unistd.h>

  7 #include <netinet/in.h>

  8 #include <pthread.h>

  9 #include "packet_header.h"

 10 #include <iostream>

 11 #include <string>

 12 using namespace std;

 13 

 14 #define MAXBYTE2CAPTURE 2048

 15 

 16 pthread_t g_thread[2];

 17 pthread_mutex_t g_mutex;

 18 

 19 int isprint(char c)

 20 {

 21     return 0;

 22 }

 23 

 24 void print_buf(u_char* pBuf, u_int32 len)

 25 {

 26     if (!pBuf)

 27     {

 28         return;

 29     }

 30 

 31     for(int i=0; i<len; i++)

 32     {

 33         printf("%02x ",  (u_char*)pBuf[i]);

 34 

 35         if ((i%16 == 0 && i!=0) || i == len-1)

 36         {

 37             printf("\r\n");

 38         }

 39     }

 40 }

 41 

 42 void parse_ethII(u_char* pData, u_int32 len)

 43 {

 44     if (!pData || len <14)

 45     {

 46         return;

 47     }

 48 

 49     printf("eth II frame: \r\n");

 50     print_buf(pData, 14);

 51 

 52     /* parse src mac and dst mac */

 53     EthHeader_t* pEth = (EthHeader_t*)pData;

 54     printf("destination: %02x:%02x:%02x:%02x:%02x:%02x ",

 55         pEth->dest_hwaddr[0],

 56         pEth->dest_hwaddr[1],

 57         pEth->dest_hwaddr[2],

 58         pEth->dest_hwaddr[3],

 59         pEth->dest_hwaddr[4],

 60         pEth->dest_hwaddr[5]);

 61 

 62     printf("source : %02x:%02x:%02x:%02x:%02x:%02x",

 63         pEth->source_hwaddr[0],

 64         pEth->source_hwaddr[1],

 65         pEth->source_hwaddr[2],

 66         pEth->source_hwaddr[3],

 67         pEth->source_hwaddr[4],

 68         pEth->source_hwaddr[5]);

 69 

 70     /* parse frame type */

 71     printf("\r\nframe type: 0x%x\r\n", ntohs(pEth->frame_type));

 72 }

 73 

 74 

 75 void parse_ipheader(u_char* pData, u_int32 len)

 76 {

 77     if (!pData || len <14)

 78     {

 79         return;

 80     }

 81 

 82     printf("ip header: \r\n");

 83     print_buf(pData, 20);

 84 

 85     /* parse ip header */

 86     IPHeader_t* pIpHeader = (IPHeader_t*)pData;

 87     printf("\tversion     : %02x\r\n"

 88            "\ttos         : %02x\r\n"

 89            "\ttotal length: %d(0x%02x)\r\n"

 90            "\tid          : %d(0x%02x)\r\n"

 91            "\tsegment flag: %d(0x%02x)\r\n"

 92            "\tttl         : %02x\r\n"

 93            "\tprotocol    : %02x\r\n"

 94            "\tchecksum    : %d(0x%02x)\r\n"

 95            "\tsrc ip      : %d.%d.%d.%d\r\n"

 96            "\tdst ip      : %d.%d.%d.%d\r\n",

 97         pIpHeader->Ver_HLen,

 98         pIpHeader->TOS,

 99         ntohs(pIpHeader->TotalLen), ntohs(pIpHeader->TotalLen),

100         ntohs(pIpHeader->ID), ntohs(pIpHeader->ID),

101         ntohs(pIpHeader->Flag_Segment), ntohs(pIpHeader->Flag_Segment),

102         pIpHeader->TTL,

103         pIpHeader->Protocol,

104         ntohs(pIpHeader->Checksum), ntohs(pIpHeader->Checksum),

105         pIpHeader->SrcIP[0],pIpHeader->SrcIP[1],pIpHeader->SrcIP[2],pIpHeader->SrcIP[3],

106         pIpHeader->DstIP[0],pIpHeader->DstIP[1],pIpHeader->DstIP[2],pIpHeader->DstIP[3]);

107 }

108 

109 void parse_ip6header(u_char* pData, u_int32 len)

110 {

111     if (!pData || len <14)

112     {

113         return;

114     }

115 

116     printf("ipv6 header: \r\n");

117     print_buf(pData, 40);

118 

119     /* parse ipv6 header */

120     IPv6Header_t* pIpv6Header = (IPv6Header_t*)pData;

121     printf("\tversion           : %x\r\n"

122            "\ttraffic class     : %x\r\n"

123            "\tflow label        : %x\r\n"

124            "\tpayload length    : %x\r\n"

125            "\tnext header       : %x\r\n"

126            "\thop limit         : %x\r\n"

127            "\tsource            : %x\r\n"

128            "\tdestination       : %x\r\n",

129            pIpv6Header->ip6_ctlun.ip6_un2_vfc,

130            pIpv6Header->ip6_ctlun.ip6_unl.ip6_unl_flow,

131            pIpv6Header->ip6_ctlun.ip6_unl.ip6_unl_flow,

132            pIpv6Header->ip6_ctlun.ip6_unl.ip6_unl_plen,

133            pIpv6Header->ip6_ctlun.ip6_unl.ip6_unl_nxt,

134            pIpv6Header->ip6_ctlun.ip6_unl.ip6_unl_hlim,

135            pIpv6Header->ip6_src,

136            pIpv6Header->ip6_dst);

137 }

138 

139 

140 void parse_packet(const u_char* packet, u_int32 len)

141 {

142     u_short ftype = 0;

143 

144     if (!packet)

145     {

146         return ;

147     }

148 

149     u_char* pMbuf = (u_char*)packet;

150     parse_ethII(pMbuf, len);

151 

152     ftype = ntohs(((EthHeader_t*)pMbuf)->frame_type);

153     switch(ftype)

154     {

155         case 0x0800:  /* ipv4 */

156             pMbuf = (u_char*)packet + 14;

157             parse_ipheader(pMbuf, len-14);

158             break;

159         case 0x86dd: /* ipv6 */

160             pMbuf = (u_char*)packet + 14;

161             parse_ip6header(pMbuf, len-14);

162             break;

163         default:

164             printf("frame type : 0x%x\r\n", ftype);

165             break;

166     }

167 

168     printf("\r\n");

169 }

170 

171 void processPacket(u_char *arg, const struct pcap_pkthdr *pkthdr, const u_char *packet)

172 {

173     int i = 0, *counter = (int *)arg;

174 

175     printf("--------------------------------------------\r\n");

176     printf("Packet Count: %d\n", ++(*counter));

177     printf("Received Packet Size: %d\n", pkthdr->len);

178     printf("Payload:\n");

179 

180 #if 1

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

182     {

183         if (isprint(packet[i]))

184         {

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

186         }

187         else

188         {

189             printf("%02x ", packet[i]);

190         }

191 

192         if ((i % 16 == 0 && i != 0) || i == pkthdr->len-1)

193         {

194             printf("\n");

195         }

196 

197     }

198 #endif

199 

200     parse_packet(packet, pkthdr->len);

201 

202     return;

203 }

204 

205 

206 void* thread_recv_pkt(void *)

207 {

208     while(1)

209     {

210         cout << "recv pkt: " << endl;

211         sleep(1);

212     }

213 }

214 

215 void* thread_send_pkt(void *)

216 {

217     while (1)

218     {

219         cout << "send pkt: " << endl;

220         sleep(1);

221     }

222 }

223 

224 int create_pkt_process_task()

225 {

226     int ret = 0;

227 

228     memset(&g_thread, 0, sizeof(g_thread));

229 

230     ret = pthread_create(&g_thread[0], NULL, thread_send_pkt, NULL);

231     if (0 == ret)

232     {

233         cout << "packet send thread create successfully." << endl;

234     }

235     else

236     {

237         cout << "packet send thread create failed." << endl;

238     }

239 

240     ret = pthread_create(&g_thread[1], NULL, thread_recv_pkt, NULL);

241     if (0 == ret)

242     {

243         cout << "packet send thread create successfully." << endl;

244     }

245     else

246     {

247         cout << "packet send thread create failed." << endl;

248     }

249 

250     return 0;

251 }

252 

253 void pkt_process_task_wait()

254 {

255     if(g_thread[0] !=0)

256     {                   //comment4

257        pthread_join(g_thread[0],NULL);

258        printf("线程1 已经结束\n");

259     }

260 

261     if(g_thread[1] !=0)

262     {                //comment5

263         pthread_join(g_thread[1],NULL);

264         printf("线程2 已经结束\n");

265     }

266 }

267 

268 int main()

269 {

270 

271     int i = 0, count = 0;

272     pcap_t *descr = NULL;

273     char errbuf[PCAP_ERRBUF_SIZE], *device = NULL;

274 

275     memset(errbuf, 0, PCAP_ERRBUF_SIZE);

276 

277     create_pkt_process_task();

278     pkt_process_task_wait();

279 

280     /* Get the name of the first device suitable for capture */

281     device = pcap_lookupdev(errbuf);

282     if (!device)

283     {

284         printf("Open device failed.");

285         return -1;

286     }

287 

288     printf("Opening device %s\n", device);

289 

290     /* Open device in promiscuous mode */

291     descr = pcap_open_live(device, MAXBYTE2CAPTURE, 1, 512, errbuf);

292 

293     /* Loop forever & call processPacket() for every received packet */

294     pcap_loop(descr, -1, processPacket, (u_char *)&count);

295 

296     return 0;

297 }

 

你可能感兴趣的:(ipv4)