繁体   English   中英

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

[英]How to extract out the payload/data of an ethernet II frame?

我正在尝试使用 golang 在用户空间中实现 UDP 协议。 我已经达到了能够获取原始以太网 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],
    }
}

I've seen here( https://commons.wikimedia.org/wiki/File:Ethernet_Type_II_Frame_format.svg ) that an ethernet II frame can be anywhere between 64 to 1518 bytes long, but since there is no field in the header which says关于有效载荷长度的任何事情,我只是假设所有帧的长度都是 1518,在这种情况下,理论上我的代码应该可以工作。 但由于帧大多以不同的长度到达,我的假设失败了。 如何解析接收到的字节并仅获取有效负载? 我应该将dataBytes长度保持为什么?

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

  1. L2 - 数据链路(例如 Mac 地址、以太网类型、VLAN...)
  2. L3 - 网络(例如 IPv4 / IPv6 /...)
  3. L4 - 运输(例如 UDP / TCP /...)
  4. L5 - Payload 一些将 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 -有关 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。 更多关于以太类型

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

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

在这个阶段你知道总长度,第 4 层是 UDP。 检查维基https://en.wikipedia.org/wiki/User_Datagram_Protocol L4 看起来像 - 对于 UDP (TCP 不同,其他协议不同..):

Source prot   - 2 B
Dest port     - 2 B
Length        - 2 B
Checksum      - 2 B

总结一下——需要:

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

如果没有 VLAN 或 IPv4 以外的任何其他以太网类型,并且 IHL<=4 则有效负载从14 + 20 + 8开始

  • 14 B 用于 L2
  • 20 B 用于 L3
  • 8 B 用于 L4

祝你好运!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM