xref: /aosp_15_r20/external/scapy/scapy/contrib/gtp_v2.py (revision 7dc08ffc4802948ccbc861daaf1e81c405c2c4bd)
1*7dc08ffcSJunyu Lai#! /usr/bin/env python
2*7dc08ffcSJunyu Lai
3*7dc08ffcSJunyu Lai# Copyright (C) 2017 Alessio Deiana <[email protected]>
4*7dc08ffcSJunyu Lai# 2017 Alexis Sultan <[email protected]>
5*7dc08ffcSJunyu Lai
6*7dc08ffcSJunyu Lai# This file is part of Scapy
7*7dc08ffcSJunyu Lai# Scapy is free software: you can redistribute it and/or modify
8*7dc08ffcSJunyu Lai# it under the terms of the GNU General Public License as published by
9*7dc08ffcSJunyu Lai# the Free Software Foundation, either version 2 of the License, or
10*7dc08ffcSJunyu Lai# any later version.
11*7dc08ffcSJunyu Lai#
12*7dc08ffcSJunyu Lai# Scapy is distributed in the hope that it will be useful,
13*7dc08ffcSJunyu Lai# but WITHOUT ANY WARRANTY; without even the implied warranty of
14*7dc08ffcSJunyu Lai# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15*7dc08ffcSJunyu Lai# GNU General Public License for more details.
16*7dc08ffcSJunyu Lai#
17*7dc08ffcSJunyu Lai# You should have received a copy of the GNU General Public License
18*7dc08ffcSJunyu Lai# along with Scapy. If not, see <http://www.gnu.org/licenses/>.
19*7dc08ffcSJunyu Lai
20*7dc08ffcSJunyu Lai# scapy.contrib.description = GTPv2
21*7dc08ffcSJunyu Lai# scapy.contrib.status = loads
22*7dc08ffcSJunyu Lai
23*7dc08ffcSJunyu Laiimport time
24*7dc08ffcSJunyu Laiimport logging
25*7dc08ffcSJunyu Lai
26*7dc08ffcSJunyu Laifrom scapy.packet import *
27*7dc08ffcSJunyu Laifrom scapy.fields import *
28*7dc08ffcSJunyu Laifrom scapy.layers.inet import IP, UDP
29*7dc08ffcSJunyu Laifrom scapy.layers.inet6 import IP6Field
30*7dc08ffcSJunyu Laifrom scapy.compat import orb
31*7dc08ffcSJunyu Lai
32*7dc08ffcSJunyu Laiimport scapy.contrib.gtp as gtp
33*7dc08ffcSJunyu Lai
34*7dc08ffcSJunyu LaiRATType = {
35*7dc08ffcSJunyu Lai    6: "EUTRAN",
36*7dc08ffcSJunyu Lai}
37*7dc08ffcSJunyu Lai
38*7dc08ffcSJunyu LaiGTPmessageType = {1: "echo_request",
39*7dc08ffcSJunyu Lai                     2: "echo_response",
40*7dc08ffcSJunyu Lai                     32: "create_session_req",
41*7dc08ffcSJunyu Lai                     33: "create_session_res",
42*7dc08ffcSJunyu Lai                     34: "modify_bearer_req",
43*7dc08ffcSJunyu Lai                     35: "modify_bearer_res",
44*7dc08ffcSJunyu Lai                     36: "delete_session_req",
45*7dc08ffcSJunyu Lai                     37: "delete_session_res",
46*7dc08ffcSJunyu Lai                     70: "downlink_data_notif_failure_indic",
47*7dc08ffcSJunyu Lai                     170: "realease_bearers_req",
48*7dc08ffcSJunyu Lai                     171: "realease_bearers_res",
49*7dc08ffcSJunyu Lai                     176: "downlink_data_notif",
50*7dc08ffcSJunyu Lai                     177: "downlink_data_notif_ack",
51*7dc08ffcSJunyu Lai                  }
52*7dc08ffcSJunyu Lai
53*7dc08ffcSJunyu LaiIEType = {1: "IMSI",
54*7dc08ffcSJunyu Lai             2: "Cause",
55*7dc08ffcSJunyu Lai             3: "Recovery Restart",
56*7dc08ffcSJunyu Lai             71: "APN",
57*7dc08ffcSJunyu Lai             72: "AMBR",
58*7dc08ffcSJunyu Lai             73: "EPS Bearer ID",
59*7dc08ffcSJunyu Lai             74: "IPv4",
60*7dc08ffcSJunyu Lai             75: "MEI",
61*7dc08ffcSJunyu Lai             76: "MSISDN",
62*7dc08ffcSJunyu Lai             77: "Indication",
63*7dc08ffcSJunyu Lai             78: "Protocol Configuration Options",
64*7dc08ffcSJunyu Lai             79: "PAA",
65*7dc08ffcSJunyu Lai             80: "Bearer QoS",
66*7dc08ffcSJunyu Lai             82: "RAT",
67*7dc08ffcSJunyu Lai             83: "Serving Network",
68*7dc08ffcSJunyu Lai             86: "ULI",
69*7dc08ffcSJunyu Lai             87: "F-TEID",
70*7dc08ffcSJunyu Lai             93: "Bearer Context",
71*7dc08ffcSJunyu Lai             94: "Charging ID",
72*7dc08ffcSJunyu Lai             95: "Charging Characteristics",
73*7dc08ffcSJunyu Lai             99: "PDN Type",
74*7dc08ffcSJunyu Lai             114: "UE Time zone",
75*7dc08ffcSJunyu Lai             126: "Port Number",
76*7dc08ffcSJunyu Lai             127: "APN Restriction",
77*7dc08ffcSJunyu Lai             128: "Selection Mode",
78*7dc08ffcSJunyu Lai             161: "Max MBR/APN-AMBR (MMBR)"
79*7dc08ffcSJunyu Lai          }
80*7dc08ffcSJunyu Lai
81*7dc08ffcSJunyu LaiCauseValues = {
82*7dc08ffcSJunyu Lai    16: "Request Accepted",
83*7dc08ffcSJunyu Lai}
84*7dc08ffcSJunyu Lai
85*7dc08ffcSJunyu Lai
86*7dc08ffcSJunyu Laiclass GTPHeader(Packet):
87*7dc08ffcSJunyu Lai    # 3GPP TS 29.060 V9.1.0 (2009-12)
88*7dc08ffcSJunyu Lai    # without the version
89*7dc08ffcSJunyu Lai    name = "GTP v2 Header"
90*7dc08ffcSJunyu Lai    fields_desc = [BitField("version", 2, 3),
91*7dc08ffcSJunyu Lai                   BitField("P", 1, 1),
92*7dc08ffcSJunyu Lai                   BitField("T", 1, 1),
93*7dc08ffcSJunyu Lai                   BitField("SPARE", 0, 1),
94*7dc08ffcSJunyu Lai                   BitField("SPARE", 0, 1),
95*7dc08ffcSJunyu Lai                   BitField("SPARE", 0, 1),
96*7dc08ffcSJunyu Lai                   ByteEnumField("gtp_type", None, GTPmessageType),
97*7dc08ffcSJunyu Lai                   ShortField("length", None),
98*7dc08ffcSJunyu Lai                   ConditionalField(IntField("teid", 0),
99*7dc08ffcSJunyu Lai                                    lambda pkt:pkt.T == 1),
100*7dc08ffcSJunyu Lai                   ThreeBytesField("seq", RandShort()),
101*7dc08ffcSJunyu Lai                   ByteField("SPARE", 0)
102*7dc08ffcSJunyu Lai                   ]
103*7dc08ffcSJunyu Lai
104*7dc08ffcSJunyu Lai    def post_build(self, p, pay):
105*7dc08ffcSJunyu Lai        p += pay
106*7dc08ffcSJunyu Lai        if self.length is None:
107*7dc08ffcSJunyu Lai            l = len(p)-8
108*7dc08ffcSJunyu Lai            p = p[:2] + struct.pack("!H", l) + p[4:]
109*7dc08ffcSJunyu Lai        return p
110*7dc08ffcSJunyu Lai
111*7dc08ffcSJunyu Lai    def hashret(self):
112*7dc08ffcSJunyu Lai        return struct.pack("B", self.version) + self.payload.hashret()
113*7dc08ffcSJunyu Lai
114*7dc08ffcSJunyu Lai    def answers(self, other):
115*7dc08ffcSJunyu Lai        return (isinstance(other, GTPHeader) and
116*7dc08ffcSJunyu Lai                self.version == other.version and
117*7dc08ffcSJunyu Lai                self.payload.answers(other.payload))
118*7dc08ffcSJunyu Lai
119*7dc08ffcSJunyu Lai
120*7dc08ffcSJunyu Laiclass IE_IPv4(gtp.IE_Base):
121*7dc08ffcSJunyu Lai    name = "IE IPv4"
122*7dc08ffcSJunyu Lai    fields_desc = [ByteEnumField("ietype", 74, IEType),
123*7dc08ffcSJunyu Lai                   ShortField("length", 0),
124*7dc08ffcSJunyu Lai                   BitField("CR_flag", 0, 4),
125*7dc08ffcSJunyu Lai                   BitField("instance", 0, 4),
126*7dc08ffcSJunyu Lai                   IPField("address", RandIP())]
127*7dc08ffcSJunyu Lai
128*7dc08ffcSJunyu Lai
129*7dc08ffcSJunyu Laiclass IE_MEI(gtp.IE_Base):
130*7dc08ffcSJunyu Lai    name = "IE MEI"
131*7dc08ffcSJunyu Lai    fields_desc = [ByteEnumField("ietype", 75, IEType),
132*7dc08ffcSJunyu Lai                   ShortField("length", 0),
133*7dc08ffcSJunyu Lai                   BitField("CR_flag", 0, 4),
134*7dc08ffcSJunyu Lai                   BitField("instance", 0, 4),
135*7dc08ffcSJunyu Lai                   LongField("MEI", 0)]
136*7dc08ffcSJunyu Lai
137*7dc08ffcSJunyu Lai
138*7dc08ffcSJunyu Laidef IE_Dispatcher(s):
139*7dc08ffcSJunyu Lai    """Choose the correct Information Element class."""
140*7dc08ffcSJunyu Lai
141*7dc08ffcSJunyu Lai    # Get the IE type
142*7dc08ffcSJunyu Lai    ietype = orb(s[0])
143*7dc08ffcSJunyu Lai    cls = ietypecls.get(ietype, Raw)
144*7dc08ffcSJunyu Lai
145*7dc08ffcSJunyu Lai    # if ietype greater than 128 are TLVs
146*7dc08ffcSJunyu Lai    if cls is Raw and ietype > 128:
147*7dc08ffcSJunyu Lai        cls = IE_NotImplementedTLV
148*7dc08ffcSJunyu Lai
149*7dc08ffcSJunyu Lai    return cls(s)
150*7dc08ffcSJunyu Lai
151*7dc08ffcSJunyu Lai
152*7dc08ffcSJunyu Laiclass IE_EPSBearerID(gtp.IE_Base):
153*7dc08ffcSJunyu Lai    name = "IE EPS Bearer ID"
154*7dc08ffcSJunyu Lai    fields_desc = [ByteEnumField("ietype", 73, IEType),
155*7dc08ffcSJunyu Lai                   ShortField("length", 0),
156*7dc08ffcSJunyu Lai                   BitField("CR_flag", 0, 4),
157*7dc08ffcSJunyu Lai                   BitField("instance", 0, 4),
158*7dc08ffcSJunyu Lai                   ByteField("EBI", 0)]
159*7dc08ffcSJunyu Lai
160*7dc08ffcSJunyu Lai
161*7dc08ffcSJunyu Laiclass IE_RAT(gtp.IE_Base):
162*7dc08ffcSJunyu Lai    name = "IE RAT"
163*7dc08ffcSJunyu Lai    fields_desc = [ByteEnumField("ietype", 82, IEType),
164*7dc08ffcSJunyu Lai                   ShortField("length", 0),
165*7dc08ffcSJunyu Lai                   BitField("CR_flag", 0, 4),
166*7dc08ffcSJunyu Lai                   BitField("instance", 0, 4),
167*7dc08ffcSJunyu Lai                   ByteEnumField("RAT_type", None, RATType)]
168*7dc08ffcSJunyu Lai
169*7dc08ffcSJunyu Lai
170*7dc08ffcSJunyu Laiclass IE_ServingNetwork(gtp.IE_Base):
171*7dc08ffcSJunyu Lai    name = "IE Serving Network"
172*7dc08ffcSJunyu Lai    fields_desc = [ByteEnumField("ietype", 83, IEType),
173*7dc08ffcSJunyu Lai                   ShortField("length", 0),
174*7dc08ffcSJunyu Lai                   BitField("CR_flag", 0, 4),
175*7dc08ffcSJunyu Lai                   BitField("instance", 0, 4),
176*7dc08ffcSJunyu Lai                   gtp.TBCDByteField("MCC", "", 2),
177*7dc08ffcSJunyu Lai                   gtp.TBCDByteField("MNC", "", 1)]
178*7dc08ffcSJunyu Lai
179*7dc08ffcSJunyu Lai
180*7dc08ffcSJunyu Laiclass ULI_RAI(gtp.IE_Base):
181*7dc08ffcSJunyu Lai    name = "IE Tracking Area Identity"
182*7dc08ffcSJunyu Lai    fields_desc = [
183*7dc08ffcSJunyu Lai        gtp.TBCDByteField("MCC", "", 2),
184*7dc08ffcSJunyu Lai        # MNC: if the third digit of MCC is 0xf, then the length of
185*7dc08ffcSJunyu Lai        # MNC is 1 byte
186*7dc08ffcSJunyu Lai        gtp.TBCDByteField("MNC", "", 1),
187*7dc08ffcSJunyu Lai        ShortField("LAC", 0),
188*7dc08ffcSJunyu Lai        ShortField("RAC", 0)]
189*7dc08ffcSJunyu Lai
190*7dc08ffcSJunyu Lai
191*7dc08ffcSJunyu Laiclass ULI_SAI(gtp.IE_Base):
192*7dc08ffcSJunyu Lai    name = "IE Tracking Area Identity"
193*7dc08ffcSJunyu Lai    fields_desc = [
194*7dc08ffcSJunyu Lai        gtp.TBCDByteField("MCC", "", 2),
195*7dc08ffcSJunyu Lai        gtp.TBCDByteField("MNC", "", 1),
196*7dc08ffcSJunyu Lai        ShortField("LAC", 0),
197*7dc08ffcSJunyu Lai        ShortField("SAC", 0)]
198*7dc08ffcSJunyu Lai
199*7dc08ffcSJunyu Lai
200*7dc08ffcSJunyu Laiclass ULI_TAI(gtp.IE_Base):
201*7dc08ffcSJunyu Lai    name = "IE Tracking Area Identity"
202*7dc08ffcSJunyu Lai    fields_desc = [
203*7dc08ffcSJunyu Lai        gtp.TBCDByteField("MCC", "", 2),
204*7dc08ffcSJunyu Lai        gtp.TBCDByteField("MNC", "", 1),
205*7dc08ffcSJunyu Lai        ShortField("TAC", 0)]
206*7dc08ffcSJunyu Lai
207*7dc08ffcSJunyu Lai
208*7dc08ffcSJunyu Laiclass ULI_ECGI(gtp.IE_Base):
209*7dc08ffcSJunyu Lai    name = "IE E-UTRAN Cell Identifier"
210*7dc08ffcSJunyu Lai    fields_desc = [
211*7dc08ffcSJunyu Lai        gtp.TBCDByteField("MCC", "", 2),
212*7dc08ffcSJunyu Lai        gtp.TBCDByteField("MNC", "", 1),
213*7dc08ffcSJunyu Lai        BitField("SPARE", 0, 4),
214*7dc08ffcSJunyu Lai        BitField("ECI", 0, 28)]
215*7dc08ffcSJunyu Lai
216*7dc08ffcSJunyu Lai
217*7dc08ffcSJunyu Laiclass IE_ULI(gtp.IE_Base):
218*7dc08ffcSJunyu Lai    name = "IE ULI"
219*7dc08ffcSJunyu Lai    fields_desc = [ByteEnumField("ietype", 86, IEType),
220*7dc08ffcSJunyu Lai                   ShortField("length", 0),
221*7dc08ffcSJunyu Lai                   BitField("CR_flag", 0, 4),
222*7dc08ffcSJunyu Lai                   BitField("instance", 0, 4),
223*7dc08ffcSJunyu Lai                   BitField("SPARE", 0, 2),
224*7dc08ffcSJunyu Lai                   BitField("LAI_Present", 0, 1),
225*7dc08ffcSJunyu Lai                   BitField("ECGI_Present", 0, 1),
226*7dc08ffcSJunyu Lai                   BitField("TAI_Present", 0, 1),
227*7dc08ffcSJunyu Lai                   BitField("RAI_Present", 0, 1),
228*7dc08ffcSJunyu Lai                   BitField("SAI_Present", 0, 1),
229*7dc08ffcSJunyu Lai                   BitField("CGI_Present", 0, 1),
230*7dc08ffcSJunyu Lai                   ConditionalField(
231*7dc08ffcSJunyu Lai        PacketField("SAI", 0, ULI_SAI), lambda pkt: bool(pkt.SAI_Present)),
232*7dc08ffcSJunyu Lai        ConditionalField(
233*7dc08ffcSJunyu Lai        PacketField("RAI", 0, ULI_RAI), lambda pkt: bool(pkt.RAI_Present)),
234*7dc08ffcSJunyu Lai        ConditionalField(
235*7dc08ffcSJunyu Lai        PacketField("TAI", 0, ULI_TAI), lambda pkt: bool(pkt.TAI_Present)),
236*7dc08ffcSJunyu Lai        ConditionalField(PacketField("ECGI", 0, ULI_ECGI),
237*7dc08ffcSJunyu Lai                         lambda pkt: bool(pkt.ECGI_Present))]
238*7dc08ffcSJunyu Lai
239*7dc08ffcSJunyu Lai
240*7dc08ffcSJunyu Laiclass IE_FTEID(gtp.IE_Base):
241*7dc08ffcSJunyu Lai    name = "IE F-TEID"
242*7dc08ffcSJunyu Lai    fields_desc = [ByteEnumField("ietype", 87, IEType),
243*7dc08ffcSJunyu Lai                   ShortField("length", 0),
244*7dc08ffcSJunyu Lai                   BitField("CR_flag", 0, 4),
245*7dc08ffcSJunyu Lai                   BitField("instance", 0, 4),
246*7dc08ffcSJunyu Lai                   BitField("ipv4_present", 0, 1),
247*7dc08ffcSJunyu Lai                   BitField("ipv6_present", 0, 1),
248*7dc08ffcSJunyu Lai                   BitField("InterfaceType", 0, 6),
249*7dc08ffcSJunyu Lai                   XIntField("GRE_Key", 0),
250*7dc08ffcSJunyu Lai                   ConditionalField(
251*7dc08ffcSJunyu Lai        IPField("ipv4", RandIP()), lambda pkt: pkt.ipv4_present),
252*7dc08ffcSJunyu Lai        ConditionalField(XBitField("ipv6", "2001::", 128),
253*7dc08ffcSJunyu Lai                         lambda pkt: pkt.ipv6_present)]
254*7dc08ffcSJunyu Lai
255*7dc08ffcSJunyu Lai
256*7dc08ffcSJunyu Laiclass IE_BearerContext(gtp.IE_Base):
257*7dc08ffcSJunyu Lai    name = "IE Bearer Context"
258*7dc08ffcSJunyu Lai    fields_desc = [ByteEnumField("ietype", 93, IEType),
259*7dc08ffcSJunyu Lai                   ShortField("length", 0),
260*7dc08ffcSJunyu Lai                   BitField("CR_flag", 0, 4),
261*7dc08ffcSJunyu Lai                   BitField("instance", 0, 4),
262*7dc08ffcSJunyu Lai                   PacketListField("IE_list", None, IE_Dispatcher,
263*7dc08ffcSJunyu Lai                                   length_from=lambda pkt: pkt.length)]
264*7dc08ffcSJunyu Lai
265*7dc08ffcSJunyu Lai
266*7dc08ffcSJunyu Laiclass IE_NotImplementedTLV(gtp.IE_Base):
267*7dc08ffcSJunyu Lai    name = "IE not implemented"
268*7dc08ffcSJunyu Lai    fields_desc = [ByteEnumField("ietype", 0, IEType),
269*7dc08ffcSJunyu Lai                   ShortField("length",  None),
270*7dc08ffcSJunyu Lai                   StrLenField("data", "", length_from=lambda x: x.length)]
271*7dc08ffcSJunyu Lai
272*7dc08ffcSJunyu Lai
273*7dc08ffcSJunyu Laiclass IE_IMSI(gtp.IE_Base):
274*7dc08ffcSJunyu Lai    name = "IE IMSI"
275*7dc08ffcSJunyu Lai    fields_desc = [ByteEnumField("ietype", 1, IEType),
276*7dc08ffcSJunyu Lai                   ShortField("length",  None),
277*7dc08ffcSJunyu Lai                   BitField("CR_flag", 0, 4),
278*7dc08ffcSJunyu Lai                   BitField("instance", 0, 4),
279*7dc08ffcSJunyu Lai                   gtp.TBCDByteField("IMSI", "33607080910",
280*7dc08ffcSJunyu Lai                                        length_from=lambda x: x.length)]
281*7dc08ffcSJunyu Lai
282*7dc08ffcSJunyu Lai
283*7dc08ffcSJunyu Laiclass IE_Cause(gtp.IE_Base):
284*7dc08ffcSJunyu Lai    name = "IE Cause"
285*7dc08ffcSJunyu Lai    fields_desc = [ByteEnumField("ietype", 2, IEType),
286*7dc08ffcSJunyu Lai                   ShortField("length",  None),
287*7dc08ffcSJunyu Lai                   BitField("CR_flag", 0, 4),
288*7dc08ffcSJunyu Lai                   BitField("instance", 0, 4),
289*7dc08ffcSJunyu Lai                   ByteEnumField("Cause", 1, CauseValues),
290*7dc08ffcSJunyu Lai                   BitField("SPARE", 0, 5),
291*7dc08ffcSJunyu Lai                   BitField("PCE", 0, 1),
292*7dc08ffcSJunyu Lai                   BitField("BCE", 0, 1),
293*7dc08ffcSJunyu Lai                   BitField("CS", 0, 1)]
294*7dc08ffcSJunyu Lai
295*7dc08ffcSJunyu Lai
296*7dc08ffcSJunyu Laiclass IE_RecoveryRestart(gtp.IE_Base):
297*7dc08ffcSJunyu Lai    name = "IE Recovery Restart"
298*7dc08ffcSJunyu Lai    fields_desc = [ByteEnumField("ietype", 3, IEType),
299*7dc08ffcSJunyu Lai                   ShortField("length",  None),
300*7dc08ffcSJunyu Lai                   BitField("CR_flag", 0, 4),
301*7dc08ffcSJunyu Lai                   BitField("instance", 0, 4),
302*7dc08ffcSJunyu Lai                   ByteField("restart_counter", 0)]
303*7dc08ffcSJunyu Lai
304*7dc08ffcSJunyu Lai
305*7dc08ffcSJunyu Laiclass IE_APN(gtp.IE_Base):
306*7dc08ffcSJunyu Lai    name = "IE APN"
307*7dc08ffcSJunyu Lai    fields_desc = [ByteEnumField("ietype", 71, IEType),
308*7dc08ffcSJunyu Lai                   ShortField("length",  None),
309*7dc08ffcSJunyu Lai                   BitField("CR_flag", 0, 4),
310*7dc08ffcSJunyu Lai                   BitField("instance", 0, 4),
311*7dc08ffcSJunyu Lai                   gtp.APNStrLenField("APN", "internet",
312*7dc08ffcSJunyu Lai                                         length_from=lambda x: x.length)]
313*7dc08ffcSJunyu Lai
314*7dc08ffcSJunyu Lai
315*7dc08ffcSJunyu Laiclass IE_AMBR(gtp.IE_Base):
316*7dc08ffcSJunyu Lai    name = "IE AMBR"
317*7dc08ffcSJunyu Lai    fields_desc = [ByteEnumField("ietype", 72, IEType),
318*7dc08ffcSJunyu Lai                   ShortField("length",  None),
319*7dc08ffcSJunyu Lai                   BitField("CR_flag", 0, 4),
320*7dc08ffcSJunyu Lai                   BitField("instance", 0, 4),
321*7dc08ffcSJunyu Lai                   IntField("AMBR_Uplink", 0),
322*7dc08ffcSJunyu Lai                   IntField("AMBR_Downlink", 0)]
323*7dc08ffcSJunyu Lai
324*7dc08ffcSJunyu Lai
325*7dc08ffcSJunyu Laiclass IE_MSISDN(gtp.IE_Base):
326*7dc08ffcSJunyu Lai    name = "IE MSISDN"
327*7dc08ffcSJunyu Lai    fields_desc = [ByteEnumField("ietype", 76, IEType),
328*7dc08ffcSJunyu Lai                   ShortField("length",  None),
329*7dc08ffcSJunyu Lai                   BitField("CR_flag", 0, 4),
330*7dc08ffcSJunyu Lai                   BitField("instance", 0, 4),
331*7dc08ffcSJunyu Lai                   gtp.TBCDByteField("digits", "33123456789",
332*7dc08ffcSJunyu Lai                                        length_from=lambda x: x.length)]
333*7dc08ffcSJunyu Lai
334*7dc08ffcSJunyu Lai
335*7dc08ffcSJunyu Laiclass IE_Indication(gtp.IE_Base):
336*7dc08ffcSJunyu Lai    name = "IE Cause"
337*7dc08ffcSJunyu Lai    fields_desc = [ByteEnumField("ietype", 77, IEType),
338*7dc08ffcSJunyu Lai                   ShortField("length",  None),
339*7dc08ffcSJunyu Lai                   BitField("CR_flag", 0, 4),
340*7dc08ffcSJunyu Lai                   BitField("instance", 0, 4),
341*7dc08ffcSJunyu Lai                   BitField("DAF", 0, 1),
342*7dc08ffcSJunyu Lai                   BitField("DTF", 0, 1),
343*7dc08ffcSJunyu Lai                   BitField("HI", 0, 1),
344*7dc08ffcSJunyu Lai                   BitField("DFI", 0, 1),
345*7dc08ffcSJunyu Lai                   BitField("OI", 0, 1),
346*7dc08ffcSJunyu Lai                   BitField("ISRSI", 0, 1),
347*7dc08ffcSJunyu Lai                   BitField("ISRAI", 0, 1),
348*7dc08ffcSJunyu Lai                   BitField("SGWCI", 0, 1),
349*7dc08ffcSJunyu Lai                   BitField("SQCI", 0, 1),
350*7dc08ffcSJunyu Lai                   BitField("UIMSI", 0, 1),
351*7dc08ffcSJunyu Lai                   BitField("CFSI", 0, 1),
352*7dc08ffcSJunyu Lai                   BitField("CRSI", 0, 1),
353*7dc08ffcSJunyu Lai                   BitField("PS", 0, 1),
354*7dc08ffcSJunyu Lai                   BitField("PT", 0, 1),
355*7dc08ffcSJunyu Lai                   BitField("SI", 0, 1),
356*7dc08ffcSJunyu Lai                   BitField("MSV", 0, 1),
357*7dc08ffcSJunyu Lai
358*7dc08ffcSJunyu Lai                   ConditionalField(
359*7dc08ffcSJunyu Lai                       BitField("RetLoc", 0, 1), lambda pkt: pkt.length > 2),
360*7dc08ffcSJunyu Lai                   ConditionalField(
361*7dc08ffcSJunyu Lai                       BitField("PBIC", 0, 1), lambda pkt: pkt.length > 2),
362*7dc08ffcSJunyu Lai                   ConditionalField(
363*7dc08ffcSJunyu Lai                       BitField("SRNI", 0, 1), lambda pkt: pkt.length > 2),
364*7dc08ffcSJunyu Lai                   ConditionalField(
365*7dc08ffcSJunyu Lai                       BitField("S6AF", 0, 1), lambda pkt: pkt.length > 2),
366*7dc08ffcSJunyu Lai                   ConditionalField(
367*7dc08ffcSJunyu Lai                       BitField("S4AF", 0, 1), lambda pkt: pkt.length > 2),
368*7dc08ffcSJunyu Lai                   ConditionalField(
369*7dc08ffcSJunyu Lai                       BitField("MBMDT", 0, 1), lambda pkt: pkt.length > 2),
370*7dc08ffcSJunyu Lai                   ConditionalField(
371*7dc08ffcSJunyu Lai                       BitField("ISRAU", 0, 1), lambda pkt: pkt.length > 2),
372*7dc08ffcSJunyu Lai                   ConditionalField(
373*7dc08ffcSJunyu Lai                       BitField("CCRSI", 0, 1), lambda pkt: pkt.length > 2),
374*7dc08ffcSJunyu Lai
375*7dc08ffcSJunyu Lai                   ConditionalField(
376*7dc08ffcSJunyu Lai        BitField("CPRAI", 0, 1), lambda pkt: pkt.length > 3),
377*7dc08ffcSJunyu Lai        ConditionalField(
378*7dc08ffcSJunyu Lai        BitField("ARRL", 0, 1), lambda pkt: pkt.length > 3),
379*7dc08ffcSJunyu Lai        ConditionalField(
380*7dc08ffcSJunyu Lai        BitField("PPOFF", 0, 1), lambda pkt: pkt.length > 3),
381*7dc08ffcSJunyu Lai        ConditionalField(
382*7dc08ffcSJunyu Lai        BitField("PPON", 0, 1), lambda pkt: pkt.length > 3),
383*7dc08ffcSJunyu Lai        ConditionalField(
384*7dc08ffcSJunyu Lai        BitField("PPSI", 0, 1), lambda pkt: pkt.length > 3),
385*7dc08ffcSJunyu Lai        ConditionalField(
386*7dc08ffcSJunyu Lai        BitField("CSFBI", 0, 1), lambda pkt: pkt.length > 3),
387*7dc08ffcSJunyu Lai        ConditionalField(
388*7dc08ffcSJunyu Lai        BitField("CLII", 0, 1), lambda pkt: pkt.length > 3),
389*7dc08ffcSJunyu Lai        ConditionalField(
390*7dc08ffcSJunyu Lai        BitField("CPSR", 0, 1), lambda pkt: pkt.length > 3),
391*7dc08ffcSJunyu Lai
392*7dc08ffcSJunyu Lai    ]
393*7dc08ffcSJunyu Lai
394*7dc08ffcSJunyu LaiPDN_TYPES = {
395*7dc08ffcSJunyu Lai    1: "IPv4",
396*7dc08ffcSJunyu Lai    2: "IPv6",
397*7dc08ffcSJunyu Lai    3: "IPv4/IPv6",
398*7dc08ffcSJunyu Lai}
399*7dc08ffcSJunyu Lai
400*7dc08ffcSJunyu LaiPCO_OPTION_TYPES = {
401*7dc08ffcSJunyu Lai    3: "IPv4",
402*7dc08ffcSJunyu Lai    129: "Primary DNS Server IP address",
403*7dc08ffcSJunyu Lai    130: "Primary NBNS Server IP address",
404*7dc08ffcSJunyu Lai    131: "Secondary DNS Server IP address",
405*7dc08ffcSJunyu Lai    132: "Secondary NBNS Server IP address",
406*7dc08ffcSJunyu Lai}
407*7dc08ffcSJunyu Lai
408*7dc08ffcSJunyu Lai
409*7dc08ffcSJunyu Laiclass PCO_Option(Packet):
410*7dc08ffcSJunyu Lai    def extract_padding(self, pkt):
411*7dc08ffcSJunyu Lai        return "", pkt
412*7dc08ffcSJunyu Lai
413*7dc08ffcSJunyu Lai
414*7dc08ffcSJunyu Laiclass PCO_IPv4(PCO_Option):
415*7dc08ffcSJunyu Lai    name = "IPv4"
416*7dc08ffcSJunyu Lai    fields_desc = [ByteEnumField("type", None, PCO_OPTION_TYPES),
417*7dc08ffcSJunyu Lai                   ByteField("length", 0),
418*7dc08ffcSJunyu Lai                   IPField("address", RandIP())]
419*7dc08ffcSJunyu Lai
420*7dc08ffcSJunyu Lai
421*7dc08ffcSJunyu Laiclass PCO_Primary_DNS(PCO_Option):
422*7dc08ffcSJunyu Lai    name = "Primary DNS Server IP Address"
423*7dc08ffcSJunyu Lai    fields_desc = [ByteEnumField("type", None, PCO_OPTION_TYPES),
424*7dc08ffcSJunyu Lai                   ByteField("length", 0),
425*7dc08ffcSJunyu Lai                   IPField("address", RandIP())]
426*7dc08ffcSJunyu Lai
427*7dc08ffcSJunyu Lai
428*7dc08ffcSJunyu Laiclass PCO_Primary_NBNS(PCO_Option):
429*7dc08ffcSJunyu Lai    name = "Primary DNS Server IP Address"
430*7dc08ffcSJunyu Lai    fields_desc = [ByteEnumField("type", None, PCO_OPTION_TYPES),
431*7dc08ffcSJunyu Lai                   ByteField("length", 0),
432*7dc08ffcSJunyu Lai                   IPField("address", RandIP())]
433*7dc08ffcSJunyu Lai
434*7dc08ffcSJunyu Lai
435*7dc08ffcSJunyu Laiclass PCO_Secondary_DNS(PCO_Option):
436*7dc08ffcSJunyu Lai    name = "Secondary DNS Server IP Address"
437*7dc08ffcSJunyu Lai    fields_desc = [ByteEnumField("type", None, PCO_OPTION_TYPES),
438*7dc08ffcSJunyu Lai                   ByteField("length", 0),
439*7dc08ffcSJunyu Lai                   IPField("address", RandIP())]
440*7dc08ffcSJunyu Lai
441*7dc08ffcSJunyu Lai
442*7dc08ffcSJunyu Laiclass PCO_Secondary_NBNS(PCO_Option):
443*7dc08ffcSJunyu Lai    name = "Secondary NBNS Server IP Address"
444*7dc08ffcSJunyu Lai    fields_desc = [ByteEnumField("type", None, PCO_OPTION_TYPES),
445*7dc08ffcSJunyu Lai                   ByteField("length", 0),
446*7dc08ffcSJunyu Lai                   IPField("address", RandIP())]
447*7dc08ffcSJunyu Lai
448*7dc08ffcSJunyu Lai
449*7dc08ffcSJunyu LaiPCO_PROTOCOL_TYPES = {
450*7dc08ffcSJunyu Lai    0x0001: 'P-CSCF IPv6 Address Request',
451*7dc08ffcSJunyu Lai    0x0003: 'DNS Server IPv6 Address Request',
452*7dc08ffcSJunyu Lai    0x0005: 'MS Support of Network Requested Bearer Control indicator',
453*7dc08ffcSJunyu Lai    0x000a: 'IP Allocation via NAS',
454*7dc08ffcSJunyu Lai    0x000d: 'DNS Server IPv4 Address Request',
455*7dc08ffcSJunyu Lai    0x000c: 'P-CSCF IPv4 Address Request',
456*7dc08ffcSJunyu Lai    0x0010: 'IPv4 Link MTU Request',
457*7dc08ffcSJunyu Lai    0x8021: 'IPCP',
458*7dc08ffcSJunyu Lai    0xc023: 'Password Authentification Protocol',
459*7dc08ffcSJunyu Lai    0xc223: 'Challenge Handshake Authentication Protocol',
460*7dc08ffcSJunyu Lai}
461*7dc08ffcSJunyu Lai
462*7dc08ffcSJunyu LaiPCO_OPTION_CLASSES = {
463*7dc08ffcSJunyu Lai    3: PCO_IPv4,
464*7dc08ffcSJunyu Lai    129: PCO_Primary_DNS,
465*7dc08ffcSJunyu Lai    130: PCO_Primary_NBNS,
466*7dc08ffcSJunyu Lai    131: PCO_Secondary_DNS,
467*7dc08ffcSJunyu Lai    132: PCO_Secondary_NBNS,
468*7dc08ffcSJunyu Lai}
469*7dc08ffcSJunyu Lai
470*7dc08ffcSJunyu Lai
471*7dc08ffcSJunyu Laidef PCO_option_dispatcher(s):
472*7dc08ffcSJunyu Lai    """Choose the correct PCO element."""
473*7dc08ffcSJunyu Lai    option = orb(s[0])
474*7dc08ffcSJunyu Lai
475*7dc08ffcSJunyu Lai    cls = PCO_OPTION_CLASSES.get(option, Raw)
476*7dc08ffcSJunyu Lai    return cls(s)
477*7dc08ffcSJunyu Lai
478*7dc08ffcSJunyu Lai
479*7dc08ffcSJunyu Laidef len_options(pkt):
480*7dc08ffcSJunyu Lai    return pkt.length-4 if pkt.length else 0
481*7dc08ffcSJunyu Lai
482*7dc08ffcSJunyu Lai
483*7dc08ffcSJunyu Laiclass PCO_P_CSCF_IPv6_Address_Request(PCO_Option):
484*7dc08ffcSJunyu Lai    name = "PCO PCO-P CSCF IPv6 Address Request"
485*7dc08ffcSJunyu Lai    fields_desc = [ShortEnumField("type", None, PCO_PROTOCOL_TYPES),
486*7dc08ffcSJunyu Lai                   ByteField("length", 0),
487*7dc08ffcSJunyu Lai                   ConditionalField(XBitField("address",
488*7dc08ffcSJunyu Lai                                              "2001:db8:0:42::", 128),
489*7dc08ffcSJunyu Lai                                    lambda pkt: pkt.length)]
490*7dc08ffcSJunyu Lai
491*7dc08ffcSJunyu Lai
492*7dc08ffcSJunyu Laiclass PCO_DNS_Server_IPv6(PCO_Option):
493*7dc08ffcSJunyu Lai    name = "PCO DNS Server IPv6 Address Request"
494*7dc08ffcSJunyu Lai    fields_desc = [ShortEnumField("type", None, PCO_PROTOCOL_TYPES),
495*7dc08ffcSJunyu Lai                   ByteField("length", 0),
496*7dc08ffcSJunyu Lai                   ConditionalField(XBitField("address",
497*7dc08ffcSJunyu Lai                                              "2001:db8:0:42::", 128),
498*7dc08ffcSJunyu Lai                                    lambda pkt: pkt.length)]
499*7dc08ffcSJunyu Lai
500*7dc08ffcSJunyu Lai
501*7dc08ffcSJunyu Laiclass PCO_SOF(PCO_Option):
502*7dc08ffcSJunyu Lai    name = "PCO MS Support of Network Requested Bearer Control indicator"
503*7dc08ffcSJunyu Lai    fields_desc = [ShortEnumField("type", None, PCO_PROTOCOL_TYPES),
504*7dc08ffcSJunyu Lai                   ByteField("length", 0),
505*7dc08ffcSJunyu Lai                   ]
506*7dc08ffcSJunyu Lai
507*7dc08ffcSJunyu Lai
508*7dc08ffcSJunyu Laiclass PCO_PPP(PCO_Option):
509*7dc08ffcSJunyu Lai    name = "PPP IP Control Protocol"
510*7dc08ffcSJunyu Lai    fields_desc = [ByteField("Code", 0),
511*7dc08ffcSJunyu Lai                   ByteField("Identifier", 0),
512*7dc08ffcSJunyu Lai                   ShortField("length", 0),
513*7dc08ffcSJunyu Lai                   PacketListField("Options", None, PCO_option_dispatcher,
514*7dc08ffcSJunyu Lai                                   length_from=len_options)]
515*7dc08ffcSJunyu Lai
516*7dc08ffcSJunyu Lai    def extract_padding(self, pkt):
517*7dc08ffcSJunyu Lai        return "", pkt
518*7dc08ffcSJunyu Lai
519*7dc08ffcSJunyu Lai
520*7dc08ffcSJunyu Laiclass PCO_IP_Allocation_via_NAS(PCO_Option):
521*7dc08ffcSJunyu Lai    name = "PCO IP Address allocation via NAS Signaling"
522*7dc08ffcSJunyu Lai    fields_desc = [ShortEnumField("type", None, PCO_PROTOCOL_TYPES),
523*7dc08ffcSJunyu Lai                   ByteField("length", 0),
524*7dc08ffcSJunyu Lai                   PacketListField("Options", None, PCO_option_dispatcher,
525*7dc08ffcSJunyu Lai                                   length_from=len_options)]
526*7dc08ffcSJunyu Lai
527*7dc08ffcSJunyu Lai
528*7dc08ffcSJunyu Laiclass PCO_P_CSCF_IPv4_Address_Request(PCO_Option):
529*7dc08ffcSJunyu Lai    name = "PCO PCO-P CSCF IPv4 Address Request"
530*7dc08ffcSJunyu Lai    fields_desc = [ShortEnumField("type", None, PCO_PROTOCOL_TYPES),
531*7dc08ffcSJunyu Lai                   ByteField("length", 0),
532*7dc08ffcSJunyu Lai                   ConditionalField(IPField("address", RandIP()),
533*7dc08ffcSJunyu Lai                                    lambda pkt: pkt.length)]
534*7dc08ffcSJunyu Lai
535*7dc08ffcSJunyu Lai
536*7dc08ffcSJunyu Laiclass PCO_DNS_Server_IPv4(PCO_Option):
537*7dc08ffcSJunyu Lai    name = "PCO DNS Server IPv4 Address Request"
538*7dc08ffcSJunyu Lai    fields_desc = [ShortEnumField("type", None, PCO_PROTOCOL_TYPES),
539*7dc08ffcSJunyu Lai                   ByteField("length", 0),
540*7dc08ffcSJunyu Lai                   ConditionalField(IPField("address", RandIP()),
541*7dc08ffcSJunyu Lai                                    lambda pkt: pkt.length)]
542*7dc08ffcSJunyu Lai
543*7dc08ffcSJunyu Lai
544*7dc08ffcSJunyu Laiclass PCO_IPv4_Link_MTU_Request(PCO_Option):
545*7dc08ffcSJunyu Lai    name = "PCO IPv4 Link MTU Request"
546*7dc08ffcSJunyu Lai    fields_desc = [ShortEnumField("type", None, PCO_PROTOCOL_TYPES),
547*7dc08ffcSJunyu Lai                   ByteField("length", 0),
548*7dc08ffcSJunyu Lai                   ConditionalField(ShortField("MTU_size", 1500),
549*7dc08ffcSJunyu Lai                                    lambda pkt: pkt.length)]
550*7dc08ffcSJunyu Lai
551*7dc08ffcSJunyu Lai
552*7dc08ffcSJunyu Laiclass PCO_IPCP(PCO_Option):
553*7dc08ffcSJunyu Lai    name = "PCO Internet Protocol Control Protocol"
554*7dc08ffcSJunyu Lai    fields_desc = [ShortEnumField("type", None, PCO_PROTOCOL_TYPES),
555*7dc08ffcSJunyu Lai                   ByteField("length", 0),
556*7dc08ffcSJunyu Lai                   PacketField("PPP", None, PCO_PPP)]
557*7dc08ffcSJunyu Lai
558*7dc08ffcSJunyu Lai
559*7dc08ffcSJunyu Laiclass PCO_PPP_Auth(PCO_Option):
560*7dc08ffcSJunyu Lai    name = "PPP Password Authentification Protocol"
561*7dc08ffcSJunyu Lai    fields_desc = [ByteField("Code", 0),
562*7dc08ffcSJunyu Lai                   ByteField("Identifier", 0),
563*7dc08ffcSJunyu Lai                   ShortField("length", 0),
564*7dc08ffcSJunyu Lai                   ByteField("PeerID_length", 0),
565*7dc08ffcSJunyu Lai                   ConditionalField(StrFixedLenField(
566*7dc08ffcSJunyu Lai                       "PeerID",
567*7dc08ffcSJunyu Lai                       "",
568*7dc08ffcSJunyu Lai                       length_from=lambda pkt: pkt.PeerID_length),
569*7dc08ffcSJunyu Lai                       lambda pkt: pkt.PeerID_length),
570*7dc08ffcSJunyu Lai                   ByteField("Password_length", 0),
571*7dc08ffcSJunyu Lai                   ConditionalField(
572*7dc08ffcSJunyu Lai                       StrFixedLenField(
573*7dc08ffcSJunyu Lai                           "Password",
574*7dc08ffcSJunyu Lai                           "",
575*7dc08ffcSJunyu Lai                           length_from=lambda pkt: pkt.Password_length),
576*7dc08ffcSJunyu Lai                       lambda pkt: pkt.Password_length)]
577*7dc08ffcSJunyu Lai
578*7dc08ffcSJunyu Lai
579*7dc08ffcSJunyu Laiclass PCO_PasswordAuthentificationProtocol(PCO_Option):
580*7dc08ffcSJunyu Lai    name = "PCO Password Authentification Protocol"
581*7dc08ffcSJunyu Lai    fields_desc = [ShortEnumField("type", None, PCO_PROTOCOL_TYPES),
582*7dc08ffcSJunyu Lai                   ByteField("length", 0),
583*7dc08ffcSJunyu Lai                   PacketField("PPP", None, PCO_PPP_Auth)]
584*7dc08ffcSJunyu Lai
585*7dc08ffcSJunyu Lai
586*7dc08ffcSJunyu Laiclass PCO_PPP_Challenge(PCO_Option):
587*7dc08ffcSJunyu Lai    name = "PPP Password Authentification Protocol"
588*7dc08ffcSJunyu Lai    fields_desc = [ByteField("Code", 0),
589*7dc08ffcSJunyu Lai                   ByteField("Identifier", 0),
590*7dc08ffcSJunyu Lai                   ShortField("length", 0),
591*7dc08ffcSJunyu Lai                   ByteField("value_size", 0),
592*7dc08ffcSJunyu Lai                   ConditionalField(StrFixedLenField(
593*7dc08ffcSJunyu Lai                       "value", "",
594*7dc08ffcSJunyu Lai                       length_from=lambda pkt: pkt.value_size),
595*7dc08ffcSJunyu Lai                       lambda pkt: pkt.value_size),
596*7dc08ffcSJunyu Lai                   ConditionalField(StrFixedLenField(
597*7dc08ffcSJunyu Lai                       "name", "",
598*7dc08ffcSJunyu Lai                       length_from=lambda pkt: pkt.length-pkt.value_size-5),
599*7dc08ffcSJunyu Lai                       lambda pkt: pkt.length)]
600*7dc08ffcSJunyu Lai
601*7dc08ffcSJunyu Lai
602*7dc08ffcSJunyu Laiclass PCO_ChallengeHandshakeAuthenticationProtocol(PCO_Option):
603*7dc08ffcSJunyu Lai    name = "PCO Password Authentification Protocol"
604*7dc08ffcSJunyu Lai    fields_desc = [ShortEnumField("type", None, PCO_PROTOCOL_TYPES),
605*7dc08ffcSJunyu Lai                   ByteField("length", 0),
606*7dc08ffcSJunyu Lai                   PacketField("PPP", None, PCO_PPP_Challenge)]
607*7dc08ffcSJunyu Lai
608*7dc08ffcSJunyu Lai
609*7dc08ffcSJunyu LaiPCO_PROTOCOL_CLASSES = {
610*7dc08ffcSJunyu Lai    0x0001: PCO_P_CSCF_IPv6_Address_Request,
611*7dc08ffcSJunyu Lai    0x0003: PCO_DNS_Server_IPv6,
612*7dc08ffcSJunyu Lai    0x0005: PCO_SOF,
613*7dc08ffcSJunyu Lai    0x000a: PCO_IP_Allocation_via_NAS,
614*7dc08ffcSJunyu Lai    0x000c: PCO_P_CSCF_IPv4_Address_Request,
615*7dc08ffcSJunyu Lai    0x000d: PCO_DNS_Server_IPv4,
616*7dc08ffcSJunyu Lai    0x0010: PCO_IPv4_Link_MTU_Request,
617*7dc08ffcSJunyu Lai    0x8021: PCO_IPCP,
618*7dc08ffcSJunyu Lai    0xc023: PCO_PasswordAuthentificationProtocol,
619*7dc08ffcSJunyu Lai    0xc223: PCO_ChallengeHandshakeAuthenticationProtocol,
620*7dc08ffcSJunyu Lai}
621*7dc08ffcSJunyu Lai
622*7dc08ffcSJunyu Lai
623*7dc08ffcSJunyu Laidef PCO_protocol_dispatcher(s):
624*7dc08ffcSJunyu Lai    """Choose the correct PCO element."""
625*7dc08ffcSJunyu Lai    proto_num = orb(s[0])*256+orb(s[1])
626*7dc08ffcSJunyu Lai    cls = PCO_PROTOCOL_CLASSES.get(proto_num, Raw)
627*7dc08ffcSJunyu Lai    return cls(s)
628*7dc08ffcSJunyu Lai
629*7dc08ffcSJunyu Lai
630*7dc08ffcSJunyu Laiclass IE_PCO(gtp.IE_Base):
631*7dc08ffcSJunyu Lai    name = "IE Protocol Configuration Options"
632*7dc08ffcSJunyu Lai    fields_desc = [ByteEnumField("ietype", 78, IEType),
633*7dc08ffcSJunyu Lai                   ShortField("length",  None),
634*7dc08ffcSJunyu Lai                   BitField("CR_flag", 0, 4),
635*7dc08ffcSJunyu Lai                   BitField("instance", 0, 4),
636*7dc08ffcSJunyu Lai                   BitField("Extension", 0, 1),
637*7dc08ffcSJunyu Lai                   BitField("SPARE", 0, 4),
638*7dc08ffcSJunyu Lai                   BitField("PPP", 0, 3),
639*7dc08ffcSJunyu Lai                   PacketListField("Protocols", None, PCO_protocol_dispatcher,
640*7dc08ffcSJunyu Lai                                   length_from=lambda pkt: pkt.length-1)]
641*7dc08ffcSJunyu Lai
642*7dc08ffcSJunyu Lai
643*7dc08ffcSJunyu Laiclass IE_PAA(gtp.IE_Base):
644*7dc08ffcSJunyu Lai    name = "IE PAA"
645*7dc08ffcSJunyu Lai    fields_desc = [ByteEnumField("ietype", 79, IEType),
646*7dc08ffcSJunyu Lai                   ShortField("length",  None),
647*7dc08ffcSJunyu Lai                   BitField("CR_flag", 0, 4),
648*7dc08ffcSJunyu Lai                   BitField("instance", 0, 4),
649*7dc08ffcSJunyu Lai                   BitField("SPARE", 0, 5),
650*7dc08ffcSJunyu Lai                   BitEnumField("PDN_type", None, 3, PDN_TYPES),
651*7dc08ffcSJunyu Lai                   ConditionalField(
652*7dc08ffcSJunyu Lai                       ByteField("ipv6_prefix_length", 8),
653*7dc08ffcSJunyu Lai                       lambda pkt: pkt.PDN_type in (2, 3)),
654*7dc08ffcSJunyu Lai                   ConditionalField(
655*7dc08ffcSJunyu Lai                       XBitField("ipv6", "2001:db8:0:42::", 128),
656*7dc08ffcSJunyu Lai                       lambda pkt: pkt.PDN_type in (2, 3)),
657*7dc08ffcSJunyu Lai                   ConditionalField(
658*7dc08ffcSJunyu Lai                       IPField("ipv4", 0), lambda pkt: pkt.PDN_type in (1, 3)),
659*7dc08ffcSJunyu Lai                   ]
660*7dc08ffcSJunyu Lai
661*7dc08ffcSJunyu Lai
662*7dc08ffcSJunyu Laiclass IE_Bearer_QoS(gtp.IE_Base):
663*7dc08ffcSJunyu Lai    name = "IE Bearer Quality of Service"
664*7dc08ffcSJunyu Lai    fields_desc = [ByteEnumField("ietype", 80, IEType),
665*7dc08ffcSJunyu Lai                   ShortField("length",  None),
666*7dc08ffcSJunyu Lai                   BitField("CR_flag", 0, 4),
667*7dc08ffcSJunyu Lai                   BitField("instance", 0, 4),
668*7dc08ffcSJunyu Lai                   BitField("SPARE", 0, 1),
669*7dc08ffcSJunyu Lai                   BitField("PCI", 0, 1),
670*7dc08ffcSJunyu Lai                   BitField("PriorityLevel", 0, 4),
671*7dc08ffcSJunyu Lai                   BitField("SPARE", 0, 1),
672*7dc08ffcSJunyu Lai                   BitField("PVI", 0, 1),
673*7dc08ffcSJunyu Lai                   ByteField("QCI", 0),
674*7dc08ffcSJunyu Lai                   BitField("MaxBitRateForUplink", 0, 40),
675*7dc08ffcSJunyu Lai                   BitField("MaxBitRateForDownlink", 0, 40),
676*7dc08ffcSJunyu Lai                   BitField("GuaranteedBitRateForUplink", 0, 40),
677*7dc08ffcSJunyu Lai                   BitField("GuaranteedBitRateForDownlink", 0, 40)]
678*7dc08ffcSJunyu Lai
679*7dc08ffcSJunyu Lai
680*7dc08ffcSJunyu Laiclass IE_ChargingID(gtp.IE_Base):
681*7dc08ffcSJunyu Lai    name = "IE Charging ID"
682*7dc08ffcSJunyu Lai    fields_desc = [ByteEnumField("ietype", 94, IEType),
683*7dc08ffcSJunyu Lai                   ShortField("length",  None),
684*7dc08ffcSJunyu Lai                   BitField("CR_flag", 0, 4),
685*7dc08ffcSJunyu Lai                   BitField("instance", 0, 4),
686*7dc08ffcSJunyu Lai                   IntField("ChargingID", 0)]
687*7dc08ffcSJunyu Lai
688*7dc08ffcSJunyu Lai
689*7dc08ffcSJunyu Laiclass IE_ChargingCharacteristics(gtp.IE_Base):
690*7dc08ffcSJunyu Lai    name = "IE Charging ID"
691*7dc08ffcSJunyu Lai    fields_desc = [ByteEnumField("ietype", 95, IEType),
692*7dc08ffcSJunyu Lai                   ShortField("length",  None),
693*7dc08ffcSJunyu Lai                   BitField("CR_flag", 0, 4),
694*7dc08ffcSJunyu Lai                   BitField("instance", 0, 4),
695*7dc08ffcSJunyu Lai                   XShortField("ChargingCharacteristric", 0)]
696*7dc08ffcSJunyu Lai
697*7dc08ffcSJunyu Lai
698*7dc08ffcSJunyu Laiclass IE_PDN_type(gtp.IE_Base):
699*7dc08ffcSJunyu Lai    name = "IE PDN Type"
700*7dc08ffcSJunyu Lai    fields_desc = [ByteEnumField("ietype", 99, IEType),
701*7dc08ffcSJunyu Lai                   ShortField("length",  None),
702*7dc08ffcSJunyu Lai                   BitField("CR_flag", 0, 4),
703*7dc08ffcSJunyu Lai                   BitField("instance", 0, 4),
704*7dc08ffcSJunyu Lai                   BitField("SPARE", 0, 5),
705*7dc08ffcSJunyu Lai                   BitEnumField("PDN_type", None, 3, PDN_TYPES)]
706*7dc08ffcSJunyu Lai
707*7dc08ffcSJunyu Lai
708*7dc08ffcSJunyu Laiclass IE_UE_Timezone(gtp.IE_Base):
709*7dc08ffcSJunyu Lai    name = "IE UE Time zone"
710*7dc08ffcSJunyu Lai    fields_desc = [ByteEnumField("ietype", 114, IEType),
711*7dc08ffcSJunyu Lai                   ShortField("length",  None),
712*7dc08ffcSJunyu Lai                   BitField("CR_flag", 0, 4),
713*7dc08ffcSJunyu Lai                   BitField("instance", 0, 4),
714*7dc08ffcSJunyu Lai                   ByteField("Timezone", 0),
715*7dc08ffcSJunyu Lai                   ByteField("DST", 0)]
716*7dc08ffcSJunyu Lai
717*7dc08ffcSJunyu Lai
718*7dc08ffcSJunyu Laiclass IE_Port_Number(gtp.IE_Base):
719*7dc08ffcSJunyu Lai    name = "IE Port Number"
720*7dc08ffcSJunyu Lai    fields_desc = [ByteEnumField("ietype", 126, IEType),
721*7dc08ffcSJunyu Lai                   ShortField("length", 2),
722*7dc08ffcSJunyu Lai                   BitField("CR_flag", 0, 4),
723*7dc08ffcSJunyu Lai                   BitField("instance", 0, 4),
724*7dc08ffcSJunyu Lai                   ShortField("PortNumber", RandShort())]
725*7dc08ffcSJunyu Lai
726*7dc08ffcSJunyu Lai
727*7dc08ffcSJunyu Laiclass IE_APN_Restriction(gtp.IE_Base):
728*7dc08ffcSJunyu Lai    name = "IE APN Restriction"
729*7dc08ffcSJunyu Lai    fields_desc = [ByteEnumField("ietype", 127, IEType),
730*7dc08ffcSJunyu Lai                   ShortField("length",  None),
731*7dc08ffcSJunyu Lai                   BitField("CR_flag", 0, 4),
732*7dc08ffcSJunyu Lai                   BitField("instance", 0, 4),
733*7dc08ffcSJunyu Lai                   ByteField("APN_Restriction", 0)]
734*7dc08ffcSJunyu Lai
735*7dc08ffcSJunyu Lai
736*7dc08ffcSJunyu Laiclass IE_SelectionMode(gtp.IE_Base):
737*7dc08ffcSJunyu Lai    name = "IE Selection Mode"
738*7dc08ffcSJunyu Lai    fields_desc = [ByteEnumField("ietype", 128, IEType),
739*7dc08ffcSJunyu Lai                   ShortField("length",  None),
740*7dc08ffcSJunyu Lai                   BitField("CR_flag", 0, 4),
741*7dc08ffcSJunyu Lai                   BitField("instance", 0, 4),
742*7dc08ffcSJunyu Lai                   BitField("SPARE", 0, 6),
743*7dc08ffcSJunyu Lai                   BitField("SelectionMode", 0, 2)]
744*7dc08ffcSJunyu Lai
745*7dc08ffcSJunyu Lai
746*7dc08ffcSJunyu Laiclass IE_MMBR(gtp.IE_Base):
747*7dc08ffcSJunyu Lai    name = "IE Max MBR/APN-AMBR (MMBR)"
748*7dc08ffcSJunyu Lai    fields_desc = [ByteEnumField("ietype", 72, IEType),
749*7dc08ffcSJunyu Lai                   ShortField("length",  None),
750*7dc08ffcSJunyu Lai                   BitField("CR_flag", 0, 4),
751*7dc08ffcSJunyu Lai                   BitField("instance", 0, 4),
752*7dc08ffcSJunyu Lai                   IntField("uplink_rate", 0),
753*7dc08ffcSJunyu Lai                   IntField("downlink_rate", 0)]
754*7dc08ffcSJunyu Lai
755*7dc08ffcSJunyu Lai
756*7dc08ffcSJunyu Laiietypecls = {1: IE_IMSI,
757*7dc08ffcSJunyu Lai             2: IE_Cause,
758*7dc08ffcSJunyu Lai             3: IE_RecoveryRestart,
759*7dc08ffcSJunyu Lai             71: IE_APN,
760*7dc08ffcSJunyu Lai             72: IE_AMBR,
761*7dc08ffcSJunyu Lai             73: IE_EPSBearerID,
762*7dc08ffcSJunyu Lai             74: IE_IPv4,
763*7dc08ffcSJunyu Lai             75: IE_MEI,
764*7dc08ffcSJunyu Lai             76: IE_MSISDN,
765*7dc08ffcSJunyu Lai             77: IE_Indication,
766*7dc08ffcSJunyu Lai             78: IE_PCO,
767*7dc08ffcSJunyu Lai             79: IE_PAA,
768*7dc08ffcSJunyu Lai             80: IE_Bearer_QoS,
769*7dc08ffcSJunyu Lai             82: IE_RAT,
770*7dc08ffcSJunyu Lai             83: IE_ServingNetwork,
771*7dc08ffcSJunyu Lai             86: IE_ULI,
772*7dc08ffcSJunyu Lai             87: IE_FTEID,
773*7dc08ffcSJunyu Lai             93: IE_BearerContext,
774*7dc08ffcSJunyu Lai             94: IE_ChargingID,
775*7dc08ffcSJunyu Lai             95: IE_ChargingCharacteristics,
776*7dc08ffcSJunyu Lai             99: IE_PDN_type,
777*7dc08ffcSJunyu Lai             114: IE_UE_Timezone,
778*7dc08ffcSJunyu Lai             126: IE_Port_Number,
779*7dc08ffcSJunyu Lai             127: IE_APN_Restriction,
780*7dc08ffcSJunyu Lai             128: IE_SelectionMode,
781*7dc08ffcSJunyu Lai             161: IE_MMBR}
782*7dc08ffcSJunyu Lai
783*7dc08ffcSJunyu Lai#
784*7dc08ffcSJunyu Lai# GTPv2 Commands
785*7dc08ffcSJunyu Lai# 3GPP TS 29.060 V9.1.0 (2009-12)
786*7dc08ffcSJunyu Lai#
787*7dc08ffcSJunyu Lai
788*7dc08ffcSJunyu Lai
789*7dc08ffcSJunyu Laiclass GTPV2Command(Packet):
790*7dc08ffcSJunyu Lai    fields_desc = [PacketListField("IE_list", None, IE_Dispatcher)]
791*7dc08ffcSJunyu Lai
792*7dc08ffcSJunyu Lai
793*7dc08ffcSJunyu Laiclass GTPV2EchoRequest(GTPV2Command):
794*7dc08ffcSJunyu Lai    name = "GTPv2 Echo Request"
795*7dc08ffcSJunyu Lai
796*7dc08ffcSJunyu Lai
797*7dc08ffcSJunyu Laiclass GTPV2EchoResponse(GTPV2Command):
798*7dc08ffcSJunyu Lai    name = "GTPv2 Echo Response"
799*7dc08ffcSJunyu Lai
800*7dc08ffcSJunyu Lai
801*7dc08ffcSJunyu Laiclass GTPV2CreateSessionRequest(GTPV2Command):
802*7dc08ffcSJunyu Lai    name = "GTPv2 Create Session Request"
803*7dc08ffcSJunyu Lai
804*7dc08ffcSJunyu Lai
805*7dc08ffcSJunyu Laiclass GTPV2CreateSessionResponse(GTPV2Command):
806*7dc08ffcSJunyu Lai    name = "GTPv2 Create Session Response"
807*7dc08ffcSJunyu Lai
808*7dc08ffcSJunyu Lai
809*7dc08ffcSJunyu Laiclass GTPV2DeleteSessionRequest(GTPV2Command):
810*7dc08ffcSJunyu Lai    name = "GTPv2 Delete Session Request"
811*7dc08ffcSJunyu Lai
812*7dc08ffcSJunyu Lai
813*7dc08ffcSJunyu Laiclass GTPV2DeleteSessionResponse(GTPV2Command):
814*7dc08ffcSJunyu Lai    name = "GTPv2 Delete Session Request"
815*7dc08ffcSJunyu Lai
816*7dc08ffcSJunyu Lai
817*7dc08ffcSJunyu Laiclass GTPV2ModifyBearerCommand(GTPV2Command):
818*7dc08ffcSJunyu Lai    name = "GTPv2 Modify Bearer Command"
819*7dc08ffcSJunyu Lai
820*7dc08ffcSJunyu Lai
821*7dc08ffcSJunyu Laiclass GTPV2ModifyBearerFailureNotification(GTPV2Command):
822*7dc08ffcSJunyu Lai    name = "GTPv2 Modify Bearer Command"
823*7dc08ffcSJunyu Lai
824*7dc08ffcSJunyu Lai
825*7dc08ffcSJunyu Laiclass GTPV2DownlinkDataNotifFailureIndication(GTPV2Command):
826*7dc08ffcSJunyu Lai    name = "GTPv2 Downlink Data Notification Failure Indication"
827*7dc08ffcSJunyu Lai
828*7dc08ffcSJunyu Lai
829*7dc08ffcSJunyu Laiclass GTPV2ModifyBearerRequest(GTPV2Command):
830*7dc08ffcSJunyu Lai    name = "GTPv2 Modify Bearer Request"
831*7dc08ffcSJunyu Lai
832*7dc08ffcSJunyu Lai
833*7dc08ffcSJunyu Laiclass GTPV2ModifyBearerResponse(GTPV2Command):
834*7dc08ffcSJunyu Lai    name = "GTPv2 Modify Bearer Response"
835*7dc08ffcSJunyu Lai
836*7dc08ffcSJunyu Lai
837*7dc08ffcSJunyu Laiclass GTPV2UpdateBearerRequest(GTPV2Command):
838*7dc08ffcSJunyu Lai    name = "GTPv2 Update Bearer Request"
839*7dc08ffcSJunyu Lai
840*7dc08ffcSJunyu Lai
841*7dc08ffcSJunyu Laiclass GTPV2UpdateBearerResponse(GTPV2Command):
842*7dc08ffcSJunyu Lai    name = "GTPv2 Update Bearer Response"
843*7dc08ffcSJunyu Lai
844*7dc08ffcSJunyu Lai
845*7dc08ffcSJunyu Laiclass GTPV2DeleteBearerRequest(GTPV2Command):
846*7dc08ffcSJunyu Lai    name = "GTPv2 Delete Bearer Request"
847*7dc08ffcSJunyu Lai
848*7dc08ffcSJunyu Lai
849*7dc08ffcSJunyu Laiclass GTPV2SuspendNotification(GTPV2Command):
850*7dc08ffcSJunyu Lai    name = "GTPv2 Suspend Notification"
851*7dc08ffcSJunyu Lai
852*7dc08ffcSJunyu Lai
853*7dc08ffcSJunyu Laiclass GTPV2SuspendAcknowledge(GTPV2Command):
854*7dc08ffcSJunyu Lai    name = "GTPv2 Suspend Acknowledge"
855*7dc08ffcSJunyu Lai
856*7dc08ffcSJunyu Lai
857*7dc08ffcSJunyu Laiclass GTPV2ResumeNotification(GTPV2Command):
858*7dc08ffcSJunyu Lai    name = "GTPv2 Resume Notification"
859*7dc08ffcSJunyu Lai
860*7dc08ffcSJunyu Lai
861*7dc08ffcSJunyu Laiclass GTPV2ResumeAcknowledge(GTPV2Command):
862*7dc08ffcSJunyu Lai    name = "GTPv2 Resume Acknowledge"
863*7dc08ffcSJunyu Lai
864*7dc08ffcSJunyu Lai
865*7dc08ffcSJunyu Laiclass GTPV2DeleteBearerResponse(GTPV2Command):
866*7dc08ffcSJunyu Lai    name = "GTPv2 Delete Bearer Response"
867*7dc08ffcSJunyu Lai
868*7dc08ffcSJunyu Lai
869*7dc08ffcSJunyu Laiclass GTPV2CreateIndirectDataForwardingTunnelRequest(GTPV2Command):
870*7dc08ffcSJunyu Lai    name = "GTPv2 Create Indirect Data Forwarding Tunnel Request"
871*7dc08ffcSJunyu Lai
872*7dc08ffcSJunyu Lai
873*7dc08ffcSJunyu Laiclass GTPV2CreateIndirectDataForwardingTunnelResponse(GTPV2Command):
874*7dc08ffcSJunyu Lai    name = "GTPv2 Create Indirect Data Forwarding Tunnel Response"
875*7dc08ffcSJunyu Lai
876*7dc08ffcSJunyu Lai
877*7dc08ffcSJunyu Laiclass GTPV2DeleteIndirectDataForwardingTunnelRequest(GTPV2Command):
878*7dc08ffcSJunyu Lai    name = "GTPv2 Delete Indirect Data Forwarding Tunnel Request"
879*7dc08ffcSJunyu Lai
880*7dc08ffcSJunyu Lai
881*7dc08ffcSJunyu Laiclass GTPV2DeleteIndirectDataForwardingTunnelResponse(GTPV2Command):
882*7dc08ffcSJunyu Lai    name = "GTPv2 Delete Indirect Data Forwarding Tunnel Response"
883*7dc08ffcSJunyu Lai
884*7dc08ffcSJunyu Lai
885*7dc08ffcSJunyu Laiclass GTPV2ReleaseBearerRequest(GTPV2Command):
886*7dc08ffcSJunyu Lai    name = "GTPv2 Release Bearer Request"
887*7dc08ffcSJunyu Lai
888*7dc08ffcSJunyu Lai
889*7dc08ffcSJunyu Laiclass GTPV2ReleaseBearerResponse(GTPV2Command):
890*7dc08ffcSJunyu Lai    name = "GTPv2 Release Bearer Response"
891*7dc08ffcSJunyu Lai
892*7dc08ffcSJunyu Lai
893*7dc08ffcSJunyu Laiclass GTPV2DownlinkDataNotif(GTPV2Command):
894*7dc08ffcSJunyu Lai    name = "GTPv2 Download Data Notification"
895*7dc08ffcSJunyu Lai
896*7dc08ffcSJunyu Lai
897*7dc08ffcSJunyu Laiclass GTPV2DownlinkDataNotifAck(GTPV2Command):
898*7dc08ffcSJunyu Lai    name = "GTPv2 Download Data Notification Acknowledgment"
899*7dc08ffcSJunyu Lai
900*7dc08ffcSJunyu Laibind_layers(GTPHeader, GTPV2EchoRequest, gtp_type=1, T=0)
901*7dc08ffcSJunyu Laibind_layers(GTPHeader, GTPV2EchoResponse, gtp_type=2, T=0)
902*7dc08ffcSJunyu Laibind_layers(GTPHeader, GTPV2CreateSessionRequest, gtp_type=32)
903*7dc08ffcSJunyu Laibind_layers(GTPHeader, GTPV2CreateSessionResponse, gtp_type=33)
904*7dc08ffcSJunyu Laibind_layers(GTPHeader, GTPV2ModifyBearerRequest, gtp_type=34)
905*7dc08ffcSJunyu Laibind_layers(GTPHeader, GTPV2ModifyBearerResponse, gtp_type=35)
906*7dc08ffcSJunyu Laibind_layers(GTPHeader, GTPV2DeleteSessionRequest, gtp_type=36)
907*7dc08ffcSJunyu Laibind_layers(GTPHeader, GTPV2DeleteSessionResponse, gtp_type=37)
908*7dc08ffcSJunyu Laibind_layers(GTPHeader, GTPV2ModifyBearerCommand, gtp_type=64)
909*7dc08ffcSJunyu Laibind_layers(GTPHeader, GTPV2ModifyBearerFailureNotification, gtp_type=65)
910*7dc08ffcSJunyu Laibind_layers(GTPHeader, GTPV2DownlinkDataNotifFailureIndication, gtp_type=70)
911*7dc08ffcSJunyu Laibind_layers(GTPHeader, GTPV2UpdateBearerRequest, gtp_type=97)
912*7dc08ffcSJunyu Laibind_layers(GTPHeader, GTPV2UpdateBearerResponse, gtp_type=98)
913*7dc08ffcSJunyu Laibind_layers(GTPHeader, GTPV2DeleteBearerRequest, gtp_type=99)
914*7dc08ffcSJunyu Laibind_layers(GTPHeader, GTPV2DeleteBearerResponse, gtp_type=100)
915*7dc08ffcSJunyu Laibind_layers(GTPHeader, GTPV2SuspendNotification, gtp_type=162)
916*7dc08ffcSJunyu Laibind_layers(GTPHeader, GTPV2SuspendAcknowledge, gtp_type=163)
917*7dc08ffcSJunyu Laibind_layers(GTPHeader, GTPV2ResumeNotification, gtp_type=164)
918*7dc08ffcSJunyu Laibind_layers(GTPHeader, GTPV2ResumeAcknowledge, gtp_type=165)
919*7dc08ffcSJunyu Laibind_layers(
920*7dc08ffcSJunyu Lai    GTPHeader, GTPV2CreateIndirectDataForwardingTunnelRequest, gtp_type=166)
921*7dc08ffcSJunyu Laibind_layers(
922*7dc08ffcSJunyu Lai    GTPHeader, GTPV2CreateIndirectDataForwardingTunnelResponse, gtp_type=167)
923*7dc08ffcSJunyu Laibind_layers(
924*7dc08ffcSJunyu Lai    GTPHeader, GTPV2DeleteIndirectDataForwardingTunnelRequest, gtp_type=168)
925*7dc08ffcSJunyu Laibind_layers(
926*7dc08ffcSJunyu Lai    GTPHeader, GTPV2DeleteIndirectDataForwardingTunnelResponse, gtp_type=169)
927*7dc08ffcSJunyu Laibind_layers(GTPHeader, GTPV2ReleaseBearerRequest, gtp_type=170)
928*7dc08ffcSJunyu Laibind_layers(GTPHeader, GTPV2ReleaseBearerResponse, gtp_type=171)
929*7dc08ffcSJunyu Laibind_layers(GTPHeader, GTPV2DownlinkDataNotif, gtp_type=176)
930*7dc08ffcSJunyu Laibind_layers(GTPHeader, GTPV2DownlinkDataNotifAck, gtp_type=177)
931