1 // Copyright 2014, Google, Inc. All rights reserved.
3 // Use of this source code is governed by a BSD-style license
4 // that can be found in the LICENSE file in the root of the source
11 "github.com/google/gopacket"
17 func TestSerializeIPv6HeaderTLVOptions(t *testing.T) {
22 A Hop-by-Hop or Destination Options header containing both options X
23 and Y from Examples 1 and 2 would have one of the two following
24 formats, depending on which option appeared first:
26 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
27 | Next Header | Hdr Ext Len=3 | Option Type=X |Opt Data Len=12|
28 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
30 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
34 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
35 | PadN Option=1 |Opt Data Len=1 | 0 | Option Type=Y |
36 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
37 |Opt Data Len=7 | 1-octet field | 2-octet field |
38 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
40 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
41 | PadN Option=1 |Opt Data Len=2 | 0 | 0 |
42 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
44 opt1 := &ipv6HeaderTLVOption{}
45 opt1.OptionType = 0x1e
46 opt1.OptionData = []byte{0xaa, 0xaa, 0xaa, 0xaa, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb}
47 opt1.OptionAlignment = [2]uint8{8, 2}
49 opt2 := &ipv6HeaderTLVOption{}
50 opt2.OptionType = 0x3e
51 opt2.OptionData = []byte{0x11, 0x22, 0x22, 0x44, 0x44, 0x44, 0x44}
52 opt2.OptionAlignment = [2]uint8{4, 3}
54 l := serializeIPv6HeaderTLVOptions(nil, []*ipv6HeaderTLVOption{opt1, opt2}, true)
56 serializeIPv6HeaderTLVOptions(b, []*ipv6HeaderTLVOption{opt1, opt2}, true)
58 want := []byte{0x1e, 0x0c, 0xaa, 0xaa, 0xaa, 0xaa, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0x01, 0x01, 0x00, 0x3e, 0x07, 0x11, 0x22, 0x22, 0x44, 0x44, 0x44, 0x44, 0x01, 0x02, 0x00, 0x00}
60 if !bytes.Equal(got, want) {
61 t.Errorf("IPv6HeaderTLVOption serialize (X,Y) failed:\ngot:\n%#v\n\nwant:\n%#v\n\n", got, want)
65 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
66 | Next Header | Hdr Ext Len=3 | Pad1 Option=0 | Option Type=Y |
67 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
68 |Opt Data Len=7 | 1-octet field | 2-octet field |
69 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
71 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
72 | PadN Option=1 |Opt Data Len=4 | 0 | 0 |
73 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
74 | 0 | 0 | Option Type=X |Opt Data Len=12|
75 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
77 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
81 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
84 l = serializeIPv6HeaderTLVOptions(nil, []*ipv6HeaderTLVOption{opt2, opt1}, true)
86 serializeIPv6HeaderTLVOptions(b, []*ipv6HeaderTLVOption{opt2, opt1}, true)
88 want = []byte{0x00, 0x3e, 0x07, 0x11, 0x22, 0x22, 0x44, 0x44, 0x44, 0x44, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x0c, 0xaa, 0xaa, 0xaa, 0xaa, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb}
90 if !bytes.Equal(got, want) {
91 t.Errorf("IPv6HeaderTLVOption serialize (Y,X) failed:\ngot:\n%#v\n\nwant:\n%#v\n\n", got, want)
95 var testPacketIPv6HopByHop0 = []byte{
96 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x40, 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00,
97 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00,
98 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x3b, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00,
101 func TestPacketIPv6HopByHop0Serialize(t *testing.T) {
102 var serialize []gopacket.SerializableLayer = make([]gopacket.SerializableLayer, 0, 2)
107 ip6.NextHeader = IPProtocolIPv6HopByHop
109 ip6.SrcIP = net.ParseIP("2001:db8::1")
110 ip6.DstIP = net.ParseIP("2001:db8::2")
111 serialize = append(serialize, ip6)
113 tlv := &IPv6HopByHopOption{}
114 tlv.OptionType = 0x01 //PadN
115 tlv.OptionData = []byte{0x00, 0x00, 0x00, 0x00}
116 hop := &IPv6HopByHop{}
117 hop.Options = append(hop.Options, tlv)
118 hop.NextHeader = IPProtocolNoNextHeader
121 buf := gopacket.NewSerializeBuffer()
122 opts := gopacket.SerializeOptions{FixLengths: true}
123 err = gopacket.SerializeLayers(buf, opts, serialize...)
129 want := testPacketIPv6HopByHop0
130 if !bytes.Equal(got, want) {
131 t.Errorf("IPv6HopByHop serialize failed:\ngot:\n%#v\n\nwant:\n%#v\n\n", got, want)
135 func TestPacketIPv6HopByHop0Decode(t *testing.T) {
137 BaseLayer: BaseLayer{
139 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x40, 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00,
140 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00,
141 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
143 Payload: []byte{0x3b, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00},
149 NextHeader: IPProtocolIPv6HopByHop,
151 SrcIP: net.IP{0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
152 DstIP: net.IP{0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00,
153 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
157 hop.ipv6ExtensionBase = ipv6ExtensionBase{
158 BaseLayer: BaseLayer{
159 Contents: []byte{0x3b, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00},
162 NextHeader: IPProtocolNoNextHeader,
163 HeaderLength: uint8(0),
166 opt := &IPv6HopByHopOption{
167 OptionType: uint8(0x01),
168 OptionLength: uint8(0x04),
170 OptionData: []byte{0x00, 0x00, 0x00, 0x00},
172 hop.Options = append(hop.Options, opt)
175 p := gopacket.NewPacket(testPacketIPv6HopByHop0, LinkTypeRaw, gopacket.Default)
176 if p.ErrorLayer() != nil {
177 t.Error("Failed to decode packet:", p.ErrorLayer().Error())
179 checkLayers(p, []gopacket.LayerType{LayerTypeIPv6, LayerTypeIPv6HopByHop}, t)
180 if got, ok := p.Layer(LayerTypeIPv6).(*IPv6); ok {
182 want.HopByHop = got.HopByHop // avoid comparing pointers
183 if !reflect.DeepEqual(got, want) {
184 t.Errorf("IPv6 packet processing failed:\ngot:\n%#v\n\nwant:\n%#v\n\n", got, want)
187 t.Error("No IPv6 layer type found in packet")
189 if got, ok := p.Layer(LayerTypeIPv6HopByHop).(*IPv6HopByHop); ok {
191 if !reflect.DeepEqual(got, want) {
192 t.Errorf("IPv6HopByHop packet processing failed:\ngot\n%#v\n\nwant:\n%#v\n\n", got, want)
195 t.Error("No IPv6HopByHop layer type found in packet")
199 // testPacketIPv6Destination0 is the packet:
200 // 12:40:14.429409595 IP6 2001:db8::1 > 2001:db8::2: DSTOPT no next header
201 // 0x0000: 6000 0000 0008 3c40 2001 0db8 0000 0000 `.....<@........
202 // 0x0010: 0000 0000 0000 0001 2001 0db8 0000 0000 ................
203 // 0x0020: 0000 0000 0000 0002 3b00 0104 0000 0000 ........;.......
204 var testPacketIPv6Destination0 = []byte{
205 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3c, 0x40, 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00,
206 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00,
207 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x3b, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00,
210 func TestPacketIPv6Destination0Serialize(t *testing.T) {
211 var serialize []gopacket.SerializableLayer = make([]gopacket.SerializableLayer, 0, 2)
216 ip6.NextHeader = IPProtocolIPv6Destination
218 ip6.SrcIP = net.ParseIP("2001:db8::1")
219 ip6.DstIP = net.ParseIP("2001:db8::2")
220 serialize = append(serialize, ip6)
222 tlv := &IPv6DestinationOption{}
223 tlv.OptionType = 0x01 //PadN
224 tlv.OptionData = []byte{0x00, 0x00, 0x00, 0x00}
225 dst := &IPv6Destination{}
226 dst.Options = append(dst.Options, tlv)
227 dst.NextHeader = IPProtocolNoNextHeader
228 serialize = append(serialize, dst)
230 buf := gopacket.NewSerializeBuffer()
231 opts := gopacket.SerializeOptions{FixLengths: true}
232 err = gopacket.SerializeLayers(buf, opts, serialize...)
238 want := testPacketIPv6Destination0
239 if !bytes.Equal(got, want) {
240 t.Errorf("IPv6Destination serialize failed:\ngot:\n%#v\n\nwant:\n%#v\n\n", got, want)
244 func TestPacketIPv6Destination0Decode(t *testing.T) {
246 BaseLayer: BaseLayer{
248 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3c, 0x40, 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00,
249 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00,
250 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
252 Payload: []byte{0x3b, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00},
258 NextHeader: IPProtocolIPv6Destination,
260 SrcIP: net.IP{0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
261 DstIP: net.IP{0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00,
262 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
265 dst := &IPv6Destination{}
266 dst.BaseLayer = BaseLayer{
267 Contents: []byte{0x3b, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00},
270 dst.NextHeader = IPProtocolNoNextHeader
271 dst.HeaderLength = uint8(0)
273 opt := &IPv6DestinationOption{
274 OptionType: uint8(0x01),
275 OptionLength: uint8(0x04),
277 OptionData: []byte{0x00, 0x00, 0x00, 0x00},
279 dst.Options = append(dst.Options, opt)
281 p := gopacket.NewPacket(testPacketIPv6Destination0, LinkTypeRaw, gopacket.Default)
282 if p.ErrorLayer() != nil {
283 t.Error("Failed to decode packet:", p.ErrorLayer().Error())
285 checkLayers(p, []gopacket.LayerType{LayerTypeIPv6, LayerTypeIPv6Destination}, t)
286 if got, ok := p.Layer(LayerTypeIPv6).(*IPv6); ok {
288 if !reflect.DeepEqual(got, want) {
289 t.Errorf("IPv6 packet processing failed:\ngot:\n%#v\n\nwant:\n%#v\n\n", got, want)
292 t.Error("No IPv6 layer type found in packet")
294 if got, ok := p.Layer(LayerTypeIPv6Destination).(*IPv6Destination); ok {
296 if !reflect.DeepEqual(got, want) {
297 t.Errorf("IPv6Destination packet processing failed:\ngot:\n%#v\n\nwant:\n%#v\n\n", got, want)
300 t.Error("No IPv6Destination layer type found in packet")
304 var testPacketIPv6JumbogramHeader = []byte{
305 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00,
306 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00,
307 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x3b, 0x00, 0xc2, 0x04, 0x00, 0x01, 0x00, 0x08,
310 func TestIPv6JumbogramSerialize(t *testing.T) {
311 var serialize []gopacket.SerializableLayer = make([]gopacket.SerializableLayer, 0, 2)
316 ip6.NextHeader = IPProtocolNoNextHeader
318 ip6.SrcIP = net.ParseIP("2001:db8::1")
319 ip6.DstIP = net.ParseIP("2001:db8::2")
320 serialize = append(serialize, ip6)
322 payload := make([]byte, ipv6MaxPayloadLength+1)
323 for i := range payload {
326 serialize = append(serialize, gopacket.Payload(payload))
328 buf := gopacket.NewSerializeBuffer()
329 opts := gopacket.SerializeOptions{FixLengths: true}
330 err = gopacket.SerializeLayers(buf, opts, serialize...)
336 w := new(bytes.Buffer)
337 w.Write(testPacketIPv6JumbogramHeader)
341 if !bytes.Equal(got, want) {
342 t.Errorf("IPv6 Jumbogram serialize failed:\ngot:\n%v\n\nwant:\n%v\n\n",
343 gopacket.LongBytesGoString(got), gopacket.LongBytesGoString(want))
347 func TestIPv6JumbogramDecode(t *testing.T) {
348 payload := make([]byte, ipv6MaxPayloadLength+1)
349 for i := range payload {
354 BaseLayer: BaseLayer{
356 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00,
357 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00,
358 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
365 NextHeader: IPProtocolIPv6HopByHop,
367 SrcIP: net.IP{0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
368 DstIP: net.IP{0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00,
369 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
371 buf := new(bytes.Buffer)
372 buf.Write([]byte{0x3b, 0x00, 0xc2, 0x04, 0x00, 0x01, 0x00, 0x08})
374 ip6.Payload = buf.Bytes()
377 hop.Contents = []byte{0x3b, 0x00, 0xc2, 0x04, 0x00, 0x01, 0x00, 0x08}
378 hop.Payload = payload
379 hop.NextHeader = IPProtocolNoNextHeader
380 hop.HeaderLength = uint8(0)
382 opt := &IPv6HopByHopOption{}
383 opt.OptionType = uint8(0xc2)
384 opt.OptionLength = uint8(0x04)
386 opt.OptionData = []byte{0x00, 0x01, 0x00, 0x08}
387 hop.Options = append(hop.Options, opt)
390 pkt := new(bytes.Buffer)
391 pkt.Write(testPacketIPv6JumbogramHeader)
394 p := gopacket.NewPacket(pkt.Bytes(), LinkTypeRaw, gopacket.Default)
395 if p.ErrorLayer() != nil {
396 t.Error("Failed to decode packet:", p.ErrorLayer().Error())
398 checkLayers(p, []gopacket.LayerType{LayerTypeIPv6, LayerTypeIPv6HopByHop, gopacket.LayerTypePayload}, t)
400 if got, ok := p.Layer(LayerTypeIPv6).(*IPv6); ok {
402 want.HopByHop = got.HopByHop // Hack, avoid comparing pointers
403 if !reflect.DeepEqual(got, want) {
404 t.Errorf("IPv6 packet processing failed:\ngot:\n%v\n\nwant:\n%v\n\n",
405 gopacket.LayerGoString(got), gopacket.LayerGoString(want))
408 t.Error("No IPv6 layer type found in packet")
411 if got, ok := p.Layer(LayerTypeIPv6HopByHop).(*IPv6HopByHop); ok {
413 if !reflect.DeepEqual(got, want) {
414 t.Errorf("IPv6HopByHop packet processing failed:\ngot:\n%v\n\nwant:\n%v\n\n",
415 gopacket.LayerGoString(got), gopacket.LayerGoString(want))
418 t.Error("No IPv6HopByHop layer type found in packet")
421 if got, ok := p.Layer(gopacket.LayerTypePayload).(*gopacket.Payload); ok {
422 want := (*gopacket.Payload)(&payload)
423 if !reflect.DeepEqual(got, want) {
424 t.Errorf("Payload packet processing failed:\ngot:\n%v\n\nwant:\n%v\n\n",
425 gopacket.LayerGoString(got), gopacket.LayerGoString(want))
428 t.Error("No Payload layer type found in packet")