Don't like ads? PRO users don't see any ads ;-)
Guest

Scapy layer: GTP

By: ffranz on Apr 15th, 2012  |  syntax: Python  |  size: 14.57 KB  |  hits: 164  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. ## This file is not now part of Scapy
  2. ## Look iniqua.com for more informations
  3. ## ffranz <ffranz@iniqua.com>
  4. ## This program is published under a GPLv2 license
  5.  
  6. import time
  7. import logging
  8.  
  9. from scapy.packet import *
  10. from scapy.fields import *
  11. from scapy.layers.inet import UDP
  12. from scapy.all import *
  13.  
  14. #   ToDo:
  15. #   GTPv0/1
  16. #
  17. #   GTP-C
  18. # ---------------------------
  19. #
  20. #   GTPHeader()
  21. #
  22. #  
  23. #   GTP-U
  24. # ---------------------------
  25. #
  26. #   GTP_U_Header()
  27.  
  28. GTPmessageType = { 1 : "echo_request",
  29.                    2 : "echo_response",
  30.                    16 : "create_pdp_context_req",
  31.                    20 : "delete_pdp_context_req",
  32.                    21 : "delete_pdp_context_res",
  33.                    26 : "error_indication",
  34.                    255: "gtp_u_header" }
  35.  
  36. IEType = {  1 : "Cause",
  37.             2 : "IMSI",
  38.             3 : "RAI",
  39.             4 : "TLLI",
  40.             5 : "P_TMSI",
  41.            14 : "Recovery",
  42.            15 : "SelectionMode",
  43.            16 : "TEIDI",
  44.            17 : "TEICP",
  45.            19 : "TeardownInd",
  46.            20 : "NSAPI",
  47.            26 : "ChargingChrt",
  48.            27 : "TraceReference",
  49.            28 : "TraceType",
  50.            128: "EndUserAddress",
  51.            131: "AccessPointName",
  52.            133: "GSNAddress" }
  53.  
  54. CauseValues = {  0 : "Request IMSI",
  55.                  1 : "Request IMEI",
  56.                  2 : "Request IMSI and IMEI",
  57.                  3 : "No identity needed",
  58.                  4 : "MS Refuses",
  59.                  5 : "MS is not GPRS Responding",
  60.                  128 : "Request accepted",
  61.                  129 : "New PDP type due to network prefernce",
  62.                  130 : "New PDP type due to single address bearer only",
  63.                  192 : "Non-exitent",
  64.                  193 : "Invalid message format",
  65.                  194 : "IMSI not known",
  66.                  195 : "MS is GPRS Detached",
  67.                  196 : "MS is not GPRS Responding",
  68.                  197 : "MS Refuses",
  69.                  198 : "Version not supported",
  70.                  199 : "No resources available",
  71.                  200 : "Service not supported",
  72.                  201 : "Mandatory IE incorrect",
  73.                  202 : "Mandatory IE missing",
  74.                  203 : "Optional IE incorrect",
  75.                  204 : "System failure",
  76.                  205 : "Roaming restriction",
  77.                  206 : "P-TMSI Signature mismatch",
  78.                  207 : "GRPS connection suspended",
  79.                  208 : "Authentication failure",
  80.                  209 : "User authentication failed",
  81.                  210 : "Context not found",
  82.                  211 : "All dynamic PDP addresses are occupied",
  83.                  212 : "No memory is available",
  84.                  213 : "Realocation failure",
  85.                  214 : "Unknown mandatory extension header",
  86.                  215 : "Semantic error in the TFT operation",
  87.                  216 : "Syntactic error in TFT operation",
  88.                  217 : "Semantc errors in packet filter(s)",
  89.                  218 : "Syntactic errors in packet filter(s)",
  90.                  219 : "Missing or unknown APN",
  91.                  220 : "Unknown PDP address or PDP type",
  92.                  221 : "PDP context without TFT already activated",
  93.                  222 : "APN access denied : no subscription",
  94.                  223 : "APN Restriction type incompatibility with currently active PDP Contexts",
  95.                  224 : "MS MBMS Capabilities Insufficient",
  96.                  225 : "Invalid Correlation : ID",
  97.                  226 : "MBMS Bearer Context Superseded",
  98.                  227 : "Bearer Control Mode violation",
  99.                  228 : "Collision with network initiated request" }
  100.  
  101. Selection_Mode = { 11111100:"MSorAPN",
  102.                    11111101:"MS",
  103.                    11111110:"NET",
  104.                    11111111:"FutureUse" }
  105.  
  106. TeardownInd_value = {   254 : "False",
  107.                         255 : "True" }
  108.  
  109. class GTPHeader(Packet):
  110.         # 3GPP TS 29.060 V9.1.0 (2009-12)
  111.         name = "GTP Header"
  112.         fields_desc = [ BitField("version",     1,      3),
  113.                         BitField("PT",          1,      1),
  114.                         BitField("Reserved",    0,      1),
  115.                         BitField("E",           0,      1),
  116.                         BitField("S",           1,      1),
  117.                         BitField("PN",          0,      1),
  118.                         ByteEnumField("type",   None, GTPmessageType),
  119.                         BitField("length",      None,   16),
  120.                         XBitField("TEID",       0,      32),]
  121.                        
  122.  
  123.         def post_build(self, p, pay):
  124.                 p +=pay
  125.                 warning("Packet length: " + str(len(p)-8))
  126.                 if self.length is None:
  127.                         l = len(p)-8
  128.                         p = p[:1] + struct.pack("!i",l)+ p[4:]
  129.                 if self.type is None:
  130.                         if isinstance(self.payload, GTPEchoRequest):
  131.                                 t = 1
  132.                         elif isinstance(self.payload, GTPEchoResponse):
  133.                                 t = 2
  134.                         elif isinstance(self.payload, GTPCreatePDPContextRequest):
  135.                                 t = 16
  136.                         elif isinstance(self.payload, GTPDeletePDPContextRequest):
  137.                                 t = 20
  138.                         elif isinstance(self.payload, GTPDeletePDPContextResponse):
  139.                                 t = 21
  140.                         elif isinstance(self.payload, GTPErrorIndication):
  141.                                 t = 26
  142.                         else:
  143.                                 warning("GTPHeader: cannot GPT type! Set type 1 (Echo Request).")
  144.                                 t = 1
  145.                         p = p[:1] + struct.pack("!B",t) + p[3:]
  146.                 #if self.payload.seq is not None:
  147.                 #       warning("TODO: Set S bit '1' because seq number is present.")
  148.                 #else:
  149.                 #       warning("TODO: Set S bit '0' because seq number is not present.")
  150.                 return p
  151.  
  152. class GTPEchoRequest(Packet):
  153.         # 3GPP TS 29.060 V9.1.0 (2009-12)
  154.         name = "GTP Echo Request"
  155.         fields_desc = [ XBitField("seq",        0,      16),
  156.                         ByteField("npdu",       0),
  157.                         ByteField("next_ex",    0),]
  158.  
  159. class GTPEchoResponse(Packet):
  160.         # 3GPP TS 29.060 V9.1.0 (2009-12)
  161.         name = "GTP Echo Response"
  162.         fields_desc = [ XBitField("seq",        0,      16),
  163.                         ByteField("npdu",       0),
  164.                         ByteField("next_ex",    0),
  165.                         ByteEnumField("IE_Recovery",    "Recovery",     IEType),
  166.                         ByteField("res-counter",24), ]
  167.  
  168. class GTPCreatePDPContextRequest(Packet):
  169.         # 3GPP TS 29.060 V9.1.0 (2009-12)
  170.         name = "GTP Create PDP Context Request"
  171.         fields_desc = [  XBitField("seq",        0,      16),
  172.                         ByteField("npdu",       0),
  173.                         ByteField("next_ex",    0),
  174.                 # IMSI: Conditional - Suscariber identity of de MS
  175.                         ByteEnumField("IE_IMSI",        "IMSI",         IEType),
  176.                         BitField("IMSI",        0,      64),
  177.                 # RAI: Optional - Routeing Area Identity
  178.                         ByteEnumField("IE_RAI", "RAI",  IEType),
  179.                         BitField("MCC",         None,   12),
  180.                         # MNC: If only have 2 digits, then third digit (1byte) is 0xf
  181.                         BitField("MNC",         None,   12),
  182.                         BitField("LAC",         None,   16),
  183.                         ByteField("RAC",        None),
  184.                 # Selection Mode: Conditional - Indicates the origin of the APN in the message
  185.                         ByteEnumField("IE_SelectionMode",       "SelectionMode",        IEType),
  186.                         # First 6 bits are "1". Use only first 2 bits.
  187.                         BitEnumField("SelectionMode",   "MSorAPN",      8,      Selection_Mode),
  188.                 # TEIDI: Mandatory - Tunnel Endpoint Identifier Data I
  189.                         ByteEnumField("IE_TEIDI",       "TEIDI",        IEType),
  190.                         XBitField("TEIDI",      0,      32),
  191.                 # TEICP: Conditional - Tunnel Endpoint Identifier Control Plane
  192.                         ByteEnumField("IE_TEICP",    "TEICP",        IEType),
  193.                         XBitField("TEICP",      0,      32),
  194.                 # NSAPI: Mandatory - identifying a PDP context in a mobility management context specified by TEICP
  195.                         ByteEnumField("IE_NASPI",    "NSAPI",        IEType),
  196.                         XBitField("SpareNSAPI",      0x0000,      4),
  197.                         XBitField("NSAPI",      0x0000, 4),
  198.                 # Charging Characteristics: Conditional - way of informing both the SGSN and GGSN of the rules for
  199.                 #                           producing charging informarion based on opetaror configured triggers.
  200.                 #       0000 .... .... .... : spare
  201.                 #       .... 1... .... .... : normal charging
  202.                 #       .... .0.. .... .... : prepaid charging
  203.                 #       .... ..0. .... .... : flat rate charging
  204.                 #       .... ...0 .... .... : hot billing charging
  205.                         #       .... .... 0000 0000 : reserved
  206.                         ByteEnumField("IE_ChargingChrt",    "ChargingChrt",        IEType),
  207.                         XBitField("Ch_ChSpare",         None,   4),
  208.                         XBitField("normal_charging",    None,   1),
  209.                         XBitField("prepaid_charging",   None,   1),
  210.                         XBitField("flat_rate_charging", None,   1),
  211.                         XBitField("hot_billing_charging",       None,   1),
  212.                         XBitField("Ch_ChReserved",      0,      8),
  213.                 # Trace Reference: Optional - Identifies a record or a collection of records for a particular trace.
  214.                         ByteEnumField("IE_TraceReference",      "TraceReference",       IEType),
  215.                         XBitField("Trace_reference",    None,   16),
  216.                 # Trace Type: Optional - Indicate the type of the trace
  217.                         ByteEnumField("IE_TraceType",   "TraceType",    IEType),
  218.                         XBitField("Trace_type", None,   16),
  219.                 # End User Address: Conditional - to supply protocol specific information of the external packet
  220.                 # data network accessed by the GGPRS suscribers.
  221.                 #       - Request
  222.                 #               1       Type (1byte)
  223.                 #               2-3     Length (2bytes) - value 2
  224.                 #               4       Spare + PDP Type Organization
  225.                 #               5       PDP Type Number
  226.                 #       - Response
  227.                 #               6-n     PDP Address
  228.                         ByteEnumField("IE_EndUserAddress",      "EndUserAddress",       IEType),
  229.                         BitField("EndUserAddressLength",        2,      16),
  230.                         BitField("EndUserAddress",      1111,   4),
  231.                         BitField("PDPTypeOrganization", 1,      4),
  232.                         XByteField("PDPTypeNumber",     None),
  233.                 # Access Point Name: Conditional - Sent by SGSN or by GGSN as defined in 3GPP TS 23.060
  234.                         ByteEnumField("IE_AccessPointName",     "AccessPointName",      IEType),
  235.                         ByteField("APNLength",  None),
  236.                                 #,      length_from=lambda pkt:len(pkt.APNUrl)),
  237.                         StrField("APNUrl",      "apn.es"),
  238.                 # Protocol Configuration:
  239.                 # GSN Address:
  240.                         ByteEnumField("IE_GSNAddress1", "GSNAddress",   IEType),
  241.                         LongField("GSNAddressLength",   4),
  242.                         IPField("IPGSN1",       "0.0.0.0"), ]
  243.                 # GSN Address:
  244.                                
  245.  
  246. class GTPErrorIndication(Packet):
  247.         # 3GPP TS 29.060 V9.1.0 (2009-12)
  248.         name = "GTP Error Indication"
  249.         fields_desc = [ XBitField("seq",        0,      16),
  250.                         ByteField("npdu",       0),
  251.                         ByteField("next_ex",    0),
  252.                 # TEIDI: Mandatory - Tunnel Endpoint Identifier Data I
  253.                         ByteEnumField("IE_TEIDI",       "TEIDI",        IEType),
  254.                         XBitField("TEIDI",      0,      32),
  255.                 # GSN Address:
  256.                         ByteEnumField("IE_GSNAddress1", "GSNAddress",   IEType),
  257.                         BitField("GSNAddressLength",    4,      16),
  258.                         IPField("IPGSN1",       "252.253.254.255"), ]
  259.  
  260. class GTPDeletePDPContextRequest(Packet):
  261.         # 3GPP TS 29.060 V9.1.0 (2009-12)      
  262.         name = "GTP Delete PDP Context Request"
  263.         fields_desc = [ XBitField("seq",        0,      16),
  264.                         ByteField("npdu",       0),
  265.                         ByteField("next_ex",    0),
  266.                 # Teardown Ind: conditional - If this element is set to "1", all PDP Contexts thatt share the same PDP
  267.                 #                               address or two IP addresses with the PDP context indentified by the
  268.                 #                               NSAPI included in the Delete PDP Context Request Message shall be torn down.
  269.                         ByteEnumField("IE_TeardownInd", "TeardownInd",  IEType),
  270.                         ByteEnumField("TeardownInd",    "True", TeardownInd_value),
  271.                 # NSAPI: Mandatory - identifying a PDP context in a mobility management context specified by TEICP
  272.                         ByteEnumField("IE_NSAPI",       "NSAPI",        IEType),
  273.                         XBitField("SpareNSAPI",      0x0000,      4),
  274.                         XBitField("NSAPI",      0x0000,    4), ]
  275.                 # Protocol Configuration Options: Optional - TODO
  276.  
  277.                 # Private Extansions: Optional - Contains vendor specific information. TODO
  278.                
  279.  
  280. class GTPDeletePDPContextResponse(Packet):
  281.         # 3GPP TS 29.060 V9.1.0 (2009-12)
  282.         name = "GTP Delete PDP Context Response"
  283.         fields_desc = [ XBitField("seq",        0,      16),
  284.                         ByteField("npdu",       0),
  285.                         ByteField("next_ex",    0),
  286.                 # Cause: Mandatory -
  287.                         ByteEnumField("IE_Cause",       "Cause",        IEType),
  288.                         BitField("Response",    None,   1),
  289.                         BitField("Rejection",   None,   1),
  290.                         BitEnumField("CauseValue",      None,   6,      CauseValues), ]
  291.                 # Protocol Configuration Options: Optional - TODO
  292.  
  293.                 # User Location Information: Optional - TODO
  294.  
  295.                 # MS Time Zone: Optional - TODO
  296.  
  297.                 # Private Extension: Optional - TODO
  298.  
  299. class GTP_U_Header(Packet):
  300.         # 3GPP TS 29.060 V9.1.0 (2009-12)
  301.         name = "GTP-U Header"
  302.         # GTP-U protocol is used to transmit T-PDUs between GSN pairs (or between an SGSN and an RNC in UMTS),
  303.         # encapsulated in G-PDUs. A G-PDU is a packet including a GTP-U header and a T-PDU. The Path Protocol
  304.         # defines the path and the GTP-U header defines the tunnel. Several tunnels may be multiplexed on a single path.
  305.         fields_desc = [ BitField("version",     1,      3),
  306.                         BitField("PT",          1,      1),
  307.                         BitField("Reserved",    0,      1),
  308.                         BitField("E",           0,      1),
  309.                         BitField("S",           0,      1),
  310.                         BitField("PN",          0,      1),
  311.                         ByteEnumField("type",   None, GTPmessageType),
  312.                         BitField("length",      None,   16),
  313.                         XBitField("TEID",       0,      32),
  314.                 # Conditional fields:
  315.                 #        XBitField("seq",        0,     16),
  316.                         ByteField("npdu",       0),
  317.                         ByteField("next_ex",    0),
  318.  
  319.                         ConditionalField(XBitField("seq",        0,      16), lambda pkt:pkt.S == 1),
  320.                 #       ConditionalField(ByteField("npdu",       0), lambda pkt:pkt.PT == 1),
  321.                 #       ConditionalField(ByteField("next_ex",    0), lambda pkt:pkt.E == 1),
  322.                         ]
  323.  
  324.         def post_build(self, p, pay):
  325.                 p += pay
  326.                 warning("Packet length: " + str(len(p)-8))
  327.                 if self.length is None:
  328.                         l = len(p)-8
  329.                         p = p[:1] + struct.pack("!i",l)+ p[4:]
  330.                 if self.type is None:
  331.                         if isinstance(self.payload, IP):
  332.                                 t = 255
  333.                         else:
  334.                                 warning("GTP-U Header: Not PDU detected.")
  335.                                 t = 255
  336.                         p = p[:1] + struct.pack("!B",t) + p[3:]
  337.                 return p
  338.  
  339. class GTPmorethan1500(Packet):
  340.         # 3GPP TS 29.060 V9.1.0 (2009-12)
  341.         name = "GTP More than 1500"
  342.         # GTP-U protocol is used to transmit T-PDUs between GSN pairs (or between an SGSN and an RNC in UMTS),
  343.         # encapsulated in G-PDUs. A G-PDU is a packet including a GTP-U header and a T-PDU. The Path Protocol
  344.         # defines the path and the GTP-U header defines the tunnel. Several tunnels may be multiplexed on a single path.
  345.         fields_desc = [ ByteEnumField("IE_Cause",       "Cause",        IEType),
  346.                         BitField("IE",     1,      12000),]
  347.  
  348.        
  349. # Bind GTP-C
  350. bind_layers( UDP,       GTPHeader)
  351. bind_layers( GTPHeader, GTPEchoRequest)
  352. bind_layers( GTPHeader, GTPEchoResponse)
  353. bind_layers( GTPHeader, GTPCreatePDPContextRequest)
  354. bind_layers( GTPHeader, GTPDeletePDPContextRequest)
  355. bind_layers( GTPHeader, GTPDeletePDPContextResponse)
  356. #Bind GTP-U
  357. bind_layers( UDP,       GTP_U_Header)
  358. bind_layers( GTP_U_Header,      IP)
  359.  
  360. if __name__ == "__main__":
  361.         interact(mydict=globals(), mybanner="Test GTP add-on v0.1")