>1、数据包捕获模块结构
数据包捕获模块用于监视和验证网络流量情况,它可以截取或者阅读网络上OSI协议模型中各个协议层次上的数据包。
本文所设计的数据包捕获程序可以捕获通过原始套接口(Socket)的原始数据包(Raw Packet),当一个数据包到达网络接口时,数据包捕获程序就直接从缓存区读取捕获的数据包,以供数据分析和处理时调用。数据捕获模块的结构如图1所示:
↓
图1 数据捕获程序结构图
2、数据包捕获模块原理分析
(1)网卡设置原理
在一个实际的系统中,数据的收发是由网卡来完成的,网卡接收到传输来的数据,网卡内的程序接收数据帧的目的MAC地址,根据计算机上的网卡驱动程序设置的接收模式判断该不该接收,认为不该接收就丢掉不管。而对于网卡来说一般有四种接收模式:广播模式组播模式、直接方式、混杂模式。数据包捕获程序首先使网络接口(网卡)处于混杂状态,从而可截获网络上的内容,并且通过相应的软件处理,可以实时分析这些数据的内容,为数据包过滤作准备。
(2)基本函数说明
本文中在Linux主机上用C语言编写数据包捕获程序,所编写的程序中用到很多Linux中的预定义函数,在此节将对这些基本函数的功能和使用特点进行说明。
1)ioctl函数定义
ioctl()函数非常庞杂,它可以控制各种文件的属性。它用于控制特殊文件的底层设备参数,这些特殊文件通常是指终端、套接字和接口。ioctl函数原型为:
int ioctl(int handle,int cmd[,int *argdx,int argcx]);
2)socket函数定义
常用的Socket类型有两种:流式Socket(SOCK_STREAM)和数据包式Socket (SOCK_DGRAM)。流式是一种面向连接的Socket,针对面向连接的TCP服务应用;数据报式Socket是一种无连接的Socket,针对无连接的UDP服务应用。Socket函数原型为:
int socket(int domain, int type,int protocol);
3)recvfrom()函数定义
用recvfrom()函数来实现接收数据包,recvfrom()是具备“阻塞式I/O”特性的函数,能够在没有数据包到达的情况下暂时挂起等待,直至接收到数据包后,再激活转入下一步处理。recvfrom()函数的原型为:
int recvfrom(SOCKET s,char FAR *buf,int len,int flags,struct sockaddr FAR *from,int *fromlen);
本函数从已连接套接口上接收数据,并捕获数据发送源的地址。对于SOCK_STREAM类型的套接口,最多可以接收缓冲区大小个数据。如果套接口被设置为线内接收带外数据(选项为 SO_OOBINLINE),且有带外数据未读入,则返回带外数据。应用程序可通过调用ioctlsocket()的SOCATMARK命令来确定是否有带外数据待读入。对于SOCK_STREAM类型套接口,忽略from和fromlen参数。