header_test.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. // Copyright 2012 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package ipv4
  5. import (
  6. "bytes"
  7. "encoding/binary"
  8. "net"
  9. "reflect"
  10. "runtime"
  11. "strings"
  12. "testing"
  13. "golang.org/x/net/internal/socket"
  14. )
  15. type headerTest struct {
  16. wireHeaderFromKernel []byte
  17. wireHeaderToKernel []byte
  18. wireHeaderFromTradBSDKernel []byte
  19. wireHeaderToTradBSDKernel []byte
  20. wireHeaderFromFreeBSD10Kernel []byte
  21. wireHeaderToFreeBSD10Kernel []byte
  22. *Header
  23. }
  24. var headerLittleEndianTests = []headerTest{
  25. // TODO(mikio): Add platform dependent wire header formats when
  26. // we support new platforms.
  27. {
  28. wireHeaderFromKernel: []byte{
  29. 0x45, 0x01, 0xbe, 0xef,
  30. 0xca, 0xfe, 0x45, 0xdc,
  31. 0xff, 0x01, 0xde, 0xad,
  32. 172, 16, 254, 254,
  33. 192, 168, 0, 1,
  34. },
  35. wireHeaderToKernel: []byte{
  36. 0x45, 0x01, 0xbe, 0xef,
  37. 0xca, 0xfe, 0x45, 0xdc,
  38. 0xff, 0x01, 0xde, 0xad,
  39. 172, 16, 254, 254,
  40. 192, 168, 0, 1,
  41. },
  42. wireHeaderFromTradBSDKernel: []byte{
  43. 0x45, 0x01, 0xdb, 0xbe,
  44. 0xca, 0xfe, 0xdc, 0x45,
  45. 0xff, 0x01, 0xde, 0xad,
  46. 172, 16, 254, 254,
  47. 192, 168, 0, 1,
  48. },
  49. wireHeaderToTradBSDKernel: []byte{
  50. 0x45, 0x01, 0xef, 0xbe,
  51. 0xca, 0xfe, 0xdc, 0x45,
  52. 0xff, 0x01, 0xde, 0xad,
  53. 172, 16, 254, 254,
  54. 192, 168, 0, 1,
  55. },
  56. wireHeaderFromFreeBSD10Kernel: []byte{
  57. 0x45, 0x01, 0xef, 0xbe,
  58. 0xca, 0xfe, 0xdc, 0x45,
  59. 0xff, 0x01, 0xde, 0xad,
  60. 172, 16, 254, 254,
  61. 192, 168, 0, 1,
  62. },
  63. wireHeaderToFreeBSD10Kernel: []byte{
  64. 0x45, 0x01, 0xef, 0xbe,
  65. 0xca, 0xfe, 0xdc, 0x45,
  66. 0xff, 0x01, 0xde, 0xad,
  67. 172, 16, 254, 254,
  68. 192, 168, 0, 1,
  69. },
  70. Header: &Header{
  71. Version: Version,
  72. Len: HeaderLen,
  73. TOS: 1,
  74. TotalLen: 0xbeef,
  75. ID: 0xcafe,
  76. Flags: DontFragment,
  77. FragOff: 1500,
  78. TTL: 255,
  79. Protocol: 1,
  80. Checksum: 0xdead,
  81. Src: net.IPv4(172, 16, 254, 254),
  82. Dst: net.IPv4(192, 168, 0, 1),
  83. },
  84. },
  85. // with option headers
  86. {
  87. wireHeaderFromKernel: []byte{
  88. 0x46, 0x01, 0xbe, 0xf3,
  89. 0xca, 0xfe, 0x45, 0xdc,
  90. 0xff, 0x01, 0xde, 0xad,
  91. 172, 16, 254, 254,
  92. 192, 168, 0, 1,
  93. 0xff, 0xfe, 0xfe, 0xff,
  94. },
  95. wireHeaderToKernel: []byte{
  96. 0x46, 0x01, 0xbe, 0xf3,
  97. 0xca, 0xfe, 0x45, 0xdc,
  98. 0xff, 0x01, 0xde, 0xad,
  99. 172, 16, 254, 254,
  100. 192, 168, 0, 1,
  101. 0xff, 0xfe, 0xfe, 0xff,
  102. },
  103. wireHeaderFromTradBSDKernel: []byte{
  104. 0x46, 0x01, 0xdb, 0xbe,
  105. 0xca, 0xfe, 0xdc, 0x45,
  106. 0xff, 0x01, 0xde, 0xad,
  107. 172, 16, 254, 254,
  108. 192, 168, 0, 1,
  109. 0xff, 0xfe, 0xfe, 0xff,
  110. },
  111. wireHeaderToTradBSDKernel: []byte{
  112. 0x46, 0x01, 0xf3, 0xbe,
  113. 0xca, 0xfe, 0xdc, 0x45,
  114. 0xff, 0x01, 0xde, 0xad,
  115. 172, 16, 254, 254,
  116. 192, 168, 0, 1,
  117. 0xff, 0xfe, 0xfe, 0xff,
  118. },
  119. wireHeaderFromFreeBSD10Kernel: []byte{
  120. 0x46, 0x01, 0xf3, 0xbe,
  121. 0xca, 0xfe, 0xdc, 0x45,
  122. 0xff, 0x01, 0xde, 0xad,
  123. 172, 16, 254, 254,
  124. 192, 168, 0, 1,
  125. 0xff, 0xfe, 0xfe, 0xff,
  126. },
  127. wireHeaderToFreeBSD10Kernel: []byte{
  128. 0x46, 0x01, 0xf3, 0xbe,
  129. 0xca, 0xfe, 0xdc, 0x45,
  130. 0xff, 0x01, 0xde, 0xad,
  131. 172, 16, 254, 254,
  132. 192, 168, 0, 1,
  133. 0xff, 0xfe, 0xfe, 0xff,
  134. },
  135. Header: &Header{
  136. Version: Version,
  137. Len: HeaderLen + 4,
  138. TOS: 1,
  139. TotalLen: 0xbef3,
  140. ID: 0xcafe,
  141. Flags: DontFragment,
  142. FragOff: 1500,
  143. TTL: 255,
  144. Protocol: 1,
  145. Checksum: 0xdead,
  146. Src: net.IPv4(172, 16, 254, 254),
  147. Dst: net.IPv4(192, 168, 0, 1),
  148. Options: []byte{0xff, 0xfe, 0xfe, 0xff},
  149. },
  150. },
  151. }
  152. func TestMarshalHeader(t *testing.T) {
  153. if socket.NativeEndian != binary.LittleEndian {
  154. t.Skip("no test for non-little endian machine yet")
  155. }
  156. for _, tt := range headerLittleEndianTests {
  157. b, err := tt.Header.Marshal()
  158. if err != nil {
  159. t.Fatal(err)
  160. }
  161. var wh []byte
  162. switch runtime.GOOS {
  163. case "darwin", "dragonfly", "netbsd":
  164. wh = tt.wireHeaderToTradBSDKernel
  165. case "freebsd":
  166. switch {
  167. case freebsdVersion < 1000000:
  168. wh = tt.wireHeaderToTradBSDKernel
  169. case 1000000 <= freebsdVersion && freebsdVersion < 1100000:
  170. wh = tt.wireHeaderToFreeBSD10Kernel
  171. default:
  172. wh = tt.wireHeaderToKernel
  173. }
  174. default:
  175. wh = tt.wireHeaderToKernel
  176. }
  177. if !bytes.Equal(b, wh) {
  178. t.Fatalf("got %#v; want %#v", b, wh)
  179. }
  180. }
  181. }
  182. func TestParseHeader(t *testing.T) {
  183. if socket.NativeEndian != binary.LittleEndian {
  184. t.Skip("no test for big endian machine yet")
  185. }
  186. for _, tt := range headerLittleEndianTests {
  187. var wh []byte
  188. switch runtime.GOOS {
  189. case "darwin", "dragonfly", "netbsd":
  190. wh = tt.wireHeaderFromTradBSDKernel
  191. case "freebsd":
  192. switch {
  193. case freebsdVersion < 1000000:
  194. wh = tt.wireHeaderFromTradBSDKernel
  195. case 1000000 <= freebsdVersion && freebsdVersion < 1100000:
  196. wh = tt.wireHeaderFromFreeBSD10Kernel
  197. default:
  198. wh = tt.wireHeaderFromKernel
  199. }
  200. default:
  201. wh = tt.wireHeaderFromKernel
  202. }
  203. h, err := ParseHeader(wh)
  204. if err != nil {
  205. t.Fatal(err)
  206. }
  207. if err := h.Parse(wh); err != nil {
  208. t.Fatal(err)
  209. }
  210. if !reflect.DeepEqual(h, tt.Header) {
  211. t.Fatalf("got %#v; want %#v", h, tt.Header)
  212. }
  213. s := h.String()
  214. if strings.Contains(s, ",") {
  215. t.Fatalf("should be space-separated values: %s", s)
  216. }
  217. }
  218. }