自写网卡抓包程序

网上网卡抓包程序已经较多,我也就在这里写下近段时间我的感悟,一作自己整理思路,二为需要的人取用。本文所做的网卡抓包程序类似于简化版wireshark功能。废话不多说,我们开始。

我们的目标是获取所有经过本地网卡的报头信息,包括链路层的MAC头,网络层的IP头,传输层的tcp或udp头,以及应用层的http头,并将其完整打印出来。

整个思路其实很简单,无非就是获取经过网卡的数据帧,然后将其按照格式打印出来即可。

想要获取数据帧,就不得不借用原始套接字(raw socket),raw socket的原理按我理解相当于在数据帧进入网卡时直接通过调用raw socket将数据帧备份一遍,直接将备份的数据帧交由你写的抓包程序处理,而原本的数据帧仍然一步步通过协议栈解析。

一般情况下我们使用的raw socket有两类:1、socket(AF_INET, SOCK_RAW, IPPROTO_TCP|IPPROTO_UDP|IPPROTO_ICMP)发送和接收ip数据包。2、socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP|ETH_P_ARP|ETH_P_ALL))发送接收以太网数据帧。这里我们选用第二种。此函数的第三个变量是socket的protocol,定义于<netinet/in.h>。常用的协议有ETH_P_IP  , ETH_P_ARP,ETH_P_RARP或ETH_P_ALL,从字面上我们就可以很好理解。同时此函数返回值与一般的socket一样,就是个套接字。

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. ret = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &nrecv_buff, sizeof(int));  
  2. if (ret < 0)  
  3. {  
  4.     perror("[Error]Set socket option");  
  5.     close(fd);  
  6.     exit(0);  
  7. }  

由于主机上的网卡可能不止一块,我们需要bind到某一块网卡上,这里就需要了解一个重要的结构类型struct ifreq。ifreq结构定义在/usr/include/net/if.h中,用来配置ip地址,激活接口,配置MTU等接口信息的。其中包含了一个接口名称和union(有可能是IP地址,广播地址,子网掩码,MAC号,MTU等)。ifreq包含在ifconf结构中。而ifconf结构通常是用来保存所有接口的信息的。利用ioctl与ifreq结构体我们可以获得某个网卡(特定接口名称ethx)的ip地址。

关于ioctl的解释可以参考my.oschina.net/dream0303/blog/179893。这里我们定义一个名为ifr的ifreq结构体,先strcpy(ifr.ifr_name, g_ifname)g_ifname可为(ethx自设),利用ioctl(fd, SIOCGIFINDEX, &ifr)即可得到此网卡的接口地址。(当有多块网卡时,每个网卡都会有一个索引值,值会随着正在被使用的网卡个数变化,这个索引值就是网卡的接口地址)。因此,通过索引值,我们就可以定位到本机上指定的一块网卡。需要注意的是,在我的测试机上有两块网卡,一块网卡仅服务于内网,因此我之前bind时接收到的全是arp数据包。

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. strcpy(ifr.ifr_name, g_ifname);  
  2. printf("Get networkcard port!\n");  
  3. ret = ioctl(fd, SIOCGIFINDEX, &ifr);  
  4. if (ret < 0)  
  5. {  
  6.     perror("[Error]Get networkcard ip");  
  7.     close(fd);  
  8.     exit(0);  
  9. }  

然后通过网卡接口地址,将原始套接字绑定到网卡上,ret = bind(fd, (struct sockaddr *)&sock, sizeof(sock))这里的sock便不再是之前TCP连接时的 struct sockaddr_in 了,而是struct  sockaddr_ll,具体定义可以参考hi.baidu.com/sjb811023/item/e0463c16ee4f5ba7feded5ff。

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值