教大家怎么捕获网络数据包 -电脑资料

电脑资料 时间:2019-01-01 我要投稿
【meiwen.anslib.com - 电脑资料】

    前   言

    经常看到网友们讨论关于数据包的截获、分析等问题,幸好本人也对此略有所知,也写过很多的sniffer,所以就想写一系列的文章来详细深入的探讨关于数据包的知识,

教大家怎么捕获网络数据包

    我希望通过这一系列的文章,能使得关于数据包的知识得以普及,所以这系列的每一篇文章我都会有由浅入深的解释、详细的分析、以及编码步骤,另外附上带有详细注释的源码(为了照顾大多数朋友,我提供的都是MFC的源码)。

    不过由于也是初学者,疏漏之处还望不吝指正。

    本文凝聚着笔者心血,如要转载,请指明原作者及出处,谢谢!^_^

    OK,. Let’s go !  Have fun!! q^_^p

    第二篇   手把手教你捕获数据包

    目录:

    一.捕获数据包的实现原理

    二.捕获数据包的编程实现:

    1.   raw socket的实现方法

    2.   Winpcap的实现方法

    a.      枚举本机网卡的信息

    b.      打开相应网卡并设置为混杂模式

    c.       截获数据包并保存为文件

    作者:

    CSDN  VC/MFC 网络编程版主 PiggyXP

    一.捕获数据包的实现原理:--------------------------------------------------------------------

    在通常情况下,网络通信的套接字程序只能响应与自己硬件地址相匹配的或是以广播形式发出的数据帧,对于其他形式的数据帧比如已到达网络接口但却不是发给此地址的数据帧,网络接口在验证投递地址并非自身地址之后将不引起响应,也就是说应用程序无法收取与自己无关的的数据包。

    所以我们要想实现截获流经网络设备的所有数据包,就要采取一点特别的手段了:

    将网卡设置为混杂模式。

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

    但是要注意一点,这种截获仅仅是数据包的一份拷贝,而不能对其进行截断,要想截断网络流量就要采用一些更底层的办法了,不在本文的讨论范围之内。

    二. 捕获数据包的编程实现:

    1.raw socket的实现方法--------------------------------------------------------------------

    不同于我们常用的数据流套接字和数据报套接字,在创建了原始套接字后,需要用WSAIoctl()函数来设置一下,它的定义是这样的

    int WSAIoctl(

    SOCKET s,

    DWORD dwIoControlCode,

    LPVOID lpvInBuffer,

    DWORD cbInBuffer,

    LPVOID lpvOutBuffer,

    DWORD cbOutBuffer,

    LPDWORD lpcbBytesReturned,

    LPWSAOVERLAPPED lpOverlapped,

    LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine

    );

    虽然咋一看参数比较多,但是其实我们最关心的只是其中的第二项而已,我们需要做的就是把第二项设置为SIO_RCVALL,讲了这么多其实要做的就是这么一行代码,很简单吧?^_^

    当然我们还可以指定是否亲自处理IP头,但是这并不是必须的,

电脑资料

教大家怎么捕获网络数据包》(http://meiwen.anslib.com)。

    完整的代码类似与如下这样,加粗的代码是与平常不同的需要注意的地方:

    ( 为了让代码一目了然,我把错误处理去掉了,下同)

    #include “WinSock2.h”

    #define SIO_RCVALL _WSAIOW(IOC_VENDOR,1)

    SOCKET SnifferSocket

    WSADATA wsaData;

    iFlag=WSAStartup(MAKEWORD(2,2),&wsaData);           //开启winsock.dll

    SnifferSocket=WSASocket(AF_INET,             //创建raw  socket

    SOCK_RAW,IPPROTO_IP,NULL,0,WSA_FLAG_OVERLAPPED);

    char FAR name[128];                                //获取本机IP地址

    gethostname(name, sizeof(name));

    struct hostent FAR * pHostent;

    pHostent = gethostbyname(name);

    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);

    bind(SnifferSocket,(LPSOCKADDR)&sa,sizeof(sa));            //绑定

    // 置ioctl来接收所有网络数据,关键步骤

    DWORD dwBufferLen[10] ;

最新文章