[关闭]
@xunuo 2017-07-21T17:03:27.000000Z 字数 15270 阅读 1427

DNS数据包分析


网络数据包分析


基础知识点链接

dns的实现是在端口号=53的基础上的;然后就可以设定过滤条件为"port 53";只抓端口号为53的数据包;

  1. #include "pcap.h"
  2. #include<cstdlib>
  3. #include<vector>
  4. #include<string>
  5. using namespace std;
  6. /*ip地址*/
  7. typedef struct ip_address
  8. {
  9. u_char byte1;
  10. u_char byte2;
  11. u_char byte3;
  12. u_char byte4;
  13. } ip_address;
  14. /*以太网协议头*/
  15. struct ether_header
  16. {
  17. u_int8_t ether_dhost[6]; //目的Mac地址
  18. u_int8_t ether_shost[6]; //源Mac地址
  19. u_int16_t ether_type; //协议类型
  20. };
  21. /*IPv4协议头*/
  22. struct ip_header
  23. {
  24. #if defined(WORDS_BIENDIAN)
  25. u_int8_t ip_version : 4, ip_header_length : 4;
  26. #else
  27. u_int8_t ip_header_length : 4, ip_version : 4;
  28. #endif
  29. u_int8_t ip_tos;
  30. u_int16_t ip_length;
  31. u_int16_t ip_id;
  32. u_int16_t ip_off;
  33. u_int8_t ip_ttl;
  34. u_int8_t ip_protocol;
  35. u_int16_t ip_checksum;
  36. ip_address saddr; /*源地址(Source address)*/
  37. ip_address daddr; /*目的地址(Destination address)*/
  38. };
  39. /*UDP协议头*/
  40. struct udphdr
  41. {
  42. u_int16_t source_port; /*源地址端口*/
  43. u_int16_t dest_port; /*目的地址端口*/
  44. u_int16_t len; /*UDP长度*/
  45. u_int16_t check; /*UDP校验和*/
  46. };
  47. //TCP协议头
  48. #define __LITTLE_ENDIAN_BITFIELD
  49. struct tcphdr
  50. {
  51. u_int16_t source_port; /*源地址端口*/
  52. u_int16_t dest_port; /*目的地址端口*/
  53. u_int32_t seq; /*序列号*/
  54. u_int32_t ack_seq; /*确认序列号*/
  55. u_int8_t tcp_header_length : 4;
  56. #if defined(__LITTLE_ENDIAN_BITFIELD)
  57. u_int16_t res1 : 4, /*保留*/
  58. doff : 4, /*偏移*/
  59. fin : 1, /*关闭连接标志*/
  60. syn : 1, /*请求连接标志*/
  61. rst : 1, /*重置连接标志*/
  62. psh : 1, /*接收方尽快将数据放到应用层标志*/
  63. ack : 1, /*确认序号标志*/
  64. urg : 1, /*紧急指针标志*/
  65. ece : 1, /*拥塞标志位*/
  66. cwr : 1; /*拥塞标志位*/
  67. #elif defined(__BIG_ENDIAN_BITFIELD)
  68. u_int16_t doff : 4, /*偏移*/
  69. res1 : 4, /*保留*/
  70. cwr : 1, /*拥塞标志位*/
  71. ece : 1, /*拥塞标志位*/
  72. urg : 1, /*紧急指针标志*/
  73. ack : 1, /*确认序号标志*/
  74. psh : 1, /*接收方尽快将数据放到应用层标志*/
  75. rst : 1, /*重置连接标志*/
  76. syn : 1, /*请求连接标志*/
  77. fin : 1; /*关闭连接标志*/
  78. #else
  79. u_int16_t flag;
  80. #endif
  81. u_int16_t window; /*滑动窗口大小*/
  82. u_int16_t check; /*校验和*/
  83. u_int16_t urg_ptr; /*紧急字段指针*/
  84. };
  85. struct queries
  86. {
  87. u_int16_t type;//类型;
  88. u_int16_t clas;//采用的方法;
  89. };
  90. struct answers
  91. {
  92. u_int16_t nameoff;//有偏移域名所占的两个字节
  93. u_int16_t type;
  94. u_int16_t clas;
  95. u_int32_t time;//生存时间
  96. u_int16_t len;
  97. };
  98. struct authority
  99. {
  100. u_int16_t nameoff;
  101. u_int16_t type;
  102. u_int16_t clas;
  103. u_int32_t time;
  104. u_int16_t len;
  105. };
  106. /*DNS头*/
  107. struct dnshdr
  108. {
  109. u_int16_t tra_id;//事务ID;
  110. u_int16_t flag;//操作代码(0/1);
  111. u_int16_t qes;//问题计数;
  112. u_int16_t ansrrs;//回答RR数;
  113. u_int16_t au_rrs;//权威RR数;
  114. u_int16_t add_rrs;//附加RRs;
  115. };
  116. /*flag是位置,cnt是标签*/
  117. int p=0;
  118. void domainname(int &flag, int &cnt, int &j,const u_char* packet_content,char ansname[])
  119. {
  120. int num = packet_content[flag];
  121. while (num > 0)
  122. {
  123. if (packet_content[flag] == 0xc0)//有偏移;
  124. {
  125. flag += 1;
  126. int off = packet_content[flag];
  127. domainname(off, cnt, j, packet_content, ansname);
  128. if (p = 1)
  129. break;
  130. }
  131. else
  132. {
  133. for (int i = 1; i <= num; i++)
  134. {
  135. ansname[j] = packet_content[flag + i];
  136. j++;
  137. if (i == num&&packet_content[flag + num + 1] != 0)
  138. {
  139. ansname[j] = '.';
  140. j++;
  141. }
  142. }
  143. flag += num + 1;
  144. cnt++;
  145. num = packet_content[flag];
  146. }
  147. }
  148. if (num == 0)
  149. p = 1;
  150. }
  151. void sixtoten(int &flag,int &num,const u_char* packet_content)
  152. {
  153. int m = 16777216;//(m=16^6)
  154. for (int i = 0; i < 4; i++)
  155. {
  156. //printf("%02x %d\n", packet_content[flag + i], packet_content[flag + i]);
  157. int number = packet_content[flag + i];
  158. num += number*m;
  159. m /= 256;
  160. }
  161. flag += 4;
  162. }
  163. void dns_protool_packet_callback(u_char *argument, const struct pcap_pkthdr* packet_header, const u_char* packet_content)
  164. {
  165. struct dnshdr *dns_protocol;
  166. dns_protocol = (struct dnshdr *) packet_content;
  167. printf("---------DNS---------\n");
  168. if (ntohs(dns_protocol->flag) == 0x0100)
  169. printf("请求报文\n");
  170. else
  171. printf("应答报文\n");
  172. printf("DNS ID:%04x\n", ntohs(dns_protocol->tra_id));
  173. printf("操作代码:%04x\n", ntohs(dns_protocol->flag));
  174. printf("问题计数:%d\n", ntohs(dns_protocol->qes));
  175. printf("回答RR数:%d\n", ntohs(dns_protocol->ansrrs));
  176. printf("权威RR数:%d\n", ntohs(dns_protocol->au_rrs));
  177. printf("附加RR数:%d\n", ntohs(dns_protocol->add_rrs));
  178. struct queries *dns_que;
  179. const u_char* dns_packet_content;
  180. char name[200];
  181. memset(name, 0, sizeof(name));
  182. int quenum = ntohs(dns_protocol->qes);
  183. int flag = 12;
  184. /*---------Queries:------*/
  185. while (quenum--)
  186. {
  187. int cnt = 0, j = 0;
  188. printf("---------Queries:------\n");
  189. domainname(flag, cnt, j, packet_content,name);
  190. printf("域名(Name):%s\n", name);
  191. printf("域名长度(Name Length):%d\n", j);
  192. printf("标签长度(Label Count):%d\n", cnt);
  193. dns_packet_content = packet_content + 12 + 2 + j;
  194. dns_que = (struct queries *) dns_packet_content;
  195. printf("type:%04x\n", ntohs(dns_que->type));
  196. printf("Class:%04x\n", ntohs(dns_que->clas));
  197. flag += 4 + 1;
  198. }
  199. /*---------Answers:------*/
  200. int ansnum = ntohs(dns_protocol->ansrrs);
  201. if (ansnum > 0)
  202. {
  203. printf("---------Answers:------\n");
  204. int off1;
  205. while (ansnum--)
  206. {
  207. struct answers *dns_ans;
  208. const u_char* dns_ans_packet_content;
  209. dns_ans_packet_content = packet_content + flag;
  210. dns_ans = (struct answers *) dns_ans_packet_content;
  211. char ansname[200];
  212. memset(ansname, 0, sizeof(ansname));
  213. int cnt = 0;
  214. int j = 0;
  215. flag += 1;
  216. off1 = packet_content[flag];
  217. /*printf("off1:%02x\n", off1);*/
  218. domainname(off1, cnt, j, packet_content,ansname);
  219. /*printf("flag:%d\n", flag);*/
  220. printf("域名(Ansname):%s\n", ansname);
  221. printf("类型(Type):%04x\n", ntohs(dns_ans->type));
  222. printf("类(Class):%04x\n", ntohs(dns_ans->clas));
  223. printf("生存时间(Time to live):%08x\n", ntohs(dns_ans->time));
  224. flag += 10;
  225. printf("数据长度(Data length):%d\n",packet_content[flag]);
  226. if (packet_content[ flag] == 4)//Address
  227. {
  228. struct ip_address *dns_add;
  229. const u_char* dns_add_packet_content;
  230. flag += 1;
  231. dns_add_packet_content = packet_content + flag;
  232. dns_add = (struct ip_address *) dns_add_packet_content;
  233. printf("地址(Adress):%d.%d.%d.%d\n", dns_add->byte1, dns_add->byte2, dns_add->byte3, dns_add->byte4);
  234. flag += 4;
  235. printf("--------------------\n");
  236. }
  237. else//域名
  238. {
  239. char cname[200];
  240. memset(cname, 0, sizeof(cname));
  241. flag+=1;
  242. printf("flag and packet:%d %02x\n", flag, packet_content[flag]);
  243. int j = cnt = 0;
  244. domainname(flag, cnt, j, packet_content,cname);
  245. printf("域名(Cname):%s\n", cname);
  246. flag += 1;
  247. /*printf("flag::::%d\n", flag);*/
  248. printf("--------------------\n");
  249. }
  250. }
  251. }
  252. /*---------Authoritative nameservers:------*/
  253. int authonum = ntohs(dns_protocol->au_rrs);
  254. if (authonum > 0)
  255. {
  256. printf("---------Authoritative nameservers:------\n");
  257. int off1;
  258. while (authonum--)
  259. {
  260. struct authority *dns_aut;
  261. const u_char* dns_aut_packet_content;
  262. dns_aut_packet_content = packet_content + flag;
  263. dns_aut = (struct authority *) dns_aut_packet_content;
  264. char autname[200];
  265. memset(autname, 0, sizeof(autname));
  266. int cnt = 0;
  267. int j = 0;
  268. flag += 1;
  269. off1 = packet_content[flag];
  270. /*printf("off1:%02x\n", off1);*/
  271. if (off1 == 0)
  272. {
  273. autname[0] = '<';
  274. autname[1] = 'R';
  275. autname[2] = 'o';
  276. autname[3] = 'o';
  277. autname[4] = 't';
  278. autname[5] = '>';
  279. flag += 1;
  280. }
  281. else
  282. domainname(off1, cnt, j, packet_content, autname);
  283. /*printf("flag:%d\n", flag);*/
  284. printf("域名(Ansname):%s\n", autname);
  285. printf("类型(Type):%04x\n", ntohs(dns_aut->type));
  286. printf("类(Class):%04x\n", ntohs(dns_aut->clas));
  287. printf("生存时间(Time to live):%08x\n", ntohs(dns_aut->time));
  288. flag += 10;
  289. /*printf("flag:%d\n", flag);*/
  290. printf("数据长度(Data length):%d\n", packet_content[flag]);
  291. if (packet_content[flag] == 4)//Address
  292. {
  293. struct ip_address *dns_add;
  294. const u_char* dns_add_packet_content;
  295. flag += 1;
  296. dns_add_packet_content = packet_content + flag;
  297. dns_add = (struct ip_address *) dns_add_packet_content;
  298. printf("地址(Adress):%d.%d.%d.%d\n", dns_add->byte1, dns_add->byte2, dns_add->byte3, dns_add->byte4);
  299. flag += 4;
  300. //printf("--------------------\n");
  301. }
  302. else//域名
  303. {
  304. char cname[200];
  305. memset(cname, 0, sizeof(cname));
  306. flag += 1;
  307. /*printf("flag and packet:%d %02x\n", flag, packet_content[flag]);*/
  308. int j = cnt = 0;
  309. domainname(flag, cnt, j, packet_content, cname);
  310. printf("Primary name server:%s\n", cname);
  311. flag += 1;
  312. /*printf("flag:%d\n", flag);*/
  313. //printf("--------------------\n");
  314. }
  315. char mail[200];
  316. memset(mail, 0, sizeof(mail));
  317. printf("flag and packet:%d %02x\n", flag, packet_content[flag]);
  318. j = cnt = 0;
  319. domainname(flag, cnt, j, packet_content, mail);
  320. printf("Responsible authority's mailbox:%s\n", mail);
  321. flag += 1;
  322. printf("flag:%d\n", flag);
  323. int serialnum = 0;
  324. sixtoten(flag, serialnum, packet_content);
  325. printf("Seral Number:%d\n", serialnum);
  326. int refreshint = 0;
  327. sixtoten(flag, refreshint, packet_content);
  328. printf("Refresh Interval:%d\n", refreshint);
  329. int retyinterval = 0;
  330. sixtoten(flag, retyinterval, packet_content);
  331. printf("Retry Interval:%d\n", retyinterval);
  332. int expirelimit = 0;
  333. sixtoten(flag, expirelimit, packet_content);
  334. printf("Expire limit:%d\n", expirelimit);
  335. int mimimunttl = 0;
  336. sixtoten(flag, mimimunttl, packet_content);
  337. printf("Mininum TTL:%d\n", mimimunttl);
  338. }
  339. }
  340. /*---------Additional records------*/
  341. int addnum = ntohs(dns_protocol->add_rrs);
  342. if (addnum > 0)
  343. {
  344. printf("---------Additional records:------\n");
  345. int off1;
  346. while (addnum--)
  347. {
  348. struct authority *dns_add;
  349. const u_char* dns_add_packet_content;
  350. /*printf("flag:%d\n", flag);*/
  351. dns_add_packet_content = packet_content + flag;
  352. dns_add = (struct authority *) dns_add_packet_content;
  353. char autname[200];
  354. memset(autname, 0, sizeof(autname));
  355. int cnt = 0;
  356. int j = 0;
  357. flag += 1;
  358. off1 = packet_content[flag];
  359. /*printf("off1:%02x\n", off1);*/
  360. domainname(off1, cnt, j, packet_content, autname);
  361. /*printf("flag:%d\n", flag);*/
  362. printf("域名(Ansname):%s\n", autname);
  363. printf("类型(Type):%04x\n", ntohs(dns_add->type));
  364. printf("类(Class):%04x\n", ntohs(dns_add->clas));
  365. printf("生存时间(Time to live):%08x\n", ntohs(dns_add->time));
  366. flag += 10;
  367. printf("数据长度(Data length):%d\n", packet_content[flag]);
  368. if (packet_content[flag] == 4)//Address
  369. {
  370. struct ip_address *dns_add;
  371. const u_char* dns_add_packet_content;
  372. flag += 1;
  373. dns_add_packet_content = packet_content + flag;
  374. dns_add = (struct ip_address *) dns_add_packet_content;
  375. printf("地址(Adress):%d.%d.%d.%d\n", dns_add->byte1, dns_add->byte2, dns_add->byte3, dns_add->byte4);
  376. flag += 4;
  377. printf("--------------------\n");
  378. }
  379. else//域名
  380. {
  381. char cname[200];
  382. memset(cname, 0, sizeof(cname));
  383. flag += 1;
  384. /*printf("flag and packet:%d %02x\n", flag, packet_content[flag]);*/
  385. int j = cnt = 0;
  386. domainname(flag, cnt, j, packet_content, cname);
  387. printf("域名(Cname):%s\n", cname);
  388. flag += 1;
  389. /*printf("flag::::%d\n", flag);*/
  390. printf("--------------------\n");
  391. }
  392. }
  393. }
  394. }
  395. //UDP协议分析
  396. void udp_protool_packet_callback(u_char *argument, const struct pcap_pkthdr* packet_header, const u_char* packet_content)
  397. {
  398. struct udphdr *udp_protocol;
  399. u_int header_length = 0;
  400. u_int16_t checksum;
  401. udp_protocol = (struct udphdr *) packet_content;
  402. checksum = ntohs(udp_protocol->check);
  403. u_int16_t source_port; /*源地址端口*/
  404. u_int16_t dest_port; /*目的地址端口*/
  405. u_int16_t len; /*UDP长度*/
  406. u_int16_t check; /*UDP校验和*/
  407. printf("---------UDP协议---------\n");
  408. printf("源端口:%d\n", ntohs(udp_protocol->source_port));
  409. printf("目的端口:%d\n", ntohs(udp_protocol->dest_port));
  410. printf("UDP数据包长度:%d\n", ntohs(udp_protocol->len));
  411. printf("UDP校验和:%d\n", checksum);
  412. if (ntohs(udp_protocol->source_port) == 53 || ntohs(udp_protocol->dest_port) == 53)
  413. {
  414. //printf("dns data:\n%s\n", packet_content + sizeof(udphdr));
  415. dns_protool_packet_callback(argument, packet_header, packet_content + sizeof(udphdr));
  416. }
  417. }
  418. //TCP协议分析
  419. void tcp_protool_packet_callback(u_char *argument, const struct pcap_pkthdr* packet_header, const u_char* packet_content)
  420. {
  421. struct tcphdr *tcp_protocol;
  422. u_int header_length = 0;
  423. u_int offset;
  424. u_char tos;
  425. u_int16_t checksum;
  426. tcp_protocol = (struct tcphdr *) packet_content;
  427. checksum = ntohs(tcp_protocol->check);
  428. printf("---------TCP协议---------\n");
  429. printf("源端口:%d\n", ntohs(tcp_protocol->source_port));
  430. printf("目的端口:%d\n", ntohs(tcp_protocol->dest_port));
  431. printf("SEQ:%d\n", ntohl(tcp_protocol->seq));
  432. printf("ACK SEQ:%d\n", ntohl(tcp_protocol->ack_seq));
  433. printf("TCP校验和:%d\n", checksum);
  434. if (ntohs(tcp_protocol->source_port) == 80 || ntohs(tcp_protocol->dest_port) == 80)//http协议
  435. printf("http data:\n%s\n", packet_content + sizeof(tcphdr));
  436. }
  437. //IP协议分析
  438. void ip_protool_packet_callback(u_char *argument, const struct pcap_pkthdr* packet_header, const u_char* packet_content)
  439. {
  440. struct ip_header *ip_protocol;
  441. u_int offset;
  442. u_char tos;
  443. u_int16_t checksum;
  444. ip_protocol = (struct ip_header *)packet_content;
  445. checksum = ntohs(ip_protocol->ip_checksum);
  446. tos = ip_protocol->ip_tos;
  447. offset = ntohs(ip_protocol->ip_off);
  448. printf("---------IP协议---------\n");
  449. printf("版本号:%d\n", ip_protocol->ip_version);
  450. printf("首部长度:%d %d\n", ip_protocol->ip_header_length, sizeof(ip_header));
  451. printf("服务质量:%d\n", tos);
  452. printf("总长度:%d\n", ntohs(ip_protocol->ip_length));
  453. printf("标识:%d\n", ntohs(ip_protocol->ip_id));
  454. printf("偏移:%d\n", (offset & 0x1fff) * 8);
  455. printf("生存时间:%d\n", ip_protocol->ip_ttl);
  456. printf("协议类型:%d\n", ip_protocol->ip_protocol);
  457. printf("检验和:%d\n", checksum);
  458. printf("源IP地址:%d.%d.%d.%d\n", ip_protocol->saddr.byte1, ip_protocol->saddr.byte2, ip_protocol->saddr.byte3, ip_protocol->saddr.byte4);
  459. printf("目的地址:%d.%d.%d.%d\n", ip_protocol->daddr.byte1, ip_protocol->daddr.byte2, ip_protocol->daddr.byte3, ip_protocol->daddr.byte4);
  460. switch (ip_protocol->ip_protocol)
  461. {
  462. case 1: printf("上层协议是ICMP协议\n"); break;
  463. case 2: printf("上层协议是IGMP协议\n"); break;
  464. case 6:
  465. {
  466. printf("上层协议是TCP协议\n");
  467. tcp_protool_packet_callback(argument, packet_header, packet_content + sizeof(ip_header));
  468. }
  469. break;
  470. case 17:
  471. {
  472. printf("上层协议是UDP协议\n");
  473. udp_protool_packet_callback(argument, packet_header, packet_content + sizeof(ip_header));
  474. }
  475. break;
  476. default:break;
  477. }
  478. }
  479. //以太网协议分析
  480. void ethernet_protocol_packet_callback(u_char *argument, const struct pcap_pkthdr* packet_header, const u_char* packet_content)
  481. {
  482. u_short ethernet_type;
  483. struct ether_header *ethernet_protocol;
  484. u_char *mac_string;
  485. static int packet_number = 1;
  486. printf("----------------------------------------------\n");
  487. printf("捕获第%d个网络数据包\n", packet_number);
  488. printf("该数据包的具体内容:\n");
  489. for (int i = 1; i <= packet_header->len; i++)
  490. {
  491. printf("%02x(%d) ", packet_content[i - 1],i-1-42);
  492. if (i % 8 == 0)
  493. printf(" ");
  494. if (i % 16 == 0)
  495. printf("\n");
  496. }
  497. printf("\n");
  498. printf("数据包长度:%d\n", packet_header->len);
  499. printf("---------以太网协议---------\n");
  500. ethernet_protocol = (struct ether_header*)packet_content;//获得数据包内容
  501. ethernet_type = ntohs(ethernet_protocol->ether_type);//获得以太网类型
  502. printf("以太网类型:%04x\n", ethernet_type);
  503. mac_string = ethernet_protocol->ether_shost;
  504. printf("MAC帧源地址:%02x:%02x:%02x:%02x:%02x:%02x\n", *mac_string, *(mac_string + 1), *(mac_string + 2), *(mac_string + 3), *(mac_string + 4), *(mac_string + 5));
  505. mac_string = ethernet_protocol->ether_dhost;
  506. printf("MAC帧目的地址:%02x:%02x:%02x:%02x:%02x:%02x\n", *mac_string, *(mac_string + 1), *(mac_string + 2), *(mac_string + 3), *(mac_string + 4), *(mac_string + 5));
  507. switch (ethernet_type)
  508. {
  509. case 0x0800:
  510. {
  511. printf("上层协议是IPv4协议\n");
  512. ip_protool_packet_callback(argument, packet_header, packet_content + sizeof(ether_header));
  513. }
  514. break;
  515. case 0x0806:
  516. printf("上层协议是ARP协议\n");
  517. break;
  518. case 0x8035:
  519. printf("上层协议是RARP协议\n");
  520. break;
  521. case 0x814C:
  522. printf("上层协议是简单网络管理协议SNMP\n");
  523. break;
  524. case 0x8137:
  525. printf("上层协议是因特网包交换(IPX:Internet Packet Exchange)\n");
  526. break;
  527. case 0x86DD:
  528. printf("上层协议是IPv6协议\n");
  529. break;
  530. case 0x880B:
  531. printf("上层协议是点对点协议(PPP:Point-to-Point Protocol)\n");
  532. break;
  533. default:break;
  534. }
  535. printf("----------------------------------------------\n");
  536. packet_number++;
  537. }
  538. int main()
  539. {
  540. pcap_if_t * allAdapters; //适配器列表
  541. pcap_if_t * adapter; //跑适配器列表
  542. pcap_t * adapterHandle; //适配器句柄
  543. //char error_content[PCAP_ERRBUF_SIZE]; //存储错误信息
  544. bpf_u_int32 net_mask = 0; //掩码地址
  545. bpf_u_int32 net_ip = 0; //网络地址
  546. char *net_interface; //网络接口
  547. struct bpf_program bpf_filter; //BPF过滤规则
  548. char bpf_filter_string[] = "port 53"; //过滤规则字符串,只分析IPv4的数据包
  549. char errorBuffer[PCAP_ERRBUF_SIZE]; //错误信息缓冲区
  550. if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &allAdapters, errorBuffer) == -1) //检索机器连接的所有网络适配器
  551. {
  552. fprintf(stderr, "Error in pcap_findalldevs_ex function: %s\n", errorBuffer);
  553. return -1;
  554. }
  555. if (allAdapters == NULL) //不存在任何适配器
  556. {
  557. printf("\nNo adapters found! Make sure WinPcap is installed.\n");
  558. return 0;
  559. }
  560. int crtAdapter = 0;
  561. for (adapter = allAdapters; adapter != NULL; adapter = adapter->next)
  562. { //遍历输入适配器信息(名称和描述信息)
  563. printf("\n%d.%s ", ++crtAdapter, adapter->name);
  564. printf("-- %s\n", adapter->description);
  565. }
  566. printf("\n");
  567. int adapterNumber;
  568. printf("Enter the adapter number between 1 and %d:", crtAdapter);//选择要捕获数据包的适配器
  569. scanf_s("%d", &adapterNumber);
  570. if (adapterNumber < 1 || adapterNumber > crtAdapter)
  571. {
  572. printf("\nAdapter number out of range.\n");
  573. pcap_freealldevs(allAdapters);// 释放适配器列表
  574. return -1;
  575. }
  576. adapter = allAdapters;
  577. for (crtAdapter = 0; crtAdapter < adapterNumber - 1; crtAdapter++)
  578. adapter = adapter->next;
  579. adapterHandle = pcap_open(adapter->name, 65536, PCAP_OPENFLAG_PROMISCUOUS, 1000, NULL, errorBuffer);// 打开指定适配器
  580. if (adapterHandle == NULL)//指定适配器打开失败
  581. {
  582. fprintf(stderr, "\nUnable to open the adapter\n", adapter->name);
  583. pcap_freealldevs(allAdapters);// 释放适配器列表
  584. return -1;
  585. }
  586. char errbuf[2048];
  587. pcap_createsrcstr(NULL, 0, NULL, "80", NULL, errbuf);
  588. printf("\nCapture session started on adapter %s\n", adapter->name);
  589. pcap_freealldevs(allAdapters);//释放适配器列表
  590. pcap_compile(adapterHandle, &bpf_filter, bpf_filter_string, 0, net_ip); //编译过滤规则
  591. pcap_setfilter(adapterHandle, &bpf_filter);//设置过滤规则
  592. if (pcap_datalink(adapterHandle) != DLT_EN10MB) //DLT_EN10MB表示以太网
  593. return 0;
  594. pcap_loop(adapterHandle, 100, ethernet_protocol_packet_callback, NULL); //捕获65536个数据包进行分析
  595. pcap_close(adapterHandle);
  596. return 0;
  597. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注