对网络数据包进行嗅探

例如我现在发表了一个帖子,点击提问按钮,我如何截获点击提问按钮时所发出去的包呢?并把我发表的内容取出来。  
---------------------------------------------------------------  
---------------------------------------------------------------  
 
选自小猪的Blog:  
 
一.捕获数据包的实现原理  
 
二.捕获数据包的编程实现:  
 
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头,但是这并不是必须的。  
 
完整的代码类似与如下这样,加粗的代码是与平常不同的需要注意的地方:  
 
(  为了让代码一目了然,我把错误处理去掉了,下同)  
 
   
 
#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]  ;  
 
   DWORD  dwBufferInLen  =  1  ;  
 
   DWORD  dwBytesReturned  =  0  ;  
 
   WSAIoctl(SnifferSocket,  IO_RCVALL,&dwBufferInLen,  izeof(dwBufferInLen),  
 
               &dwBufferLen,  sizeof(dwBufferLen),&dwBytesReturned  ,  NULL  ,  NULL  );  
 
     
 
至此,实际就可以开始对网络数据包进行嗅探了,而对于数据包的接收还是和普通的socket一样,通过recv()函数来完成,因为这里涉及到不同的socket模型,接收方法差别很大,所以在此就不提供接收的代码了。  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值