【问题标题】:Access MAC address from sk_buff从 sk_buff 访问 MAC 地址
【发布时间】:2012-04-25 01:10:18
【问题描述】:

我正在编写一个内核模块来从存储在 sk_buff 中的数据包中获取 MAC 地址。我使用以下代码打印源和目标的 MAC 地址:

struct ethhdr *mh = eth_hdr(skb);  
printk(KERN_EMERG "Source MAC=%x:%x:%x:%x:%x:%x\n",mh->h_source[0],mh->h_source[1],mh->h_source[2],mh->h_source[3],mh->h_source[4],mh->h_source[5]);  

可以使用h_dest 代替h_source 访问目标地址。
我的问题是源 MAC 地址总是a8:c0:0:0:a8:c0 而目标 MAC 地址总是一些垃圾值而不是我自己的 MAC 地址。
谁能帮我解决这个问题?我想获取正确的 MAC 地址。

【问题讨论】:

  • 你可以使用 %pM 用 printk 打印 mac 地址。

标签: linux


【解决方案1】:

您在内核的哪个位置执行此操作?

a8:c0 看起来很可疑。它转换为十进制的 168.192,这让我怀疑您实际上是在查看 IPv4 标头而不是以太网标头。

【讨论】:

    【解决方案2】:

    使用eth_hdr 仅在 skb 实际上具有 MAC 标头时才有意义。如果没有,skb 的 MAC 头指针只会指向数据包中的其他数据。

    【讨论】:

      【解决方案3】:

      使用mac_len 可以帮助您解决这个问题。通常你会得到 14 个(6 个用于目标 mac + 6 个用于源 mac + 2 个用于协议)字节或 0(数据包来自环回)。请注意,如果返回 0,eth_hdr 将直接指向数据(在 ip 协议的情况下指向 ip 标头),而不是像 jørgensen 所说的那样指向以太网帧标头。

      获取非零mac_len的mac,可以直接使用eth_hdr返回的指针:

      struct ethhdr* pHdr = eth_hdr(skb);  
      printk(KERN_EMERG "Source MAC=%x:%x:%x:%x:%x:%x\n", pHdr[6], pHdr[7], pHdr[8], pHdr[9], pHdr[10], pHdr[11]);  
      

      如果您对计算环回数据包的 MAC 地址感兴趣,请参阅protocol 字段。例如,如果它等于 08 00 (8),则可以从目标 ip 地址获取 mac。如果地址是ff:ff:ff:ff,你就知道mac是ff:ff:ff:ff:ff:ff(广播)。如果没有,请使用设备的 mac 地址,或任何您喜欢的地址。

      【讨论】:

        【解决方案4】:

        您需要在第 2 层处理数据包才能访问以太网标头。如果您的 linux 内核模块在第 3 层(Netfilter 挂钩)获取数据包,则 MAC 地址不存在于数据包中。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-12-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多