diff --git a/ipv4/header.go b/ipv4/header.go index 363d9c21..f31be59d 100644 --- a/ipv4/header.go +++ b/ipv4/header.go @@ -63,9 +63,17 @@ func (h *Header) Marshal() ([]byte, error) { b[1] = byte(h.TOS) flagsAndFragOff := (h.FragOff & 0x1fff) | int(h.Flags<<13) switch runtime.GOOS { - case "darwin", "dragonfly", "freebsd", "netbsd": + case "darwin", "dragonfly", "netbsd": nativeEndian.PutUint16(b[2:4], uint16(h.TotalLen)) nativeEndian.PutUint16(b[6:8], uint16(flagsAndFragOff)) + case "freebsd": + if freebsdVersion < 1100000 { + nativeEndian.PutUint16(b[2:4], uint16(h.TotalLen)) + nativeEndian.PutUint16(b[6:8], uint16(flagsAndFragOff)) + } else { + binary.BigEndian.PutUint16(b[2:4], uint16(h.TotalLen)) + binary.BigEndian.PutUint16(b[6:8], uint16(flagsAndFragOff)) + } default: binary.BigEndian.PutUint16(b[2:4], uint16(h.TotalLen)) binary.BigEndian.PutUint16(b[6:8], uint16(flagsAndFragOff)) @@ -113,11 +121,16 @@ func ParseHeader(b []byte) (*Header, error) { h.TotalLen = int(nativeEndian.Uint16(b[2:4])) + hdrlen h.FragOff = int(nativeEndian.Uint16(b[6:8])) case "freebsd": - h.TotalLen = int(nativeEndian.Uint16(b[2:4])) - if freebsdVersion < 1000000 { - h.TotalLen += hdrlen + if freebsdVersion < 1100000 { + h.TotalLen = int(nativeEndian.Uint16(b[2:4])) + if freebsdVersion < 1000000 { + h.TotalLen += hdrlen + } + h.FragOff = int(nativeEndian.Uint16(b[6:8])) + } else { + h.TotalLen = int(binary.BigEndian.Uint16(b[2:4])) + h.FragOff = int(binary.BigEndian.Uint16(b[6:8])) } - h.FragOff = int(nativeEndian.Uint16(b[6:8])) default: h.TotalLen = int(binary.BigEndian.Uint16(b[2:4])) h.FragOff = int(binary.BigEndian.Uint16(b[6:8])) diff --git a/ipv4/header_test.go b/ipv4/header_test.go index 85cb9c48..4e571397 100644 --- a/ipv4/header_test.go +++ b/ipv4/header_test.go @@ -18,8 +18,9 @@ type headerTest struct { wireHeaderFromKernel [HeaderLen]byte wireHeaderToKernel [HeaderLen]byte wireHeaderFromTradBSDKernel [HeaderLen]byte - wireHeaderFromFreeBSD10Kernel [HeaderLen]byte wireHeaderToTradBSDKernel [HeaderLen]byte + wireHeaderFromFreeBSD10Kernel [HeaderLen]byte + wireHeaderToFreeBSD10Kernel [HeaderLen]byte *Header } @@ -47,6 +48,13 @@ var headerLittleEndianTest = headerTest{ 172, 16, 254, 254, 192, 168, 0, 1, }, + wireHeaderToTradBSDKernel: [HeaderLen]byte{ + 0x45, 0x01, 0xef, 0xbe, + 0xca, 0xfe, 0xdc, 0x45, + 0xff, 0x01, 0xde, 0xad, + 172, 16, 254, 254, + 192, 168, 0, 1, + }, wireHeaderFromFreeBSD10Kernel: [HeaderLen]byte{ 0x45, 0x01, 0xef, 0xbe, 0xca, 0xfe, 0xdc, 0x45, @@ -54,7 +62,7 @@ var headerLittleEndianTest = headerTest{ 172, 16, 254, 254, 192, 168, 0, 1, }, - wireHeaderToTradBSDKernel: [HeaderLen]byte{ + wireHeaderToFreeBSD10Kernel: [HeaderLen]byte{ 0x45, 0x01, 0xef, 0xbe, 0xca, 0xfe, 0xdc, 0x45, 0xff, 0x01, 0xde, 0xad, @@ -92,10 +100,13 @@ func TestMarshalHeader(t *testing.T) { case "darwin", "dragonfly", "netbsd": wh = tt.wireHeaderToTradBSDKernel[:] case "freebsd": - if freebsdVersion < 1000000 { + switch { + case freebsdVersion < 1000000: wh = tt.wireHeaderToTradBSDKernel[:] - } else { - wh = tt.wireHeaderFromFreeBSD10Kernel[:] + case 1000000 <= freebsdVersion && freebsdVersion < 1100000: + wh = tt.wireHeaderToFreeBSD10Kernel[:] + default: + wh = tt.wireHeaderToKernel[:] } default: wh = tt.wireHeaderToKernel[:] @@ -116,10 +127,13 @@ func TestParseHeader(t *testing.T) { case "darwin", "dragonfly", "netbsd": wh = tt.wireHeaderFromTradBSDKernel[:] case "freebsd": - if freebsdVersion < 1000000 { + switch { + case freebsdVersion < 1000000: wh = tt.wireHeaderFromTradBSDKernel[:] - } else { + case 1000000 <= freebsdVersion && freebsdVersion < 1100000: wh = tt.wireHeaderFromFreeBSD10Kernel[:] + default: + wh = tt.wireHeaderFromKernel[:] } default: wh = tt.wireHeaderFromKernel[:]