• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#! /usr/bin/env python
2
3## Copyright (C) 2017 Alexis Sultan    <alexis.sultan@sfr.com>
4##               2017 Alessio Deiana <adeiana@gmail.com>
5##               2014 Guillaume Valadon <guillaume.valadon@ssi.gouv.fr>
6##               2012 ffranz <ffranz@iniqua.com>
7##
8## This program is published under a GPLv2 license
9
10# scapy.contrib.description = GTP
11# scapy.contrib.status = loads
12
13from __future__ import absolute_import
14import time
15import logging
16
17from scapy.packet import *
18from scapy.fields import *
19from scapy.layers.inet import IP, UDP
20from scapy.layers.inet6 import IP6Field
21from scapy.error import warning
22from scapy.modules.six.moves import range
23from scapy.compat import chb, orb, plain_str
24
25# GTP Data types
26
27RATType = {
28    1: "UTRAN",
29    2: "GETRAN",
30    3: "WLAN",
31    4: "GAN",
32    5: "HSPA"
33}
34
35GTPmessageType = {   1: "echo_request",
36                     2: "echo_response",
37                    16: "create_pdp_context_req",
38                    17: "create_pdp_context_res",
39                    18: "update_pdp_context_req",
40                    19: "update_pdp_context_resp",
41                    20: "delete_pdp_context_req",
42                    21: "delete_pdp_context_res",
43                    26: "error_indication",
44                    27: "pdu_notification_req",
45                    31: "supported_extension_headers_notification",
46                   254: "end_marker",
47                   255: "g_pdu" }
48
49IEType = {   1: "Cause",
50             2: "IMSI",
51             3: "RAI",
52             4: "TLLI",
53             5: "P_TMSI",
54             8: "IE_ReorderingRequired",
55            14: "Recovery",
56            15: "SelectionMode",
57            16: "TEIDI",
58            17: "TEICP",
59            19: "TeardownInd",
60            20: "NSAPI",
61            26: "ChargingChrt",
62            27: "TraceReference",
63            28: "TraceType",
64           127: "ChargingId",
65           128: "EndUserAddress",
66           131: "AccessPointName",
67           132: "ProtocolConfigurationOptions",
68           133: "GSNAddress",
69           134: "MSInternationalNumber",
70           135: "QoS",
71           148: "CommonFlags",
72           149: "APNRestriction",
73           151: "RatType",
74           152: "UserLocationInformation",
75           153: "MSTimeZone",
76           154: "IMEI",
77           181: "MSInfoChangeReportingAction",
78           184: "BearerControlMode",
79           191: "EvolvedAllocationRetentionPriority",
80           255: "PrivateExtention"}
81
82CauseValues = {  0: "Request IMSI",
83                 1: "Request IMEI",
84                 2: "Request IMSI and IMEI",
85                 3: "No identity needed",
86                 4: "MS Refuses",
87                 5: "MS is not GPRS Responding",
88               128: "Request accepted",
89               129: "New PDP type due to network preference",
90               130: "New PDP type due to single address bearer only",
91               192: "Non-existent",
92               193: "Invalid message format",
93               194: "IMSI not known",
94               195: "MS is GPRS Detached",
95               196: "MS is not GPRS Responding",
96               197: "MS Refuses",
97               198: "Version not supported",
98               199: "No resources available",
99               200: "Service not supported",
100               201: "Mandatory IE incorrect",
101               202: "Mandatory IE missing",
102               203: "Optional IE incorrect",
103               204: "System failure",
104               205: "Roaming restriction",
105               206: "P-TMSI Signature mismatch",
106               207: "GPRS connection suspended",
107               208: "Authentication failure",
108               209: "User authentication failed",
109               210: "Context not found",
110               211: "All dynamic PDP addresses are occupied",
111               212: "No memory is available",
112               213: "Reallocation failure",
113               214: "Unknown mandatory extension header",
114               215: "Semantic error in the TFT operation",
115               216: "Syntactic error in TFT operation",
116               217: "Semantic errors in packet filter(s)",
117               218: "Syntactic errors in packet filter(s)",
118               219: "Missing or unknown APN",
119               220: "Unknown PDP address or PDP type",
120               221: "PDP context without TFT already activated",
121               222: "APN access denied : no subscription",
122               223: "APN Restriction type incompatibility with currently active PDP Contexts",
123               224: "MS MBMS Capabilities Insufficient",
124               225: "Invalid Correlation : ID",
125               226: "MBMS Bearer Context Superseded",
126               227: "Bearer Control Mode violation",
127               228: "Collision with network initiated request" }
128
129Selection_Mode = { 11111100: "MS or APN",
130                   11111101: "MS",
131                   11111110: "NET",
132                   11111111: "FutureUse" }
133
134TrueFalse_value = {254: "False",
135                   255: "True"}
136
137# http://www.arib.or.jp/IMT-2000/V720Mar09/5_Appendix/Rel8/29/29281-800.pdf
138ExtensionHeadersTypes = {
139        0: "No more extension headers",
140        1: "Reserved",
141        2: "Reserved",
142        64: "UDP Port",
143        192: "PDCP PDU Number",
144        193: "Reserved",
145        194: "Reserved"
146    }
147
148
149class TBCDByteField(StrFixedLenField):
150
151    def i2h(self, pkt, val):
152        return val
153
154    def m2i(self, pkt, val):
155        ret = []
156        for v in val:
157            byte = orb(v)
158            left = byte >> 4
159            right = byte & 0xf
160            if left == 0xf:
161                ret.append(TBCD_TO_ASCII[right:right + 1])
162            else:
163                ret += [TBCD_TO_ASCII[right:right + 1], TBCD_TO_ASCII[left:left + 1]]
164        return b"".join(ret)
165
166    def i2m(self, pkt, val):
167        val = str(val)
168        ret_string = ""
169        for i in range(0, len(val), 2):
170            tmp = val[i:i+2]
171            if len(tmp) == 2:
172              ret_string += chr(int(tmp[1] + tmp[0], 16))
173            else:
174              ret_string += chr(int("F" + tmp[0], 16))
175        return ret_string
176
177
178TBCD_TO_ASCII = b"0123456789*#abc"
179
180class GTP_ExtensionHeader(Packet):
181    @classmethod
182    def dispatch_hook(cls, _pkt=None, *args, **kargs):
183        if _pkt == None:
184            return GTP_UDPPort_ExtensionHeader
185        return cls
186
187class GTP_UDPPort_ExtensionHeader(GTP_ExtensionHeader):
188    fields_desc=[ ByteField("length", 0x40),
189                  ShortField("udp_port", None),
190                  ByteEnumField("next_ex", 0, ExtensionHeadersTypes), ]
191
192class GTP_PDCP_PDU_ExtensionHeader(GTP_ExtensionHeader):
193    fields_desc=[ ByteField("length", 0x01),
194                  ShortField("pdcp_pdu", None),
195                  ByteEnumField("next_ex", 0, ExtensionHeadersTypes), ]
196
197
198class GTPHeader(Packet):
199    # 3GPP TS 29.060 V9.1.0 (2009-12)
200    name = "GTP-C Header"
201    fields_desc=[ BitField("version", 1, 3),
202                  BitField("PT", 1, 1),
203                  BitField("reserved", 0, 1),
204                  BitField("E", 0, 1),
205                  BitField("S", 0, 1),
206                  BitField("PN", 0, 1),
207                  ByteEnumField("gtp_type", None, GTPmessageType),
208                  ShortField("length", None),
209                  IntField("teid", 0),
210                  ConditionalField(XBitField("seq", 0, 16), lambda pkt:pkt.E==1 or pkt.S==1 or pkt.PN==1),
211                  ConditionalField(ByteField("npdu", 0), lambda pkt:pkt.E==1 or pkt.S==1 or pkt.PN==1),
212                  ConditionalField(ByteEnumField("next_ex", 0, ExtensionHeadersTypes), lambda pkt:pkt.E==1 or pkt.S==1 or pkt.PN==1), ]
213
214    def post_build(self, p, pay):
215        p += pay
216        if self.length is None:
217            l = len(p)-8
218            p = p[:2] + struct.pack("!H", l)+ p[4:]
219        return p
220
221    def hashret(self):
222        return struct.pack("B", self.version) + self.payload.hashret()
223
224    def answers(self, other):
225        return (isinstance(other, GTPHeader) and
226                self.version == other.version and
227                self.payload.answers(other.payload))
228
229    @classmethod
230    def dispatch_hook(cls, _pkt=None, *args, **kargs):
231        if _pkt and len(_pkt) >= 1:
232            if (orb(_pkt[0]) >> 5) & 0x7 == 2:
233                from . import gtp_v2
234                return gtp_v2.GTPHeader
235        if _pkt and len(_pkt) >= 8:
236            _gtp_type = orb(_pkt[1:2])
237            return GTPforcedTypes.get(_gtp_type, GTPHeader)
238        return cls
239
240class GTP_U_Header(GTPHeader):
241    # 3GPP TS 29.060 V9.1.0 (2009-12)
242    name = "GTP-U Header"
243    # GTP-U protocol is used to transmit T-PDUs between GSN pairs (or between an SGSN and an RNC in UMTS),
244    # encapsulated in G-PDUs. A G-PDU is a packet including a GTP-U header and a T-PDU. The Path Protocol
245    # defines the path and the GTP-U header defines the tunnel. Several tunnels may be multiplexed on a single path.
246
247# Some gtp_types have to be associated with a certain type of header
248GTPforcedTypes = {
249    16: GTPHeader,
250    17: GTPHeader,
251    18: GTPHeader,
252    19: GTPHeader,
253    20: GTPHeader,
254    21: GTPHeader,
255    26: GTP_U_Header,
256    27: GTPHeader,
257    254: GTP_U_Header,
258    255: GTP_U_Header
259    }
260
261class GTPEchoRequest(Packet):
262    # 3GPP TS 29.060 V9.1.0 (2009-12)
263    name = "GTP Echo Request"
264
265    def hashret(self):
266        return struct.pack("H", self.seq)
267
268
269class IE_Base(Packet):
270
271    def extract_padding(self, pkt):
272        return "", pkt
273
274
275class IE_Cause(IE_Base):
276    name = "Cause"
277    fields_desc = [ByteEnumField("ietype", 1, IEType),
278                   ByteEnumField("CauseValue", None, CauseValues)]
279
280
281class IE_IMSI(IE_Base):
282    name = "IMSI - Subscriber identity of the MS"
283    fields_desc = [ByteEnumField("ietype", 2, IEType),
284                   TBCDByteField("imsi", str(RandNum(0, 999999999999999)), 8)]
285
286
287class IE_Routing(IE_Base):
288    name = "Routing Area Identity"
289    fields_desc = [ ByteEnumField("ietype", 3, IEType),
290                    TBCDByteField("MCC", "", 2),
291                    # MNC: if the third digit of MCC is 0xf,
292                    # then the length of MNC is 1 byte
293                    TBCDByteField("MNC", "", 1),
294                    ShortField("LAC", None),
295                    ByteField("RAC", None) ]
296
297
298class IE_ReorderingRequired(IE_Base):
299    name = "Recovery"
300    fields_desc = [ByteEnumField("ietype", 8, IEType),
301                   ByteEnumField("reordering_required", 254, TrueFalse_value)]
302
303
304class IE_Recovery(IE_Base):
305    name = "Recovery"
306    fields_desc = [ ByteEnumField("ietype", 14, IEType),
307                    ByteField("restart_counter", 24) ]
308
309
310class IE_SelectionMode(IE_Base):
311    # Indicates the origin of the APN in the message
312    name = "Selection Mode"
313    fields_desc = [ ByteEnumField("ietype", 15, IEType),
314                    BitEnumField("SelectionMode", "MS or APN",
315                                 8, Selection_Mode) ]
316
317
318class IE_TEIDI(IE_Base):
319    name = "Tunnel Endpoint Identifier Data"
320    fields_desc = [ ByteEnumField("ietype", 16, IEType),
321                    XIntField("TEIDI", RandInt()) ]
322
323
324class IE_TEICP(IE_Base):
325    name = "Tunnel Endpoint Identifier Control Plane"
326    fields_desc = [ ByteEnumField("ietype", 17, IEType),
327                    XIntField("TEICI", RandInt())]
328
329
330class IE_Teardown(IE_Base):
331    name = "Teardown Indicator"
332    fields_desc = [ ByteEnumField("ietype", 19, IEType),
333                    ByteEnumField("indicator", "True", TrueFalse_value) ]
334
335
336class IE_NSAPI(IE_Base):
337    # Identifies a PDP context in a mobility management context specified by TEICP
338    name = "NSAPI"
339    fields_desc = [ ByteEnumField("ietype", 20, IEType),
340                    XBitField("sparebits", 0x0000, 4),
341                    XBitField("NSAPI", RandNum(0, 15), 4) ]
342
343
344class IE_ChargingCharacteristics(IE_Base):
345    # Way of informing both the SGSN and GGSN of the rules for
346    name = "Charging Characteristics"
347    fields_desc = [ ByteEnumField("ietype", 26, IEType),
348                    # producing charging information based on operator configured triggers.
349                    #    0000 .... .... .... : spare
350                    #    .... 1... .... .... : normal charging
351                    #    .... .0.. .... .... : prepaid charging
352                    #    .... ..0. .... .... : flat rate charging
353                    #    .... ...0 .... .... : hot billing charging
354                    #    .... .... 0000 0000 : reserved
355                    XBitField("Ch_ChSpare", None, 4),
356                    XBitField("normal_charging", None, 1),
357                    XBitField("prepaid_charging", None, 1),
358                    XBitField("flat_rate_charging", None, 1),
359                    XBitField("hot_billing_charging", None, 1),
360                    XBitField("Ch_ChReserved", 0, 8) ]
361
362class IE_TraceReference(IE_Base):
363    # Identifies a record or a collection of records for a particular trace.
364    name = "Trace Reference"
365    fields_desc = [ ByteEnumField("ietype", 27, IEType),
366                    XBitField("Trace_reference", None, 16) ]
367
368
369class IE_TraceType(IE_Base):
370    # Indicates the type of the trace
371    name = "Trace Type"
372    fields_desc = [ ByteEnumField("ietype", 28, IEType),
373                    XBitField("Trace_type", None, 16) ]
374
375
376class IE_ChargingId(IE_Base):
377    name = "Charging ID"
378    fields_desc = [ByteEnumField("ietype", 127, IEType),
379                   XIntField("Charging_id", RandInt())]
380
381
382class IE_EndUserAddress(IE_Base):
383    # Supply protocol specific information of the external packet
384    name = "End User Addresss"
385    fields_desc = [ ByteEnumField("ietype", 128, IEType),
386                    #         data network accessed by the GGPRS subscribers.
387                    #            - Request
388                    #                1    Type (1byte)
389                    #                2-3    Length (2bytes) - value 2
390                    #                4    Spare + PDP Type Organization
391                    #                5    PDP Type Number
392                    #            - Response
393                    #                6-n    PDP Address
394                    ShortField("length", 2),
395                    BitField("SPARE", 15, 4),
396                    BitField("PDPTypeOrganization", 1, 4),
397                    XByteField("PDPTypeNumber", None),
398                    ConditionalField(IPField("PDPAddress", RandIP()),
399                                     lambda pkt: pkt.length > 2)]
400
401
402class APNStrLenField(StrLenField):
403    # Inspired by DNSStrField
404    def m2i(self, pkt, s):
405        ret_s = b""
406        tmp_s = s
407        while tmp_s:
408            tmp_len = orb(tmp_s[0]) + 1
409            if tmp_len > len(tmp_s):
410                warning("APN prematured end of character-string (size=%i, remaining bytes=%i)" % (tmp_len, len(tmp_s)))
411            ret_s +=  tmp_s[1:tmp_len]
412            tmp_s = tmp_s[tmp_len:]
413            if len(tmp_s) :
414                ret_s += b"."
415        s = ret_s
416        return s
417    def i2m(self, pkt, s):
418        s = b"".join(chb(len(x)) + x for x in s.split("."))
419        return s
420
421
422class IE_AccessPointName(IE_Base):
423    # Sent by SGSN or by GGSN as defined in 3GPP TS 23.060
424    name = "Access Point Name"
425    fields_desc = [ ByteEnumField("ietype", 131, IEType),
426                    ShortField("length",  None),
427                    APNStrLenField("APN", "nternet", length_from=lambda x: x.length) ]
428
429    def post_build(self, p, pay):
430        if self.length is None:
431            l = len(p)-3
432            p = p[:2] + struct.pack("!B", l)+ p[3:]
433        return p
434
435
436class IE_ProtocolConfigurationOptions(IE_Base):
437    name = "Protocol Configuration Options"
438    fields_desc = [ ByteEnumField("ietype", 132, IEType),
439            ShortField("length", 4),
440            StrLenField("Protocol_Configuration", "",
441                        length_from=lambda x: x.length) ]
442
443
444class IE_GSNAddress(IE_Base):
445    name = "GSN Address"
446    fields_desc = [ ByteEnumField("ietype", 133, IEType),
447                    ShortField("length", 4),
448                    IPField("address", RandIP()) ]
449
450
451class IE_MSInternationalNumber(IE_Base):
452    name = "MS International Number"
453    fields_desc = [ ByteEnumField("ietype", 134, IEType),
454                    ShortField("length", None),
455                    FlagsField("flags", 0x91, 8, ["Extension","","","International Number","","","","ISDN numbering"]),
456                    TBCDByteField("digits", "33607080910", length_from=lambda x: x.length-1) ]
457
458
459class QoS_Profile(IE_Base):
460    name = "QoS profile"
461    fields_desc = [ByteField("qos_ei", 0),
462                   ByteField("length", None),
463                   XBitField("spare", 0x00, 2),
464                   XBitField("delay_class", 0x000, 3),
465                   XBitField("reliability_class", 0x000, 3),
466                   XBitField("peak_troughput", 0x0000, 4),
467                   BitField("spare", 0, 1),
468                   XBitField("precedence_class", 0x000, 3),
469                   XBitField("spare", 0x000, 3),
470                   XBitField("mean_troughput", 0x00000, 5),
471                   XBitField("traffic_class", 0x000, 3),
472                   XBitField("delivery_order", 0x00, 2),
473                   XBitField("delivery_of_err_sdu", 0x000, 3),
474                   ByteField("max_sdu_size", None),
475                   ByteField("max_bitrate_up", None),
476                   ByteField("max_bitrate_down", None),
477                   XBitField("redidual_ber", 0x0000, 4),
478                   XBitField("sdu_err_ratio", 0x0000, 4),
479                   XBitField("transfer_delay", 0x00000, 5),
480                   XBitField("traffic_handling_prio", 0x000, 3),
481                   ByteField("guaranteed_bit_rate_up", None),
482                   ByteField("guaranteed_bit_rate_down", None)]
483
484
485class IE_QoS(IE_Base):
486    name = "QoS"
487    fields_desc = [ByteEnumField("ietype", 135, IEType),
488                   ShortField("length", None),
489                   ByteField("allocation_retention_prioiry", 1),
490
491                   ConditionalField(XBitField("spare", 0x00, 2),
492                                    lambda pkt: pkt.length > 1),
493                   ConditionalField(XBitField("delay_class", 0x000, 3),
494                                    lambda pkt: pkt.length > 1),
495                   ConditionalField(XBitField("reliability_class", 0x000, 3),
496                                    lambda pkt: pkt.length > 1),
497
498                   ConditionalField(XBitField("peak_troughput", 0x0000, 4),
499                                    lambda pkt: pkt.length > 2),
500                   ConditionalField(BitField("spare", 0, 1),
501                                    lambda pkt: pkt.length > 2),
502                   ConditionalField(XBitField("precedence_class", 0x000, 3),
503                                    lambda pkt: pkt.length > 2),
504
505                   ConditionalField(XBitField("spare", 0x000, 3),
506                                    lambda pkt: pkt.length > 3),
507                   ConditionalField(XBitField("mean_troughput", 0x00000, 5),
508                                    lambda pkt: pkt.length > 3),
509
510                   ConditionalField(XBitField("traffic_class", 0x000, 3),
511                                    lambda pkt: pkt.length > 4),
512                   ConditionalField(XBitField("delivery_order", 0x00, 2),
513                                    lambda pkt: pkt.length > 4),
514                   ConditionalField(XBitField("delivery_of_err_sdu", 0x000, 3),
515                                    lambda pkt: pkt.length > 4),
516
517                   ConditionalField(ByteField("max_sdu_size", None),
518                                    lambda pkt: pkt.length > 5),
519                   ConditionalField(ByteField("max_bitrate_up", None),
520                                    lambda pkt: pkt.length > 6),
521                   ConditionalField(ByteField("max_bitrate_down", None),
522                                    lambda pkt: pkt.length > 7),
523
524                   ConditionalField(XBitField("redidual_ber", 0x0000, 4),
525                                    lambda pkt: pkt.length > 8),
526                   ConditionalField(XBitField("sdu_err_ratio", 0x0000, 4),
527                                    lambda pkt: pkt.length > 8),
528                   ConditionalField(XBitField("transfer_delay", 0x00000, 6),
529                                    lambda pkt: pkt.length > 9),
530                   ConditionalField(XBitField("traffic_handling_prio",
531                                              0x000,
532                                              2),
533                                    lambda pkt: pkt.length > 9),
534
535                   ConditionalField(ByteField("guaranteed_bit_rate_up", None),
536                                    lambda pkt: pkt.length > 10),
537                   ConditionalField(ByteField("guaranteed_bit_rate_down",
538                                              None),
539                                    lambda pkt: pkt.length > 11),
540
541                   ConditionalField(XBitField("spare", 0x000, 3),
542                                    lambda pkt: pkt.length > 12),
543                   ConditionalField(BitField("signaling_indication", 0, 1),
544                                    lambda pkt: pkt.length > 12),
545                   ConditionalField(XBitField("source_stats_desc", 0x0000, 4),
546                                    lambda pkt: pkt.length > 12),
547
548                   ConditionalField(ByteField("max_bitrate_down_ext", None),
549                                    lambda pkt: pkt.length > 13),
550                   ConditionalField(ByteField("guaranteed_bitrate_down_ext",
551                                              None),
552                                    lambda pkt: pkt.length > 14),
553                   ConditionalField(ByteField("max_bitrate_up_ext", None),
554                                    lambda pkt: pkt.length > 15),
555                   ConditionalField(ByteField("guaranteed_bitrate_up_ext",
556                                              None),
557                                    lambda pkt: pkt.length > 16),
558                   ConditionalField(ByteField("max_bitrate_down_ext2", None),
559                                    lambda pkt: pkt.length > 17),
560                   ConditionalField(ByteField("guaranteed_bitrate_down_ext2",
561                                              None),
562                                    lambda pkt: pkt.length > 18),
563                   ConditionalField(ByteField("max_bitrate_up_ext2", None),
564                                    lambda pkt: pkt.length > 19),
565                   ConditionalField(ByteField("guaranteed_bitrate_up_ext2",
566                                              None),
567                                    lambda pkt: pkt.length > 20)]
568
569
570class IE_CommonFlags(IE_Base):
571    name = "Common Flags"
572    fields_desc = [ByteEnumField("ietype", 148, IEType),
573                   ShortField("length", None),
574                   BitField("dual_addr_bearer_fl", 0, 1),
575                   BitField("upgrade_qos_supported", 0, 1),
576                   BitField("nrsn", 0, 1),
577                   BitField("no_qos_nego", 0, 1),
578                   BitField("mbms_cnting_info", 0, 1),
579                   BitField("ran_procedure_ready", 0, 1),
580                   BitField("mbms_service_type", 0, 1),
581                   BitField("prohibit_payload_compression", 0, 1)]
582
583
584class IE_APNRestriction(IE_Base):
585    name = "APN Restriction"
586    fields_desc = [ByteEnumField("ietype", 149, IEType),
587                   ShortField("length", 1),
588                   ByteField("restriction_type_value", 0)]
589
590
591class IE_RATType(IE_Base):
592    name = "Rat Type"
593    fields_desc = [ByteEnumField("ietype", 151, IEType),
594                   ShortField("length", 1),
595                   ByteEnumField("RAT_Type", None, RATType)]
596
597
598class IE_UserLocationInformation(IE_Base):
599    name = "User Location Information"
600    fields_desc = [ ByteEnumField("ietype", 152, IEType),
601                    ShortField("length", None),
602                    ByteField("type", 1),
603                    # Only type 1 is currently supported
604                    TBCDByteField("MCC", "", 2),
605                    # MNC: if the third digit of MCC is 0xf, then the length of MNC is 1 byte
606                    TBCDByteField("MNC", "", 1),
607                    ShortField("LAC", None),
608                    ShortField("SAC", None) ]
609
610
611class IE_MSTimeZone(IE_Base):
612    name = "MS Time Zone"
613    fields_desc = [ByteEnumField("ietype", 153, IEType),
614                   ShortField("length", None),
615                   ByteField("timezone", 0),
616                   BitField("Spare", 0, 1),
617                   BitField("Spare", 0, 1),
618                   BitField("Spare", 0, 1),
619                   BitField("Spare", 0, 1),
620                   BitField("Spare", 0, 1),
621                   BitField("Spare", 0, 1),
622                   XBitField("daylight_saving_time", 0x00, 2)]
623
624
625class IE_IMEI(IE_Base):
626    name = "IMEI"
627    fields_desc = [ ByteEnumField("ietype", 154, IEType),
628                    ShortField("length", None),
629                    TBCDByteField("IMEI", "", length_from=lambda x: x.length) ]
630
631
632class IE_MSInfoChangeReportingAction(IE_Base):
633    name = "MS Info Change Reporting Action"
634    fields_desc = [ByteEnumField("ietype", 181, IEType),
635                   ShortField("length", 1),
636                   ByteField("Action", 0)]
637
638
639class IE_DirectTunnelFlags(IE_Base):
640    name = "Direct Tunnel Flags"
641    fields_desc = [ByteEnumField("ietype", 182, IEType),
642                   ShortField("length", 1),
643                   BitField("Spare", 0, 1),
644                   BitField("Spare", 0, 1),
645                   BitField("Spare", 0, 1),
646                   BitField("Spare", 0, 1),
647                   BitField("Spare", 0, 1),
648                   BitField("EI", 0, 1),
649                   BitField("GCSI", 0, 1),
650                   BitField("DTI", 0, 1)]
651
652
653class IE_BearerControlMode(IE_Base):
654    name = "Bearer Control Mode"
655    fields_desc = [ByteEnumField("ietype", 184, IEType),
656                   ShortField("length", 1),
657                   ByteField("bearer_control_mode", 0)]
658
659
660class IE_EvolvedAllocationRetentionPriority(IE_Base):
661    name = "Evolved Allocation/Retention Priority"
662    fields_desc = [ByteEnumField("ietype", 191, IEType),
663                   ShortField("length", 1),
664                   BitField("Spare", 0, 1),
665                   BitField("PCI", 0, 1),
666                   XBitField("PL", 0x0000, 4),
667                   BitField("Spare", 0, 1),
668                   BitField("PVI", 0, 1)]
669
670
671class IE_CharginGatewayAddress(IE_Base):
672    name = "Chargin Gateway Address"
673    fields_desc = [ByteEnumField("ietype", 251, IEType),
674                   ShortField("length", 4),
675                   ConditionalField(IPField("ipv4_address", "127.0.0.1"),
676                                    lambda
677                                    pkt: pkt.length == 4),
678                   ConditionalField(IP6Field("ipv6_address", "::1"), lambda
679                                    pkt: pkt.length == 16)]
680
681
682class IE_PrivateExtension(IE_Base):
683    name = "Private Extension"
684    fields_desc = [ByteEnumField("ietype", 255, IEType),
685                   ShortField("length", 1),
686                   ByteField("extension identifier", 0),
687                   StrLenField("extention_value", "",
688                               length_from=lambda x: x.length)]
689
690class IE_ExtensionHeaderList(IE_Base):
691    name = "Extension Header List"
692    fields_desc = [ByteEnumField("ietype", 141, IEType),
693                   FieldLenField("length", None, length_of="extension_headers"),
694                   FieldListField("extension_headers", [64, 192], ByteField("", 0))]
695
696class IE_NotImplementedTLV(Packet):
697    name = "IE not implemented"
698    fields_desc = [ ByteEnumField("ietype", 0, IEType),
699                    ShortField("length",  None),
700                    StrLenField("data", "", length_from=lambda x: x.length) ]
701    def extract_padding(self, pkt):
702        return "",pkt
703
704
705ietypecls = {1: IE_Cause,
706             2: IE_IMSI,
707             3: IE_Routing,
708             8: IE_ReorderingRequired,
709             14: IE_Recovery,
710             15: IE_SelectionMode,
711             16: IE_TEIDI,
712             17: IE_TEICP,
713             19: IE_Teardown,
714             20: IE_NSAPI,
715             26: IE_ChargingCharacteristics,
716             27: IE_TraceReference,
717             28: IE_TraceType,
718             127: IE_ChargingId,
719             128: IE_EndUserAddress,
720             131: IE_AccessPointName,
721             132: IE_ProtocolConfigurationOptions,
722             133: IE_GSNAddress,
723             134: IE_MSInternationalNumber,
724             135: IE_QoS,
725             141: IE_ExtensionHeaderList,
726             148: IE_CommonFlags,
727             149: IE_APNRestriction,
728             151: IE_RATType,
729             152: IE_UserLocationInformation,
730             153: IE_MSTimeZone,
731             154: IE_IMEI,
732             181: IE_MSInfoChangeReportingAction,
733             182: IE_DirectTunnelFlags,
734             184: IE_BearerControlMode,
735             191: IE_EvolvedAllocationRetentionPriority,
736             251: IE_CharginGatewayAddress,
737             255: IE_PrivateExtension}
738
739
740def IE_Dispatcher(s):
741    """Choose the correct Information Element class."""
742    if len(s) < 1:
743        return Raw(s)
744    # Get the IE type
745    ietype = orb(s[0])
746    cls = ietypecls.get(ietype, Raw)
747
748    # if ietype greater than 128 are TLVs
749    if cls == Raw and ietype & 128 == 128:
750        cls = IE_NotImplementedTLV
751    return cls(s)
752
753class GTPEchoResponse(Packet):
754    # 3GPP TS 29.060 V9.1.0 (2009-12)
755    name = "GTP Echo Response"
756    fields_desc = [ PacketListField("IE_list", [], IE_Dispatcher) ]
757
758    def hashret(self):
759        return struct.pack("H", self.seq)
760
761    def answers(self, other):
762        return self.seq == other.seq
763
764
765class GTPCreatePDPContextRequest(Packet):
766    # 3GPP TS 29.060 V9.1.0 (2009-12)
767    name = "GTP Create PDP Context Request"
768    fields_desc = [ PacketListField("IE_list", [ IE_TEIDI(), IE_NSAPI(), IE_GSNAddress(),
769                                                 IE_GSNAddress(),
770                                                 IE_NotImplementedTLV(ietype=135, length=15,data=RandString(15)) ],
771                                    IE_Dispatcher) ]
772    def hashret(self):
773        return struct.pack("H", self.seq)
774
775class GTPCreatePDPContextResponse(Packet):
776    # 3GPP TS 29.060 V9.1.0 (2009-12)
777    name = "GTP Create PDP Context Response"
778    fields_desc = [ PacketListField("IE_list", [], IE_Dispatcher) ]
779
780    def hashret(self):
781        return struct.pack("H", self.seq)
782
783    def answers(self, other):
784        return self.seq == other.seq
785
786
787class GTPUpdatePDPContextRequest(Packet):
788    # 3GPP TS 29.060 V9.1.0 (2009-12)
789    name = "GTP Update PDP Context Request"
790    fields_desc = [PacketListField("IE_list", [
791                       IE_Cause(),
792                       IE_Recovery(),
793                       IE_TEIDI(),
794                       IE_TEICP(),
795                       IE_ChargingId(),
796                       IE_ProtocolConfigurationOptions(),
797                       IE_GSNAddress(),
798                       IE_GSNAddress(),
799                       IE_GSNAddress(),
800                       IE_GSNAddress(),
801                       IE_QoS(),
802                       IE_CharginGatewayAddress(),
803                       IE_CharginGatewayAddress(),
804                       IE_CommonFlags(),
805                       IE_APNRestriction(),
806                       IE_BearerControlMode(),
807                       IE_MSInfoChangeReportingAction(),
808                       IE_EvolvedAllocationRetentionPriority(),
809                       IE_PrivateExtension()],
810        IE_Dispatcher)]
811
812    def hashret(self):
813        return struct.pack("H", self.seq)
814
815
816class GTPUpdatePDPContextResponse(Packet):
817    # 3GPP TS 29.060 V9.1.0 (2009-12)
818    name = "GTP Update PDP Context Response"
819    fields_desc = [PacketListField("IE_list", None, IE_Dispatcher)]
820
821    def hashret(self):
822        return struct.pack("H", self.seq)
823
824
825class GTPErrorIndication(Packet):
826    # 3GPP TS 29.060 V9.1.0 (2009-12)
827    name = "GTP Error Indication"
828    fields_desc = [ PacketListField("IE_list", [], IE_Dispatcher) ]
829
830class GTPDeletePDPContextRequest(Packet):
831    # 3GPP TS 29.060 V9.1.0 (2009-12)
832    name = "GTP Delete PDP Context Request"
833    fields_desc = [ PacketListField("IE_list", [], IE_Dispatcher) ]
834
835class GTPDeletePDPContextResponse(Packet):
836    # 3GPP TS 29.060 V9.1.0 (2009-12)
837    name = "GTP Delete PDP Context Response"
838    fields_desc = [ PacketListField("IE_list", [], IE_Dispatcher) ]
839
840class GTPPDUNotificationRequest(Packet):
841    # 3GPP TS 29.060 V9.1.0 (2009-12)
842    name = "GTP PDU Notification Request"
843    fields_desc = [ PacketListField("IE_list", [ IE_IMSI(),
844                        IE_TEICP(TEICI=RandInt()),
845                        IE_EndUserAddress(PDPTypeNumber=0x21),
846                        IE_AccessPointName(),
847                        IE_GSNAddress(address="127.0.0.1"),
848                        ], IE_Dispatcher) ]
849
850class GTPSupportedExtensionHeadersNotification(Packet):
851    name = "GTP Supported Extension Headers Notification"
852    fields_desc = [ PacketListField("IE_list", [ IE_ExtensionHeaderList(),
853                        ], IE_Dispatcher) ]
854
855class GTPErrorIndication(Packet):
856    name = "GTP Error Indication"
857    fields_desc = [ PacketListField("IE_list", [], IE_Dispatcher) ]
858
859class GTPmorethan1500(Packet):
860    # 3GPP TS 29.060 V9.1.0 (2009-12)
861    name = "GTP More than 1500"
862    fields_desc = [ ByteEnumField("IE_Cause", "Cause", IEType),
863                    BitField("IE", 1, 12000),]
864
865# Bind GTP-C
866bind_layers(UDP, GTPHeader, dport = 2123)
867bind_layers(UDP, GTPHeader, sport = 2123)
868bind_layers(GTPHeader, GTPEchoRequest, gtp_type=1, S=1)
869bind_layers(GTPHeader, GTPEchoResponse, gtp_type=2, S=1)
870bind_layers(GTPHeader, GTPCreatePDPContextRequest, gtp_type=16)
871bind_layers(GTPHeader, GTPCreatePDPContextResponse, gtp_type=17)
872bind_layers(GTPHeader, GTPUpdatePDPContextRequest, gtp_type=18)
873bind_layers(GTPHeader, GTPUpdatePDPContextResponse, gtp_type=19)
874bind_layers(GTPHeader, GTPDeletePDPContextRequest, gtp_type=20)
875bind_layers(GTPHeader, GTPDeletePDPContextResponse, gtp_type=21)
876bind_layers(GTPHeader, GTPPDUNotificationRequest, gtp_type=27)
877bind_layers(GTPHeader, GTPSupportedExtensionHeadersNotification, gtp_type=31, S=1)
878bind_layers(GTPHeader, GTP_UDPPort_ExtensionHeader, next_ex=64, E=1)
879bind_layers(GTPHeader, GTP_PDCP_PDU_ExtensionHeader, next_ex=192, E=1)
880
881# Bind GTP-U
882bind_layers(UDP, GTP_U_Header, dport = 2152)
883bind_layers(UDP, GTP_U_Header, sport = 2152)
884bind_layers(GTP_U_Header, GTPErrorIndication, gtp_type=26, S=1)
885bind_layers(GTP_U_Header, IP, gtp_type = 255)
886
887if __name__ == "__main__":
888    from scapy.all import *
889    interact(mydict=globals(), mybanner="GTPv1 add-on")
890