Golang Go语言中darwin/amd64平台解析IP Packet Header得到的报文长度错误
Golang Go语言中darwin/amd64平台解析IP Packet Header得到的报文长度错误
直接贴代码,这是从 198.18.255.1
Ping 8.8.8.8
(原始 IP 不是这个)返回的 IP 报文:
package main
import (
"encoding/binary"
"fmt"
"golang.org/x/net/ipv4"
)
func main() {
// https://en.wikipedia.org/wiki/IPv4#Total_Length
var hdrBytes = []byte{
69, 0, // Version | IHL | DSCP | ECN
0, 84, // Total_Length
125, 47, // Identification
0, 0, // Flags | Fragment Offset
63, // Time To Live
1, // Protocol
85, 169, // Header Checksum
8, 8, 8, 8, // Source IP Address
198, 18, 255, 1, //Destination IP Address
}
header, err := ipv4.ParseHeader(hdrBytes)
if err != nil {
fmt.Printf("Parse failed. err: %v\n", err)
}
fmt.Printf("header: %v\n", header)
fmt.Printf("header.TotalLen: %d\n", header.TotalLen)
realTotalLen := binary.BigEndian.Uint16(hdrBytes[2:4])
fmt.Printf("realTotalLen: %d\n", realTotalLen)
totalLenByBigEndian := binary.BigEndian.Uint16(hdrBytes[2:4])
fmt.Printf("totalLenByBigEndian: %d\n", totalLenByBigEndian)
totalLenByLittleEndian := binary.LittleEndian.Uint16(hdrBytes[2:4])
fmt.Printf("totalLenByLittleEndian: %d\n", totalLenByLittleEndian)
}
这段是解析 IP 报文 Header 的代码,在 Linux 和 Windows 执行得到的 header.TotalLen 都是 84,但是 darwin/amd64 就是 21524 。
按照相关规范,IP 报文 Header 字段均以大端序包装。这个看起来在 darwin 用了小端序解析。但是就算用小端序,这个值也应该是 21504 。
看 Go 解析的代码,原来还在解析时加上了 hdrlen 自身的 20 长度,这个似乎有点问题。我不了解那么多关于平台相关的,但是网络 IP 报文应该和平台无关吧。
switch runtime.GOOS {
case "darwin", "ios", "dragonfly", "netbsd":
h.TotalLen = int(socket.NativeEndian.Uint16(b[2:4])) + hdrlen # 这里加了 Header 长度
h.FragOff = int(socket.NativeEndian.Uint16(b[6:8]))
case "freebsd":
if freebsdVersion < 1100000 {
h.TotalLen = int(socket.NativeEndian.Uint16(b[2:4]))
if freebsdVersion < 1000000 {
h.TotalLen += hdrlen
}
h.FragOff = int(socket.NativeEndian.Uint16(b[6:8]))
} else {
h.TotalLen = int(binary.BigEndian.Uint16(b[2:4]))
h.FragOff = int(binary.BigEndian.Uint16(b[6:8]))
}
default:
h.TotalLen = int(binary.BigEndian.Uint16(b[2:4]))
h.FragOff = int(binary.BigEndian.Uint16(b[6:8]))
}
然后 2 年前就有人提出这个问题了,但是还是没人修复。难道没人用 Mac 做 TCP/IP 网络编程吗。
更多关于Golang Go语言中darwin/amd64平台解析IP Packet Header得到的报文长度错误的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html