今天又看了一下WINCAP技术文档的第七篇——处理脱机堆文件。把其中两个程序综合了一下,再使用前面讲到的filter,自己捣鼓出来了一个程序的基本框架。
目前我这个做得还很基本,可以抓到相应的数据包,但仍存在两个问题:
1.只能人工设定先捕获多少个数据包到堆文件,再从中一个个读取
2.我抓的包(如下右)只有HTTP包的内容,没有json的内容,我不懂json和HTTP数据包到底是什么关系,json的内容并没有接在HTTP报文后面
问题2比较关键,亟待解决。问题1的话算是一个提升,现在设想是开两个线程,一个抓,一个读。然后就是后期有时间的话还可以写一个图形界面。
附上撸好的代码:HTTPdump1.cpp
1 #ifdef _MSC_VER 2 /* 3 * we do not want the warnings about the old deprecated and unsecure CRT functions 4 * since these examples can be compiled under *nix as well 5 */ 6 #define _CRT_SECURE_NO_WARNINGS 7 #endif 8 9 10 #include "stdafx.h" 11 #include <pcap.h> 12 #include <remote-ext.h> 13 14 15 #define LINE_LEN 16 16 17 /* 4 bytes IP address */ 18 typedef struct ip_address 19 { 20 u_char byte1; 21 u_char byte2; 22 u_char byte3; 23 u_char byte4; 24 }ip_address; 25 26 /* IPv4 header */ 27 typedef struct ip_header 28 { 29 u_char ver_ihl; // Version (4 bits) + Internet header length (4 bits) 30 u_char tos; // Type of service 31 u_short tlen; // Total length 32 u_short identification; // Identification 33 u_short flags_fo; // Flags (3 bits) + Fragment offset (13 bits) 34 u_char ttl; // Time to live 35 u_char proto; // Protocol 36 u_short crc; // Header checksum 37 ip_address saddr; // Source address 38 ip_address daddr; // Destination address 39 u_int op_pad; // Option + Padding 40 }ip_header; 41 42 43 /* TCP header*/ 44 typedef struct tcp_header 45 { 46 u_short sport; 47 u_short dport; 48 u_int seq; 49 u_int ack; 50 u_short ofs_res_code; 51 u_short window; 52 u_short checksum; 53 u_short urp; 54 }tcp_header; 55 56 /* packet handler函数原型 */ 57 void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data); 58 59 /* dispatcher handler函数原型*/ 60 void dispatcher_handler(u_char *, const struct pcap_pkthdr *, const u_char *); 61 62 int main(int argc,char **argv) 63 { 64 pcap_if_t *alldevs; 65 pcap_if_t *d; 66 int inum; 67 int i = 0; 68 pcap_t *adhandle; 69 pcap_t *fp; 70 char errbuf[PCAP_ERRBUF_SIZE]; 71 pcap_dumper_t *dumpfile; 72 73 u_int netmask; 74 char packet_filter[] = "ip and tcp and net 115.156.197.44 and tcp src port 80 and greater 530"; 75 struct bpf_program fcode; 76 77 struct pcap_pkthdr *header; 78 const u_char *pkt_data; 79 80 81 char source[PCAP_BUF_SIZE]; 82 83 /*检查是否命令行输入了两个参数*/ 84 if (argc != 2) 85 { 86 printf("usage: %s filename", argv[0]); 87 return -1; 88 } 89 90 /*取设备列表*/ 91 if (pcap_findalldevs(&alldevs, errbuf) == -1) 92 { 93 fprintf(stderr, "Error in pcap_findalldevs: %s\n", errbuf); 94 exit(1); 95 } 96 97 /*打印设备列表*/ 98 for (d = alldevs; d; d = d->next) 99 { 100 printf("%d. %s", ++i, d->name); 101 if (d->description) 102 printf(" (%s)\n", d->description); 103 else 104 printf(" (No description available)\n"); 105 } 106 107 if (i == 0) 108 { 109 printf("\nNo interfaces found! Make sure WinPcap is installed.\n"); 110 return -1; 111 } 112 113 printf("Enter the interface number (1-%d):", i); 114 scanf("%d", &inum); 115 116 117 if (inum < 1 || inum > i) 118 { 119 printf("\nAdapter number out of range.\n"); 120 /* 释放设备列表 */ 121 pcap_freealldevs(alldevs); 122 return -1; 123 } 124 125 /* 跳转到选中的设备 */ 126 for (d = alldevs, i = 0; i< inum - 1; d = d->next, i++); 127 128 /* 打开设备 */ 129 if ((adhandle = pcap_open_live(d->name, // name of the device 130 65536, // portion of the packet to capture. 131 // 65536 grants that the whole packet will be captured on all the MACs. 132 PCAP_OPENFLAG_PROMISCUOUS, // promiscuous mode (nonzero means promiscuous) 133 1000, // read timeout 134 errbuf // error buffer 135 )) == NULL) 136 { 137 fprintf(stderr, "\nUnable to open the adapter. %s is not supported by WinPcap\n"); 138 /* 释放设备列表 */ 139 pcap_freealldevs(alldevs); 140 return -1; 141 } 142 143 /* 检查链路层,为了简单我们只检查以太网 */ 144 if (pcap_datalink(adhandle) != DLT_EN10MB) 145 { 146 fprintf(stderr, "\nThis program works only on Ethernet networks.\n"); 147 /* 释放设备列表 */ 148 pcap_freealldevs(alldevs); 149 return -1; 150 } 151 152 if (d->addresses != NULL) 153 /* 获得接口第一个地址的掩码 */ 154 netmask = ((struct sockaddr_in *)(d->addresses->netmask))->sin_addr.S_un.S_addr; 155 else 156 /* 如果接口没有地址,我们假设一个C类的掩码 */ 157 netmask = 0xffffff; 158 159 //编译过滤器 160 if (pcap_compile(adhandle, &fcode, packet_filter, 1, netmask) <0) 161 { 162 fprintf(stderr, "\nUnable to compile the packet filter. Check the syntax.\n"); 163 /* 释放设备列表 */ 164 pcap_freealldevs(alldevs); 165 return -1; 166 } 167 168 //设置过滤器 169 if (pcap_setfilter(adhandle, &fcode)<0) 170 { 171 fprintf(stderr, "\nError setting the filter.\n"); 172 /* 释放设备列表 */ 173 pcap_freealldevs(alldevs); 174 return -1; 175 } 176 177 /* 打开堆文件 */ 178 dumpfile = pcap_dump_open(adhandle, argv[1]); 179 180 if (dumpfile == NULL) 181 { 182 fprintf(stderr, "\nError opening output file\n"); 183 return -1; 184 } 185 186 printf("\nlistening on %s...\n", d->description); 187 188 /* 我们不再需要设备,释放设备列表 */ 189 pcap_freealldevs(alldevs); 190 191 /* 开始捕获 */ 192 pcap_loop(adhandle, 4, packet_handler, (unsigned char *)dumpfile); 193 pcap_close(adhandle); 194 195 /* 打开捕获的文件 */ 196 if ((fp = pcap_open_offline(argv[1], // name of the device 197 errbuf // error buffer 198 )) == NULL) 199 { 200 fprintf(stderr, "\nUnable to open the file %s.\n", argv[1]); 201 return -1; 202 } 203 /* 读取并处理数据包,直到读到EOF */ 204 pcap_loop(fp, 10, dispatcher_handler, NULL); 205 pcap_close(fp); 206 207 return 0; 208 209 210 } 211 212 /* Callback function invoked by libpcap for every incoming packet */ 213 void packet_handler(u_char *dumpfile, const struct pcap_pkthdr *header, const u_char *pkt_data) 214 { 215 /* 将数据包保存到堆文件 */ 216 pcap_dump(dumpfile, header, pkt_data); 217 } 218 219 void dispatcher_handler(u_char *temp1,const struct pcap_pkthdr *header,const u_char *pkt_data) 220 { 221 u_int i = 0; 222 223 ip_header *ih; 224 tcp_header *th; 225 u_int ip_len; 226 227 /* 228 * unused variable 229 */ 230 (VOID*)temp1; 231 232 /* 打印时间戳和数据包长度 */ 233 printf("%ld:%ld (%ld)\n", header->ts.tv_sec, header->ts.tv_usec, header->len); 234 235 236 /* 获得ip首部地址*/ 237 ih = (ip_header *)(pkt_data +14); //length of ethernet header 238 239 /* 获得tcp首部地址*/ 240 ip_len = (ih->ver_ihl & 0xf) * 4;//其实就是20啦! 241 th = (tcp_header *)((u_char*)ih + ip_len); 242 243 //printf("%d\n", ip_len); 244 245 /* 打印数据包 */ 246 //for (i = 14+20+20; (i < header->caplen + 1); i++) 247 for (i = 14 + 20 + 20; (i < 650); i++) 248 { 249 printf("%.2x ", pkt_data[i]); 250 if ((i % LINE_LEN) == 0) printf("\n"); 251 } 252 253 printf("\n\n"); 254 255 }
时间: 2024-10-12 08:49:17