抓包程序的一些分享

昨晚同白总和adden提到抓包的问题。因为写过相关的代码,遇到过抓包的各种各样的坑,此文分享一些相关的经验。 1. Linux cooked capture 在用tcpdump或wireshark看数据包时,有时会看到数据链路层的的包头称为Linux cooked capture。这不是一个真实的包头,当用tcpdump指定从所有网络介质 -i any 抓包时,所有抓到的包的数据链路层被换成了Linux cooked capture。在wireshark官方网站对Linux cooked capture的解释中: 这是一个在linux上被libpcap抓包库使用的“假协议”(pseudo-protocal),当从“any”设备在抓包,或者本地的数据链路层包头无效时被使用。更多,见http://wiki.wireshark.org/SLL 2. IP over IP tunnel wikipedia的示例图显示IP tunnel上的包的结构是: 但实战中用libpcap库从我们的线上机的IP隧道抓包时,pcap_loop或pcap_dispatch或pcap_next函数返回的数据包只有Inner IP header + IP payload,没有Outer IP headr,也没链路层的头部。多么幸运啊! 3. 混乱的RAW_SOCKET,PF_PACKET协议族 这不是工业标准定义的神秘领域,非常之混乱,谨慎进入。如果要写这方面的socket,可供参考。个人经验,用linux原生的socket抓包时,socket()的三的参数如下组合时的神奇效果. _recv_fd = socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_IP)); 从此socket中读所有的IP包,返回的IP包没有链路层包头,因为第二个参数是SOCK_DGRAM,链路层包头返回时被去掉。第三个参数指定的是IP包。奇怪的是,如果出站的IP包的目的地址不是本机,则出站的IP包不会被抓到。 _recv_fd = socket(AF_PACKET , SOCK_RAW , htons(ETH_P_IP)); 和上一个socket的区别是,这个会返回链路层包头。和上一个socket一样,同样只能装到部分出站的包。 _recv_fd = socket(AF_INET, SOCK_RAW, IPPROTO_TCP); 这行代码只可以读入站的包,抓不到出站的包。 _recv_fd = socket(AF_PACKET , SOCK_RAW , htons(ETH_P_ALL)); ...

December 26, 2013 · 1 min · kamus