gpt4 book ai didi

linux - 如何提取以太网 II 帧的有效载荷/数据?

转载 作者:行者123 更新时间:2023-12-01 22:23:19 25 4
gpt4 key购买 nike

我正在尝试使用 golang 在用户空间中实现 UDP 协议(protocol)。我已经达到了能够获取原始以太网 II 数据包的程度。

我的代码看起来像这样:


type EthernetFrame struct {
SrcAddress []byte
DestAddress []byte
EtherType []byte
Payload []byte
CRC []byte
}

func ReadEthernetPackets(ethernetSocket int) EthernetFrame {
dataBytes := make([]byte, 1518)
syscall.Read(ethernetSocket, dataBytes)
return EthernetFrame {
SrcAddress: dataBytes[0:6],
DestAddress: dataBytes[6:12],
EtherType: dataBytes[12:14],
Payload: dataBytes[14:1515],
CRC: dataBytes[1515:1518],
}
}

我在这里( https://commons.wikimedia.org/wiki/File:Ethernet_Type_II_Frame_format.svg)看到以太网 II 帧的长度可以在 64 到 1518 字节之间,但是由于 header 中没有字段说明有效载荷长度,我只是假设所有帧的长度为 1518,在这种情况下,理论上我的代码应该可以工作。但由于帧大多以不同的长度到达,我的假设失败了。
如何解析接收到的字节并仅获取有效负载? dataBytes 我应该保留什么?长度为?

最佳答案

每个互联网数据包存在于以下层:

  • L2 - 数据链路(例如 Mac 地址、以太网类型、VLAN...)
  • L3 - 网络(例如 IPv4/IPv6/...)
  • L4 - 传输(例如 UDP/TCP/...)
  • L5 - 有效载荷
    有些人将 L5 划分为三个不同的层(L5、L6 和 L7,分别是 session 、表示和应用程序)。
    更多细节可以在 wiki OSI Moudel 中找到!

  • 对于 L2,因为您期望 IPv4(不是 IPv6,对吗?):
    EthernetFrame {
    Dest Mac Addr, # Len is 6 B
    Src Mac Addr, # Len is 6 B
    EtherType, # Len is 2 B - This value will be 0x0800
    }

    如果这是 IPv4,那么 EtherType==0x0800如果 EtherType==0x8100 ,那么这是 VLAN,然后在此之后期望读取另一个 2 B 用于 VLAN 数据 PCP/DEI/VID - more about VLAN !
    所以你的数据包看起来像:
    EthernetFrame {
    Dest Mac Addr, # Len is 6 B - Some Dest Mac
    Src Mac Addr, # Len is 6 B - Some Src Mac
    EtherType, # Len is 2 B - 0x8100 - VLAN
    VlanData, # Len is 2 B - VLAN Data - DEI / PCP / VID
    EtherType # Len is 2 B - Again, need to parse...
    }

    现在如果第二个 EtherType==0x0800那么下一层(L3 - 网络)是 IPv4。
    More about ethertype

    L3 - 网络层 - 来自 wiki https://en.wikipedia.org/wiki/IPv4 ?
    由于这个 IPv4,所以 L3 长度固定为 5 B(40 位),除非 IHL > 5。
    Version               - 4 b
    IHL - 4 b
    DSCP - 6 b
    ECN - 2 b
    Total Len - 16 b - Include header + data
    Identification - 16 b
    Flags - 3 b
    Fragment offset - 13 b
    TTL (Time to Live) - 8 b
    Protocol - 8 b (for next Layer parse, in your case will be UDP with 0x11)
    Header Checksum - 16 b
    Src IP Addr - 32 b
    Dest IP Addr - 32 b

    上面的数据包描述了 IPv4 数据包,以防 IHL<=4 .否则,就 IHL len 将选项尾添加到数据包中。

    在这个阶段,您知道总长度,并且第 4 层是 UDP。
    查看维基 https://en.wikipedia.org/wiki/User_Datagram_Protocol ?
    L4 看起来像 - 对于 UDP(TCP 不同,其他协议(protocol)不同..):
    Source prot   - 2 B
    Dest port - 2 B
    Length - 2 B
    Checksum - 2 B

    总结一下——需要:
  • 从L2开始,了解什么是ethertype,并以此为基础解析L3
  • 在 L3 上,需要学习所有总长度和 L4 协议(protocol)类型(例如 UDP 或 TCP)。
  • 在 L4 上,需要学习 len(你也从 L3 知道它!!!)。
  • 解析载荷!!

  • 如果没有 VLAN 或 IPv4 以外的任何其他以太网类型,并且 IHL<=4
    然后payload从 14 + 20 + 8开始
  • 14 B 用于 L2
  • 20 B 用于 L3
  • 8 B 用于 L4

  • 祝你好运!

    关于linux - 如何提取以太网 II 帧的有效载荷/数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61551398/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com