OSDN Git Service

new repo
[bytom/vapor.git] / vendor / golang.org / x / net / icmp / extension_test.go
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 }