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.
13 "golang.org/x/net/icmp"
14 "golang.org/x/net/internal/iana"
15 "golang.org/x/net/ipv4"
16 "golang.org/x/net/ipv6"
19 var marshalAndParseMultipartMessageForIPv4Tests = []icmp.Message{
21 Type: ipv4.ICMPTypeDestinationUnreachable, Code: 15,
22 Body: &icmp.DstUnreach{
23 Data: []byte("ERROR-INVOKING-PACKET"),
24 Extensions: []icmp.Extension{
28 Labels: []icmp.MPLSLabel{
40 Interface: &net.Interface{
46 IP: net.IPv4(192, 168, 0, 1).To4(),
53 Type: ipv4.ICMPTypeTimeExceeded, Code: 1,
54 Body: &icmp.TimeExceeded{
55 Data: []byte("ERROR-INVOKING-PACKET"),
56 Extensions: []icmp.Extension{
60 Interface: &net.Interface{
66 IP: net.IPv4(192, 168, 0, 1).To4(),
72 Labels: []icmp.MPLSLabel{
85 Type: ipv4.ICMPTypeParameterProblem, Code: 2,
86 Body: &icmp.ParamProb{
88 Data: []byte("ERROR-INVOKING-PACKET"),
89 Extensions: []icmp.Extension{
93 Labels: []icmp.MPLSLabel{
105 Interface: &net.Interface{
111 IP: net.IPv4(192, 168, 0, 1).To4(),
117 Interface: &net.Interface{
123 IP: net.IPv4(192, 168, 0, 2).To4(),
131 func TestMarshalAndParseMultipartMessageForIPv4(t *testing.T) {
132 for i, tt := range marshalAndParseMultipartMessageForIPv4Tests {
133 b, err := tt.Marshal(nil)
138 t.Errorf("#%v: got %v; want 32", i, b[5])
140 m, err := icmp.ParseMessage(iana.ProtocolICMP, b)
144 if m.Type != tt.Type || m.Code != tt.Code {
145 t.Errorf("#%v: got %v; want %v", i, m, &tt)
148 case ipv4.ICMPTypeDestinationUnreachable:
149 got, want := m.Body.(*icmp.DstUnreach), tt.Body.(*icmp.DstUnreach)
150 if !reflect.DeepEqual(got.Extensions, want.Extensions) {
151 t.Error(dumpExtensions(i, got.Extensions, want.Extensions))
153 if len(got.Data) != 128 {
154 t.Errorf("#%v: got %v; want 128", i, len(got.Data))
156 case ipv4.ICMPTypeTimeExceeded:
157 got, want := m.Body.(*icmp.TimeExceeded), tt.Body.(*icmp.TimeExceeded)
158 if !reflect.DeepEqual(got.Extensions, want.Extensions) {
159 t.Error(dumpExtensions(i, got.Extensions, want.Extensions))
161 if len(got.Data) != 128 {
162 t.Errorf("#%v: got %v; want 128", i, len(got.Data))
164 case ipv4.ICMPTypeParameterProblem:
165 got, want := m.Body.(*icmp.ParamProb), tt.Body.(*icmp.ParamProb)
166 if !reflect.DeepEqual(got.Extensions, want.Extensions) {
167 t.Error(dumpExtensions(i, got.Extensions, want.Extensions))
169 if len(got.Data) != 128 {
170 t.Errorf("#%v: got %v; want 128", i, len(got.Data))
176 var marshalAndParseMultipartMessageForIPv6Tests = []icmp.Message{
178 Type: ipv6.ICMPTypeDestinationUnreachable, Code: 6,
179 Body: &icmp.DstUnreach{
180 Data: []byte("ERROR-INVOKING-PACKET"),
181 Extensions: []icmp.Extension{
182 &icmp.MPLSLabelStack{
185 Labels: []icmp.MPLSLabel{
197 Interface: &net.Interface{
203 IP: net.ParseIP("fe80::1"),
211 Type: ipv6.ICMPTypeTimeExceeded, Code: 1,
212 Body: &icmp.TimeExceeded{
213 Data: []byte("ERROR-INVOKING-PACKET"),
214 Extensions: []icmp.Extension{
218 Interface: &net.Interface{
224 IP: net.ParseIP("fe80::1"),
228 &icmp.MPLSLabelStack{
231 Labels: []icmp.MPLSLabel{
243 Interface: &net.Interface{
249 IP: net.ParseIP("fe80::1"),
258 func TestMarshalAndParseMultipartMessageForIPv6(t *testing.T) {
259 pshicmp := icmp.IPv6PseudoHeader(net.ParseIP("fe80::1"), net.ParseIP("ff02::1"))
260 for i, tt := range marshalAndParseMultipartMessageForIPv6Tests {
261 for _, psh := range [][]byte{pshicmp, nil} {
262 b, err := tt.Marshal(psh)
267 t.Errorf("#%v: got %v; want 16", i, b[4])
269 m, err := icmp.ParseMessage(iana.ProtocolIPv6ICMP, b)
273 if m.Type != tt.Type || m.Code != tt.Code {
274 t.Errorf("#%v: got %v; want %v", i, m, &tt)
277 case ipv6.ICMPTypeDestinationUnreachable:
278 got, want := m.Body.(*icmp.DstUnreach), tt.Body.(*icmp.DstUnreach)
279 if !reflect.DeepEqual(got.Extensions, want.Extensions) {
280 t.Error(dumpExtensions(i, got.Extensions, want.Extensions))
282 if len(got.Data) != 128 {
283 t.Errorf("#%v: got %v; want 128", i, len(got.Data))
285 case ipv6.ICMPTypeTimeExceeded:
286 got, want := m.Body.(*icmp.TimeExceeded), tt.Body.(*icmp.TimeExceeded)
287 if !reflect.DeepEqual(got.Extensions, want.Extensions) {
288 t.Error(dumpExtensions(i, got.Extensions, want.Extensions))
290 if len(got.Data) != 128 {
291 t.Errorf("#%v: got %v; want 128", i, len(got.Data))
298 func dumpExtensions(i int, gotExts, wantExts []icmp.Extension) string {
300 for j, got := range gotExts {
301 switch got := got.(type) {
302 case *icmp.MPLSLabelStack:
303 want := wantExts[j].(*icmp.MPLSLabelStack)
304 if !reflect.DeepEqual(got, want) {
305 s += fmt.Sprintf("#%v/%v: got %#v; want %#v\n", i, j, got, want)
307 case *icmp.InterfaceInfo:
308 want := wantExts[j].(*icmp.InterfaceInfo)
309 if !reflect.DeepEqual(got, want) {
310 s += fmt.Sprintf("#%v/%v: got %#v, %#v, %#v; want %#v, %#v, %#v\n", i, j, got, got.Interface, got.Addr, want, want.Interface, want.Addr)
317 var multipartMessageBodyLenTests = []struct {
325 Data: make([]byte, ipv4.HeaderLen),
327 4 + ipv4.HeaderLen, // unused and original datagram
332 Data: make([]byte, ipv4.HeaderLen),
334 4 + ipv4.HeaderLen, // unused and original datagram
339 Data: make([]byte, ipv4.HeaderLen),
341 4 + ipv4.HeaderLen, // [pointer, unused] and original datagram
347 Data: make([]byte, ipv4.HeaderLen),
348 Extensions: []icmp.Extension{
349 &icmp.MPLSLabelStack{},
352 4 + 4 + 4 + 0 + 128, // [pointer, length, unused], extension header, object header, object payload, original datagram
357 Data: make([]byte, 128),
358 Extensions: []icmp.Extension{
359 &icmp.MPLSLabelStack{},
362 4 + 4 + 4 + 0 + 128, // [pointer, length, unused], extension header, object header, object payload and original datagram
367 Data: make([]byte, 129),
368 Extensions: []icmp.Extension{
369 &icmp.MPLSLabelStack{},
372 4 + 4 + 4 + 0 + 132, // [pointer, length, unused], extension header, object header, object payload and original datagram
376 iana.ProtocolIPv6ICMP,
378 Data: make([]byte, ipv6.HeaderLen),
380 4 + ipv6.HeaderLen, // unused and original datagram
383 iana.ProtocolIPv6ICMP,
385 Data: make([]byte, ipv6.HeaderLen),
387 4 + ipv6.HeaderLen, // mtu and original datagram
390 iana.ProtocolIPv6ICMP,
392 Data: make([]byte, ipv6.HeaderLen),
394 4 + ipv6.HeaderLen, // unused and original datagram
397 iana.ProtocolIPv6ICMP,
399 Data: make([]byte, ipv6.HeaderLen),
401 4 + ipv6.HeaderLen, // pointer and original datagram
405 iana.ProtocolIPv6ICMP,
407 Data: make([]byte, 127),
408 Extensions: []icmp.Extension{
409 &icmp.MPLSLabelStack{},
412 4 + 4 + 4 + 0 + 128, // [length, unused], extension header, object header, object payload and original datagram
415 iana.ProtocolIPv6ICMP,
417 Data: make([]byte, 128),
418 Extensions: []icmp.Extension{
419 &icmp.MPLSLabelStack{},
422 4 + 4 + 4 + 0 + 128, // [length, unused], extension header, object header, object payload and original datagram
425 iana.ProtocolIPv6ICMP,
427 Data: make([]byte, 129),
428 Extensions: []icmp.Extension{
429 &icmp.MPLSLabelStack{},
432 4 + 4 + 4 + 0 + 136, // [length, unused], extension header, object header, object payload and original datagram
436 func TestMultipartMessageBodyLen(t *testing.T) {
437 for i, tt := range multipartMessageBodyLenTests {
438 if out := tt.in.Len(tt.proto); out != tt.out {
439 t.Errorf("#%d: got %d; want %d", i, out, tt.out)