Winpcap学习


前言


详细内容见:winpcap中文文档
这里面有时用适配器(adapter),有时用接口(interface),下文使用适配器。(其实适配器也可以是一个接口)
参考文章:WINPCAP抓包并用回调函数处理包


宏定义和结构体(工欲善其事,必先利其器)

//宏定义
#define PCAP_ERRBUF_SIZE   256

宏定义还有其他的,这个是比较常用的,用于设置一个字符缓冲区(字符串)

//一个单链表
typedef struct pcap_if pcap_if_t; 
struct pcap_if {
    struct pcap_if *next; 
    char *name;     
    char *description;  
    struct pcap_addr *addresses; 
    u_int flags;        
};

用来保存适配器的名称及描述,遍历使用单链表的遍历方法,其它数据可以暂时忽略。

//一个已打开的捕捉实例的描述符。不透明。
typedef struct pcap pcap_t;

用来保存一个打开的适配器。使用前先定义,再用来接受相应函数的返回值即可,细节不用考虑。

//用于远程机器认证,a remote machine 
struct pcap_rmtauth{
     int type;
     char *username;
     char *password;
 };

不需要的话可以设为NULL

struct pcap_pkthdr {
     struct timeval ts;  
     bpf_u_int32 caplen; 
     bpf_u_int32 len;    
 };

winpcap自己给数据包设置的一个包头,包括时间戳、捕获长度、实际长度,相当于一个附加信息,掌握这个结构可以用来输出这些信息。

 struct pcap_addr {
     struct pcap_addr *next; 
     struct sockaddr *addr;      
     struct sockaddr *netmask;   
     struct sockaddr *broadaddr; 
     struct sockaddr *dstaddr;   
 };

适配器的地址

获取适配器列表(先有设备才可以进行抓包和发送)

//获取设备列表,即适配器列表
//保存在单链表里,错误信息放在errbuf里
int pcap_findalldevs	(	pcap_if_t ** alldevsp,
							char * 	errbuf	 
						)	


int pcap_findalldevs_ex	(	char * 	source,
							struct pcap_rmtauth * 	auth,
							pcap_if_t ** 	alldevs,
							char * 	errbuf	 
)	

//获取之后,要释放其占用的内存资源
void pcap_freealldevs	(	pcap_if_t * 	alldevsp	 ) 	
参数说明补充
alldevsp存放设备的地址一个单链表
errbuf错误信息字符串
auth用于远程认证不需要可以写为NULL

选择一个适配器打开(开始使用设备)

//打开适配器并捕获数据包
pcap_t* pcap_open	(	const char * 	source,
						int 	snaplen,
						int 	flags,
						int 	read_timeout,
						struct pcap_rmtauth * 	auth,
						char * 	errbuf	 
					)	

参数意义补充
source设备名获取适配器列表其中的一个,name部分
snaplen捕获数据包中的哪些部分,也就是长度将值定为65535,它比我们能遇到的最大的MTU还要大。因此,我们确信我们总能收到完整的数据包。
flags指示适配器是否要被设置成混杂模式一般情况下,适配器只接收发给它自己的数据包, 而那些在其他机器之间通讯的数据包,将会被丢弃。 相反,如果适配器是混杂模式,那么不管这个数据包是不是发给我的,我都会去捕获。也就是说,我会去捕获所有的数据包。
read_timeout指定读取数据的超时时间,以毫秒计(1s=1000ms)
返回值一个打开的捕捉实例,网络适配器的描述符用于后续捕获数据包

获取数据包及处理(处理适配器收到的数据包)

方法一

//捕获工作
int pcap_dispatch	(	pcap_t * 	p,
						int 	cnt,
						pcap_handler 	callback,
						u_char * 	user	 
					)
int pcap_loop	(	pcap_t * 	p,
					int 	cnt,
					pcap_handler 	callback,
					u_char * 	user	 
				)		
//callback是一个回调函数,用来处理数据包,要自己实现
//user只是用来描述这次抓包,可以置为NULL

