summaryrefslogtreecommitdiff
path: root/vendor/golang.org/x/net/icmp/multipart_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/golang.org/x/net/icmp/multipart_test.go')
-rw-r--r--vendor/golang.org/x/net/icmp/multipart_test.go575
1 files changed, 575 insertions, 0 deletions
diff --git a/vendor/golang.org/x/net/icmp/multipart_test.go b/vendor/golang.org/x/net/icmp/multipart_test.go
new file mode 100644
index 0000000..7440882
--- /dev/null
+++ b/vendor/golang.org/x/net/icmp/multipart_test.go
@@ -0,0 +1,575 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package icmp_test
+
+import (
+ "errors"
+ "fmt"
+ "net"
+ "reflect"
+ "testing"
+
+ "golang.org/x/net/icmp"
+ "golang.org/x/net/internal/iana"
+ "golang.org/x/net/ipv4"
+ "golang.org/x/net/ipv6"
+)
+
+func TestMarshalAndParseMultipartMessage(t *testing.T) {
+ fn := func(t *testing.T, proto int, tm icmp.Message) error {
+ b, err := tm.Marshal(nil)
+ if err != nil {
+ return err
+ }
+ switch tm.Type {
+ case ipv4.ICMPTypeExtendedEchoRequest, ipv6.ICMPTypeExtendedEchoRequest:
+ default:
+ switch proto {
+ case iana.ProtocolICMP:
+ if b[5] != 32 {
+ return fmt.Errorf("got %d; want 32", b[5])
+ }
+ case iana.ProtocolIPv6ICMP:
+ if b[4] != 16 {
+ return fmt.Errorf("got %d; want 16", b[4])
+ }
+ default:
+ return fmt.Errorf("unknown protocol: %d", proto)
+ }
+ }
+ m, err := icmp.ParseMessage(proto, b)
+ if err != nil {
+ return err
+ }
+ if m.Type != tm.Type || m.Code != tm.Code {
+ return fmt.Errorf("got %v; want %v", m, &tm)
+ }
+ switch m.Type {
+ case ipv4.ICMPTypeExtendedEchoRequest, ipv6.ICMPTypeExtendedEchoRequest:
+ got, want := m.Body.(*icmp.ExtendedEchoRequest), tm.Body.(*icmp.ExtendedEchoRequest)
+ if !reflect.DeepEqual(got.Extensions, want.Extensions) {
+ return errors.New(dumpExtensions(got.Extensions, want.Extensions))
+ }
+ case ipv4.ICMPTypeDestinationUnreachable:
+ got, want := m.Body.(*icmp.DstUnreach), tm.Body.(*icmp.DstUnreach)
+ if !reflect.DeepEqual(got.Extensions, want.Extensions) {
+ return errors.New(dumpExtensions(got.Extensions, want.Extensions))
+ }
+ if len(got.Data) != 128 {
+ return fmt.Errorf("got %d; want 128", len(got.Data))
+ }
+ case ipv4.ICMPTypeTimeExceeded:
+ got, want := m.Body.(*icmp.TimeExceeded), tm.Body.(*icmp.TimeExceeded)
+ if !reflect.DeepEqual(got.Extensions, want.Extensions) {
+ return errors.New(dumpExtensions(got.Extensions, want.Extensions))
+ }
+ if len(got.Data) != 128 {
+ return fmt.Errorf("got %d; want 128", len(got.Data))
+ }
+ case ipv4.ICMPTypeParameterProblem:
+ got, want := m.Body.(*icmp.ParamProb), tm.Body.(*icmp.ParamProb)
+ if !reflect.DeepEqual(got.Extensions, want.Extensions) {
+ return errors.New(dumpExtensions(got.Extensions, want.Extensions))
+ }
+ if len(got.Data) != 128 {
+ return fmt.Errorf("got %d; want 128", len(got.Data))
+ }
+ case ipv6.ICMPTypeDestinationUnreachable:
+ got, want := m.Body.(*icmp.DstUnreach), tm.Body.(*icmp.DstUnreach)
+ if !reflect.DeepEqual(got.Extensions, want.Extensions) {
+ return errors.New(dumpExtensions(got.Extensions, want.Extensions))
+ }
+ if len(got.Data) != 128 {
+ return fmt.Errorf("got %d; want 128", len(got.Data))
+ }
+ case ipv6.ICMPTypeTimeExceeded:
+ got, want := m.Body.(*icmp.TimeExceeded), tm.Body.(*icmp.TimeExceeded)
+ if !reflect.DeepEqual(got.Extensions, want.Extensions) {
+ return errors.New(dumpExtensions(got.Extensions, want.Extensions))
+ }
+ if len(got.Data) != 128 {
+ return fmt.Errorf("got %d; want 128", len(got.Data))
+ }
+ default:
+ return fmt.Errorf("unknown message type: %v", m.Type)
+ }
+ return nil
+ }
+
+ t.Run("IPv4", func(t *testing.T) {
+ for i, tm := range []icmp.Message{
+ {
+ Type: ipv4.ICMPTypeDestinationUnreachable, Code: 15,
+ Body: &icmp.DstUnreach{
+ Data: []byte("ERROR-INVOKING-PACKET"),
+ Extensions: []icmp.Extension{
+ &icmp.MPLSLabelStack{
+ Class: 1,
+ Type: 1,
+ Labels: []icmp.MPLSLabel{
+ {
+ Label: 16014,
+ TC: 0x4,
+ S: true,
+ TTL: 255,
+ },
+ },
+ },
+ &icmp.InterfaceInfo{
+ Class: 2,
+ Type: 0x0f,
+ Interface: &net.Interface{
+ Index: 15,
+ Name: "en101",
+ MTU: 8192,
+ },
+ Addr: &net.IPAddr{
+ IP: net.IPv4(192, 168, 0, 1).To4(),
+ },
+ },
+ },
+ },
+ },
+ {
+ Type: ipv4.ICMPTypeTimeExceeded, Code: 1,
+ Body: &icmp.TimeExceeded{
+ Data: []byte("ERROR-INVOKING-PACKET"),
+ Extensions: []icmp.Extension{
+ &icmp.InterfaceInfo{
+ Class: 2,
+ Type: 0x0f,
+ Interface: &net.Interface{
+ Index: 15,
+ Name: "en101",
+ MTU: 8192,
+ },
+ Addr: &net.IPAddr{
+ IP: net.IPv4(192, 168, 0, 1).To4(),
+ },
+ },
+ &icmp.MPLSLabelStack{
+ Class: 1,
+ Type: 1,
+ Labels: []icmp.MPLSLabel{
+ {
+ Label: 16014,
+ TC: 0x4,
+ S: true,
+ TTL: 255,
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ Type: ipv4.ICMPTypeParameterProblem, Code: 2,
+ Body: &icmp.ParamProb{
+ Pointer: 8,
+ Data: []byte("ERROR-INVOKING-PACKET"),
+ Extensions: []icmp.Extension{
+ &icmp.MPLSLabelStack{
+ Class: 1,
+ Type: 1,
+ Labels: []icmp.MPLSLabel{
+ {
+ Label: 16014,
+ TC: 0x4,
+ S: true,
+ TTL: 255,
+ },
+ },
+ },
+ &icmp.InterfaceInfo{
+ Class: 2,
+ Type: 0x0f,
+ Interface: &net.Interface{
+ Index: 15,
+ Name: "en101",
+ MTU: 8192,
+ },
+ Addr: &net.IPAddr{
+ IP: net.IPv4(192, 168, 0, 1).To4(),
+ },
+ },
+ &icmp.InterfaceInfo{
+ Class: 2,
+ Type: 0x2f,
+ Interface: &net.Interface{
+ Index: 16,
+ Name: "en102",
+ MTU: 8192,
+ },
+ Addr: &net.IPAddr{
+ IP: net.IPv4(192, 168, 0, 2).To4(),
+ },
+ },
+ },
+ },
+ },
+ {
+ Type: ipv4.ICMPTypeExtendedEchoRequest, Code: 0,
+ Body: &icmp.ExtendedEchoRequest{
+ ID: 1, Seq: 2, Local: true,
+ Extensions: []icmp.Extension{
+ &icmp.InterfaceIdent{
+ Class: 3,
+ Type: 1,
+ Name: "en101",
+ },
+ },
+ },
+ },
+ {
+ Type: ipv4.ICMPTypeExtendedEchoRequest, Code: 0,
+ Body: &icmp.ExtendedEchoRequest{
+ ID: 1, Seq: 2, Local: true,
+ Extensions: []icmp.Extension{
+ &icmp.InterfaceIdent{
+ Class: 3,
+ Type: 2,
+ Index: 911,
+ },
+ &icmp.InterfaceIdent{
+ Class: 3,
+ Type: 1,
+ Name: "en101",
+ },
+ },
+ },
+ },
+ {
+ Type: ipv4.ICMPTypeExtendedEchoRequest, Code: 0,
+ Body: &icmp.ExtendedEchoRequest{
+ ID: 1, Seq: 2,
+ Extensions: []icmp.Extension{
+ &icmp.InterfaceIdent{
+ Class: 3,
+ Type: 3,
+ AFI: iana.AddrFamily48bitMAC,
+ Addr: []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab},
+ },
+ },
+ },
+ },
+ } {
+ if err := fn(t, iana.ProtocolICMP, tm); err != nil {
+ t.Errorf("#%d: %v", i, err)
+ }
+ }
+ })
+ t.Run("IPv6", func(t *testing.T) {
+ for i, tm := range []icmp.Message{
+ {
+ Type: ipv6.ICMPTypeDestinationUnreachable, Code: 6,
+ Body: &icmp.DstUnreach{
+ Data: []byte("ERROR-INVOKING-PACKET"),
+ Extensions: []icmp.Extension{
+ &icmp.MPLSLabelStack{
+ Class: 1,
+ Type: 1,
+ Labels: []icmp.MPLSLabel{
+ {
+ Label: 16014,
+ TC: 0x4,
+ S: true,
+ TTL: 255,
+ },
+ },
+ },
+ &icmp.InterfaceInfo{
+ Class: 2,
+ Type: 0x0f,
+ Interface: &net.Interface{
+ Index: 15,
+ Name: "en101",
+ MTU: 8192,
+ },
+ Addr: &net.IPAddr{
+ IP: net.ParseIP("fe80::1"),
+ Zone: "en101",
+ },
+ },
+ },
+ },
+ },
+ {
+ Type: ipv6.ICMPTypeTimeExceeded, Code: 1,
+ Body: &icmp.TimeExceeded{
+ Data: []byte("ERROR-INVOKING-PACKET"),
+ Extensions: []icmp.Extension{
+ &icmp.InterfaceInfo{
+ Class: 2,
+ Type: 0x0f,
+ Interface: &net.Interface{
+ Index: 15,
+ Name: "en101",
+ MTU: 8192,
+ },
+ Addr: &net.IPAddr{
+ IP: net.ParseIP("fe80::1"),
+ Zone: "en101",
+ },
+ },
+ &icmp.MPLSLabelStack{
+ Class: 1,
+ Type: 1,
+ Labels: []icmp.MPLSLabel{
+ {
+ Label: 16014,
+ TC: 0x4,
+ S: true,
+ TTL: 255,
+ },
+ },
+ },
+ &icmp.InterfaceInfo{
+ Class: 2,
+ Type: 0x2f,
+ Interface: &net.Interface{
+ Index: 16,
+ Name: "en102",
+ MTU: 8192,
+ },
+ Addr: &net.IPAddr{
+ IP: net.ParseIP("fe80::1"),
+ Zone: "en102",
+ },
+ },
+ },
+ },
+ },
+ {
+ Type: ipv6.ICMPTypeExtendedEchoRequest, Code: 0,
+ Body: &icmp.ExtendedEchoRequest{
+ ID: 1, Seq: 2, Local: true,
+ Extensions: []icmp.Extension{
+ &icmp.InterfaceIdent{
+ Class: 3,
+ Type: 1,
+ Name: "en101",
+ },
+ },
+ },
+ },
+ {
+ Type: ipv6.ICMPTypeExtendedEchoRequest, Code: 0,
+ Body: &icmp.ExtendedEchoRequest{
+ ID: 1, Seq: 2, Local: true,
+ Extensions: []icmp.Extension{
+ &icmp.InterfaceIdent{
+ Class: 3,
+ Type: 1,
+ Name: "en101",
+ },
+ &icmp.InterfaceIdent{
+ Class: 3,
+ Type: 2,
+ Index: 911,
+ },
+ },
+ },
+ },
+ {
+ Type: ipv6.ICMPTypeExtendedEchoRequest, Code: 0,
+ Body: &icmp.ExtendedEchoRequest{
+ ID: 1, Seq: 2,
+ Extensions: []icmp.Extension{
+ &icmp.InterfaceIdent{
+ Class: 3,
+ Type: 3,
+ AFI: iana.AddrFamilyIPv4,
+ Addr: []byte{192, 0, 2, 1},
+ },
+ },
+ },
+ },
+ } {
+ if err := fn(t, iana.ProtocolIPv6ICMP, tm); err != nil {
+ t.Errorf("#%d: %v", i, err)
+ }
+ }
+ })
+}
+
+func dumpExtensions(gotExts, wantExts []icmp.Extension) string {
+ var s string
+ for i, got := range gotExts {
+ switch got := got.(type) {
+ case *icmp.MPLSLabelStack:
+ want := wantExts[i].(*icmp.MPLSLabelStack)
+ if !reflect.DeepEqual(got, want) {
+ s += fmt.Sprintf("#%d: got %#v; want %#v\n", i, got, want)
+ }
+ case *icmp.InterfaceInfo:
+ want := wantExts[i].(*icmp.InterfaceInfo)
+ if !reflect.DeepEqual(got, want) {
+ s += fmt.Sprintf("#%d: got %#v, %#v, %#v; want %#v, %#v, %#v\n", i, got, got.Interface, got.Addr, want, want.Interface, want.Addr)
+ }
+ case *icmp.InterfaceIdent:
+ want := wantExts[i].(*icmp.InterfaceIdent)
+ if !reflect.DeepEqual(got, want) {
+ s += fmt.Sprintf("#%d: got %#v; want %#v\n", i, got, want)
+ }
+ }
+ }
+ if len(s) == 0 {
+ return "<nil>"
+ }
+ return s[:len(s)-1]
+}
+
+func TestMultipartMessageBodyLen(t *testing.T) {
+ for i, tt := range []struct {
+ proto int
+ in icmp.MessageBody
+ out int
+ }{
+ {
+ iana.ProtocolICMP,
+ &icmp.DstUnreach{
+ Data: make([]byte, ipv4.HeaderLen),
+ },
+ 4 + ipv4.HeaderLen, // unused and original datagram
+ },
+ {
+ iana.ProtocolICMP,
+ &icmp.TimeExceeded{
+ Data: make([]byte, ipv4.HeaderLen),
+ },
+ 4 + ipv4.HeaderLen, // unused and original datagram
+ },
+ {
+ iana.ProtocolICMP,
+ &icmp.ParamProb{
+ Data: make([]byte, ipv4.HeaderLen),
+ },
+ 4 + ipv4.HeaderLen, // [pointer, unused] and original datagram
+ },
+
+ {
+ iana.ProtocolICMP,
+ &icmp.ParamProb{
+ Data: make([]byte, ipv4.HeaderLen),
+ Extensions: []icmp.Extension{
+ &icmp.MPLSLabelStack{},
+ },
+ },
+ 4 + 4 + 4 + 0 + 128, // [pointer, length, unused], extension header, object header, object payload, original datagram
+ },
+ {
+ iana.ProtocolICMP,
+ &icmp.ParamProb{
+ Data: make([]byte, 128),
+ Extensions: []icmp.Extension{
+ &icmp.MPLSLabelStack{},
+ },
+ },
+ 4 + 4 + 4 + 0 + 128, // [pointer, length, unused], extension header, object header, object payload and original datagram
+ },
+ {
+ iana.ProtocolICMP,
+ &icmp.ParamProb{
+ Data: make([]byte, 129),
+ Extensions: []icmp.Extension{
+ &icmp.MPLSLabelStack{},
+ },
+ },
+ 4 + 4 + 4 + 0 + 132, // [pointer, length, unused], extension header, object header, object payload and original datagram
+ },
+
+ {
+ iana.ProtocolIPv6ICMP,
+ &icmp.DstUnreach{
+ Data: make([]byte, ipv6.HeaderLen),
+ },
+ 4 + ipv6.HeaderLen, // unused and original datagram
+ },
+ {
+ iana.ProtocolIPv6ICMP,
+ &icmp.PacketTooBig{
+ Data: make([]byte, ipv6.HeaderLen),
+ },
+ 4 + ipv6.HeaderLen, // mtu and original datagram
+ },
+ {
+ iana.ProtocolIPv6ICMP,
+ &icmp.TimeExceeded{
+ Data: make([]byte, ipv6.HeaderLen),
+ },
+ 4 + ipv6.HeaderLen, // unused and original datagram
+ },
+ {
+ iana.ProtocolIPv6ICMP,
+ &icmp.ParamProb{
+ Data: make([]byte, ipv6.HeaderLen),
+ },
+ 4 + ipv6.HeaderLen, // pointer and original datagram
+ },
+
+ {
+ iana.ProtocolIPv6ICMP,
+ &icmp.DstUnreach{
+ Data: make([]byte, 127),
+ Extensions: []icmp.Extension{
+ &icmp.MPLSLabelStack{},
+ },
+ },
+ 4 + 4 + 4 + 0 + 128, // [length, unused], extension header, object header, object payload and original datagram
+ },
+ {
+ iana.ProtocolIPv6ICMP,
+ &icmp.DstUnreach{
+ Data: make([]byte, 128),
+ Extensions: []icmp.Extension{
+ &icmp.MPLSLabelStack{},
+ },
+ },
+ 4 + 4 + 4 + 0 + 128, // [length, unused], extension header, object header, object payload and original datagram
+ },
+ {
+ iana.ProtocolIPv6ICMP,
+ &icmp.DstUnreach{
+ Data: make([]byte, 129),
+ Extensions: []icmp.Extension{
+ &icmp.MPLSLabelStack{},
+ },
+ },
+ 4 + 4 + 4 + 0 + 136, // [length, unused], extension header, object header, object payload and original datagram
+ },
+
+ {
+ iana.ProtocolICMP,
+ &icmp.ExtendedEchoRequest{},
+ 4, // [id, seq, l-bit]
+ },
+ {
+ iana.ProtocolICMP,
+ &icmp.ExtendedEchoRequest{
+ Extensions: []icmp.Extension{
+ &icmp.InterfaceIdent{},
+ },
+ },
+ 4 + 4 + 4, // [id, seq, l-bit], extension header, object header
+ },
+ {
+ iana.ProtocolIPv6ICMP,
+ &icmp.ExtendedEchoRequest{
+ Extensions: []icmp.Extension{
+ &icmp.InterfaceIdent{
+ Type: 3,
+ AFI: iana.AddrFamilyNSAP,
+ Addr: []byte{0x49, 0x00, 0x01, 0xaa, 0xaa, 0xbb, 0xbb, 0xcc, 0xcc, 0x00},
+ },
+ },
+ },
+ 4 + 4 + 4 + 16, // [id, seq, l-bit], extension header, object header, object payload
+ },
+ } {
+ if out := tt.in.Len(tt.proto); out != tt.out {
+ t.Errorf("#%d: got %d; want %d", i, out, tt.out)
+ }
+ }
+}