summaryrefslogtreecommitdiff
path: root/vendor/golang.org/x/net/icmp/extension_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/golang.org/x/net/icmp/extension_test.go')
-rw-r--r--vendor/golang.org/x/net/icmp/extension_test.go333
1 files changed, 333 insertions, 0 deletions
diff --git a/vendor/golang.org/x/net/icmp/extension_test.go b/vendor/golang.org/x/net/icmp/extension_test.go
new file mode 100644
index 0000000..a7669da
--- /dev/null
+++ b/vendor/golang.org/x/net/icmp/extension_test.go
@@ -0,0 +1,333 @@
+// 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
+
+import (
+ "fmt"
+ "net"
+ "reflect"
+ "testing"
+
+ "golang.org/x/net/internal/iana"
+ "golang.org/x/net/ipv4"
+ "golang.org/x/net/ipv6"
+)
+
+func TestMarshalAndParseExtension(t *testing.T) {
+ fn := func(t *testing.T, proto int, typ Type, hdr, obj []byte, te Extension) error {
+ b, err := te.Marshal(proto)
+ if err != nil {
+ return err
+ }
+ if !reflect.DeepEqual(b, obj) {
+ return fmt.Errorf("got %#v; want %#v", b, obj)
+ }
+ switch typ {
+ case ipv4.ICMPTypeExtendedEchoRequest, ipv6.ICMPTypeExtendedEchoRequest:
+ exts, l, err := parseExtensions(typ, append(hdr, obj...), 0)
+ if err != nil {
+ return err
+ }
+ if l != 0 {
+ return fmt.Errorf("got %d; want 0", l)
+ }
+ if !reflect.DeepEqual(exts, []Extension{te}) {
+ return fmt.Errorf("got %#v; want %#v", exts[0], te)
+ }
+ default:
+ for i, wire := range []struct {
+ data []byte // original datagram
+ inlattr int // length of padded original datagram, a hint
+ outlattr int // length of padded original datagram, a want
+ err error
+ }{
+ {nil, 0, -1, errNoExtension},
+ {make([]byte, 127), 128, -1, errNoExtension},
+
+ {make([]byte, 128), 127, -1, errNoExtension},
+ {make([]byte, 128), 128, -1, errNoExtension},
+ {make([]byte, 128), 129, -1, errNoExtension},
+
+ {append(make([]byte, 128), append(hdr, obj...)...), 127, 128, nil},
+ {append(make([]byte, 128), append(hdr, obj...)...), 128, 128, nil},
+ {append(make([]byte, 128), append(hdr, obj...)...), 129, 128, nil},
+
+ {append(make([]byte, 512), append(hdr, obj...)...), 511, -1, errNoExtension},
+ {append(make([]byte, 512), append(hdr, obj...)...), 512, 512, nil},
+ {append(make([]byte, 512), append(hdr, obj...)...), 513, -1, errNoExtension},
+ } {
+ exts, l, err := parseExtensions(typ, wire.data, wire.inlattr)
+ if err != wire.err {
+ return fmt.Errorf("#%d: got %v; want %v", i, err, wire.err)
+ }
+ if wire.err != nil {
+ continue
+ }
+ if l != wire.outlattr {
+ return fmt.Errorf("#%d: got %d; want %d", i, l, wire.outlattr)
+ }
+ if !reflect.DeepEqual(exts, []Extension{te}) {
+ return fmt.Errorf("#%d: got %#v; want %#v", i, exts[0], te)
+ }
+ }
+ }
+ return nil
+ }
+
+ t.Run("MPLSLabelStack", func(t *testing.T) {
+ for _, et := range []struct {
+ proto int
+ typ Type
+ hdr []byte
+ obj []byte
+ ext Extension
+ }{
+ // MPLS label stack with no label
+ {
+ proto: iana.ProtocolICMP,
+ typ: ipv4.ICMPTypeDestinationUnreachable,
+ hdr: []byte{
+ 0x20, 0x00, 0x00, 0x00,
+ },
+ obj: []byte{
+ 0x00, 0x04, 0x01, 0x01,
+ },
+ ext: &MPLSLabelStack{
+ Class: classMPLSLabelStack,
+ Type: typeIncomingMPLSLabelStack,
+ },
+ },
+ // MPLS label stack with a single label
+ {
+ proto: iana.ProtocolIPv6ICMP,
+ typ: ipv6.ICMPTypeDestinationUnreachable,
+ hdr: []byte{
+ 0x20, 0x00, 0x00, 0x00,
+ },
+ obj: []byte{
+ 0x00, 0x08, 0x01, 0x01,
+ 0x03, 0xe8, 0xe9, 0xff,
+ },
+ ext: &MPLSLabelStack{
+ Class: classMPLSLabelStack,
+ Type: typeIncomingMPLSLabelStack,
+ Labels: []MPLSLabel{
+ {
+ Label: 16014,
+ TC: 0x4,
+ S: true,
+ TTL: 255,
+ },
+ },
+ },
+ },
+ // MPLS label stack with multiple labels
+ {
+ proto: iana.ProtocolICMP,
+ typ: ipv4.ICMPTypeDestinationUnreachable,
+ hdr: []byte{
+ 0x20, 0x00, 0x00, 0x00,
+ },
+ obj: []byte{
+ 0x00, 0x0c, 0x01, 0x01,
+ 0x03, 0xe8, 0xde, 0xfe,
+ 0x03, 0xe8, 0xe1, 0xff,
+ },
+ ext: &MPLSLabelStack{
+ Class: classMPLSLabelStack,
+ Type: typeIncomingMPLSLabelStack,
+ Labels: []MPLSLabel{
+ {
+ Label: 16013,
+ TC: 0x7,
+ S: false,
+ TTL: 254,
+ },
+ {
+ Label: 16014,
+ TC: 0,
+ S: true,
+ TTL: 255,
+ },
+ },
+ },
+ },
+ } {
+ if err := fn(t, et.proto, et.typ, et.hdr, et.obj, et.ext); err != nil {
+ t.Error(err)
+ }
+ }
+ })
+ t.Run("InterfaceInfo", func(t *testing.T) {
+ for _, et := range []struct {
+ proto int
+ typ Type
+ hdr []byte
+ obj []byte
+ ext Extension
+ }{
+ // Interface information with no attribute
+ {
+ proto: iana.ProtocolICMP,
+ typ: ipv4.ICMPTypeDestinationUnreachable,
+ hdr: []byte{
+ 0x20, 0x00, 0x00, 0x00,
+ },
+ obj: []byte{
+ 0x00, 0x04, 0x02, 0x00,
+ },
+ ext: &InterfaceInfo{
+ Class: classInterfaceInfo,
+ },
+ },
+ // Interface information with ifIndex and name
+ {
+ proto: iana.ProtocolICMP,
+ typ: ipv4.ICMPTypeDestinationUnreachable,
+ hdr: []byte{
+ 0x20, 0x00, 0x00, 0x00,
+ },
+ obj: []byte{
+ 0x00, 0x10, 0x02, 0x0a,
+ 0x00, 0x00, 0x00, 0x10,
+ 0x08, byte('e'), byte('n'), byte('1'),
+ byte('0'), byte('1'), 0x00, 0x00,
+ },
+ ext: &InterfaceInfo{
+ Class: classInterfaceInfo,
+ Type: 0x0a,
+ Interface: &net.Interface{
+ Index: 16,
+ Name: "en101",
+ },
+ },
+ },
+ // Interface information with ifIndex, IPAddr, name and MTU
+ {
+ proto: iana.ProtocolIPv6ICMP,
+ typ: ipv6.ICMPTypeDestinationUnreachable,
+ hdr: []byte{
+ 0x20, 0x00, 0x00, 0x00,
+ },
+ obj: []byte{
+ 0x00, 0x28, 0x02, 0x0f,
+ 0x00, 0x00, 0x00, 0x0f,
+ 0x00, 0x02, 0x00, 0x00,
+ 0xfe, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01,
+ 0x08, byte('e'), byte('n'), byte('1'),
+ byte('0'), byte('1'), 0x00, 0x00,
+ 0x00, 0x00, 0x20, 0x00,
+ },
+ ext: &InterfaceInfo{
+ Class: classInterfaceInfo,
+ Type: 0x0f,
+ Interface: &net.Interface{
+ Index: 15,
+ Name: "en101",
+ MTU: 8192,
+ },
+ Addr: &net.IPAddr{
+ IP: net.ParseIP("fe80::1"),
+ Zone: "en101",
+ },
+ },
+ },
+ } {
+ if err := fn(t, et.proto, et.typ, et.hdr, et.obj, et.ext); err != nil {
+ t.Error(err)
+ }
+ }
+ })
+ t.Run("InterfaceIdent", func(t *testing.T) {
+ for _, et := range []struct {
+ proto int
+ typ Type
+ hdr []byte
+ obj []byte
+ ext Extension
+ }{
+ // Interface identification by name
+ {
+ proto: iana.ProtocolICMP,
+ typ: ipv4.ICMPTypeExtendedEchoRequest,
+ hdr: []byte{
+ 0x20, 0x00, 0x00, 0x00,
+ },
+ obj: []byte{
+ 0x00, 0x0c, 0x03, 0x01,
+ byte('e'), byte('n'), byte('1'), byte('0'),
+ byte('1'), 0x00, 0x00, 0x00,
+ },
+ ext: &InterfaceIdent{
+ Class: classInterfaceIdent,
+ Type: typeInterfaceByName,
+ Name: "en101",
+ },
+ },
+ // Interface identification by index
+ {
+ proto: iana.ProtocolIPv6ICMP,
+ typ: ipv6.ICMPTypeExtendedEchoRequest,
+ hdr: []byte{
+ 0x20, 0x00, 0x00, 0x00,
+ },
+ obj: []byte{
+ 0x00, 0x0c, 0x03, 0x02,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x03, 0x8f,
+ },
+ ext: &InterfaceIdent{
+ Class: classInterfaceIdent,
+ Type: typeInterfaceByIndex,
+ Index: 911,
+ },
+ },
+ // Interface identification by address
+ {
+ proto: iana.ProtocolICMP,
+ typ: ipv4.ICMPTypeExtendedEchoRequest,
+ hdr: []byte{
+ 0x20, 0x00, 0x00, 0x00,
+ },
+ obj: []byte{
+ 0x00, 0x10, 0x03, 0x03,
+ byte(iana.AddrFamily48bitMAC >> 8), byte(iana.AddrFamily48bitMAC & 0x0f), 0x06, 0x00,
+ 0x01, 0x23, 0x45, 0x67,
+ 0x89, 0xab, 0x00, 0x00,
+ },
+ ext: &InterfaceIdent{
+ Class: classInterfaceIdent,
+ Type: typeInterfaceByAddress,
+ AFI: iana.AddrFamily48bitMAC,
+ Addr: []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab},
+ },
+ },
+ } {
+ if err := fn(t, et.proto, et.typ, et.hdr, et.obj, et.ext); err != nil {
+ t.Error(err)
+ }
+ }
+ })
+}
+
+func TestParseInterfaceName(t *testing.T) {
+ ifi := InterfaceInfo{Interface: &net.Interface{}}
+ for i, tt := range []struct {
+ b []byte
+ error
+ }{
+ {[]byte{0, 'e', 'n', '0'}, errInvalidExtension},
+ {[]byte{4, 'e', 'n', '0'}, nil},
+ {[]byte{7, 'e', 'n', '0', 0xff, 0xff, 0xff, 0xff}, errInvalidExtension},
+ {[]byte{8, 'e', 'n', '0', 0xff, 0xff, 0xff}, errMessageTooShort},
+ } {
+ if _, err := ifi.parseName(tt.b); err != tt.error {
+ t.Errorf("#%d: got %v; want %v", i, err, tt.error)
+ }
+ }
+}