github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/net/icmp/extension_test.go (about)

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