这个问题其实是我几个月前碰到,只是那时好像还在回忆着什么,心系上海,还没有完全适应这个新环境,加上这个问题也不是什么太深奥的问题,觉得太简单了,就搁置了。今天周末闲来无事就顺便写来来了。加上深圳经常下雨,越来越喜欢了。

本文没什么深度,仅为记录,以及阐述一个“看文档学习原理->猜测并自行实现->对比标准实现确认”的方法。

问题是这样的:
在Linux上如果使用tcpdump去抓取lo口的数据包,你只能抓到一遍,而不是两遍,按常理来讲,数据包在outgoing路径上和incoming路径上都会被抓到,对于lo口而言,两个路径都要经过它本身,为什么只能抓到一个呢?难道lo口做了什么特殊的处理吗?

依然是传统的三招破解:看文档学习原理,猜测实现,确认实现

1.看文档学习原理

最直接的就是先去man tcpdump,前面的参数详解部分可以不看,只看最后面的NOTES或者BUGS部分就好,其BUGS部分有一个细节正中这个话题:
BUGS
...
   On Linux systems with 2.0[.x] kernels:
          packets on the loopback device will be seen twice;
          packet filtering cannot be done in the kernel, so that all packets must be copied from the kernel in order to be filtered in user mode;
          all of a packet, not just the part that's within the snapshot length, will be copied from the kernel (the 2.0[.x] packet capture mechanism, if asked to copy only part of a packet to userland, will not report the true
          length of the packet; this would cause most IP packets to get an error from tcpdump);
          capturing on some PPP devices won't work correctly.

看样子已经说的很清楚了,“packets on the loopback device will be seen twice”描述了问题,“packet filtering cannot be done in the kernel, so that all packets must be copied from the kernel in order to be filtered in user mode”假装说明了原因。

2.猜测实现

如果在Linux内核内部对lo进行特殊的抓包过滤,那就太不靠谱了,如果有这么一个需求就这么过滤一次的话,内核会遍布if-else...switch-case...搞不好还要引入正儿八经的多态。内核只要提供足够的信息,用户态自己过滤即可。在看代码之前,做出以上猜测是合理的。

3.确认实现

最直接的先看内核代码的packet_rcv函数,这个函数是tcpdump抓包的入口函数(当然如果经过了PF_RING的优化,就不是这样了,但简单来讲,大多数就是这样):

static int packet_rcv(struct sk_buff *skb, struct device *dev,  struct packet_type *pt)
{struct sock *sk;struct sockaddr_ll *sll = (struct sockaddr_ll*)skb->cb;/** When we registered the protocol we saved the socket in the data*    field for just this event.*/sk = (struct sock *) pt->data;// 注意,PACKET_LOOPBACK只是和multicast相关的,与我们讨论的无关if (skb->pkt_type == PACKET_LOOPBACK) {kfree_skb(skb);return 0;}skb->dev = dev;sll->sll_family = AF_PACKET;sll->sll_hatype = dev->type;sll->sll_protocol = skb->protocol;sll->sll_pkttype = skb->pkt_type;sll->sll_ifindex = dev->ifindex;sll->sll_halen = 0;
...
}

然后看一下发送路径的处理:

void dev_queue_xmit_nit(struct sk_buff *skb, struct device *dev)
{...skb2->pkt_type = PACKET_OUTGOING;ptype->func(skb2, skb->dev, ptype);...
}

看来,PACKET_OUTGOING是一个核心的标志,它可以告诉tcpdump数据包是从哪里路径发出的。最后,我们看一下pcap的数据包读取函数pcap_read_linux_mmap:

if (sll->sll_pkttype == PACKET_OUTGOING) {/** Outgoing packet.* If this is from the loopback device, reject it;* we'll see the packet as an incoming packet as well,* and we don't want to see it twice.*/if (sll->sll_ifindex == handle->md.lo_ifindex)goto skip;/** If the user only wants incoming packets, reject it.*/if (handle->direction == PCAP_D_IN)goto skip;
} 

直接看注释就好了。

只可惜,Linux 2.0的内核中,并没有提供这个PACKET_OUTGOING信息,抓上去的就是一个裸包,没有足够的信息,当然就无法区分两个方向了,这也是tcpdmp的manual中那个BUG的根源。这个BUG的解决也帮助我们理解了为什么lo口抓包只抓到一个方向的,而不是两遍。还让我们知道了,lo口抓包抓取的是incoming方向的数据包。