这两个函数非常的相似,区别就是 pcap_ dispatch() 当超时时间到了(timeout expires)就返回 (尽管不能保证) ,而 pcap_loop() 不会因此而返回,只有当 cnt 数据包被捕获,所以,pcap_loop()会在一小段时间内,阻塞网络的利用。pcap_loop()对于我们这个简单的范例来说,可以满足需求,不过, pcap_dispatch() 函数一般用于比较复杂的程序中。
这两个函数都有一个 回调 参数, packet_handler指向一个可以接收数据包的函数。

!!!问题来了,数据包去哪里了?
数据包被上面两个函数作为参数传递给了回调函数。
!!!回调函数要自己实现,参数列表已经定义好了,不允许改变

//回调函数
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data);
参数说明补充
paramuserpcap_loop()里面的user信息
headerwinpcap设置的一些附加信息
pkt_data指向抓到的数据包字符串

请注意,使用 pcap_loop() 函数可能会遇到障碍,主要因为它直接由数据包捕获驱动所调用。因此,用户程序是不能直接控制它的。

方法二

//不用回调方法捕获数据包,一次获取一个
int pcap_next_ex	(	pcap_t * 	p,
						struct pcap_pkthdr ** 	pkt_header,
						const u_char ** 	pkt_data	 
					)	
参数说明补充
p网络适配器的描述符
pkt_header可以初始化和返回给用户的指针指向 pcap_pkthdr 结构体
pkt_data可以初始化和返回给用户的指针指向数据报数据的缓冲
返回值-1出错或EOF,0超时,>0成功

使用要点:这个方法需要用户自己先定义两个指针用来接收pcap_pkthdr和数据包。

过滤数据包(获取想要的数据包)

//过滤数据包
int pcap_compile	(	pcap_t * 	p,
						struct bpf_program * 	fp,
						char * 	str,
						int 	optimize,
						bpf_u_int32 	netmask	 
					)	

int pcap_setfilter	(	pcap_t * 	p,
						struct bpf_program * 	fp	 
					)	

发送数据包(当然也是用适配器发送了,需要打开)

//发送单个数据包
nt pcap_sendpacket	(	pcap_t * 	p,
						u_char * 	buf,
						int 	size	 
					)	

buf是要发送的数据缓冲区(即字符串),size是数据的长度
!!!为什么要设置size?
在数据包中,可以有很多字节为零,而在C语言中字符数组的结尾"\0"也是一个全零的字节,不设置size就不能区分数据的长度。
同样的,C语言中的字符串函数也不适用于数据包的构建,构建数据包的时候也需要设置一个size便于操作。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
WinPcap是一个用于在Windows操作系统上进行网络数据包捕获和分析的库。它具有过滤数据包的引擎,可以有效地获取网络中的特定数据包。\[1\] 要开始使用WinPcap,首先需要从官方网站http://www.winpcap.org/default.htm下载并安装WinPcap软件包。安装完成后,可以使用pcap_compile()和pcap_setfilter()函数来过滤数据包。这些函数可以帮助你指定捕获特定类型或特定源/目的地的数据包。\[1\] 一旦适配器被打开,捕获工作就可以使用pcap_dispatch()或pcap_loop()函数进行。这两个函数都可以用于捕获数据包,但有一些区别。pcap_dispatch()函数在超时时间到达后会返回,而pcap_loop()函数只有在捕获到指定数量的数据包后才会返回。因此,pcap_loop()函数会在一段时间内阻塞网络的利用。对于简单的应用程序,pcap_loop()函数通常足够满足需求,而pcap_dispatch()函数更适用于复杂的程序。\[2\] 在使用WinPcap时,可以使用命令行工具或编写自己的程序来进行数据包捕获和分析。可以使用ping命令来生成网络流量,并使用WinPcap来捕获和分析这些数据包。\[3\] 总结来说,要使用WinPcap,首先需要下载并安装WinPcap软件包。然后,可以使用pcap_compile()和pcap_setfilter()函数来过滤数据包。最后,可以使用pcap_dispatch()或pcap_loop()函数来捕获和分析数据包。 #### 引用[.reference_title] - *1* *2* [Winpcap网络编程七之Winpcap学习教程,抓包,抓包!](https://blog.csdn.net/u010467643/article/details/39924789)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [最火的抓包工具winpcap使用教程](https://blog.csdn.net/liuyuzhu111/article/details/50135059)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值