You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

259 lines
5.8 KiB

  1. // Copyright 2015 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 icmp
  5. import (
  6. "net"
  7. "reflect"
  8. "testing"
  9. "golang.org/x/net/internal/iana"
  10. )
  11. var marshalAndParseExtensionTests = []struct {
  12. proto int
  13. hdr []byte
  14. obj []byte
  15. exts []Extension
  16. }{
  17. // MPLS label stack with no label
  18. {
  19. proto: iana.ProtocolICMP,
  20. hdr: []byte{
  21. 0x20, 0x00, 0x00, 0x00,
  22. },
  23. obj: []byte{
  24. 0x00, 0x04, 0x01, 0x01,
  25. },
  26. exts: []Extension{
  27. &MPLSLabelStack{
  28. Class: classMPLSLabelStack,
  29. Type: typeIncomingMPLSLabelStack,
  30. },
  31. },
  32. },
  33. // MPLS label stack with a single label
  34. {
  35. proto: iana.ProtocolIPv6ICMP,
  36. hdr: []byte{
  37. 0x20, 0x00, 0x00, 0x00,
  38. },
  39. obj: []byte{
  40. 0x00, 0x08, 0x01, 0x01,
  41. 0x03, 0xe8, 0xe9, 0xff,
  42. },
  43. exts: []Extension{
  44. &MPLSLabelStack{
  45. Class: classMPLSLabelStack,
  46. Type: typeIncomingMPLSLabelStack,
  47. Labels: []MPLSLabel{
  48. {
  49. Label: 16014,
  50. TC: 0x4,
  51. S: true,
  52. TTL: 255,
  53. },
  54. },
  55. },
  56. },
  57. },
  58. // MPLS label stack with multiple labels
  59. {
  60. proto: iana.ProtocolICMP,
  61. hdr: []byte{
  62. 0x20, 0x00, 0x00, 0x00,
  63. },
  64. obj: []byte{
  65. 0x00, 0x0c, 0x01, 0x01,
  66. 0x03, 0xe8, 0xde, 0xfe,
  67. 0x03, 0xe8, 0xe1, 0xff,
  68. },
  69. exts: []Extension{
  70. &MPLSLabelStack{
  71. Class: classMPLSLabelStack,
  72. Type: typeIncomingMPLSLabelStack,
  73. Labels: []MPLSLabel{
  74. {
  75. Label: 16013,
  76. TC: 0x7,
  77. S: false,
  78. TTL: 254,
  79. },
  80. {
  81. Label: 16014,
  82. TC: 0,
  83. S: true,
  84. TTL: 255,
  85. },
  86. },
  87. },
  88. },
  89. },
  90. // Interface information with no attribute
  91. {
  92. proto: iana.ProtocolICMP,
  93. hdr: []byte{
  94. 0x20, 0x00, 0x00, 0x00,
  95. },
  96. obj: []byte{
  97. 0x00, 0x04, 0x02, 0x00,
  98. },
  99. exts: []Extension{
  100. &InterfaceInfo{
  101. Class: classInterfaceInfo,
  102. },
  103. },
  104. },
  105. // Interface information with ifIndex and name
  106. {
  107. proto: iana.ProtocolICMP,
  108. hdr: []byte{
  109. 0x20, 0x00, 0x00, 0x00,
  110. },
  111. obj: []byte{
  112. 0x00, 0x10, 0x02, 0x0a,
  113. 0x00, 0x00, 0x00, 0x10,
  114. 0x08, byte('e'), byte('n'), byte('1'),
  115. byte('0'), byte('1'), 0x00, 0x00,
  116. },
  117. exts: []Extension{
  118. &InterfaceInfo{
  119. Class: classInterfaceInfo,
  120. Type: 0x0a,
  121. Interface: &net.Interface{
  122. Index: 16,
  123. Name: "en101",
  124. },
  125. },
  126. },
  127. },
  128. // Interface information with ifIndex, IPAddr, name and MTU
  129. {
  130. proto: iana.ProtocolIPv6ICMP,
  131. hdr: []byte{
  132. 0x20, 0x00, 0x00, 0x00,
  133. },
  134. obj: []byte{
  135. 0x00, 0x28, 0x02, 0x0f,
  136. 0x00, 0x00, 0x00, 0x0f,
  137. 0x00, 0x02, 0x00, 0x00,
  138. 0xfe, 0x80, 0x00, 0x00,
  139. 0x00, 0x00, 0x00, 0x00,
  140. 0x00, 0x00, 0x00, 0x00,
  141. 0x00, 0x00, 0x00, 0x01,
  142. 0x08, byte('e'), byte('n'), byte('1'),
  143. byte('0'), byte('1'), 0x00, 0x00,
  144. 0x00, 0x00, 0x20, 0x00,
  145. },
  146. exts: []Extension{
  147. &InterfaceInfo{
  148. Class: classInterfaceInfo,
  149. Type: 0x0f,
  150. Interface: &net.Interface{
  151. Index: 15,
  152. Name: "en101",
  153. MTU: 8192,
  154. },
  155. Addr: &net.IPAddr{
  156. IP: net.ParseIP("fe80::1"),
  157. Zone: "en101",
  158. },
  159. },
  160. },
  161. },
  162. }
  163. func TestMarshalAndParseExtension(t *testing.T) {
  164. for i, tt := range marshalAndParseExtensionTests {
  165. for j, ext := range tt.exts {
  166. var err error
  167. var b []byte
  168. switch ext := ext.(type) {
  169. case *MPLSLabelStack:
  170. b, err = ext.Marshal(tt.proto)
  171. if err != nil {
  172. t.Errorf("#%v/%v: %v", i, j, err)
  173. continue
  174. }
  175. case *InterfaceInfo:
  176. b, err = ext.Marshal(tt.proto)
  177. if err != nil {
  178. t.Errorf("#%v/%v: %v", i, j, err)
  179. continue
  180. }
  181. }
  182. if !reflect.DeepEqual(b, tt.obj) {
  183. t.Errorf("#%v/%v: got %#v; want %#v", i, j, b, tt.obj)
  184. continue
  185. }
  186. }
  187. for j, wire := range []struct {
  188. data []byte // original datagram
  189. inlattr int // length of padded original datagram, a hint
  190. outlattr int // length of padded original datagram, a want
  191. err error
  192. }{
  193. {nil, 0, -1, errNoExtension},
  194. {make([]byte, 127), 128, -1, errNoExtension},
  195. {make([]byte, 128), 127, -1, errNoExtension},
  196. {make([]byte, 128), 128, -1, errNoExtension},
  197. {make([]byte, 128), 129, -1, errNoExtension},
  198. {append(make([]byte, 128), append(tt.hdr, tt.obj...)...), 127, 128, nil},
  199. {append(make([]byte, 128), append(tt.hdr, tt.obj...)...), 128, 128, nil},
  200. {append(make([]byte, 128), append(tt.hdr, tt.obj...)...), 129, 128, nil},
  201. {append(make([]byte, 512), append(tt.hdr, tt.obj...)...), 511, -1, errNoExtension},
  202. {append(make([]byte, 512), append(tt.hdr, tt.obj...)...), 512, 512, nil},
  203. {append(make([]byte, 512), append(tt.hdr, tt.obj...)...), 513, -1, errNoExtension},
  204. } {
  205. exts, l, err := parseExtensions(wire.data, wire.inlattr)
  206. if err != wire.err {
  207. t.Errorf("#%v/%v: got %v; want %v", i, j, err, wire.err)
  208. continue
  209. }
  210. if wire.err != nil {
  211. continue
  212. }
  213. if l != wire.outlattr {
  214. t.Errorf("#%v/%v: got %v; want %v", i, j, l, wire.outlattr)
  215. }
  216. if !reflect.DeepEqual(exts, tt.exts) {
  217. for j, ext := range exts {
  218. switch ext := ext.(type) {
  219. case *MPLSLabelStack:
  220. want := tt.exts[j].(*MPLSLabelStack)
  221. t.Errorf("#%v/%v: got %#v; want %#v", i, j, ext, want)
  222. case *InterfaceInfo:
  223. want := tt.exts[j].(*InterfaceInfo)
  224. t.Errorf("#%v/%v: got %#v; want %#v", i, j, ext, want)
  225. }
  226. }
  227. continue
  228. }
  229. }
  230. }
  231. }
  232. var parseInterfaceNameTests = []struct {
  233. b []byte
  234. error
  235. }{
  236. {[]byte{0, 'e', 'n', '0'}, errInvalidExtension},
  237. {[]byte{4, 'e', 'n', '0'}, nil},
  238. {[]byte{7, 'e', 'n', '0', 0xff, 0xff, 0xff, 0xff}, errInvalidExtension},
  239. {[]byte{8, 'e', 'n', '0', 0xff, 0xff, 0xff}, errMessageTooShort},
  240. }
  241. func TestParseInterfaceName(t *testing.T) {
  242. ifi := InterfaceInfo{Interface: &net.Interface{}}
  243. for i, tt := range parseInterfaceNameTests {
  244. if _, err := ifi.parseName(tt.b); err != tt.error {
  245. t.Errorf("#%d: got %v; want %v", i, err, tt.error)
  246. }
  247. }
  248. }