背景

当前的项目需求是通过raw socket来获取当前物理机上指定条件(ip和端口)的包。
方法1:抓取所有的包,在用户态的recvfrom(or recv)后,再通过代码逻辑来进行过滤;
方法2:通过设置,在底层实现过滤;
从效率上来说,毫无疑问是方法2更好;
方法2的实现,依赖libpcap和BPF;在此先简单介绍一下libpcap的安装和使用;

安装

参考链接:
linux下安装libpcap
需要先安装:
1、安装GCC:
yum -y install gcc-c++(由于我当前的环境docker下已安装了gcc,所以这一步跳过)
2、安装flex:
yum -y install flex
没有flex,直接安装libpcap会提示"Your operating system’s lex is insufficient to compile libpcap"错误;
3、安装bison
yum -y install bison
前面安装的是flex,就需要搭配bison,如不会提示"don’t have both flex and bison;reverting to lex/yacc"错误;
4、安装libpcap
我是从官网下载的 libpcap-1.10.0.tar.gz 来安装的:
libpcap官方链接
下载了压缩包后解压,然后安装命令如下:
./configure
make
make install

使用

来一个简单的测试程序:

//device.c 
  #include <stdio.h>
  #include <pcap.h>
  int main(int argc,char *argv[]){
      char *dev, errbuf[PCAP_ERRBUF_SIZE];
      dev=pcap_lookupdev(errbuf);
      if(dev==NULL){
         fprintf(stderr,"couldn't find default device: %s\n",errbuf);
         return(2);
      }
      printf("Device: %s\n",dev);
      return(0);
  }

编译指令:gcc -o device libpcap -lpcap
注意后面的 -lpcap ,否则会提示“pcap_lookupdev 未定义的引用”的错误;
然后运行libpcap 即可。
有时编译会报错:

error while loading shared libraries: libpcap.so.1: 
cannot open shared object file: No such file or directory。

解决方案:
libpcap error解决
首先找到 ld.so.conf 文件:

[root@1b2583d83c87 TCPFilter]# find / -name ld.so.conf
/etc/ld.so.conf

在 ld.so.conf 的后面添加一行: /usr/local/lib
结果如下:

[root@1b2583d83c87 TCPFilter]# cat /etc/ld.so.conf
include ld.so.conf.d/*.conf
/usr/local/lib

保存后,记得执行 **ldconfig **,使配置生效;再重新执行libpcap 即可:

[root@1b2583d83c87 workspace]# ./libpcap
Device: eth0

后续

关于libpcap的更进一步的使用,等后面的实践后再总结;
参考链接:
linux 下 tcpdump 详解 后篇(自己实现抓包过滤)
raw socket 使用 BPF 过滤报文

后记

今天同事给我简单介绍了一下SolarFlare,算是金融行业的标配了吧?只能说真是黑科技,直接越过内核来在网卡上实现网络实现。所以我前面所说的通过内核层面的过滤来进行优化,已经没用了,sigh,还想趁着这个机会学习一下bpf和eBPF呢。
SolarFlare可以参考:
高频交易:Solarflare组建超低延迟网络
Solarflare 低延迟万兆网卡配置和性能调优实践
SolarFlare资源汇总

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