关于Linux LOOPBACK网口抓包的一个细节相关推荐

  1. linux端口抓包工具下载,linux下的抓包工具tcpdump

    linux下的抓包工具. 抓包工具比较好用的有两个,一个是snort,一个是tcpdump,这次不说snort了,觉得这个工具虽然很强大,但是比较复杂,还是tcpdump比较简单.tcpdump wi ...

  2. linux抓包库libpcap,linux下libpcap抓包分析.doc

    linux下libpcap抓包分析 HYPERLINK "/Seiyagoo/archive/2012/04/28/2475618.html" linux下libpcap抓包分析 ...

  3. Linux下USB抓包工具UsbMon的使用和包数据格式解析

    Linux下USB抓包工具UsbMon的使用和包数据格式解析 一.UsbMon的使用步骤 1.挂载debugfs 2.加载usbmon模块 3.确认usbmon是否可用 4.确认usb设备挂在哪条总线 ...

  4. LiveGBS流媒体平台GB/T28181常见问题-播放花屏、没有通道、无法语音对讲等情况下Windows和Linux中如何抓包

    LiveGBS播放花屏.没有通道.无法语音对讲等情况下Windows和Linux中如何抓包 1.第一步:抓包工具准备 1.1.Linux 1.2.windows 2.第二步:找到设备出口ip 3.第三 ...

  5. DPDK2.2.0开发杂记一—— 网口抓包分片禁止及MTU配置

    1. 禁止网口抓包分片 DPDK收发包是基础核心模块,网卡需要应用进程进行配置并启动,测试过程中发现DPDK驱动igb_uio抓包可能会出现mbuf串.当网络包比较大时,DPDK驱动会把包进行分片放到 ...

  6. 【linux】【tcpdump】linux之tcpdump抓包及wireshark分析详解

    linux的tcpdump命令主要用于网络问题的调试中,通过抓取传输过程的数据包进行分析和调试.而wireshark则是一款功能强大,使用方便的数据包分析工具,tcpdump+wireshark组合使 ...

  7. Linux命令行抓包及包解析工具tshark(wireshark)使用实例解析

    在Linux下,当我们需要抓取网络数据包分析时,通常是使用tcpdump抓取网络raw数据包存到一个文件,然后下载到本地使用wireshark界面网络分析工具进行网络包分析. 最近才发现,原来wire ...

  8. linux下libpcap抓包分析

    一.首先下载libpcap包http://www.tcpdump.org/#latest-release 然后安装,安装完成后进入安装根目录的tests文件夹,编译运行findalldevstest. ...

  9. Linux网络报文捕获/抓包技术对比:napi、libpcap、afpacket、PF_RING、PACKET_MMAP、DPDK、XDP(eXpress Data Path)

    Table of Contents 1.传统linux网络协议栈流程和性能分析 协议栈的主要问题 针对单个数据包级别的资源分配和释放 流量的串行访问 从驱动到用户态的数据拷贝 内核到用户空间的上下文切 ...

最新文章

  1. 【FPGA】FPGA中的缓冲与驱动那些事
  2. 重新学.Net[四]——效率和安全
  3. C#中数据类型的安全转换(is,as)
  4. Android-广播接收者简介
  5. 实战Jquery(一)--username校验
  6. Linux环境变量PSI指什么,PSI 文件扩展名: 它是什么以及如何打开它?
  7. 姑苏山塘飞雪披银装[组图]
  8. 【CodeForces - 471D 】【构造差分kmp】MUH and Cube Walls
  9. 计算机网络——数据通信系统(三)
  10. [置顶] woff格式字体怎么打开和编辑?
  11. 中国移动微处理器CM32M101A介绍
  12. ctfmon是什么启动项_开机启动项命令是什么-百度经验
  13. android 屏幕自动滚动效果,Android滑动屏幕效果
  14. 第一个项目的大概流程
  15. 分享:制作属于自己的O'REILLY“动物书”封面
  16. 2022全网最全的持续集成基础【你知道的和不知道都在这里】
  17. python吃显卡还是内存不足_解决Pytorch 训练与测试时爆显存(out of memory)的问题
  18. Windows系统部分软件显示乱码
  19. C语言开发情人节玫瑰
  20. 正则^ [A-Za-z_][A-Za-z_0-9]*integer类型——学JAVA前一定要搞懂的最基本的东西(2)

热门文章

  1. 我xp电脑桌面没有计算机图标不见了,XP电脑开机后桌面图标打开方式全部不见的恢复方法...
  2. adb调试android设备
  3. WPS2017 电子表格/Excel文件保护密码忘记了?
  4. 别踩白块儿 开源免费(C++)
  5. WordPress插件|ThnBoV1.3.0-缩略图美化插件
  6. 龙族幻想最新东京机器人位置_龙族幻想藤原智坐标位置一览 藤原智任务攻略...
  7. Gimp图像处理资料收集
  8. java jbutton 背景颜色_java – 在Windows上设置JButton背景颜色
  9. Android多开分身 v7.2 破解永久VIP付费版
  10. 如何才能成为年薪百万的编程高手?