基于Linux的数据包捕获模块设计实现

1、 数据包捕获模块设计流程图 

  在数据包捕获程序中,通过设置网卡工作于混杂状态,对网络链路进行监听并收集数据包,从而获得数据包头信息。 

  2、数据包捕获模块实现 

  该数据包捕获程序用C语言来编写,程序中用到很多Linux网络编程中的函数。 

  (1)设置网络接口为混杂模式 

  网络接口的混杂模式使得一个网络接口设备从只能读取目标地址为6字节MAC地址的数据包,变为可读取网络广播媒体中的所有数据包。该部分通过两次ioctl函数调用实现: 
 
  ioctl(sock, SIOCGIFFLAGS, &ifr)
  ifr.ifr_flags |= IFF_PROMISC
  ioctl(sock, SIOCGIFFLAGS, &ifr)
  第一次的ioctl函数调用,用来截获ifr(struct ifreq)结构中所含接口名称所指接口的标记。第一个参数是打开的原始套接字描述符“sock”,第二个参数是所要执行的请求操作。第三个参数是接口请 求数据结构的地址指针,该结构中包含了所以进行请求操作的接口名称值。 

  我们通过将混合标记(IFF_PROMISC)应用到接口请求结构的标记位变量中来改变接口标记位。操作符“|=”将混合标记符与原有的接口标记进行 “或”操作来设置新的接口标记。获得新的接口标记后,将其设置到实际接口中。第二次的ioctl调用,将接口设备设置为混合模式。正如第一个ioctl调 用是获得网络接口的标记,这次调用是设置ifr结构中修改过的新标记写到物理接口上。 

  (2)打开Socket设备 

  用socket函数来打开Socket设备。sock = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)).domain域使用AF_PACKET,能够既接收链路层也接收网络层的数据包。 

  (3)接收数据 

  使用recvfrom()函数来实现接收数据包:
  recvfrom(sock,(char *)buf,sizeof(buf), 
0, (struct sockaddr *)&addr,&len)
  这是从打开的网络插座Socket读取数据包的地方,但要注意,addr结构有一个强制类型转换,以适应recvfrom()函数的语法要求,recvfrom()函数在成功读取的情况下返回读取的字节数,否则返回-1。 

  (4)判断包头指针 

  该数据包捕获模块可以接收到的数据包都是原始数据包,它们的格式一般先是以太网数据帧的头部,接着是ARP或者IP数据包的头部。IP数据包后紧跟着 TCP或UDP、ICMP的头部,最后才是真正要传输的数据。于是,在拆分IP数据包时,先提取以太网数据帧的头部,再提取IP数据包的头部,然后分析 TCP或UDP、ICMP数据包的头部。最后,从数据包提取出需要的数据。 

  3、程序中用到的一些结构体解析 

  (1)sockadd_in结构体 

  在网络中第一个被创造的结构类型是sockaddr。这个数据结构是为许多类型的套接口储存地址信息。它的定义如下:
  struct sockaddr{
  unsigned shortsa_family; /*这个是地址族,通常是AF-xxxx的形式*/
  charsa_data[14]; /*14字节的地址信息*/
  };
  (2)ethhdr结构体 

  以下是相应数据结构:
  struct ethhdr
  {
  unsigned char h_dest[ETH_ALEN];/*48位的目标地址的网卡物理地址*/
  unsigned char h_source[ETH_ALEN];/*48位的源地址的物理网卡地址*/
  unsigned short h_proto;/*16位的以太网协议*/
  }
  
  (3)iphdr结构体 

  这是Linux 的ip协议报头,针对版本的不同它可以有不同的定义,我们国内一般用BIG的定义,其中version 是ip的版本,protocol是ip的协议分类,saddr是32位的源ip地址,daddr是32位的目标ip地址。 

  (4)tcphdr结构体 

  这是Linux 下tcp协议的一部分,与ip协议相同取BIG,其中source是源端口,dest 是目的端口,seq是s序,ack_seq是a序号,其余的是tcp的连接标志其中包括6个标志:syn表示连接请求,urg 表示紧急信息,fin表示连接结束,ack表示连接应答,psh表示推栈标志,rst表示中断连接。window是表示接受数据窗口大小,check是校 验码,urg ptr是紧急指针。 

  (5)udphdr结构体 

  这是Linux下ip协议中udp协议的一部分,以下是相应数据结构:
  struct udphdr
  {
  u_int16_t source;/* 源端口*/
  u_int16_t dest;/* 目的端口*/
  u_int16_t len;/* udp 长度*/
  u_int16_t check;/*校验码*/
  }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值