为什么tcpdump抓包数据校验和异常、长度超过MTU?

内核实现

tcpdump在抓取网络包时,实际它会创建一个socket,并且设置网卡为混杂模式,用于接收网络链路上所有地址的包。
发送方向:

dev_queue_xmit->dev_queue_xmit_nit:
static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)                                                                                                                                                             
{
......
	//检测到有sniffer抓包的钩子就会执行发送报文的抓包
	struct list_head *ptype_list = &ptype_all;
    list_for_each_entry_rcu(ptype, ptype_list, list) {
 
        if (pt_prev) {
            deliver_skb(skb2, pt_prev, skb->dev);
            pt_prev = ptype;
            continue;
        }
......                     
    	}
    }

接收方向:

netif_receive_skb-->__netif_receive_skb_core:

static int __netif_receive_skb_core(struct sk_buff *skb, bool pfmemalloc)
{
......
//在这里处理sniffer相关的skb接收处理,也就是tcpdump抓包的位置
list_for_each_entry_rcu(ptype, &ptype_all, list) {
        if (pt_prev)
            ret = deliver_skb(skb, pt_prev, orig_dev);
        pt_prev = ptype;
    }
......
 }

抓包数据异常原因

从上面介绍的内核实现来看,tcpdump抓取的数据分别是驱动接收处理的最后,以及驱动发送处理的开始。因此tcpdump抓取的数据可能不是最终在物理链路上发出去的和接收到的包。
使用tcpdump的抓取的包,然后利用wireshark进行分析那么可能会发现一些报错,主要会有两种异常现象:
MTU

  • 包长度超过MTU
  • 包的checksum不正确

主要原因在于:
1.硬件支持TSO、GRO特性
2.硬件支持checksum offload特性

在支持TSO和checksum offload的网卡上,skb数据在进入驱动层之前是不进行分片处理和完整的checksum计算的,而tcpdump抓取的包恰恰是在此处,而这并不代表实际链路上的包会发生错误。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值