github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/net/icmp/multipart_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_test
     6  
     7  import (
     8  	"fmt"
     9  	"net"
    10  	"reflect"
    11  	"testing"
    12  
    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"
    17  )
    18  
    19  var marshalAndParseMultipartMessageForIPv4Tests = []icmp.Message{
    20  	{
    21  		Type: ipv4.ICMPTypeDestinationUnreachable, Code: 15,
    22  		Body: &icmp.DstUnreach{
    23  			Data: []byte("ERROR-INVOKING-PACKET"),
    24  			Extensions: []icmp.Extension{
    25  				&icmp.MPLSLabelStack{
    26  					Class: 1,
    27  					Type:  1,
    28  					Labels: []icmp.MPLSLabel{
    29  						{
    30  							Label: 16014,
    31  							TC:    0x4,
    32  							S:     true,
    33  							TTL:   255,
    34  						},
    35  					},
    36  				},
    37  				&icmp.InterfaceInfo{
    38  					Class: 2,
    39  					Type:  0x0f,
    40  					Interface: &net.Interface{
    41  						Index: 15,
    42  						Name:  "en101",
    43  						MTU:   8192,
    44  					},
    45  					Addr: &net.IPAddr{
    46  						IP: net.IPv4(192, 168, 0, 1).To4(),
    47  					},
    48  				},
    49  			},
    50  		},
    51  	},
    52  	{
    53  		Type: ipv4.ICMPTypeTimeExceeded, Code: 1,
    54  		Body: &icmp.TimeExceeded{
    55  			Data: []byte("ERROR-INVOKING-PACKET"),
    56  			Extensions: []icmp.Extension{
    57  				&icmp.InterfaceInfo{
    58  					Class: 2,
    59  					Type:  0x0f,
    60  					Interface: &net.Interface{
    61  						Index: 15,
    62  						Name:  "en101",
    63  						MTU:   8192,
    64  					},
    65  					Addr: &net.IPAddr{
    66  						IP: net.IPv4(192, 168, 0, 1).To4(),
    67  					},
    68  				},
    69  				&icmp.MPLSLabelStack{
    70  					Class: 1,
    71  					Type:  1,
    72  					Labels: []icmp.MPLSLabel{
    73  						{
    74  							Label: 16014,
    75  							TC:    0x4,
    76  							S:     true,
    77  							TTL:   255,
    78  						},
    79  					},
    80  				},
    81  			},
    82  		},
    83  	},
    84  	{
    85  		Type: ipv4.ICMPTypeParameterProblem, Code: 2,
    86  		Body: &icmp.ParamProb{
    87  			Pointer: 8,
    88  			Data:    []byte("ERROR-INVOKING-PACKET"),
    89  			Extensions: []icmp.Extension{
    90  				&icmp.MPLSLabelStack{
    91  					Class: 1,
    92  					Type:  1,
    93  					Labels: []icmp.MPLSLabel{
    94  						{
    95  							Label: 16014,
    96  							TC:    0x4,
    97  							S:     true,
    98  							TTL:   255,
    99  						},
   100  					},
   101  				},
   102  				&icmp.InterfaceInfo{
   103  					Class: 2,
   104  					Type:  0x0f,
   105  					Interface: &net.Interface{
   106  						Index: 15,
   107  						Name:  "en101",
   108  						MTU:   8192,
   109  					},
   110  					Addr: &net.IPAddr{
   111  						IP: net.IPv4(192, 168, 0, 1).To4(),
   112  					},
   113  				},
   114  				&icmp.InterfaceInfo{
   115  					Class: 2,
   116  					Type:  0x2f,
   117  					Interface: &net.Interface{
   118  						Index: 16,
   119  						Name:  "en102",
   120  						MTU:   8192,
   121  					},
   122  					Addr: &net.IPAddr{
   123  						IP: net.IPv4(192, 168, 0, 2).To4(),
   124  					},
   125  				},
   126  			},
   127  		},
   128  	},
   129  }
   130  
   131  func TestMarshalAndParseMultipartMessageForIPv4(t *testing.T) {
   132  	for i, tt := range marshalAndParseMultipartMessageForIPv4Tests {
   133  		b, err := tt.Marshal(nil)
   134  		if err != nil {
   135  			t.Fatal(err)
   136  		}
   137  		if b[5] != 32 {
   138  			t.Errorf("#%v: got %v; want 32", i, b[5])
   139  		}
   140  		m, err := icmp.ParseMessage(iana.ProtocolICMP, b)
   141  		if err != nil {
   142  			t.Fatal(err)
   143  		}
   144  		if m.Type != tt.Type || m.Code != tt.Code {
   145  			t.Errorf("#%v: got %v; want %v", i, m, &tt)
   146  		}
   147  		switch m.Type {
   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))
   152  			}
   153  			if len(got.Data) != 128 {
   154  				t.Errorf("#%v: got %v; want 128", i, len(got.Data))
   155  			}
   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))
   160  			}
   161  			if len(got.Data) != 128 {
   162  				t.Errorf("#%v: got %v; want 128", i, len(got.Data))
   163  			}
   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))
   168  			}
   169  			if len(got.Data) != 128 {
   170  				t.Errorf("#%v: got %v; want 128", i, len(got.Data))
   171  			}
   172  		}
   173  	}
   174  }
   175  
   176  var marshalAndParseMultipartMessageForIPv6Tests = []icmp.Message{
   177  	{
   178  		Type: ipv6.ICMPTypeDestinationUnreachable, Code: 6,
   179  		Body: &icmp.DstUnreach{
   180  			Data: []byte("ERROR-INVOKING-PACKET"),
   181  			Extensions: []icmp.Extension{
   182  				&icmp.MPLSLabelStack{
   183  					Class: 1,
   184  					Type:  1,
   185  					Labels: []icmp.MPLSLabel{
   186  						{
   187  							Label: 16014,
   188  							TC:    0x4,
   189  							S:     true,
   190  							TTL:   255,
   191  						},
   192  					},
   193  				},
   194  				&icmp.InterfaceInfo{
   195  					Class: 2,
   196  					Type:  0x0f,
   197  					Interface: &net.Interface{
   198  						Index: 15,
   199  						Name:  "en101",
   200  						MTU:   8192,
   201  					},
   202  					Addr: &net.IPAddr{
   203  						IP:   net.ParseIP("fe80::1"),
   204  						Zone: "en101",
   205  					},
   206  				},
   207  			},
   208  		},
   209  	},
   210  	{
   211  		Type: ipv6.ICMPTypeTimeExceeded, Code: 1,
   212  		Body: &icmp.TimeExceeded{
   213  			Data: []byte("ERROR-INVOKING-PACKET"),
   214  			Extensions: []icmp.Extension{
   215  				&icmp.InterfaceInfo{
   216  					Class: 2,
   217  					Type:  0x0f,
   218  					Interface: &net.Interface{
   219  						Index: 15,
   220  						Name:  "en101",
   221  						MTU:   8192,
   222  					},
   223  					Addr: &net.IPAddr{
   224  						IP:   net.ParseIP("fe80::1"),
   225  						Zone: "en101",
   226  					},
   227  				},
   228  				&icmp.MPLSLabelStack{
   229  					Class: 1,
   230  					Type:  1,
   231  					Labels: []icmp.MPLSLabel{
   232  						{
   233  							Label: 16014,
   234  							TC:    0x4,
   235  							S:     true,
   236  							TTL:   255,
   237  						},
   238  					},
   239  				},
   240  				&icmp.InterfaceInfo{
   241  					Class: 2,
   242  					Type:  0x2f,
   243  					Interface: &net.Interface{
   244  						Index: 16,
   245  						Name:  "en102",
   246  						MTU:   8192,
   247  					},
   248  					Addr: &net.IPAddr{
   249  						IP:   net.ParseIP("fe80::1"),
   250  						Zone: "en102",
   251  					},
   252  				},
   253  			},
   254  		},
   255  	},
   256  }
   257  
   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)
   263  			if err != nil {
   264  				t.Fatal(err)
   265  			}
   266  			if b[4] != 16 {
   267  				t.Errorf("#%v: got %v; want 16", i, b[4])
   268  			}
   269  			m, err := icmp.ParseMessage(iana.ProtocolIPv6ICMP, b)
   270  			if err != nil {
   271  				t.Fatal(err)
   272  			}
   273  			if m.Type != tt.Type || m.Code != tt.Code {
   274  				t.Errorf("#%v: got %v; want %v", i, m, &tt)
   275  			}
   276  			switch m.Type {
   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))
   281  				}
   282  				if len(got.Data) != 128 {
   283  					t.Errorf("#%v: got %v; want 128", i, len(got.Data))
   284  				}
   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))
   289  				}
   290  				if len(got.Data) != 128 {
   291  					t.Errorf("#%v: got %v; want 128", i, len(got.Data))
   292  				}
   293  			}
   294  		}
   295  	}
   296  }
   297  
   298  func dumpExtensions(i int, gotExts, wantExts []icmp.Extension) string {
   299  	var s 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)
   306  			}
   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)
   311  			}
   312  		}
   313  	}
   314  	return s[:len(s)-1]
   315  }
   316  
   317  var multipartMessageBodyLenTests = []struct {
   318  	proto int
   319  	in    icmp.MessageBody
   320  	out   int
   321  }{
   322  	{
   323  		iana.ProtocolICMP,
   324  		&icmp.DstUnreach{
   325  			Data: make([]byte, ipv4.HeaderLen),
   326  		},
   327  		4 + ipv4.HeaderLen, // unused and original datagram
   328  	},
   329  	{
   330  		iana.ProtocolICMP,
   331  		&icmp.TimeExceeded{
   332  			Data: make([]byte, ipv4.HeaderLen),
   333  		},
   334  		4 + ipv4.HeaderLen, // unused and original datagram
   335  	},
   336  	{
   337  		iana.ProtocolICMP,
   338  		&icmp.ParamProb{
   339  			Data: make([]byte, ipv4.HeaderLen),
   340  		},
   341  		4 + ipv4.HeaderLen, // [pointer, unused] and original datagram
   342  	},
   343  
   344  	{
   345  		iana.ProtocolICMP,
   346  		&icmp.ParamProb{
   347  			Data: make([]byte, ipv4.HeaderLen),
   348  			Extensions: []icmp.Extension{
   349  				&icmp.MPLSLabelStack{},
   350  			},
   351  		},
   352  		4 + 4 + 4 + 0 + 128, // [pointer, length, unused], extension header, object header, object payload, original datagram
   353  	},
   354  	{
   355  		iana.ProtocolICMP,
   356  		&icmp.ParamProb{
   357  			Data: make([]byte, 128),
   358  			Extensions: []icmp.Extension{
   359  				&icmp.MPLSLabelStack{},
   360  			},
   361  		},
   362  		4 + 4 + 4 + 0 + 128, // [pointer, length, unused], extension header, object header, object payload and original datagram
   363  	},
   364  	{
   365  		iana.ProtocolICMP,
   366  		&icmp.ParamProb{
   367  			Data: make([]byte, 129),
   368  			Extensions: []icmp.Extension{
   369  				&icmp.MPLSLabelStack{},
   370  			},
   371  		},
   372  		4 + 4 + 4 + 0 + 132, // [pointer, length, unused], extension header, object header, object payload and original datagram
   373  	},
   374  
   375  	{
   376  		iana.ProtocolIPv6ICMP,
   377  		&icmp.DstUnreach{
   378  			Data: make([]byte, ipv6.HeaderLen),
   379  		},
   380  		4 + ipv6.HeaderLen, // unused and original datagram
   381  	},
   382  	{
   383  		iana.ProtocolIPv6ICMP,
   384  		&icmp.PacketTooBig{
   385  			Data: make([]byte, ipv6.HeaderLen),
   386  		},
   387  		4 + ipv6.HeaderLen, // mtu and original datagram
   388  	},
   389  	{
   390  		iana.ProtocolIPv6ICMP,
   391  		&icmp.TimeExceeded{
   392  			Data: make([]byte, ipv6.HeaderLen),
   393  		},
   394  		4 + ipv6.HeaderLen, // unused and original datagram
   395  	},
   396  	{
   397  		iana.ProtocolIPv6ICMP,
   398  		&icmp.ParamProb{
   399  			Data: make([]byte, ipv6.HeaderLen),
   400  		},
   401  		4 + ipv6.HeaderLen, // pointer and original datagram
   402  	},
   403  
   404  	{
   405  		iana.ProtocolIPv6ICMP,
   406  		&icmp.DstUnreach{
   407  			Data: make([]byte, 127),
   408  			Extensions: []icmp.Extension{
   409  				&icmp.MPLSLabelStack{},
   410  			},
   411  		},
   412  		4 + 4 + 4 + 0 + 128, // [length, unused], extension header, object header, object payload and original datagram
   413  	},
   414  	{
   415  		iana.ProtocolIPv6ICMP,
   416  		&icmp.DstUnreach{
   417  			Data: make([]byte, 128),
   418  			Extensions: []icmp.Extension{
   419  				&icmp.MPLSLabelStack{},
   420  			},
   421  		},
   422  		4 + 4 + 4 + 0 + 128, // [length, unused], extension header, object header, object payload and original datagram
   423  	},
   424  	{
   425  		iana.ProtocolIPv6ICMP,
   426  		&icmp.DstUnreach{
   427  			Data: make([]byte, 129),
   428  			Extensions: []icmp.Extension{
   429  				&icmp.MPLSLabelStack{},
   430  			},
   431  		},
   432  		4 + 4 + 4 + 0 + 136, // [length, unused], extension header, object header, object payload and original datagram
   433  	},
   434  }
   435  
   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)
   440  		}
   441  	}
   442  }