如何捕获网络包的详细描述

点评:前言


人们经常会看到论坛上的人问关于数据包截取和分析的问题。幸运的是,我对它了解很多,编写了很多嗅探器,所以我想写一系列文章来详细讨论数据包的知识。


我希望通过这一系列的文章,对数据包的知识可以推广,所以在这个系列中的每一个片文。






前言


人们经常会看到论坛上的人问关于数据包截取和分析的问题。幸运的是,我对它了解很多,编写了很多嗅探器,所以我想写一系列文章来详细讨论数据包的知识。


我希望通过这一系列的文章,可以对包知识的普及性,所以这一系列的每一篇文章,我会从浅到更深的解释和详细的分析,并附有详细的注释步骤(源代码,以照顾我的朋友提供MFC的源代码)。


也是初学者,展望遗漏。


这篇文章浓缩了作者的血液,如果你想转载,请注明原作者和来源,谢谢!^ _ ^





好啊,.让;去!玩得高兴!问^ _ ^ P!





二把手教你捕获数据包


目录 uff1a


首先,捕获数据包的原理


两。捕获数据包的编程实现:


对1.raw套接字的实现


2执行。WinPcap


枚举本地网卡的信息。


b.打开相应的网卡并将其设置为混合模式。


截取数据包并将其保存为一个文件。





作者:


CSDN VC和MFC网络编程主持人piggyxp





一种数据包捕获原理。新闻:


在一般情况下,网络通信的socket程序只能回应自己的硬件地址和匹配或数据帧的其他形式的数据帧,如网络接口已达不到网络的接口地址验证后不发货地址不会引起反应在数据帧的形式广播发送,即应用程序不能与自己无关的数据包。


因此,如果我们想捕获流经网络设备的所有数据包,我们必须采取特殊的手段:


将网卡设置为混合模式。


这样,主机的网卡就可以捕获流经网卡的所有数据包和帧。


但需要注意的是,这只是一份截获的数据包,而不是截断它。如果我们想切断网络流量,我们需要采取一些更低级的方式,这不在本文的范围之内。





两。捕获数据包的编程实现:


在一些1.raw套接字的实现方法


不像我们常用的数据流套接字和数据报套接字,在创建原始套接字,我们需要设置WSAIoctl()函数,它是这样定义的。


Int WSAIoctl(


插座的,


DWORD dwiocontrolcode,


lpvinbuffer值,


DWORD cbinbuffer,


lpvoutbuffer值,


DWORD cbOutBuffer,


小lpcbbytesreturned,


lpwsaoverlapped lpOverlapped,


lpwsaoverlapped_completion_routine lpcompletionroutine


);


虽然有很多参数,但我们最关心的只是它们的第二个参数。我们需要做的是为sio_rcvall二项集。到目前为止,我们需要做这样一行代码。很简单吗^ _ ^


当然,我们也可以指定我们是否可以亲自处理IP头,但这不是必需的。


完整的代码类似于下面的代码,而粗代码是一个注意的地方,它的方式与往常不同:


(为了使代码清晰,我已经删除了错误处理,同样的。)





#包括winsock2.h


#定义sio_rcvall _wsaiow(ioc_vendor,1)





插座sniffersocket


wsadata wsadata;


iflag = WSAStartup(makeword(2,2),wsadata) / /打开winsock.dll;





sniffersocket = wsasocket(af_inet原 / /创建,插座


sock_raw,ipproto_ip,零,0,wsa_flag_overlapped);





char远名称{ 128 };获取机器IP地址


gethostname(名称,sizeof(名字));


结构hostent远* phostent;


phostent = gethostbyname(名称);





sockaddr_in SA; / / sockaddr_in填充内容的结构


Sa.sin_family = AF_INET;


sa.sin_port = htons(6000); / /端口号可以轻易改变的,当然,当然系统不冲突


Memcpy((SA。sin_addr),phostent -> h_addr,phostent -> h_length);





绑定(sniffersocket(lpsockaddr)SA,sizeof(SA)); / /结合


/ / ioctl获得所有网络数据,关键步骤


DWORD dwbufferlen { 10 };


DWORD dwbufferinlen = 1;


DWORD dwbytesreturned = 0;


WSAIoctl(sniffersocket,io_rcvall,dwbufferinlen,izeof(dwbufferinlen),


DwBufferLen,sizeof(dwbufferlen),dwbytesreturned,null,null);


因此,实际可以开始包嗅探器,并接收数据包与插座相同,通过recv()函数来完成,因为它涉及到不同的插座型号、接收方式差别很大,所以这是不提供接收代码。





对2.winpcap实现方法:-----------------------------------------------------------------------


WinPcap驱动程序包是我们玩数据包中不可缺少的一部分。winpcap的主要功能是接收和发送数据报独立主机协议(如TCP/IP)。它主要为我们提供四大功能。


功能:


1捕获原始数据报,包括由共享网络上的每个主机发送并接收的数据,并相互交换;


2根据定制规则在数据发送到应用程序之前过滤一些特殊的数据报。


3 >在网络上发送原始数据报;


4·网络传播过程中统计信息的收集


如果环境许可(例如,你没有,我推荐的木马)我们利用WinPcap捕获数据包,因为它的功能更强大,工作效率更高,唯一的缺点是,在运行winpcap的发展过程中,安装在主机WinPcap驱动。


然后我们会发现它比原始套接字函数更强大,并且更深入到底层,最明显的原因是原始套接字捕获包不是以太头,情况就是这样。


至于如何安装和使用,请参阅系列的教你在ARP包中玩


我不多说废话。让我们把这一点,我们需要做以下一些工作利用WinPcap捕获数据包。


A. Enumerate本地网卡的信息(主要是获取网卡的名称)


的pcap_findalldevs是使用功能,它是这样定义的


/ *************************************************


国际pcap_findalldevs(pcap_if_t * alldevsp,


字符串errbuf





功能:


枚举系统中所有网络设备的信息。


参数:alldevsp:指针pcap_if_t结构。如果函数执行成功pcap_findalldevs函数,一个可用的网络卡将获得,且第一个元素的指针存储。


Errbuf:一个用于存储错误信息的字符串


返回值:int:如果返回0,则错误返回至1。


************************************************* /


我们使用此函数获取网卡名称的完整代码如下:





pcap_if_t * alldevs;


pcap_if_t * D;


焦pcap_errbuf_size errbuf { };


pcap_findalldevs(alldevs,errbuf); / /获取网络设备指针


为(a alldevs;D; / / D = D ->下)卡,然后添加到ComboBox枚举


{


名字;我们需要卡名字符串,根据你自己的需要将其保存到相应的变量中。


}


pcap_freealldevs(alldevs); / /释放alldev资源


b.打开相应的网卡并将其设置为混杂模式:在此之前,必须有一个代码让用户选择网卡并获得用户选择的网卡的名称。由于上面已经获得了所有尼克的名称,所以暂时跳过代码。