ipv4: add support for FreeBSD 11

From FreeBSD 11 both ip_len and ip_off fields of struct ip must be
provided in network byte order. See IP(4) on FreeBSD.

Change-Id: I091b551074767daf098cc1d6a256eddc4f55e304
Reviewed-on: https://go-review.googlesource.com/30736
Run-TryBot: Mikio Hara <mikioh.mikioh@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
Mikio Hara
2016-10-11 12:19:24 +09:00
parent f4b625ec9b
commit cf4effbb9d
2 changed files with 39 additions and 12 deletions

View File

@@ -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]))

View File

@@ -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[:]