| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259 | // 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 icmpimport (	"net"	"reflect"	"testing"	"golang.org/x/net/internal/iana")var marshalAndParseExtensionTests = []struct {	proto int	hdr   []byte	obj   []byte	exts  []Extension}{	// MPLS label stack with no label	{		proto: iana.ProtocolICMP,		hdr: []byte{			0x20, 0x00, 0x00, 0x00,		},		obj: []byte{			0x00, 0x04, 0x01, 0x01,		},		exts: []Extension{			&MPLSLabelStack{				Class: classMPLSLabelStack,				Type:  typeIncomingMPLSLabelStack,			},		},	},	// MPLS label stack with a single label	{		proto: iana.ProtocolIPv6ICMP,		hdr: []byte{			0x20, 0x00, 0x00, 0x00,		},		obj: []byte{			0x00, 0x08, 0x01, 0x01,			0x03, 0xe8, 0xe9, 0xff,		},		exts: []Extension{			&MPLSLabelStack{				Class: classMPLSLabelStack,				Type:  typeIncomingMPLSLabelStack,				Labels: []MPLSLabel{					{						Label: 16014,						TC:    0x4,						S:     true,						TTL:   255,					},				},			},		},	},	// MPLS label stack with multiple labels	{		proto: iana.ProtocolICMP,		hdr: []byte{			0x20, 0x00, 0x00, 0x00,		},		obj: []byte{			0x00, 0x0c, 0x01, 0x01,			0x03, 0xe8, 0xde, 0xfe,			0x03, 0xe8, 0xe1, 0xff,		},		exts: []Extension{			&MPLSLabelStack{				Class: classMPLSLabelStack,				Type:  typeIncomingMPLSLabelStack,				Labels: []MPLSLabel{					{						Label: 16013,						TC:    0x7,						S:     false,						TTL:   254,					},					{						Label: 16014,						TC:    0,						S:     true,						TTL:   255,					},				},			},		},	},	// Interface information with no attribute	{		proto: iana.ProtocolICMP,		hdr: []byte{			0x20, 0x00, 0x00, 0x00,		},		obj: []byte{			0x00, 0x04, 0x02, 0x00,		},		exts: []Extension{			&InterfaceInfo{				Class: classInterfaceInfo,			},		},	},	// Interface information with ifIndex and name	{		proto: iana.ProtocolICMP,		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,		},		exts: []Extension{			&InterfaceInfo{				Class: classInterfaceInfo,				Type:  0x0a,				Interface: &net.Interface{					Index: 16,					Name:  "en101",				},			},		},	},	// Interface information with ifIndex, IPAddr, name and MTU	{		proto: iana.ProtocolIPv6ICMP,		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,		},		exts: []Extension{			&InterfaceInfo{				Class: classInterfaceInfo,				Type:  0x0f,				Interface: &net.Interface{					Index: 15,					Name:  "en101",					MTU:   8192,				},				Addr: &net.IPAddr{					IP:   net.ParseIP("fe80::1"),					Zone: "en101",				},			},		},	},}func TestMarshalAndParseExtension(t *testing.T) {	for i, tt := range marshalAndParseExtensionTests {		for j, ext := range tt.exts {			var err error			var b []byte			switch ext := ext.(type) {			case *MPLSLabelStack:				b, err = ext.Marshal(tt.proto)				if err != nil {					t.Errorf("#%v/%v: %v", i, j, err)					continue				}			case *InterfaceInfo:				b, err = ext.Marshal(tt.proto)				if err != nil {					t.Errorf("#%v/%v: %v", i, j, err)					continue				}			}			if !reflect.DeepEqual(b, tt.obj) {				t.Errorf("#%v/%v: got %#v; want %#v", i, j, b, tt.obj)				continue			}		}		for j, 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(tt.hdr, tt.obj...)...), 127, 128, nil},			{append(make([]byte, 128), append(tt.hdr, tt.obj...)...), 128, 128, nil},			{append(make([]byte, 128), append(tt.hdr, tt.obj...)...), 129, 128, nil},			{append(make([]byte, 512), append(tt.hdr, tt.obj...)...), 511, -1, errNoExtension},			{append(make([]byte, 512), append(tt.hdr, tt.obj...)...), 512, 512, nil},			{append(make([]byte, 512), append(tt.hdr, tt.obj...)...), 513, -1, errNoExtension},		} {			exts, l, err := parseExtensions(wire.data, wire.inlattr)			if err != wire.err {				t.Errorf("#%v/%v: got %v; want %v", i, j, err, wire.err)				continue			}			if wire.err != nil {				continue			}			if l != wire.outlattr {				t.Errorf("#%v/%v: got %v; want %v", i, j, l, wire.outlattr)			}			if !reflect.DeepEqual(exts, tt.exts) {				for j, ext := range exts {					switch ext := ext.(type) {					case *MPLSLabelStack:						want := tt.exts[j].(*MPLSLabelStack)						t.Errorf("#%v/%v: got %#v; want %#v", i, j, ext, want)					case *InterfaceInfo:						want := tt.exts[j].(*InterfaceInfo)						t.Errorf("#%v/%v: got %#v; want %#v", i, j, ext, want)					}				}				continue			}		}	}}var parseInterfaceNameTests = []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},}func TestParseInterfaceName(t *testing.T) {	ifi := InterfaceInfo{Interface: &net.Interface{}}	for i, tt := range parseInterfaceNameTests {		if _, err := ifi.parseName(tt.b); err != tt.error {			t.Errorf("#%d: got %v; want %v", i, err, tt.error)		}	}}
 |