1// Copyright 2017 Google, Inc. All rights reserved.
2//
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
5// tree.
6//
7
8package layers
9
10import (
11	"github.com/google/gopacket"
12	"reflect"
13	"testing"
14)
15
16// testGTPPacket is the packet:
17//0000  00 0c 29 e3 c6 4d 00 0c  29 da d1 de 08 00 45 00   ..)..M.. ).....E.
18//0010  00 7c 00 00 40 00 40 11  67 bb c0 a8 28 b2 c0 a8   .|..@.@. g...(...
19//0020  28 b3 08 68 08 68 00 68  c1 c4 32 ff 00 58 00 00   (..h.h.h ..2..X..
20//0030  00 01 26 7b 00 00 45 00  00 54 06 76 00 00 40 01   ..&{..E. .T.v..@.
21//0040  98 2f c0 a8 28 b2 ca 0b  28 9e 00 00 39 e9 00 00   ./..(... (...9...
22//0050  28 7d 06 11 20 4b 7f 3a  0d 00 08 09 0a 0b 0c 0d   (}.. K.: ........
23//0060  0e 0f 10 11 12 13 14 15  16 17 18 19 1a 1b 1c 1d   ........ ........
24//0070  1e 1f 20 21 22 23 24 25  26 27 28 29 2a 2b 2c 2d   .. !"#$% &'()*+,-
25//0080  2e 2f 30 31 32 33 34 35  36 37                     ./012345 67
26
27var testGTPPacket = []byte{
28	0x00, 0x0c, 0x29, 0xe3, 0xc6, 0x4d, 0x00, 0x0c,
29	0x29, 0xda, 0xd1, 0xde, 0x08, 0x00, 0x45, 0x00,
30	0x00, 0x7c, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11,
31	0x67, 0xbb, 0xc0, 0xa8, 0x28, 0xb2, 0xc0, 0xa8,
32	0x28, 0xb3, 0x08, 0x68, 0x08, 0x68, 0x00, 0x68,
33	0xc1, 0xc4, 0x32, 0xff, 0x00, 0x58, 0x00, 0x00,
34	0x00, 0x01, 0x26, 0x7b, 0x00, 0x00, 0x45, 0x00,
35	0x00, 0x54, 0x06, 0x76, 0x00, 0x00, 0x40, 0x01,
36	0x98, 0x2f, 0xc0, 0xa8, 0x28, 0xb2, 0xca, 0x0b,
37	0x28, 0x9e, 0x00, 0x00, 0x39, 0xe9, 0x00, 0x00,
38	0x28, 0x7d, 0x06, 0x11, 0x20, 0x4b, 0x7f, 0x3a,
39	0x0d, 0x00, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
40	0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15,
41	0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
42	0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25,
43	0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d,
44	0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
45	0x36, 0x37,
46}
47
48func TestGTPPacket(t *testing.T) {
49	p := gopacket.NewPacket(testGTPPacket, LayerTypeEthernet, gopacket.Default)
50	if p.ErrorLayer() != nil {
51		t.Error("Failed to decode packet:", p.ErrorLayer().Error())
52	}
53	checkLayers(p, []gopacket.LayerType{LayerTypeEthernet, LayerTypeIPv4, LayerTypeUDP, LayerTypeGTPv1U, LayerTypeIPv4,
54		LayerTypeICMPv4, gopacket.LayerTypePayload}, t)
55	if got, ok := p.Layer(LayerTypeGTPv1U).(*GTPv1U); ok {
56		want := &GTPv1U{
57			Version:             1,
58			ProtocolType:        1,
59			Reserved:            0,
60			ExtensionHeaderFlag: false,
61			SequenceNumberFlag:  true,
62			NPDUFlag:            false,
63			MessageType:         255,
64			MessageLength:       88,
65			TEID:                1,
66			SequenceNumber:      9851,
67		}
68		want.BaseLayer = BaseLayer{testGTPPacket[42:54], testGTPPacket[54:]}
69		if !reflect.DeepEqual(got, want) {
70			t.Errorf("GTP packet mismatch:\ngot  :\n%#v\n\nwant :\n%#v\n\n", got, want)
71
72		}
73		buf := gopacket.NewSerializeBuffer()
74		opts := gopacket.SerializeOptions{}
75		err := got.SerializeTo(buf, opts)
76		if err != nil {
77			t.Error(err)
78		}
79		if !reflect.DeepEqual(got.Contents, buf.Bytes()) {
80			t.Errorf("GTP packet serialization failed:\ngot  :\n%#v\n\nwant :\n%#v\n\n", buf.Bytes(), got.Contents)
81		}
82	} else {
83		t.Error("Incorrect gtp packet")
84	}
85}
86
87// testGTPPacketWithEH is the packet
88//000000 00 0c 29 e3 c6 4d 00 0c 29 da d1 de 08 00 45 00 ..)..M..).....E.
89//000010 00 80 00 00 40 00 40 11 67 bb c0 a8 28 b2 c0 a8 ....@.@.g...(...
90//000020 28 b3 08 68 08 68 00 6c c1 95 36 ff 00 58 00 10 (..h.h.l..6..X..
91//000030 06 57 00 05 00 c0 01 09 04 00 45 00 00 54 06 a5 .W........E..T..
92//000040 00 00 40 01 98 00 c0 a8 28 b2 ca 0b 28 9e 00 00 ..@.....(...(...
93//000050 e3 b6 00 00 28 ac 35 11 20 4b a6 3d 0d 00 08 09 ....(.5. K.=....
94//000060 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 ................
95//000070 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 ...... !"#$%&'()
96//000080 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37
97
98var testGTPPacketWithEH = []byte{
99	0x00, 0x0c, 0x29, 0xe3, 0xc6, 0x4d, 0x00, 0x0c,
100	0x29, 0xda, 0xd1, 0xde, 0x08, 0x00, 0x45, 0x00,
101	0x00, 0x80, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11,
102	0x67, 0xbb, 0xc0, 0xa8, 0x28, 0xb2, 0xc0, 0xa8,
103	0x28, 0xb3, 0x08, 0x68, 0x08, 0x68, 0x00, 0x6c,
104	0xc1, 0x95, 0x36, 0xff, 0x00, 0x58, 0x00, 0x10,
105	0x06, 0x57, 0x00, 0x05, 0x00, 0xc0, 0x01, 0x09,
106	0x04, 0x00, 0x45, 0x00, 0x00, 0x54, 0x06, 0xa5,
107	0x00, 0x00, 0x40, 0x01, 0x98, 0x00, 0xc0, 0xa8,
108	0x28, 0xb2, 0xca, 0x0b, 0x28, 0x9e, 0x00, 0x00,
109	0xe3, 0xb6, 0x00, 0x00, 0x28, 0xac, 0x35, 0x11,
110	0x20, 0x4b, 0xa6, 0x3d, 0x0d, 0x00, 0x08, 0x09,
111	0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
112	0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
113	0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21,
114	0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29,
115	0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31,
116	0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
117}
118
119func TestGTPPacketWithEH(t *testing.T) {
120	p := gopacket.NewPacket(testGTPPacketWithEH, LayerTypeEthernet, gopacket.Default)
121	if p.ErrorLayer() != nil {
122		t.Error("Failed to decode packet:", p.ErrorLayer().Error())
123	}
124	checkLayers(p, []gopacket.LayerType{LayerTypeEthernet, LayerTypeIPv4, LayerTypeUDP, LayerTypeGTPv1U, LayerTypeIPv4,
125		LayerTypeICMPv4, gopacket.LayerTypePayload}, t)
126	if got, ok := p.Layer(LayerTypeGTPv1U).(*GTPv1U); ok {
127		want := &GTPv1U{
128			Version:             1,
129			ProtocolType:        1,
130			Reserved:            0,
131			ExtensionHeaderFlag: true,
132			SequenceNumberFlag:  true,
133			NPDUFlag:            false,
134			MessageType:         255,
135			MessageLength:       88,
136			TEID:                1050199,
137			SequenceNumber:      5,
138			GTPExtensionHeaders: []GTPExtensionHeader{GTPExtensionHeader{Type: uint8(192), Content: []byte{0x9, 0x4}}},
139		}
140		want.BaseLayer = BaseLayer{testGTPPacketWithEH[42:58], testGTPPacketWithEH[58:]}
141		if !reflect.DeepEqual(got, want) {
142			t.Errorf("GTP packet mismatch:\ngot  :\n%#v\n\nwant :\n%#v\n\n", got, want)
143
144		}
145		buf := gopacket.NewSerializeBuffer()
146		opts := gopacket.SerializeOptions{}
147		err := got.SerializeTo(buf, opts)
148		if err != nil {
149			t.Error(err)
150		}
151		if !reflect.DeepEqual(got.Contents, buf.Bytes()) {
152			t.Errorf("GTP packet serialization failed:\ngot  :\n%#v\n\nbuf :\n%#v\n\n", got.Contents, buf.Bytes())
153		}
154	} else {
155		t.Errorf("Invalid GTP packet")
156	}
157
158}
159