浏览代码

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>
Mikio Hara 9 年之前
父节点
当前提交
cf4effbb9d
共有 2 个文件被更改,包括 39 次插入12 次删除
  1. 18 5
      ipv4/header.go
  2. 21 7
      ipv4/header_test.go

+ 18 - 5
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]))

+ 21 - 7
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[:]