• 使用WinPcap编程(4)——把网络数据包存储到一个文件中


          这里用到的数据结构是pcap_dumper_t,这也是一个相当于文件描述符的东西,我们在用的时候先指定pcap_dumper_t *dumpfp;

          使用两个函数来存储网络数据,一个是pcap_dump_open(),另一个是pcap_dump()。先用前一个函数打开一个文件,然后用后一个函数把网络数据写到这个文件中。最后用pcap_dump_close()这个函数把这个文件关闭。

          函数原型如下:

    pcap_dumper_t * pcap_dump_open (pcap_t *p, const char *fname)


          1、p是我们已经打开的网络设备,从这个设备接收数据包。

          2、fname是我们要写入的文件名,随便起。

          return: 如果出错,会返回NULL。可以借此检查这个文件有没有打开。

          文件打开之后,就可以向文件之中写数据了。数据也是一个包一个包的写进去的,还要用到pcap_loop()这个函数。只不过这里的user要指定为打开文件的描述符dumpfp。在使用packet_handler 这个函数指针的时候,参数中的user就是这个dumpfp。pcap_dump()的原型如下:

    void pcap_dump (u_char *user, const struct pcap_pkthdr *h, const u_char *sp)


          1、这里的user就是文件描述符dumpfp,只不过要做一下类型转换。由于这个函数一般在pcap_loop()的函数指针所指向的packet_handler中使用,所以packet_handler中的user就是这里的user。

          2、h是pkt_header。

          3、sp这里要用pkt_data。具体参看下面的实例:

    void packet_handler(u_char *user, const struct pcap_pkthdr *pkt_header, const u_char *pkt_data)
    {
    	printf("in packet handler\n");
    	pcap_dump(NULL, pkt_header, pkt_data);
    	return;
    }


          附上一个源代码:

    #define _CRT_SECURE_NO_WARNINGS
    
    #include "pcap.h"
    
    void packet_handler(u_char *user, const struct pcap_pkthdr *pkt_header, const u_char *pkt_data);
    
    int main()
    {
    	pcap_t *cap_ins_des;
    	pcap_if_t *alldevs;
    	pcap_if_t *d;
    	char source[PCAP_BUF_SIZE];
    	char errbuf[PCAP_ERRBUF_SIZE];
    	int i;
    	u_int netmask;
    	char packet_filter[] = "ip and udp";	// the filter
    	struct bpf_program fcode;	// used in pcap_compile()
    	pcap_dumper_t *dumpfp;
    
    	/* set the source */
    	if (pcap_createsrcstr(source, PCAP_SRC_IFLOCAL, NULL, NULL, NULL, errbuf) == -1) {
    		printf("%s\n", errbuf);
    		exit(-1);
    	}
    	printf("source: %s\n", source);
    
    	/* find all devices */
    	if (pcap_findalldevs_ex(source, NULL, &alldevs, errbuf) == -1) {
    		printf("%s\n", errbuf);
    		exit(-1);
    	}
    
    	/* choose one devices */
    	d = alldevs;
    	while (d != NULL) {
    		printf("%s, %s\n", d->name, d->description);
    		d = d->next;
    	}
    	scanf("%d", &i);
    	d = alldevs;
    	while (--i)
    		d = d->next;
    	printf("selected device: %s\n", d->name);
    
    	/* open one device */ 
    	cap_ins_des = pcap_open(d->name, 65536, PCAP_OPENFLAG_PROMISCUOUS, 1000, NULL, errbuf);
    	if (cap_ins_des == NULL) {
    		printf("%s\n", errbuf);
    		pcap_freealldevs(alldevs);
    		exit(-1);
    	}
    
    	/* get the netmask, used at compiling the filter */
    	if (d->addresses != NULL)
    		netmask = ((struct sockaddr_in *)(d->addresses->netmask))->sin_addr.S_un.S_addr;	/*@#$%^&*!*/
    	else
    		netmask = 0xffffff;	/* 255.25.255.0 */
    
    	// netmask = 0;
    
    	/* compile the filter */
    	if (pcap_compile(cap_ins_des, &fcode, packet_filter, 1, netmask) < 0) {
    		printf("Error\n");
    		pcap_freealldevs(alldevs);
    		exit(-1);
    	}
    
    	/* set the filter */
    	if (pcap_setfilter(cap_ins_des, &fcode) < 0) {
    		printf("Error\n");
    		pcap_freealldevs(alldevs);
    		exit(-1);
    	}
    
    	/* open a file to dump data */
    	dumpfp = pcap_dump_open(cap_ins_des, "traffic.data");
    	if( dumpfp == NULL) {
    		printf("Error on opening output file\n");
    		exit(-1);
    	}
    
    	pcap_freealldevs(alldevs);
    
    	/* start the capture */
    	pcap_loop(cap_ins_des, 30, packet_handler, (u_char *)dumpfp);
    
    	pcap_dump_close(dumpfp);
    
    	return 0;
    }
    
    void packet_handler(u_char *user, const struct pcap_pkthdr *pkt_header, const u_char *pkt_data)
    {
    	printf("in packet handler\n");
    	pcap_dump(NULL, pkt_header, pkt_data);
    	return;
    }

          main()函数中下面的十来行是把网络数据包存到一个文件中的方法。

  • 相关阅读:
    按钮设计
    图标设计
    滤镜与通道
    路径、形状工具与选区
    类的无参方法
    类和对象
    阅读器关闭时尝试调用Read无效时的解决方法
    进入ASP .net mvc的世界
    linux命令-vim
    linux命令-分区表fstab
  • 原文地址:https://www.cnblogs.com/wangshuo/p/2116283.html
Copyright © 2020-2023  润新知