ffranz

Scapy layer: GTP

Apr 15th, 2012
330
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 14.57 KB | None | 0 0
  1. ## This file is not now part of Scapy
  2. ## Look iniqua.com for more informations
  3. ## ffranz <[email protected]>
  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")
Advertisement
Add Comment
Please, Sign In to add comment