Home | History | Annotate | Download | only in contrib
      1 #! /usr/bin/env python
      2 
      3 ## Copyright (C) 2017 Alexis Sultan    <alexis.sultan (at] sfr.com>
      4 ##               2017 Alessio Deiana <adeiana (at] gmail.com>
      5 ##               2014 Guillaume Valadon <guillaume.valadon (at] ssi.gouv.fr>
      6 ##               2012 ffranz <ffranz (at] iniqua.com>
      7 ##
      8 ## This program is published under a GPLv2 license
      9 
     10 # scapy.contrib.description = GTP
     11 # scapy.contrib.status = loads
     12 
     13 from __future__ import absolute_import
     14 import time
     15 import logging
     16 
     17 from scapy.packet import *
     18 from scapy.fields import *
     19 from scapy.layers.inet import IP, UDP
     20 from scapy.layers.inet6 import IP6Field
     21 from scapy.error import warning
     22 from scapy.modules.six.moves import range
     23 from scapy.compat import chb, orb, plain_str
     24 
     25 # GTP Data types
     26 
     27 RATType = {
     28     1: "UTRAN",
     29     2: "GETRAN",
     30     3: "WLAN",
     31     4: "GAN",
     32     5: "HSPA"
     33 }
     34 
     35 GTPmessageType = {   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 
     49 IEType = {   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 
     82 CauseValues = {  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 
    129 Selection_Mode = { 11111100: "MS or APN",
    130                    11111101: "MS",
    131                    11111110: "NET",
    132                    11111111: "FutureUse" }
    133 
    134 TrueFalse_value = {254: "False",
    135                    255: "True"}
    136 
    137 # http://www.arib.or.jp/IMT-2000/V720Mar09/5_Appendix/Rel8/29/29281-800.pdf
    138 ExtensionHeadersTypes = {
    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 
    149 class 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 
    178 TBCD_TO_ASCII = b"0123456789*#abc"
    179 
    180 class 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 
    187 class GTP_UDPPort_ExtensionHeader(GTP_ExtensionHeader):
    188     fields_desc=[ ByteField("length", 0x40),
    189                   ShortField("udp_port", None),
    190                   ByteEnumField("next_ex", 0, ExtensionHeadersTypes), ]
    191 
    192 class 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 
    198 class 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 
    240 class 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
    248 GTPforcedTypes = {
    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 
    261 class 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 
    269 class IE_Base(Packet):
    270 
    271     def extract_padding(self, pkt):
    272         return "", pkt
    273 
    274 
    275 class IE_Cause(IE_Base):
    276     name = "Cause"
    277     fields_desc = [ByteEnumField("ietype", 1, IEType),
    278                    ByteEnumField("CauseValue", None, CauseValues)]
    279 
    280 
    281 class 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 
    287 class 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 
    298 class IE_ReorderingRequired(IE_Base):
    299     name = "Recovery"
    300     fields_desc = [ByteEnumField("ietype", 8, IEType),
    301                    ByteEnumField("reordering_required", 254, TrueFalse_value)]
    302 
    303 
    304 class IE_Recovery(IE_Base):
    305     name = "Recovery"
    306     fields_desc = [ ByteEnumField("ietype", 14, IEType),
    307                     ByteField("restart_counter", 24) ]
    308 
    309 
    310 class 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 
    318 class IE_TEIDI(IE_Base):
    319     name = "Tunnel Endpoint Identifier Data"
    320     fields_desc = [ ByteEnumField("ietype", 16, IEType),
    321                     XIntField("TEIDI", RandInt()) ]
    322 
    323 
    324 class IE_TEICP(IE_Base):
    325     name = "Tunnel Endpoint Identifier Control Plane"
    326     fields_desc = [ ByteEnumField("ietype", 17, IEType),
    327                     XIntField("TEICI", RandInt())]
    328 
    329 
    330 class IE_Teardown(IE_Base):
    331     name = "Teardown Indicator"
    332     fields_desc = [ ByteEnumField("ietype", 19, IEType),
    333                     ByteEnumField("indicator", "True", TrueFalse_value) ]
    334 
    335 
    336 class 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 
    344 class 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 
    362 class 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 
    369 class 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 
    376 class IE_ChargingId(IE_Base):
    377     name = "Charging ID"
    378     fields_desc = [ByteEnumField("ietype", 127, IEType),
    379                    XIntField("Charging_id", RandInt())]
    380 
    381 
    382 class 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 
    402 class 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 
    422 class 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 
    436 class 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 
    444 class 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 
    451 class 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 
    459 class 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 
    485 class 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 
    570 class 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 
    584 class 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 
    591 class 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 
    598 class 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 
    611 class 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 
    625 class 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 
    632 class 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 
    639 class 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 
    653 class 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 
    660 class 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 
    671 class 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 
    682 class 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 
    690 class 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 
    696 class 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 
    705 ietypecls = {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 
    740 def 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 
    753 class 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 
    765 class 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 
    775 class 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 
    787 class 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 
    816 class 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 
    825 class 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 
    830 class 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 
    835 class 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 
    840 class 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 
    850 class GTPSupportedExtensionHeadersNotification(Packet):
    851     name = "GTP Supported Extension Headers Notification"
    852     fields_desc = [ PacketListField("IE_list", [ IE_ExtensionHeaderList(),
    853                         ], IE_Dispatcher) ]
    854 
    855 class GTPErrorIndication(Packet):
    856     name = "GTP Error Indication"
    857     fields_desc = [ PacketListField("IE_list", [], IE_Dispatcher) ]
    858     
    859 class 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
    866 bind_layers(UDP, GTPHeader, dport = 2123)
    867 bind_layers(UDP, GTPHeader, sport = 2123)
    868 bind_layers(GTPHeader, GTPEchoRequest, gtp_type=1, S=1)
    869 bind_layers(GTPHeader, GTPEchoResponse, gtp_type=2, S=1)
    870 bind_layers(GTPHeader, GTPCreatePDPContextRequest, gtp_type=16)
    871 bind_layers(GTPHeader, GTPCreatePDPContextResponse, gtp_type=17)
    872 bind_layers(GTPHeader, GTPUpdatePDPContextRequest, gtp_type=18)
    873 bind_layers(GTPHeader, GTPUpdatePDPContextResponse, gtp_type=19)
    874 bind_layers(GTPHeader, GTPDeletePDPContextRequest, gtp_type=20)
    875 bind_layers(GTPHeader, GTPDeletePDPContextResponse, gtp_type=21)
    876 bind_layers(GTPHeader, GTPPDUNotificationRequest, gtp_type=27)
    877 bind_layers(GTPHeader, GTPSupportedExtensionHeadersNotification, gtp_type=31, S=1)
    878 bind_layers(GTPHeader, GTP_UDPPort_ExtensionHeader, next_ex=64, E=1)
    879 bind_layers(GTPHeader, GTP_PDCP_PDU_ExtensionHeader, next_ex=192, E=1)
    880 
    881 # Bind GTP-U
    882 bind_layers(UDP, GTP_U_Header, dport = 2152)
    883 bind_layers(UDP, GTP_U_Header, sport = 2152)
    884 bind_layers(GTP_U_Header, GTPErrorIndication, gtp_type=26, S=1)
    885 bind_layers(GTP_U_Header, IP, gtp_type = 255)
    886 
    887 if __name__ == "__main__":
    888     from scapy.all import *
    889     interact(mydict=globals(), mybanner="GTPv1 add-on")
    890