簡體   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