用RAWSOCKET实现简单抓包

网络上随时都流通了大量的数据包,我们要想实现抓包,并分析的,那么该怎么做呢?其实思路很简单 大概流程如如下:

1 在合适的时候捕获数据包,保存到缓冲区,备用

2 按照一定的结构和格式去读取缓冲区的内容

由于各种公开的网络协议是已知的.所以对于数据包的分析就比较简单.这里主要讲解的是如何捕获到原始的数据包

这里我们借助LINUX系统里的套接字.TCP/IP协议套接字分为三大类,它们分别是数据流套接字(使用TCP协议),数据报套接字(UDP协议) 和原始套接字.由于数据流套接字和数据报套接字都要经过系统内核的处理,所以可控性就要低的多.所以这里我们要使用 原始套接字(原始套接字允许对较低层协议,如IP、ICMP直接访问)下面是一条创建原始套接字的语句

sockfd=socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));

其中的第一个参数表示使用的协议簇,PF_PACKET表示创建了一个链路层的socket,这样我们将捕获到最为原始的数据包 如果该参数是AF_INET,表示接收的是ip数据包

第二个参数是socket类型,对于本实例中创建的链路层socket我们可以指定类型有:

1 SOCK_DGRAM(捕获到的数据会被处理掉以太网帧部分)

2 RAW_SCOKET(以太网帧数据不会被处理掉)

最后一个参数表示绑定的协议.ETH_P_ALL表示捕获所有协议类型的包.我们可以根据自己的需要指定为ETH_P_IP或者其他的类型

现在我们创建好了套接字,接下来就是接收数据包了.这里我们用下面这个函数来接受数据

recvfrom(sockfd,buf,sizeof(buf),0,NULL,NULL);

第一个参数为套接字的文件描述符.第二个参数为接受内容的缓冲区,接下来的是缓冲区的大小.第四个参数是调用操作方式。 接下来的参数用于在这里用不到,我们指定为NULL即可.它们的含义如下:

1 from:(可选)指针,指向装有源地址的缓冲区。

2 fromlen:(可选)指针,指向from缓冲区长度值。

到目前为止,我们已经做好了数据捕获的所有任务.至于第二个过程就是根据数据帧的协议去对数据进行解析即可. 我们常用的tcp/ip/udp/icmp等协议的数据结构在这个文件夹下有定义

cd /usr/include/netinet/

最后我这里附上一个<<计算机网络>>课上做的一个简单数据包捕获的程序的源码,由于只是一个演示的程序,所以制作了 对于UDP/TCP/IP协议的分析.

查看源码