test suite reviews and discussions
 help / color / Atom feed
* [dts] [PATCH V1 1/2] dep/add gtp for the advanced rss feature support gtp packets in CVL
@ 2019-12-31 12:07 zhiwei.he
  2019-12-31 12:07 ` [dts] [PATCH V1 2/2] dep/add gtp_v2 for the advanced rss feature to support gtp_v2 " zhiwei.he
  2020-01-02  5:32 ` [dts] [PATCH V1 1/2] dep/add gtp for the advanced rss feature support gtp " Tu, Lijuan
  0 siblings, 2 replies; 3+ messages in thread
From: zhiwei.he @ 2019-12-31 12:07 UTC (permalink / raw)
  To: dts; +Cc: zhiwei.he

From: "zhiwei.he" <zhiwei.he@intel.com>

Signed-off-by: zhiwei.he <zhiwei.he@intel.com>
---
 dep/gtp.py | 909 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 909 insertions(+)
 create mode 100644 dep/gtp.py

diff --git a/dep/gtp.py b/dep/gtp.py
new file mode 100644
index 0000000..7d57789
--- /dev/null
+++ b/dep/gtp.py
@@ -0,0 +1,909 @@
+#! /usr/bin/env python
+
+# Copyright (C) 2018 Leonardo Monteiro <decastromonteiro@gmail.com>
+#               2017 Alexis Sultan    <alexis.sultan@sfr.com>
+#               2017 Alessio Deiana <adeiana@gmail.com>
+#               2014 Guillaume Valadon <guillaume.valadon@ssi.gouv.fr>
+#               2012 ffranz <ffranz@iniqua.com>
+##
+# This program is published under a GPLv2 license
+
+# scapy.contrib.description = GPRS Tunneling Protocol (GTP)
+# scapy.contrib.status = loads
+
+from __future__ import absolute_import
+import struct
+
+
+from scapy.compat import chb, orb
+from scapy.error import warning
+from scapy.fields import BitEnumField, BitField, ByteEnumField, ByteField, \
+    ConditionalField, FieldLenField, FieldListField, FlagsField, IntField, \
+    IPField, PacketListField, ShortField, StrFixedLenField, StrLenField, \
+    XBitField, XByteField, XIntField
+from scapy.layers.inet import IP, UDP
+from scapy.layers.inet6 import IP6Field
+from scapy.modules.six.moves import range
+from scapy.packet import bind_layers, Packet, Raw
+from scapy.volatile import RandInt, RandIP, RandNum, RandString
+
+
+# GTP Data types
+
+RATType = {
+    1: "UTRAN",
+    2: "GETRAN",
+    3: "WLAN",
+    4: "GAN",
+    5: "HSPA"
+}
+
+GTPmessageType = {1: "echo_request",
+                  2: "echo_response",
+                  16: "create_pdp_context_req",
+                  17: "create_pdp_context_res",
+                  18: "update_pdp_context_req",
+                  19: "update_pdp_context_resp",
+                  20: "delete_pdp_context_req",
+                  21: "delete_pdp_context_res",
+                  26: "error_indication",
+                  27: "pdu_notification_req",
+                  31: "supported_extension_headers_notification",
+                  254: "end_marker",
+                  255: "g_pdu"}
+
+IEType = {1: "Cause",
+             2: "IMSI",
+             3: "RAI",
+             4: "TLLI",
+             5: "P_TMSI",
+             8: "IE_ReorderingRequired",
+          14: "Recovery",
+          15: "SelectionMode",
+          16: "TEIDI",
+          17: "TEICP",
+          19: "TeardownInd",
+          20: "NSAPI",
+          26: "ChargingChrt",
+          27: "TraceReference",
+          28: "TraceType",
+          127: "ChargingId",
+          128: "EndUserAddress",
+          131: "AccessPointName",
+          132: "ProtocolConfigurationOptions",
+          133: "GSNAddress",
+          134: "MSInternationalNumber",
+          135: "QoS",
+          148: "CommonFlags",
+          149: "APNRestriction",
+          151: "RatType",
+          152: "UserLocationInformation",
+          153: "MSTimeZone",
+          154: "IMEI",
+          181: "MSInfoChangeReportingAction",
+          184: "BearerControlMode",
+          191: "EvolvedAllocationRetentionPriority",
+          255: "PrivateExtention"}
+
+CauseValues = {0: "Request IMSI",
+               1: "Request IMEI",
+               2: "Request IMSI and IMEI",
+               3: "No identity needed",
+               4: "MS Refuses",
+               5: "MS is not GPRS Responding",
+               128: "Request accepted",
+               129: "New PDP type due to network preference",
+               130: "New PDP type due to single address bearer only",
+               192: "Non-existent",
+               193: "Invalid message format",
+               194: "IMSI not known",
+               195: "MS is GPRS Detached",
+               196: "MS is not GPRS Responding",
+               197: "MS Refuses",
+               198: "Version not supported",
+               199: "No resources available",
+               200: "Service not supported",
+               201: "Mandatory IE incorrect",
+               202: "Mandatory IE missing",
+               203: "Optional IE incorrect",
+               204: "System failure",
+               205: "Roaming restriction",
+               206: "P-TMSI Signature mismatch",
+               207: "GPRS connection suspended",
+               208: "Authentication failure",
+               209: "User authentication failed",
+               210: "Context not found",
+               211: "All dynamic PDP addresses are occupied",
+               212: "No memory is available",
+               213: "Reallocation failure",
+               214: "Unknown mandatory extension header",
+               215: "Semantic error in the TFT operation",
+               216: "Syntactic error in TFT operation",
+               217: "Semantic errors in packet filter(s)",
+               218: "Syntactic errors in packet filter(s)",
+               219: "Missing or unknown APN",
+               220: "Unknown PDP address or PDP type",
+               221: "PDP context without TFT already activated",
+               222: "APN access denied : no subscription",
+               223: "APN Restriction type incompatibility with currently active PDP Contexts",  # noqa: E501
+               224: "MS MBMS Capabilities Insufficient",
+               225: "Invalid Correlation : ID",
+               226: "MBMS Bearer Context Superseded",
+               227: "Bearer Control Mode violation",
+               228: "Collision with network initiated request"}
+
+Selection_Mode = {11111100: "MS or APN",
+                  11111101: "MS",
+                  11111110: "NET",
+                  11111111: "FutureUse"}
+
+TrueFalse_value = {254: "False",
+                   255: "True"}
+
+# http://www.arib.or.jp/IMT-2000/V720Mar09/5_Appendix/Rel8/29/29281-800.pdf
+ExtensionHeadersTypes = {
+    0: "No more extension headers",
+    1: "Reserved",
+    2: "Reserved",
+    64: "UDP Port",
+    192: "PDCP PDU Number",
+    193: "Reserved",
+    194: "Reserved"
+}
+
+
+class TBCDByteField(StrFixedLenField):
+
+    def i2h(self, pkt, val):
+        return val
+
+    def m2i(self, pkt, val):
+        ret = []
+        for v in val:
+            byte = orb(v)
+            left = byte >> 4
+            right = byte & 0xf
+            if left == 0xf:
+                ret.append(TBCD_TO_ASCII[right:right + 1])
+            else:
+                ret += [TBCD_TO_ASCII[right:right + 1], TBCD_TO_ASCII[left:left + 1]]  # noqa: E501
+        return b"".join(ret)
+
+    def i2m(self, pkt, val):
+        val = str(val)
+        ret_string = ""
+        for i in range(0, len(val), 2):
+            tmp = val[i:i + 2]
+            if len(tmp) == 2:
+                ret_string += chr(int(tmp[1] + tmp[0], 16))
+            else:
+                ret_string += chr(int("F" + tmp[0], 16))
+        return ret_string
+
+
+TBCD_TO_ASCII = b"0123456789*#abc"
+
+
+class GTP_ExtensionHeader(Packet):
+    @classmethod
+    def dispatch_hook(cls, _pkt=None, *args, **kargs):
+        if _pkt is None:
+            return GTP_UDPPort_ExtensionHeader
+        return cls
+
+
+class GTP_UDPPort_ExtensionHeader(GTP_ExtensionHeader):
+    fields_desc = [ByteField("length", 0x40),
+                   ShortField("udp_port", None),
+                   ByteEnumField("next_ex", 0, ExtensionHeadersTypes), ]
+
+
+class GTP_PDCP_PDU_ExtensionHeader(GTP_ExtensionHeader):
+    fields_desc = [ByteField("length", 0x01),
+                   ShortField("pdcp_pdu", None),
+                   ByteEnumField("next_ex", 0, ExtensionHeadersTypes), ]
+
+
+class GTPHeader(Packet):
+    # 3GPP TS 29.060 V9.1.0 (2009-12)
+    name = "GTP-C Header"
+    fields_desc = [BitField("version", 1, 3),
+                   BitField("PT", 1, 1),
+                   BitField("reserved", 0, 1),
+                   BitField("E", 0, 1),
+                   BitField("S", 0, 1),
+                   BitField("PN", 0, 1),
+                   ByteEnumField("gtp_type", None, GTPmessageType),
+                   ShortField("length", None),
+                   IntField("teid", 0),
+                   ConditionalField(XBitField("seq", 0, 16), lambda pkt:pkt.E == 1 or pkt.S == 1 or pkt.PN == 1),  # noqa: E501
+                   ConditionalField(ByteField("npdu", 0), lambda pkt:pkt.E == 1 or pkt.S == 1 or pkt.PN == 1),  # noqa: E501
+                   ConditionalField(ByteEnumField("next_ex", 0, ExtensionHeadersTypes), lambda pkt:pkt.E == 1 or pkt.S == 1 or pkt.PN == 1), ]  # noqa: E501
+
+    def post_build(self, p, pay):
+        p += pay
+        if self.length is None:
+            tmp_len = len(p) - 8
+            p = p[:2] + struct.pack("!H", tmp_len) + p[4:]
+        return p
+
+    def hashret(self):
+        return struct.pack("B", self.version) + self.payload.hashret()
+
+    def answers(self, other):
+        return (isinstance(other, GTPHeader) and
+                self.version == other.version and
+                self.payload.answers(other.payload))
+
+    @classmethod
+    def dispatch_hook(cls, _pkt=None, *args, **kargs):
+        if _pkt and len(_pkt) >= 1:
+            if (orb(_pkt[0]) >> 5) & 0x7 == 2:
+                from . import gtp_v2
+                return gtp_v2.GTPHeader
+        if _pkt and len(_pkt) >= 8:
+            _gtp_type = orb(_pkt[1:2])
+            return GTPforcedTypes.get(_gtp_type, GTPHeader)
+        return cls
+
+
+class GTP_U_Header(GTPHeader):
+    # 3GPP TS 29.060 V9.1.0 (2009-12)
+    name = "GTP-U Header"
+    # GTP-U protocol is used to transmit T-PDUs between GSN pairs (or between an SGSN and an RNC in UMTS),  # noqa: E501
+    # encapsulated in G-PDUs. A G-PDU is a packet including a GTP-U header and a T-PDU. The Path Protocol  # noqa: E501
+    # defines the path and the GTP-U header defines the tunnel. Several tunnels may be multiplexed on a single path.  # noqa: E501
+
+
+# Some gtp_types have to be associated with a certain type of header
+GTPforcedTypes = {
+    16: GTPHeader,
+    17: GTPHeader,
+    18: GTPHeader,
+    19: GTPHeader,
+    20: GTPHeader,
+    21: GTPHeader,
+    26: GTP_U_Header,
+    27: GTPHeader,
+    254: GTP_U_Header,
+    255: GTP_U_Header
+}
+
+
+class GTPEchoRequest(Packet):
+    # 3GPP TS 29.060 V9.1.0 (2009-12)
+    name = "GTP Echo Request"
+
+    def hashret(self):
+        return struct.pack("H", self.seq)
+
+
+class IE_Base(Packet):
+
+    def extract_padding(self, pkt):
+        return "", pkt
+
+
+class IE_Cause(IE_Base):
+    name = "Cause"
+    fields_desc = [ByteEnumField("ietype", 1, IEType),
+                   ByteEnumField("CauseValue", None, CauseValues)]
+
+
+class IE_IMSI(IE_Base):
+    name = "IMSI - Subscriber identity of the MS"
+    fields_desc = [ByteEnumField("ietype", 2, IEType),
+                   TBCDByteField("imsi", str(RandNum(0, 999999999999999)), 8)]
+
+
+class IE_Routing(IE_Base):
+    name = "Routing Area Identity"
+    fields_desc = [ByteEnumField("ietype", 3, IEType),
+                   TBCDByteField("MCC", "", 2),
+                   # MNC: if the third digit of MCC is 0xf,
+                   # then the length of MNC is 1 byte
+                   TBCDByteField("MNC", "", 1),
+                   ShortField("LAC", None),
+                   ByteField("RAC", None)]
+
+
+class IE_ReorderingRequired(IE_Base):
+    name = "Recovery"
+    fields_desc = [ByteEnumField("ietype", 8, IEType),
+                   ByteEnumField("reordering_required", 254, TrueFalse_value)]
+
+
+class IE_Recovery(IE_Base):
+    name = "Recovery"
+    fields_desc = [ByteEnumField("ietype", 14, IEType),
+                   ByteField("restart_counter", 24)]
+
+
+class IE_SelectionMode(IE_Base):
+    # Indicates the origin of the APN in the message
+    name = "Selection Mode"
+    fields_desc = [ByteEnumField("ietype", 15, IEType),
+                   BitEnumField("SelectionMode", "MS or APN",
+                                8, Selection_Mode)]
+
+
+class IE_TEIDI(IE_Base):
+    name = "Tunnel Endpoint Identifier Data"
+    fields_desc = [ByteEnumField("ietype", 16, IEType),
+                   XIntField("TEIDI", RandInt())]
+
+
+class IE_TEICP(IE_Base):
+    name = "Tunnel Endpoint Identifier Control Plane"
+    fields_desc = [ByteEnumField("ietype", 17, IEType),
+                   XIntField("TEICI", RandInt())]
+
+
+class IE_Teardown(IE_Base):
+    name = "Teardown Indicator"
+    fields_desc = [ByteEnumField("ietype", 19, IEType),
+                   ByteEnumField("indicator", "True", TrueFalse_value)]
+
+
+class IE_NSAPI(IE_Base):
+    # Identifies a PDP context in a mobility management context specified by TEICP  # noqa: E501
+    name = "NSAPI"
+    fields_desc = [ByteEnumField("ietype", 20, IEType),
+                   XBitField("sparebits", 0x0000, 4),
+                   XBitField("NSAPI", RandNum(0, 15), 4)]
+
+
+class IE_ChargingCharacteristics(IE_Base):
+    # Way of informing both the SGSN and GGSN of the rules for
+    name = "Charging Characteristics"
+    fields_desc = [ByteEnumField("ietype", 26, IEType),
+                   # producing charging information based on operator configured triggers.  # noqa: E501
+                   #    0000 .... .... .... : spare
+                   #    .... 1... .... .... : normal charging
+                   #    .... .0.. .... .... : prepaid charging
+                   #    .... ..0. .... .... : flat rate charging
+                   #    .... ...0 .... .... : hot billing charging
+                   #    .... .... 0000 0000 : reserved
+                   XBitField("Ch_ChSpare", None, 4),
+                   XBitField("normal_charging", None, 1),
+                   XBitField("prepaid_charging", None, 1),
+                   XBitField("flat_rate_charging", None, 1),
+                   XBitField("hot_billing_charging", None, 1),
+                   XBitField("Ch_ChReserved", 0, 8)]
+
+
+class IE_TraceReference(IE_Base):
+    # Identifies a record or a collection of records for a particular trace.
+    name = "Trace Reference"
+    fields_desc = [ByteEnumField("ietype", 27, IEType),
+                   XBitField("Trace_reference", None, 16)]
+
+
+class IE_TraceType(IE_Base):
+    # Indicates the type of the trace
+    name = "Trace Type"
+    fields_desc = [ByteEnumField("ietype", 28, IEType),
+                   XBitField("Trace_type", None, 16)]
+
+
+class IE_ChargingId(IE_Base):
+    name = "Charging ID"
+    fields_desc = [ByteEnumField("ietype", 127, IEType),
+                   XIntField("Charging_id", RandInt())]
+
+
+class IE_EndUserAddress(IE_Base):
+    # Supply protocol specific information of the external packet
+    name = "End User Address"
+    fields_desc = [ByteEnumField("ietype", 128, IEType),
+                   #         data network accessed by the GGPRS subscribers.
+                   #            - Request
+                   #                1    Type (1byte)
+                   #                2-3    Length (2bytes) - value 2
+                   #                4    Spare + PDP Type Organization
+                   #                5    PDP Type Number
+                   #            - Response
+                   #                6-n    PDP Address
+                   ShortField("length", 2),
+                   BitField("SPARE", 15, 4),
+                   BitField("PDPTypeOrganization", 1, 4),
+                   XByteField("PDPTypeNumber", None),
+                   ConditionalField(IPField("PDPAddress", RandIP()),
+                                    lambda pkt: pkt.length == 6 or pkt.length == 22),  # noqa: E501
+                   ConditionalField(IP6Field("IPv6_PDPAddress", '::1'),
+                                    lambda pkt: pkt.length == 18 or pkt.length == 22)]  # noqa: E501
+
+
+class APNStrLenField(StrLenField):
+    # Inspired by DNSStrField
+    def m2i(self, pkt, s):
+        ret_s = b""
+        tmp_s = s
+        while tmp_s:
+            tmp_len = orb(tmp_s[0]) + 1
+            if tmp_len > len(tmp_s):
+                warning("APN prematured end of character-string (size=%i, remaining bytes=%i)" % (tmp_len, len(tmp_s)))  # noqa: E501
+            ret_s += tmp_s[1:tmp_len]
+            tmp_s = tmp_s[tmp_len:]
+            if len(tmp_s):
+                ret_s += b"."
+        s = ret_s
+        return s
+
+    def i2m(self, pkt, s):
+        s = b"".join(chb(len(x)) + x for x in s.split("."))
+        return s
+
+
+class IE_AccessPointName(IE_Base):
+    # Sent by SGSN or by GGSN as defined in 3GPP TS 23.060
+    name = "Access Point Name"
+    fields_desc = [ByteEnumField("ietype", 131, IEType),
+                   ShortField("length", None),
+                   APNStrLenField("APN", "nternet", length_from=lambda x: x.length)]  # noqa: E501
+
+    def post_build(self, p, pay):
+        if self.length is None:
+            tmp_len = len(p) - 3
+            p = p[:2] + struct.pack("!B", tmp_len) + p[3:]
+        return p
+
+
+class IE_ProtocolConfigurationOptions(IE_Base):
+    name = "Protocol Configuration Options"
+    fields_desc = [ByteEnumField("ietype", 132, IEType),
+                   ShortField("length", 4),
+                   StrLenField("Protocol_Configuration", "",
+                               length_from=lambda x: x.length)]
+
+
+class IE_GSNAddress(IE_Base):
+    name = "GSN Address"
+    fields_desc = [ByteEnumField("ietype", 133, IEType),
+                   ShortField("length", 4),
+                   IPField("address", RandIP())]
+
+
+class IE_MSInternationalNumber(IE_Base):
+    name = "MS International Number"
+    fields_desc = [ByteEnumField("ietype", 134, IEType),
+                   ShortField("length", None),
+                   FlagsField("flags", 0x91, 8, ["Extension", "", "", "International Number", "", "", "", "ISDN numbering"]),  # noqa: E501
+                   TBCDByteField("digits", "33607080910", length_from=lambda x: x.length - 1)]  # noqa: E501
+
+
+class QoS_Profile(IE_Base):
+    name = "QoS profile"
+    fields_desc = [ByteField("qos_ei", 0),
+                   ByteField("length", None),
+                   XBitField("spare", 0x00, 2),
+                   XBitField("delay_class", 0x000, 3),
+                   XBitField("reliability_class", 0x000, 3),
+                   XBitField("peak_troughput", 0x0000, 4),
+                   BitField("spare", 0, 1),
+                   XBitField("precedence_class", 0x000, 3),
+                   XBitField("spare", 0x000, 3),
+                   XBitField("mean_troughput", 0x00000, 5),
+                   XBitField("traffic_class", 0x000, 3),
+                   XBitField("delivery_order", 0x00, 2),
+                   XBitField("delivery_of_err_sdu", 0x000, 3),
+                   ByteField("max_sdu_size", None),
+                   ByteField("max_bitrate_up", None),
+                   ByteField("max_bitrate_down", None),
+                   XBitField("redidual_ber", 0x0000, 4),
+                   XBitField("sdu_err_ratio", 0x0000, 4),
+                   XBitField("transfer_delay", 0x00000, 5),
+                   XBitField("traffic_handling_prio", 0x000, 3),
+                   ByteField("guaranteed_bit_rate_up", None),
+                   ByteField("guaranteed_bit_rate_down", None)]
+
+
+class IE_QoS(IE_Base):
+    name = "QoS"
+    fields_desc = [ByteEnumField("ietype", 135, IEType),
+                   ShortField("length", None),
+                   ByteField("allocation_retention_prioiry", 1),
+
+                   ConditionalField(XBitField("spare", 0x00, 2),
+                                    lambda pkt: pkt.length > 1),
+                   ConditionalField(XBitField("delay_class", 0x000, 3),
+                                    lambda pkt: pkt.length > 1),
+                   ConditionalField(XBitField("reliability_class", 0x000, 3),
+                                    lambda pkt: pkt.length > 1),
+
+                   ConditionalField(XBitField("peak_troughput", 0x0000, 4),
+                                    lambda pkt: pkt.length > 2),
+                   ConditionalField(BitField("spare", 0, 1),
+                                    lambda pkt: pkt.length > 2),
+                   ConditionalField(XBitField("precedence_class", 0x000, 3),
+                                    lambda pkt: pkt.length > 2),
+
+                   ConditionalField(XBitField("spare", 0x000, 3),
+                                    lambda pkt: pkt.length > 3),
+                   ConditionalField(XBitField("mean_troughput", 0x00000, 5),
+                                    lambda pkt: pkt.length > 3),
+
+                   ConditionalField(XBitField("traffic_class", 0x000, 3),
+                                    lambda pkt: pkt.length > 4),
+                   ConditionalField(XBitField("delivery_order", 0x00, 2),
+                                    lambda pkt: pkt.length > 4),
+                   ConditionalField(XBitField("delivery_of_err_sdu", 0x000, 3),
+                                    lambda pkt: pkt.length > 4),
+
+                   ConditionalField(ByteField("max_sdu_size", None),
+                                    lambda pkt: pkt.length > 5),
+                   ConditionalField(ByteField("max_bitrate_up", None),
+                                    lambda pkt: pkt.length > 6),
+                   ConditionalField(ByteField("max_bitrate_down", None),
+                                    lambda pkt: pkt.length > 7),
+
+                   ConditionalField(XBitField("redidual_ber", 0x0000, 4),
+                                    lambda pkt: pkt.length > 8),
+                   ConditionalField(XBitField("sdu_err_ratio", 0x0000, 4),
+                                    lambda pkt: pkt.length > 8),
+                   ConditionalField(XBitField("transfer_delay", 0x00000, 6),
+                                    lambda pkt: pkt.length > 9),
+                   ConditionalField(XBitField("traffic_handling_prio",
+                                              0x000,
+                                              2),
+                                    lambda pkt: pkt.length > 9),
+
+                   ConditionalField(ByteField("guaranteed_bit_rate_up", None),
+                                    lambda pkt: pkt.length > 10),
+                   ConditionalField(ByteField("guaranteed_bit_rate_down",
+                                              None),
+                                    lambda pkt: pkt.length > 11),
+
+                   ConditionalField(XBitField("spare", 0x000, 3),
+                                    lambda pkt: pkt.length > 12),
+                   ConditionalField(BitField("signaling_indication", 0, 1),
+                                    lambda pkt: pkt.length > 12),
+                   ConditionalField(XBitField("source_stats_desc", 0x0000, 4),
+                                    lambda pkt: pkt.length > 12),
+
+                   ConditionalField(ByteField("max_bitrate_down_ext", None),
+                                    lambda pkt: pkt.length > 13),
+                   ConditionalField(ByteField("guaranteed_bitrate_down_ext",
+                                              None),
+                                    lambda pkt: pkt.length > 14),
+                   ConditionalField(ByteField("max_bitrate_up_ext", None),
+                                    lambda pkt: pkt.length > 15),
+                   ConditionalField(ByteField("guaranteed_bitrate_up_ext",
+                                              None),
+                                    lambda pkt: pkt.length > 16),
+                   ConditionalField(ByteField("max_bitrate_down_ext2", None),
+                                    lambda pkt: pkt.length > 17),
+                   ConditionalField(ByteField("guaranteed_bitrate_down_ext2",
+                                              None),
+                                    lambda pkt: pkt.length > 18),
+                   ConditionalField(ByteField("max_bitrate_up_ext2", None),
+                                    lambda pkt: pkt.length > 19),
+                   ConditionalField(ByteField("guaranteed_bitrate_up_ext2",
+                                              None),
+                                    lambda pkt: pkt.length > 20)]
+
+
+class IE_CommonFlags(IE_Base):
+    name = "Common Flags"
+    fields_desc = [ByteEnumField("ietype", 148, IEType),
+                   ShortField("length", None),
+                   BitField("dual_addr_bearer_fl", 0, 1),
+                   BitField("upgrade_qos_supported", 0, 1),
+                   BitField("nrsn", 0, 1),
+                   BitField("no_qos_nego", 0, 1),
+                   BitField("mbms_cnting_info", 0, 1),
+                   BitField("ran_procedure_ready", 0, 1),
+                   BitField("mbms_service_type", 0, 1),
+                   BitField("prohibit_payload_compression", 0, 1)]
+
+
+class IE_APNRestriction(IE_Base):
+    name = "APN Restriction"
+    fields_desc = [ByteEnumField("ietype", 149, IEType),
+                   ShortField("length", 1),
+                   ByteField("restriction_type_value", 0)]
+
+
+class IE_RATType(IE_Base):
+    name = "Rat Type"
+    fields_desc = [ByteEnumField("ietype", 151, IEType),
+                   ShortField("length", 1),
+                   ByteEnumField("RAT_Type", None, RATType)]
+
+
+class IE_UserLocationInformation(IE_Base):
+    name = "User Location Information"
+    fields_desc = [ByteEnumField("ietype", 152, IEType),
+                   ShortField("length", None),
+                   ByteField("type", 1),
+                   # Only type 1 is currently supported
+                   TBCDByteField("MCC", "", 2),
+                   # MNC: if the third digit of MCC is 0xf, then the length of MNC is 1 byte  # noqa: E501
+                   TBCDByteField("MNC", "", 1),
+                   ShortField("LAC", None),
+                   ShortField("SAC", None)]
+
+
+class IE_MSTimeZone(IE_Base):
+    name = "MS Time Zone"
+    fields_desc = [ByteEnumField("ietype", 153, IEType),
+                   ShortField("length", None),
+                   ByteField("timezone", 0),
+                   BitField("Spare", 0, 1),
+                   BitField("Spare", 0, 1),
+                   BitField("Spare", 0, 1),
+                   BitField("Spare", 0, 1),
+                   BitField("Spare", 0, 1),
+                   BitField("Spare", 0, 1),
+                   XBitField("daylight_saving_time", 0x00, 2)]
+
+
+class IE_IMEI(IE_Base):
+    name = "IMEI"
+    fields_desc = [ByteEnumField("ietype", 154, IEType),
+                   ShortField("length", None),
+                   TBCDByteField("IMEI", "", length_from=lambda x: x.length)]
+
+
+class IE_MSInfoChangeReportingAction(IE_Base):
+    name = "MS Info Change Reporting Action"
+    fields_desc = [ByteEnumField("ietype", 181, IEType),
+                   ShortField("length", 1),
+                   ByteField("Action", 0)]
+
+
+class IE_DirectTunnelFlags(IE_Base):
+    name = "Direct Tunnel Flags"
+    fields_desc = [ByteEnumField("ietype", 182, IEType),
+                   ShortField("length", 1),
+                   BitField("Spare", 0, 1),
+                   BitField("Spare", 0, 1),
+                   BitField("Spare", 0, 1),
+                   BitField("Spare", 0, 1),
+                   BitField("Spare", 0, 1),
+                   BitField("EI", 0, 1),
+                   BitField("GCSI", 0, 1),
+                   BitField("DTI", 0, 1)]
+
+
+class IE_BearerControlMode(IE_Base):
+    name = "Bearer Control Mode"
+    fields_desc = [ByteEnumField("ietype", 184, IEType),
+                   ShortField("length", 1),
+                   ByteField("bearer_control_mode", 0)]
+
+
+class IE_EvolvedAllocationRetentionPriority(IE_Base):
+    name = "Evolved Allocation/Retention Priority"
+    fields_desc = [ByteEnumField("ietype", 191, IEType),
+                   ShortField("length", 1),
+                   BitField("Spare", 0, 1),
+                   BitField("PCI", 0, 1),
+                   XBitField("PL", 0x0000, 4),
+                   BitField("Spare", 0, 1),
+                   BitField("PVI", 0, 1)]
+
+
+class IE_CharginGatewayAddress(IE_Base):
+    name = "Chargin Gateway Address"
+    fields_desc = [ByteEnumField("ietype", 251, IEType),
+                   ShortField("length", 4),
+                   ConditionalField(IPField("ipv4_address", "127.0.0.1"),
+                                    lambda
+                                    pkt: pkt.length == 4),
+                   ConditionalField(IP6Field("ipv6_address", "::1"), lambda
+                                    pkt: pkt.length == 16)]
+
+
+class IE_PrivateExtension(IE_Base):
+    name = "Private Extension"
+    fields_desc = [ByteEnumField("ietype", 255, IEType),
+                   ShortField("length", 1),
+                   ByteField("extension identifier", 0),
+                   StrLenField("extention_value", "",
+                               length_from=lambda x: x.length)]
+
+
+class IE_ExtensionHeaderList(IE_Base):
+    name = "Extension Header List"
+    fields_desc = [ByteEnumField("ietype", 141, IEType),
+                   FieldLenField("length", None, length_of="extension_headers"),  # noqa: E501
+                   FieldListField("extension_headers", [64, 192], ByteField("", 0))]  # noqa: E501
+
+
+class IE_NotImplementedTLV(Packet):
+    name = "IE not implemented"
+    fields_desc = [ByteEnumField("ietype", 0, IEType),
+                   ShortField("length", None),
+                   StrLenField("data", "", length_from=lambda x: x.length)]
+
+    def extract_padding(self, pkt):
+        return "", pkt
+
+
+ietypecls = {1: IE_Cause,
+             2: IE_IMSI,
+             3: IE_Routing,
+             8: IE_ReorderingRequired,
+             14: IE_Recovery,
+             15: IE_SelectionMode,
+             16: IE_TEIDI,
+             17: IE_TEICP,
+             19: IE_Teardown,
+             20: IE_NSAPI,
+             26: IE_ChargingCharacteristics,
+             27: IE_TraceReference,
+             28: IE_TraceType,
+             127: IE_ChargingId,
+             128: IE_EndUserAddress,
+             131: IE_AccessPointName,
+             132: IE_ProtocolConfigurationOptions,
+             133: IE_GSNAddress,
+             134: IE_MSInternationalNumber,
+             135: IE_QoS,
+             141: IE_ExtensionHeaderList,
+             148: IE_CommonFlags,
+             149: IE_APNRestriction,
+             151: IE_RATType,
+             152: IE_UserLocationInformation,
+             153: IE_MSTimeZone,
+             154: IE_IMEI,
+             181: IE_MSInfoChangeReportingAction,
+             182: IE_DirectTunnelFlags,
+             184: IE_BearerControlMode,
+             191: IE_EvolvedAllocationRetentionPriority,
+             251: IE_CharginGatewayAddress,
+             255: IE_PrivateExtension}
+
+
+def IE_Dispatcher(s):
+    """Choose the correct Information Element class."""
+    if len(s) < 1:
+        return Raw(s)
+    # Get the IE type
+    ietype = orb(s[0])
+    cls = ietypecls.get(ietype, Raw)
+
+    # if ietype greater than 128 are TLVs
+    if cls == Raw and ietype & 128 == 128:
+        cls = IE_NotImplementedTLV
+    return cls(s)
+
+
+class GTPEchoResponse(Packet):
+    # 3GPP TS 29.060 V9.1.0 (2009-12)
+    name = "GTP Echo Response"
+    fields_desc = [PacketListField("IE_list", [], IE_Dispatcher)]
+
+    def hashret(self):
+        return struct.pack("H", self.seq)
+
+    def answers(self, other):
+        return self.seq == other.seq
+
+
+class GTPCreatePDPContextRequest(Packet):
+    # 3GPP TS 29.060 V9.1.0 (2009-12)
+    name = "GTP Create PDP Context Request"
+    fields_desc = [PacketListField("IE_list", [IE_TEIDI(), IE_NSAPI(), IE_GSNAddress(),  # noqa: E501
+                                               IE_GSNAddress(),
+                                               IE_NotImplementedTLV(ietype=135, length=15, data=RandString(15))],  # noqa: E501
+                                   IE_Dispatcher)]
+
+    def hashret(self):
+        return struct.pack("H", self.seq)
+
+
+class GTPCreatePDPContextResponse(Packet):
+    # 3GPP TS 29.060 V9.1.0 (2009-12)
+    name = "GTP Create PDP Context Response"
+    fields_desc = [PacketListField("IE_list", [], IE_Dispatcher)]
+
+    def hashret(self):
+        return struct.pack("H", self.seq)
+
+    def answers(self, other):
+        return self.seq == other.seq
+
+
+class GTPUpdatePDPContextRequest(Packet):
+    # 3GPP TS 29.060 V9.1.0 (2009-12)
+    name = "GTP Update PDP Context Request"
+    fields_desc = [PacketListField("IE_list", [
+        IE_Cause(),
+        IE_Recovery(),
+        IE_TEIDI(),
+        IE_TEICP(),
+        IE_ChargingId(),
+        IE_ProtocolConfigurationOptions(),
+        IE_GSNAddress(),
+        IE_GSNAddress(),
+        IE_GSNAddress(),
+        IE_GSNAddress(),
+        IE_QoS(),
+        IE_CharginGatewayAddress(),
+        IE_CharginGatewayAddress(),
+        IE_CommonFlags(),
+        IE_APNRestriction(),
+        IE_BearerControlMode(),
+        IE_MSInfoChangeReportingAction(),
+        IE_EvolvedAllocationRetentionPriority(),
+        IE_PrivateExtension()],
+        IE_Dispatcher)]
+
+    def hashret(self):
+        return struct.pack("H", self.seq)
+
+
+class GTPUpdatePDPContextResponse(Packet):
+    # 3GPP TS 29.060 V9.1.0 (2009-12)
+    name = "GTP Update PDP Context Response"
+    fields_desc = [PacketListField("IE_list", None, IE_Dispatcher)]
+
+    def hashret(self):
+        return struct.pack("H", self.seq)
+
+
+class GTPErrorIndication(Packet):
+    # 3GPP TS 29.060 V9.1.0 (2009-12)
+    name = "GTP Error Indication"
+    fields_desc = [PacketListField("IE_list", [], IE_Dispatcher)]
+
+
+class GTPDeletePDPContextRequest(Packet):
+    # 3GPP TS 29.060 V9.1.0 (2009-12)
+    name = "GTP Delete PDP Context Request"
+    fields_desc = [PacketListField("IE_list", [], IE_Dispatcher)]
+
+
+class GTPDeletePDPContextResponse(Packet):
+    # 3GPP TS 29.060 V9.1.0 (2009-12)
+    name = "GTP Delete PDP Context Response"
+    fields_desc = [PacketListField("IE_list", [], IE_Dispatcher)]
+
+
+class GTPPDUNotificationRequest(Packet):
+    # 3GPP TS 29.060 V9.1.0 (2009-12)
+    name = "GTP PDU Notification Request"
+    fields_desc = [PacketListField("IE_list", [IE_IMSI(),
+                                               IE_TEICP(TEICI=RandInt()),
+                                               IE_EndUserAddress(PDPTypeNumber=0x21),  # noqa: E501
+                                               IE_AccessPointName(),
+                                               IE_GSNAddress(address="127.0.0.1"),  # noqa: E501
+                                               ], IE_Dispatcher)]
+
+
+class GTPSupportedExtensionHeadersNotification(Packet):
+    name = "GTP Supported Extension Headers Notification"
+    fields_desc = [PacketListField("IE_list", [IE_ExtensionHeaderList(),
+                                               ], IE_Dispatcher)]
+
+
+class GTPmorethan1500(Packet):
+    # 3GPP TS 29.060 V9.1.0 (2009-12)
+    name = "GTP More than 1500"
+    fields_desc = [ByteEnumField("IE_Cause", "Cause", IEType),
+                   BitField("IE", 1, 12000), ]
+
+
+# Bind GTP-C
+bind_layers(UDP, GTPHeader, dport=2123)
+bind_layers(UDP, GTPHeader, sport=2123)
+bind_layers(GTPHeader, GTPEchoRequest, gtp_type=1, S=1)
+bind_layers(GTPHeader, GTPEchoResponse, gtp_type=2, S=1)
+bind_layers(GTPHeader, GTPCreatePDPContextRequest, gtp_type=16)
+bind_layers(GTPHeader, GTPCreatePDPContextResponse, gtp_type=17)
+bind_layers(GTPHeader, GTPUpdatePDPContextRequest, gtp_type=18)
+bind_layers(GTPHeader, GTPUpdatePDPContextResponse, gtp_type=19)
+bind_layers(GTPHeader, GTPDeletePDPContextRequest, gtp_type=20)
+bind_layers(GTPHeader, GTPDeletePDPContextResponse, gtp_type=21)
+bind_layers(GTPHeader, GTPPDUNotificationRequest, gtp_type=27)
+bind_layers(GTPHeader, GTPSupportedExtensionHeadersNotification, gtp_type=31, S=1)  # noqa: E501
+bind_layers(GTPHeader, GTP_UDPPort_ExtensionHeader, next_ex=64, E=1)
+bind_layers(GTPHeader, GTP_PDCP_PDU_ExtensionHeader, next_ex=192, E=1)
+
+# Bind GTP-U
+bind_layers(UDP, GTP_U_Header, dport=2152)
+bind_layers(UDP, GTP_U_Header, sport=2152)
+bind_layers(GTP_U_Header, GTPErrorIndication, gtp_type=26, S=1)
+bind_layers(GTP_U_Header, IP, gtp_type=255)
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [dts] [PATCH V1 2/2] dep/add gtp_v2 for the advanced rss feature to support gtp_v2 packets in CVL
  2019-12-31 12:07 [dts] [PATCH V1 1/2] dep/add gtp for the advanced rss feature support gtp packets in CVL zhiwei.he
@ 2019-12-31 12:07 ` " zhiwei.he
  2020-01-02  5:32 ` [dts] [PATCH V1 1/2] dep/add gtp for the advanced rss feature support gtp " Tu, Lijuan
  1 sibling, 0 replies; 3+ messages in thread
From: zhiwei.he @ 2019-12-31 12:07 UTC (permalink / raw)
  To: dts; +Cc: zhiwei.he

From: "zhiwei.he" <zhiwei.he@intel.com>

Signed-off-by: zhiwei.he <zhiwei.he@intel.com>
---
 dep/gtp_v2.py | 936 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 936 insertions(+)
 create mode 100644 dep/gtp_v2.py

diff --git a/dep/gtp_v2.py b/dep/gtp_v2.py
new file mode 100644
index 0000000..af94918
--- /dev/null
+++ b/dep/gtp_v2.py
@@ -0,0 +1,936 @@
+#! /usr/bin/env python
+
+# Copyright (C) 2017 Alessio Deiana <adeiana@gmail.com>
+# 2017 Alexis Sultan <alexis.sultan@sfr.com>
+
+# This file is part of Scapy
+# Scapy is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 2 of the License, or
+# any later version.
+#
+# Scapy is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Scapy. If not, see <http://www.gnu.org/licenses/>.
+
+# scapy.contrib.description = GPRS Tunneling Protocol v2 (GTPv2)
+# scapy.contrib.status = loads
+
+import struct
+
+
+from scapy.compat import orb
+from scapy.fields import BitEnumField, BitField, ByteEnumField, ByteField, \
+    ConditionalField, IntField, IPField, LongField, PacketField, \
+    PacketListField, ShortEnumField, ShortField, StrFixedLenField, \
+    StrLenField, ThreeBytesField, XBitField, XIntField, XShortField
+from scapy.packet import bind_layers, Packet, Raw
+from scapy.volatile import RandIP, RandShort
+
+
+from scapy.contrib import gtp
+
+
+RATType = {
+    6: "EUTRAN",
+}
+
+GTPmessageType = {1: "echo_request",
+                     2: "echo_response",
+                     32: "create_session_req",
+                     33: "create_session_res",
+                     34: "modify_bearer_req",
+                     35: "modify_bearer_res",
+                     36: "delete_session_req",
+                     37: "delete_session_res",
+                     70: "downlink_data_notif_failure_indic",
+                     170: "realease_bearers_req",
+                     171: "realease_bearers_res",
+                     176: "downlink_data_notif",
+                     177: "downlink_data_notif_ack",
+                  }
+
+IEType = {1: "IMSI",
+             2: "Cause",
+             3: "Recovery Restart",
+             71: "APN",
+             72: "AMBR",
+             73: "EPS Bearer ID",
+             74: "IPv4",
+             75: "MEI",
+             76: "MSISDN",
+             77: "Indication",
+             78: "Protocol Configuration Options",
+             79: "PAA",
+             80: "Bearer QoS",
+             82: "RAT",
+             83: "Serving Network",
+             86: "ULI",
+             87: "F-TEID",
+             93: "Bearer Context",
+             94: "Charging ID",
+             95: "Charging Characteristics",
+             99: "PDN Type",
+             114: "UE Time zone",
+             126: "Port Number",
+             127: "APN Restriction",
+             128: "Selection Mode",
+             161: "Max MBR/APN-AMBR (MMBR)"
+          }
+
+CauseValues = {
+    16: "Request Accepted",
+}
+
+
+class GTPHeader(Packet):
+    # 3GPP TS 29.060 V9.1.0 (2009-12)
+    # without the version
+    name = "GTP v2 Header"
+    fields_desc = [BitField("version", 2, 3),
+                   BitField("P", 1, 1),
+                   BitField("T", 1, 1),
+                   BitField("SPARE", 0, 1),
+                   BitField("SPARE", 0, 1),
+                   BitField("SPARE", 0, 1),
+                   ByteEnumField("gtp_type", None, GTPmessageType),
+                   ShortField("length", None),
+                   ConditionalField(IntField("teid", 0),
+                                    lambda pkt:pkt.T == 1),
+                   ThreeBytesField("seq", RandShort()),
+                   ByteField("SPARE", 0)
+                   ]
+
+    def post_build(self, p, pay):
+        p += pay
+        if self.length is None:
+            tmp_len = len(p) - 8
+            p = p[:2] + struct.pack("!H", tmp_len) + p[4:]
+        return p
+
+    def hashret(self):
+        return struct.pack("B", self.version) + self.payload.hashret()
+
+    def answers(self, other):
+        return (isinstance(other, GTPHeader) and
+                self.version == other.version and
+                self.payload.answers(other.payload))
+
+
+class IE_IPv4(gtp.IE_Base):
+    name = "IE IPv4"
+    fields_desc = [ByteEnumField("ietype", 74, IEType),
+                   ShortField("length", 0),
+                   BitField("CR_flag", 0, 4),
+                   BitField("instance", 0, 4),
+                   IPField("address", RandIP())]
+
+
+class IE_MEI(gtp.IE_Base):
+    name = "IE MEI"
+    fields_desc = [ByteEnumField("ietype", 75, IEType),
+                   ShortField("length", 0),
+                   BitField("CR_flag", 0, 4),
+                   BitField("instance", 0, 4),
+                   LongField("MEI", 0)]
+
+
+def IE_Dispatcher(s):
+    """Choose the correct Information Element class."""
+
+    # Get the IE type
+    ietype = orb(s[0])
+    cls = ietypecls.get(ietype, Raw)
+
+    # if ietype greater than 128 are TLVs
+    if cls is Raw and ietype > 128:
+        cls = IE_NotImplementedTLV
+
+    return cls(s)
+
+
+class IE_EPSBearerID(gtp.IE_Base):
+    name = "IE EPS Bearer ID"
+    fields_desc = [ByteEnumField("ietype", 73, IEType),
+                   ShortField("length", 0),
+                   BitField("CR_flag", 0, 4),
+                   BitField("instance", 0, 4),
+                   ByteField("EBI", 0)]
+
+
+class IE_RAT(gtp.IE_Base):
+    name = "IE RAT"
+    fields_desc = [ByteEnumField("ietype", 82, IEType),
+                   ShortField("length", 0),
+                   BitField("CR_flag", 0, 4),
+                   BitField("instance", 0, 4),
+                   ByteEnumField("RAT_type", None, RATType)]
+
+
+class IE_ServingNetwork(gtp.IE_Base):
+    name = "IE Serving Network"
+    fields_desc = [ByteEnumField("ietype", 83, IEType),
+                   ShortField("length", 0),
+                   BitField("CR_flag", 0, 4),
+                   BitField("instance", 0, 4),
+                   gtp.TBCDByteField("MCC", "", 2),
+                   gtp.TBCDByteField("MNC", "", 1)]
+
+
+class ULI_RAI(gtp.IE_Base):
+    name = "IE Tracking Area Identity"
+    fields_desc = [
+        gtp.TBCDByteField("MCC", "", 2),
+        # MNC: if the third digit of MCC is 0xf, then the length of
+        # MNC is 1 byte
+        gtp.TBCDByteField("MNC", "", 1),
+        ShortField("LAC", 0),
+        ShortField("RAC", 0)]
+
+
+class ULI_SAI(gtp.IE_Base):
+    name = "IE Tracking Area Identity"
+    fields_desc = [
+        gtp.TBCDByteField("MCC", "", 2),
+        gtp.TBCDByteField("MNC", "", 1),
+        ShortField("LAC", 0),
+        ShortField("SAC", 0)]
+
+
+class ULI_TAI(gtp.IE_Base):
+    name = "IE Tracking Area Identity"
+    fields_desc = [
+        gtp.TBCDByteField("MCC", "", 2),
+        gtp.TBCDByteField("MNC", "", 1),
+        ShortField("TAC", 0)]
+
+
+class ULI_ECGI(gtp.IE_Base):
+    name = "IE E-UTRAN Cell Identifier"
+    fields_desc = [
+        gtp.TBCDByteField("MCC", "", 2),
+        gtp.TBCDByteField("MNC", "", 1),
+        BitField("SPARE", 0, 4),
+        BitField("ECI", 0, 28)]
+
+
+class IE_ULI(gtp.IE_Base):
+    name = "IE ULI"
+    fields_desc = [ByteEnumField("ietype", 86, IEType),
+                   ShortField("length", 0),
+                   BitField("CR_flag", 0, 4),
+                   BitField("instance", 0, 4),
+                   BitField("SPARE", 0, 2),
+                   BitField("LAI_Present", 0, 1),
+                   BitField("ECGI_Present", 0, 1),
+                   BitField("TAI_Present", 0, 1),
+                   BitField("RAI_Present", 0, 1),
+                   BitField("SAI_Present", 0, 1),
+                   BitField("CGI_Present", 0, 1),
+                   ConditionalField(
+        PacketField("SAI", 0, ULI_SAI), lambda pkt: bool(pkt.SAI_Present)),
+        ConditionalField(
+        PacketField("RAI", 0, ULI_RAI), lambda pkt: bool(pkt.RAI_Present)),
+        ConditionalField(
+        PacketField("TAI", 0, ULI_TAI), lambda pkt: bool(pkt.TAI_Present)),
+        ConditionalField(PacketField("ECGI", 0, ULI_ECGI),
+                         lambda pkt: bool(pkt.ECGI_Present))]
+
+
+class IE_FTEID(gtp.IE_Base):
+    name = "IE F-TEID"
+    fields_desc = [ByteEnumField("ietype", 87, IEType),
+                   ShortField("length", 0),
+                   BitField("CR_flag", 0, 4),
+                   BitField("instance", 0, 4),
+                   BitField("ipv4_present", 0, 1),
+                   BitField("ipv6_present", 0, 1),
+                   BitField("InterfaceType", 0, 6),
+                   XIntField("GRE_Key", 0),
+                   ConditionalField(
+        IPField("ipv4", RandIP()), lambda pkt: pkt.ipv4_present),
+        ConditionalField(XBitField("ipv6", "2001::", 128),
+                         lambda pkt: pkt.ipv6_present)]
+
+
+class IE_BearerContext(gtp.IE_Base):
+    name = "IE Bearer Context"
+    fields_desc = [ByteEnumField("ietype", 93, IEType),
+                   ShortField("length", 0),
+                   BitField("CR_flag", 0, 4),
+                   BitField("instance", 0, 4),
+                   PacketListField("IE_list", None, IE_Dispatcher,
+                                   length_from=lambda pkt: pkt.length)]
+
+
+class IE_NotImplementedTLV(gtp.IE_Base):
+    name = "IE not implemented"
+    fields_desc = [ByteEnumField("ietype", 0, IEType),
+                   ShortField("length", None),
+                   StrLenField("data", "", length_from=lambda x: x.length)]
+
+
+class IE_IMSI(gtp.IE_Base):
+    name = "IE IMSI"
+    fields_desc = [ByteEnumField("ietype", 1, IEType),
+                   ShortField("length", None),
+                   BitField("CR_flag", 0, 4),
+                   BitField("instance", 0, 4),
+                   gtp.TBCDByteField("IMSI", "33607080910",
+                                     length_from=lambda x: x.length)]
+
+
+class IE_Cause(gtp.IE_Base):
+    name = "IE Cause"
+    fields_desc = [ByteEnumField("ietype", 2, IEType),
+                   ShortField("length", None),
+                   BitField("CR_flag", 0, 4),
+                   BitField("instance", 0, 4),
+                   ByteEnumField("Cause", 1, CauseValues),
+                   BitField("SPARE", 0, 5),
+                   BitField("PCE", 0, 1),
+                   BitField("BCE", 0, 1),
+                   BitField("CS", 0, 1)]
+
+
+class IE_RecoveryRestart(gtp.IE_Base):
+    name = "IE Recovery Restart"
+    fields_desc = [ByteEnumField("ietype", 3, IEType),
+                   ShortField("length", None),
+                   BitField("CR_flag", 0, 4),
+                   BitField("instance", 0, 4),
+                   ByteField("restart_counter", 0)]
+
+
+class IE_APN(gtp.IE_Base):
+    name = "IE APN"
+    fields_desc = [ByteEnumField("ietype", 71, IEType),
+                   ShortField("length", None),
+                   BitField("CR_flag", 0, 4),
+                   BitField("instance", 0, 4),
+                   gtp.APNStrLenField("APN", "internet",
+                                      length_from=lambda x: x.length)]
+
+
+class IE_AMBR(gtp.IE_Base):
+    name = "IE AMBR"
+    fields_desc = [ByteEnumField("ietype", 72, IEType),
+                   ShortField("length", None),
+                   BitField("CR_flag", 0, 4),
+                   BitField("instance", 0, 4),
+                   IntField("AMBR_Uplink", 0),
+                   IntField("AMBR_Downlink", 0)]
+
+
+class IE_MSISDN(gtp.IE_Base):
+    name = "IE MSISDN"
+    fields_desc = [ByteEnumField("ietype", 76, IEType),
+                   ShortField("length", None),
+                   BitField("CR_flag", 0, 4),
+                   BitField("instance", 0, 4),
+                   gtp.TBCDByteField("digits", "33123456789",
+                                     length_from=lambda x: x.length)]
+
+
+class IE_Indication(gtp.IE_Base):
+    name = "IE Cause"
+    fields_desc = [ByteEnumField("ietype", 77, IEType),
+                   ShortField("length", None),
+                   BitField("CR_flag", 0, 4),
+                   BitField("instance", 0, 4),
+                   BitField("DAF", 0, 1),
+                   BitField("DTF", 0, 1),
+                   BitField("HI", 0, 1),
+                   BitField("DFI", 0, 1),
+                   BitField("OI", 0, 1),
+                   BitField("ISRSI", 0, 1),
+                   BitField("ISRAI", 0, 1),
+                   BitField("SGWCI", 0, 1),
+                   BitField("SQCI", 0, 1),
+                   BitField("UIMSI", 0, 1),
+                   BitField("CFSI", 0, 1),
+                   BitField("CRSI", 0, 1),
+                   BitField("PS", 0, 1),
+                   BitField("PT", 0, 1),
+                   BitField("SI", 0, 1),
+                   BitField("MSV", 0, 1),
+
+                   ConditionalField(
+                       BitField("RetLoc", 0, 1), lambda pkt: pkt.length > 2),
+                   ConditionalField(
+                       BitField("PBIC", 0, 1), lambda pkt: pkt.length > 2),
+                   ConditionalField(
+                       BitField("SRNI", 0, 1), lambda pkt: pkt.length > 2),
+                   ConditionalField(
+                       BitField("S6AF", 0, 1), lambda pkt: pkt.length > 2),
+                   ConditionalField(
+                       BitField("S4AF", 0, 1), lambda pkt: pkt.length > 2),
+                   ConditionalField(
+                       BitField("MBMDT", 0, 1), lambda pkt: pkt.length > 2),
+                   ConditionalField(
+                       BitField("ISRAU", 0, 1), lambda pkt: pkt.length > 2),
+                   ConditionalField(
+                       BitField("CCRSI", 0, 1), lambda pkt: pkt.length > 2),
+
+                   ConditionalField(
+        BitField("CPRAI", 0, 1), lambda pkt: pkt.length > 3),
+        ConditionalField(
+        BitField("ARRL", 0, 1), lambda pkt: pkt.length > 3),
+        ConditionalField(
+        BitField("PPOFF", 0, 1), lambda pkt: pkt.length > 3),
+        ConditionalField(
+        BitField("PPON", 0, 1), lambda pkt: pkt.length > 3),
+        ConditionalField(
+        BitField("PPSI", 0, 1), lambda pkt: pkt.length > 3),
+        ConditionalField(
+        BitField("CSFBI", 0, 1), lambda pkt: pkt.length > 3),
+        ConditionalField(
+        BitField("CLII", 0, 1), lambda pkt: pkt.length > 3),
+        ConditionalField(
+        BitField("CPSR", 0, 1), lambda pkt: pkt.length > 3),
+
+    ]
+
+
+PDN_TYPES = {
+    1: "IPv4",
+    2: "IPv6",
+    3: "IPv4/IPv6",
+}
+
+PCO_OPTION_TYPES = {
+    3: "IPv4",
+    129: "Primary DNS Server IP address",
+    130: "Primary NBNS Server IP address",
+    131: "Secondary DNS Server IP address",
+    132: "Secondary NBNS Server IP address",
+}
+
+
+class PCO_Option(Packet):
+    def extract_padding(self, pkt):
+        return "", pkt
+
+
+class PCO_IPv4(PCO_Option):
+    name = "IPv4"
+    fields_desc = [ByteEnumField("type", None, PCO_OPTION_TYPES),
+                   ByteField("length", 0),
+                   IPField("address", RandIP())]
+
+
+class PCO_Primary_DNS(PCO_Option):
+    name = "Primary DNS Server IP Address"
+    fields_desc = [ByteEnumField("type", None, PCO_OPTION_TYPES),
+                   ByteField("length", 0),
+                   IPField("address", RandIP())]
+
+
+class PCO_Primary_NBNS(PCO_Option):
+    name = "Primary DNS Server IP Address"
+    fields_desc = [ByteEnumField("type", None, PCO_OPTION_TYPES),
+                   ByteField("length", 0),
+                   IPField("address", RandIP())]
+
+
+class PCO_Secondary_DNS(PCO_Option):
+    name = "Secondary DNS Server IP Address"
+    fields_desc = [ByteEnumField("type", None, PCO_OPTION_TYPES),
+                   ByteField("length", 0),
+                   IPField("address", RandIP())]
+
+
+class PCO_Secondary_NBNS(PCO_Option):
+    name = "Secondary NBNS Server IP Address"
+    fields_desc = [ByteEnumField("type", None, PCO_OPTION_TYPES),
+                   ByteField("length", 0),
+                   IPField("address", RandIP())]
+
+
+PCO_PROTOCOL_TYPES = {
+    0x0001: 'P-CSCF IPv6 Address Request',
+    0x0003: 'DNS Server IPv6 Address Request',
+    0x0005: 'MS Support of Network Requested Bearer Control indicator',
+    0x000a: 'IP Allocation via NAS',
+    0x000d: 'DNS Server IPv4 Address Request',
+    0x000c: 'P-CSCF IPv4 Address Request',
+    0x0010: 'IPv4 Link MTU Request',
+    0x8021: 'IPCP',
+    0xc023: 'Password Authentication Protocol',
+    0xc223: 'Challenge Handshake Authentication Protocol',
+}
+
+PCO_OPTION_CLASSES = {
+    3: PCO_IPv4,
+    129: PCO_Primary_DNS,
+    130: PCO_Primary_NBNS,
+    131: PCO_Secondary_DNS,
+    132: PCO_Secondary_NBNS,
+}
+
+
+def PCO_option_dispatcher(s):
+    """Choose the correct PCO element."""
+    option = orb(s[0])
+
+    cls = PCO_OPTION_CLASSES.get(option, Raw)
+    return cls(s)
+
+
+def len_options(pkt):
+    return pkt.length - 4 if pkt.length else 0
+
+
+class PCO_P_CSCF_IPv6_Address_Request(PCO_Option):
+    name = "PCO PCO-P CSCF IPv6 Address Request"
+    fields_desc = [ShortEnumField("type", None, PCO_PROTOCOL_TYPES),
+                   ByteField("length", 0),
+                   ConditionalField(XBitField("address",
+                                              "2001:db8:0:42::", 128),
+                                    lambda pkt: pkt.length)]
+
+
+class PCO_DNS_Server_IPv6(PCO_Option):
+    name = "PCO DNS Server IPv6 Address Request"
+    fields_desc = [ShortEnumField("type", None, PCO_PROTOCOL_TYPES),
+                   ByteField("length", 0),
+                   ConditionalField(XBitField("address",
+                                              "2001:db8:0:42::", 128),
+                                    lambda pkt: pkt.length)]
+
+
+class PCO_SOF(PCO_Option):
+    name = "PCO MS Support of Network Requested Bearer Control indicator"
+    fields_desc = [ShortEnumField("type", None, PCO_PROTOCOL_TYPES),
+                   ByteField("length", 0),
+                   ]
+
+
+class PCO_PPP(PCO_Option):
+    name = "PPP IP Control Protocol"
+    fields_desc = [ByteField("Code", 0),
+                   ByteField("Identifier", 0),
+                   ShortField("length", 0),
+                   PacketListField("Options", None, PCO_option_dispatcher,
+                                   length_from=len_options)]
+
+    def extract_padding(self, pkt):
+        return "", pkt
+
+
+class PCO_IP_Allocation_via_NAS(PCO_Option):
+    name = "PCO IP Address allocation via NAS Signaling"
+    fields_desc = [ShortEnumField("type", None, PCO_PROTOCOL_TYPES),
+                   ByteField("length", 0),
+                   PacketListField("Options", None, PCO_option_dispatcher,
+                                   length_from=len_options)]
+
+
+class PCO_P_CSCF_IPv4_Address_Request(PCO_Option):
+    name = "PCO PCO-P CSCF IPv4 Address Request"
+    fields_desc = [ShortEnumField("type", None, PCO_PROTOCOL_TYPES),
+                   ByteField("length", 0),
+                   ConditionalField(IPField("address", RandIP()),
+                                    lambda pkt: pkt.length)]
+
+
+class PCO_DNS_Server_IPv4(PCO_Option):
+    name = "PCO DNS Server IPv4 Address Request"
+    fields_desc = [ShortEnumField("type", None, PCO_PROTOCOL_TYPES),
+                   ByteField("length", 0),
+                   ConditionalField(IPField("address", RandIP()),
+                                    lambda pkt: pkt.length)]
+
+
+class PCO_IPv4_Link_MTU_Request(PCO_Option):
+    name = "PCO IPv4 Link MTU Request"
+    fields_desc = [ShortEnumField("type", None, PCO_PROTOCOL_TYPES),
+                   ByteField("length", 0),
+                   ConditionalField(ShortField("MTU_size", 1500),
+                                    lambda pkt: pkt.length)]
+
+
+class PCO_IPCP(PCO_Option):
+    name = "PCO Internet Protocol Control Protocol"
+    fields_desc = [ShortEnumField("type", None, PCO_PROTOCOL_TYPES),
+                   ByteField("length", 0),
+                   PacketField("PPP", None, PCO_PPP)]
+
+
+class PCO_PPP_Auth(PCO_Option):
+    name = "PPP Password Authentication Protocol"
+    fields_desc = [ByteField("Code", 0),
+                   ByteField("Identifier", 0),
+                   ShortField("length", 0),
+                   ByteField("PeerID_length", 0),
+                   ConditionalField(StrFixedLenField(
+                       "PeerID",
+                       "",
+                       length_from=lambda pkt: pkt.PeerID_length),
+                       lambda pkt: pkt.PeerID_length),
+                   ByteField("Password_length", 0),
+                   ConditionalField(
+                       StrFixedLenField(
+                           "Password",
+                           "",
+                           length_from=lambda pkt: pkt.Password_length),
+                       lambda pkt: pkt.Password_length)]
+
+
+class PCO_PasswordAuthentificationProtocol(PCO_Option):
+    name = "PCO Password Authentication Protocol"
+    fields_desc = [ShortEnumField("type", None, PCO_PROTOCOL_TYPES),
+                   ByteField("length", 0),
+                   PacketField("PPP", None, PCO_PPP_Auth)]
+
+
+class PCO_PPP_Challenge(PCO_Option):
+    name = "PPP Password Authentication Protocol"
+    fields_desc = [ByteField("Code", 0),
+                   ByteField("Identifier", 0),
+                   ShortField("length", 0),
+                   ByteField("value_size", 0),
+                   ConditionalField(StrFixedLenField(
+                       "value", "",
+                       length_from=lambda pkt: pkt.value_size),
+                       lambda pkt: pkt.value_size),
+                   ConditionalField(StrFixedLenField(
+                       "name", "",
+                       length_from=lambda pkt: pkt.length - pkt.value_size - 5),  # noqa: E501
+                       lambda pkt: pkt.length)]
+
+
+class PCO_ChallengeHandshakeAuthenticationProtocol(PCO_Option):
+    name = "PCO Password Authentication Protocol"
+    fields_desc = [ShortEnumField("type", None, PCO_PROTOCOL_TYPES),
+                   ByteField("length", 0),
+                   PacketField("PPP", None, PCO_PPP_Challenge)]
+
+
+PCO_PROTOCOL_CLASSES = {
+    0x0001: PCO_P_CSCF_IPv6_Address_Request,
+    0x0003: PCO_DNS_Server_IPv6,
+    0x0005: PCO_SOF,
+    0x000a: PCO_IP_Allocation_via_NAS,
+    0x000c: PCO_P_CSCF_IPv4_Address_Request,
+    0x000d: PCO_DNS_Server_IPv4,
+    0x0010: PCO_IPv4_Link_MTU_Request,
+    0x8021: PCO_IPCP,
+    0xc023: PCO_PasswordAuthentificationProtocol,
+    0xc223: PCO_ChallengeHandshakeAuthenticationProtocol,
+}
+
+
+def PCO_protocol_dispatcher(s):
+    """Choose the correct PCO element."""
+    proto_num = orb(s[0]) * 256 + orb(s[1])
+    cls = PCO_PROTOCOL_CLASSES.get(proto_num, Raw)
+    return cls(s)
+
+
+class IE_PCO(gtp.IE_Base):
+    name = "IE Protocol Configuration Options"
+    fields_desc = [ByteEnumField("ietype", 78, IEType),
+                   ShortField("length", None),
+                   BitField("CR_flag", 0, 4),
+                   BitField("instance", 0, 4),
+                   BitField("Extension", 0, 1),
+                   BitField("SPARE", 0, 4),
+                   BitField("PPP", 0, 3),
+                   PacketListField("Protocols", None, PCO_protocol_dispatcher,
+                                   length_from=lambda pkt: pkt.length - 1)]
+
+
+class IE_PAA(gtp.IE_Base):
+    name = "IE PAA"
+    fields_desc = [ByteEnumField("ietype", 79, IEType),
+                   ShortField("length", None),
+                   BitField("CR_flag", 0, 4),
+                   BitField("instance", 0, 4),
+                   BitField("SPARE", 0, 5),
+                   BitEnumField("PDN_type", None, 3, PDN_TYPES),
+                   ConditionalField(
+                       ByteField("ipv6_prefix_length", 8),
+                       lambda pkt: pkt.PDN_type in (2, 3)),
+                   ConditionalField(
+                       XBitField("ipv6", "2001:db8:0:42::", 128),
+                       lambda pkt: pkt.PDN_type in (2, 3)),
+                   ConditionalField(
+                       IPField("ipv4", 0), lambda pkt: pkt.PDN_type in (1, 3)),
+                   ]
+
+
+class IE_Bearer_QoS(gtp.IE_Base):
+    name = "IE Bearer Quality of Service"
+    fields_desc = [ByteEnumField("ietype", 80, IEType),
+                   ShortField("length", None),
+                   BitField("CR_flag", 0, 4),
+                   BitField("instance", 0, 4),
+                   BitField("SPARE", 0, 1),
+                   BitField("PCI", 0, 1),
+                   BitField("PriorityLevel", 0, 4),
+                   BitField("SPARE", 0, 1),
+                   BitField("PVI", 0, 1),
+                   ByteField("QCI", 0),
+                   BitField("MaxBitRateForUplink", 0, 40),
+                   BitField("MaxBitRateForDownlink", 0, 40),
+                   BitField("GuaranteedBitRateForUplink", 0, 40),
+                   BitField("GuaranteedBitRateForDownlink", 0, 40)]
+
+
+class IE_ChargingID(gtp.IE_Base):
+    name = "IE Charging ID"
+    fields_desc = [ByteEnumField("ietype", 94, IEType),
+                   ShortField("length", None),
+                   BitField("CR_flag", 0, 4),
+                   BitField("instance", 0, 4),
+                   IntField("ChargingID", 0)]
+
+
+class IE_ChargingCharacteristics(gtp.IE_Base):
+    name = "IE Charging ID"
+    fields_desc = [ByteEnumField("ietype", 95, IEType),
+                   ShortField("length", None),
+                   BitField("CR_flag", 0, 4),
+                   BitField("instance", 0, 4),
+                   XShortField("ChargingCharacteristric", 0)]
+
+
+class IE_PDN_type(gtp.IE_Base):
+    name = "IE PDN Type"
+    fields_desc = [ByteEnumField("ietype", 99, IEType),
+                   ShortField("length", None),
+                   BitField("CR_flag", 0, 4),
+                   BitField("instance", 0, 4),
+                   BitField("SPARE", 0, 5),
+                   BitEnumField("PDN_type", None, 3, PDN_TYPES)]
+
+
+class IE_UE_Timezone(gtp.IE_Base):
+    name = "IE UE Time zone"
+    fields_desc = [ByteEnumField("ietype", 114, IEType),
+                   ShortField("length", None),
+                   BitField("CR_flag", 0, 4),
+                   BitField("instance", 0, 4),
+                   ByteField("Timezone", 0),
+                   ByteField("DST", 0)]
+
+
+class IE_Port_Number(gtp.IE_Base):
+    name = "IE Port Number"
+    fields_desc = [ByteEnumField("ietype", 126, IEType),
+                   ShortField("length", 2),
+                   BitField("CR_flag", 0, 4),
+                   BitField("instance", 0, 4),
+                   ShortField("PortNumber", RandShort())]
+
+
+class IE_APN_Restriction(gtp.IE_Base):
+    name = "IE APN Restriction"
+    fields_desc = [ByteEnumField("ietype", 127, IEType),
+                   ShortField("length", None),
+                   BitField("CR_flag", 0, 4),
+                   BitField("instance", 0, 4),
+                   ByteField("APN_Restriction", 0)]
+
+
+class IE_SelectionMode(gtp.IE_Base):
+    name = "IE Selection Mode"
+    fields_desc = [ByteEnumField("ietype", 128, IEType),
+                   ShortField("length", None),
+                   BitField("CR_flag", 0, 4),
+                   BitField("instance", 0, 4),
+                   BitField("SPARE", 0, 6),
+                   BitField("SelectionMode", 0, 2)]
+
+
+class IE_MMBR(gtp.IE_Base):
+    name = "IE Max MBR/APN-AMBR (MMBR)"
+    fields_desc = [ByteEnumField("ietype", 72, IEType),
+                   ShortField("length", None),
+                   BitField("CR_flag", 0, 4),
+                   BitField("instance", 0, 4),
+                   IntField("uplink_rate", 0),
+                   IntField("downlink_rate", 0)]
+
+
+ietypecls = {1: IE_IMSI,
+             2: IE_Cause,
+             3: IE_RecoveryRestart,
+             71: IE_APN,
+             72: IE_AMBR,
+             73: IE_EPSBearerID,
+             74: IE_IPv4,
+             75: IE_MEI,
+             76: IE_MSISDN,
+             77: IE_Indication,
+             78: IE_PCO,
+             79: IE_PAA,
+             80: IE_Bearer_QoS,
+             82: IE_RAT,
+             83: IE_ServingNetwork,
+             86: IE_ULI,
+             87: IE_FTEID,
+             93: IE_BearerContext,
+             94: IE_ChargingID,
+             95: IE_ChargingCharacteristics,
+             99: IE_PDN_type,
+             114: IE_UE_Timezone,
+             126: IE_Port_Number,
+             127: IE_APN_Restriction,
+             128: IE_SelectionMode,
+             161: IE_MMBR}
+
+#
+# GTPv2 Commands
+# 3GPP TS 29.060 V9.1.0 (2009-12)
+#
+
+
+class GTPV2Command(Packet):
+    fields_desc = [PacketListField("IE_list", None, IE_Dispatcher)]
+
+
+class GTPV2EchoRequest(GTPV2Command):
+    name = "GTPv2 Echo Request"
+
+
+class GTPV2EchoResponse(GTPV2Command):
+    name = "GTPv2 Echo Response"
+
+
+class GTPV2CreateSessionRequest(GTPV2Command):
+    name = "GTPv2 Create Session Request"
+
+
+class GTPV2CreateSessionResponse(GTPV2Command):
+    name = "GTPv2 Create Session Response"
+
+
+class GTPV2DeleteSessionRequest(GTPV2Command):
+    name = "GTPv2 Delete Session Request"
+
+
+class GTPV2DeleteSessionResponse(GTPV2Command):
+    name = "GTPv2 Delete Session Request"
+
+
+class GTPV2ModifyBearerCommand(GTPV2Command):
+    name = "GTPv2 Modify Bearer Command"
+
+
+class GTPV2ModifyBearerFailureNotification(GTPV2Command):
+    name = "GTPv2 Modify Bearer Command"
+
+
+class GTPV2DownlinkDataNotifFailureIndication(GTPV2Command):
+    name = "GTPv2 Downlink Data Notification Failure Indication"
+
+
+class GTPV2ModifyBearerRequest(GTPV2Command):
+    name = "GTPv2 Modify Bearer Request"
+
+
+class GTPV2ModifyBearerResponse(GTPV2Command):
+    name = "GTPv2 Modify Bearer Response"
+
+
+class GTPV2UpdateBearerRequest(GTPV2Command):
+    name = "GTPv2 Update Bearer Request"
+
+
+class GTPV2UpdateBearerResponse(GTPV2Command):
+    name = "GTPv2 Update Bearer Response"
+
+
+class GTPV2DeleteBearerRequest(GTPV2Command):
+    name = "GTPv2 Delete Bearer Request"
+
+
+class GTPV2SuspendNotification(GTPV2Command):
+    name = "GTPv2 Suspend Notification"
+
+
+class GTPV2SuspendAcknowledge(GTPV2Command):
+    name = "GTPv2 Suspend Acknowledge"
+
+
+class GTPV2ResumeNotification(GTPV2Command):
+    name = "GTPv2 Resume Notification"
+
+
+class GTPV2ResumeAcknowledge(GTPV2Command):
+    name = "GTPv2 Resume Acknowledge"
+
+
+class GTPV2DeleteBearerResponse(GTPV2Command):
+    name = "GTPv2 Delete Bearer Response"
+
+
+class GTPV2CreateIndirectDataForwardingTunnelRequest(GTPV2Command):
+    name = "GTPv2 Create Indirect Data Forwarding Tunnel Request"
+
+
+class GTPV2CreateIndirectDataForwardingTunnelResponse(GTPV2Command):
+    name = "GTPv2 Create Indirect Data Forwarding Tunnel Response"
+
+
+class GTPV2DeleteIndirectDataForwardingTunnelRequest(GTPV2Command):
+    name = "GTPv2 Delete Indirect Data Forwarding Tunnel Request"
+
+
+class GTPV2DeleteIndirectDataForwardingTunnelResponse(GTPV2Command):
+    name = "GTPv2 Delete Indirect Data Forwarding Tunnel Response"
+
+
+class GTPV2ReleaseBearerRequest(GTPV2Command):
+    name = "GTPv2 Release Bearer Request"
+
+
+class GTPV2ReleaseBearerResponse(GTPV2Command):
+    name = "GTPv2 Release Bearer Response"
+
+
+class GTPV2DownlinkDataNotif(GTPV2Command):
+    name = "GTPv2 Download Data Notification"
+
+
+class GTPV2DownlinkDataNotifAck(GTPV2Command):
+    name = "GTPv2 Download Data Notification Acknowledgment"
+
+
+bind_layers(GTPHeader, GTPV2EchoRequest, gtp_type=1, T=0)
+bind_layers(GTPHeader, GTPV2EchoResponse, gtp_type=2, T=0)
+bind_layers(GTPHeader, GTPV2CreateSessionRequest, gtp_type=32)
+bind_layers(GTPHeader, GTPV2CreateSessionResponse, gtp_type=33)
+bind_layers(GTPHeader, GTPV2ModifyBearerRequest, gtp_type=34)
+bind_layers(GTPHeader, GTPV2ModifyBearerResponse, gtp_type=35)
+bind_layers(GTPHeader, GTPV2DeleteSessionRequest, gtp_type=36)
+bind_layers(GTPHeader, GTPV2DeleteSessionResponse, gtp_type=37)
+bind_layers(GTPHeader, GTPV2ModifyBearerCommand, gtp_type=64)
+bind_layers(GTPHeader, GTPV2ModifyBearerFailureNotification, gtp_type=65)
+bind_layers(GTPHeader, GTPV2DownlinkDataNotifFailureIndication, gtp_type=70)
+bind_layers(GTPHeader, GTPV2UpdateBearerRequest, gtp_type=97)
+bind_layers(GTPHeader, GTPV2UpdateBearerResponse, gtp_type=98)
+bind_layers(GTPHeader, GTPV2DeleteBearerRequest, gtp_type=99)
+bind_layers(GTPHeader, GTPV2DeleteBearerResponse, gtp_type=100)
+bind_layers(GTPHeader, GTPV2SuspendNotification, gtp_type=162)
+bind_layers(GTPHeader, GTPV2SuspendAcknowledge, gtp_type=163)
+bind_layers(GTPHeader, GTPV2ResumeNotification, gtp_type=164)
+bind_layers(GTPHeader, GTPV2ResumeAcknowledge, gtp_type=165)
+bind_layers(
+    GTPHeader, GTPV2CreateIndirectDataForwardingTunnelRequest, gtp_type=166)
+bind_layers(
+    GTPHeader, GTPV2CreateIndirectDataForwardingTunnelResponse, gtp_type=167)
+bind_layers(
+    GTPHeader, GTPV2DeleteIndirectDataForwardingTunnelRequest, gtp_type=168)
+bind_layers(
+    GTPHeader, GTPV2DeleteIndirectDataForwardingTunnelResponse, gtp_type=169)
+bind_layers(GTPHeader, GTPV2ReleaseBearerRequest, gtp_type=170)
+bind_layers(GTPHeader, GTPV2ReleaseBearerResponse, gtp_type=171)
+bind_layers(GTPHeader, GTPV2DownlinkDataNotif, gtp_type=176)
+bind_layers(GTPHeader, GTPV2DownlinkDataNotifAck, gtp_type=177)
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [dts] [PATCH V1 1/2] dep/add gtp for the advanced rss feature support gtp packets in CVL
  2019-12-31 12:07 [dts] [PATCH V1 1/2] dep/add gtp for the advanced rss feature support gtp packets in CVL zhiwei.he
  2019-12-31 12:07 ` [dts] [PATCH V1 2/2] dep/add gtp_v2 for the advanced rss feature to support gtp_v2 " zhiwei.he
@ 2020-01-02  5:32 ` " Tu, Lijuan
  1 sibling, 0 replies; 3+ messages in thread
From: Tu, Lijuan @ 2020-01-02  5:32 UTC (permalink / raw)
  To: He, Zhiwei, dts; +Cc: He, Zhiwei

Applied the series.

> -----Original Message-----
> From: dts [mailto:dts-bounces@dpdk.org] On Behalf Of zhiwei.he
> Sent: Tuesday, December 31, 2019 8:07 PM
> To: dts@dpdk.org
> Cc: He, Zhiwei <zhiwei.he@intel.com>
> Subject: [dts] [PATCH V1 1/2] dep/add gtp for the advanced rss feature
> support gtp packets in CVL
> 
> From: "zhiwei.he" <zhiwei.he@intel.com>
> 
> Signed-off-by: zhiwei.he <zhiwei.he@intel.com>
> ---
>  dep/gtp.py | 909
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 909 insertions(+)
>  create mode 100644 dep/gtp.py
> 
> diff --git a/dep/gtp.py b/dep/gtp.py
> new file mode 100644
> index 0000000..7d57789
> --- /dev/null
> +++ b/dep/gtp.py
> @@ -0,0 +1,909 @@
> +#! /usr/bin/env python
> +
> +# Copyright (C) 2018 Leonardo Monteiro <decastromonteiro@gmail.com>
> +#               2017 Alexis Sultan    <alexis.sultan@sfr.com>
> +#               2017 Alessio Deiana <adeiana@gmail.com>
> +#               2014 Guillaume Valadon <guillaume.valadon@ssi.gouv.fr>
> +#               2012 ffranz <ffranz@iniqua.com>
> +##
> +# This program is published under a GPLv2 license
> +
> +# scapy.contrib.description = GPRS Tunneling Protocol (GTP) #
> +scapy.contrib.status = loads
> +
> +from __future__ import absolute_import
> +import struct
> +
> +
> +from scapy.compat import chb, orb
> +from scapy.error import warning
> +from scapy.fields import BitEnumField, BitField, ByteEnumField, ByteField, \
> +    ConditionalField, FieldLenField, FieldListField, FlagsField, IntField, \
> +    IPField, PacketListField, ShortField, StrFixedLenField, StrLenField, \
> +    XBitField, XByteField, XIntField
> +from scapy.layers.inet import IP, UDP
> +from scapy.layers.inet6 import IP6Field from scapy.modules.six.moves
> +import range from scapy.packet import bind_layers, Packet, Raw from
> +scapy.volatile import RandInt, RandIP, RandNum, RandString
> +
> +
> +# GTP Data types
> +
> +RATType = {
> +    1: "UTRAN",
> +    2: "GETRAN",
> +    3: "WLAN",
> +    4: "GAN",
> +    5: "HSPA"
> +}
> +
> +GTPmessageType = {1: "echo_request",
> +                  2: "echo_response",
> +                  16: "create_pdp_context_req",
> +                  17: "create_pdp_context_res",
> +                  18: "update_pdp_context_req",
> +                  19: "update_pdp_context_resp",
> +                  20: "delete_pdp_context_req",
> +                  21: "delete_pdp_context_res",
> +                  26: "error_indication",
> +                  27: "pdu_notification_req",
> +                  31: "supported_extension_headers_notification",
> +                  254: "end_marker",
> +                  255: "g_pdu"}
> +
> +IEType = {1: "Cause",
> +             2: "IMSI",
> +             3: "RAI",
> +             4: "TLLI",
> +             5: "P_TMSI",
> +             8: "IE_ReorderingRequired",
> +          14: "Recovery",
> +          15: "SelectionMode",
> +          16: "TEIDI",
> +          17: "TEICP",
> +          19: "TeardownInd",
> +          20: "NSAPI",
> +          26: "ChargingChrt",
> +          27: "TraceReference",
> +          28: "TraceType",
> +          127: "ChargingId",
> +          128: "EndUserAddress",
> +          131: "AccessPointName",
> +          132: "ProtocolConfigurationOptions",
> +          133: "GSNAddress",
> +          134: "MSInternationalNumber",
> +          135: "QoS",
> +          148: "CommonFlags",
> +          149: "APNRestriction",
> +          151: "RatType",
> +          152: "UserLocationInformation",
> +          153: "MSTimeZone",
> +          154: "IMEI",
> +          181: "MSInfoChangeReportingAction",
> +          184: "BearerControlMode",
> +          191: "EvolvedAllocationRetentionPriority",
> +          255: "PrivateExtention"}
> +
> +CauseValues = {0: "Request IMSI",
> +               1: "Request IMEI",
> +               2: "Request IMSI and IMEI",
> +               3: "No identity needed",
> +               4: "MS Refuses",
> +               5: "MS is not GPRS Responding",
> +               128: "Request accepted",
> +               129: "New PDP type due to network preference",
> +               130: "New PDP type due to single address bearer only",
> +               192: "Non-existent",
> +               193: "Invalid message format",
> +               194: "IMSI not known",
> +               195: "MS is GPRS Detached",
> +               196: "MS is not GPRS Responding",
> +               197: "MS Refuses",
> +               198: "Version not supported",
> +               199: "No resources available",
> +               200: "Service not supported",
> +               201: "Mandatory IE incorrect",
> +               202: "Mandatory IE missing",
> +               203: "Optional IE incorrect",
> +               204: "System failure",
> +               205: "Roaming restriction",
> +               206: "P-TMSI Signature mismatch",
> +               207: "GPRS connection suspended",
> +               208: "Authentication failure",
> +               209: "User authentication failed",
> +               210: "Context not found",
> +               211: "All dynamic PDP addresses are occupied",
> +               212: "No memory is available",
> +               213: "Reallocation failure",
> +               214: "Unknown mandatory extension header",
> +               215: "Semantic error in the TFT operation",
> +               216: "Syntactic error in TFT operation",
> +               217: "Semantic errors in packet filter(s)",
> +               218: "Syntactic errors in packet filter(s)",
> +               219: "Missing or unknown APN",
> +               220: "Unknown PDP address or PDP type",
> +               221: "PDP context without TFT already activated",
> +               222: "APN access denied : no subscription",
> +               223: "APN Restriction type incompatibility with currently active PDP
> Contexts",  # noqa: E501
> +               224: "MS MBMS Capabilities Insufficient",
> +               225: "Invalid Correlation : ID",
> +               226: "MBMS Bearer Context Superseded",
> +               227: "Bearer Control Mode violation",
> +               228: "Collision with network initiated request"}
> +
> +Selection_Mode = {11111100: "MS or APN",
> +                  11111101: "MS",
> +                  11111110: "NET",
> +                  11111111: "FutureUse"}
> +
> +TrueFalse_value = {254: "False",
> +                   255: "True"}
> +
> +#
> +http://www.arib.or.jp/IMT-2000/V720Mar09/5_Appendix/Rel8/29/29281-
> 800.p
> +df
> +ExtensionHeadersTypes = {
> +    0: "No more extension headers",
> +    1: "Reserved",
> +    2: "Reserved",
> +    64: "UDP Port",
> +    192: "PDCP PDU Number",
> +    193: "Reserved",
> +    194: "Reserved"
> +}
> +
> +
> +class TBCDByteField(StrFixedLenField):
> +
> +    def i2h(self, pkt, val):
> +        return val
> +
> +    def m2i(self, pkt, val):
> +        ret = []
> +        for v in val:
> +            byte = orb(v)
> +            left = byte >> 4
> +            right = byte & 0xf
> +            if left == 0xf:
> +                ret.append(TBCD_TO_ASCII[right:right + 1])
> +            else:
> +                ret += [TBCD_TO_ASCII[right:right + 1], TBCD_TO_ASCII[left:left + 1]]
> # noqa: E501
> +        return b"".join(ret)
> +
> +    def i2m(self, pkt, val):
> +        val = str(val)
> +        ret_string = ""
> +        for i in range(0, len(val), 2):
> +            tmp = val[i:i + 2]
> +            if len(tmp) == 2:
> +                ret_string += chr(int(tmp[1] + tmp[0], 16))
> +            else:
> +                ret_string += chr(int("F" + tmp[0], 16))
> +        return ret_string
> +
> +
> +TBCD_TO_ASCII = b"0123456789*#abc"
> +
> +
> +class GTP_ExtensionHeader(Packet):
> +    @classmethod
> +    def dispatch_hook(cls, _pkt=None, *args, **kargs):
> +        if _pkt is None:
> +            return GTP_UDPPort_ExtensionHeader
> +        return cls
> +
> +
> +class GTP_UDPPort_ExtensionHeader(GTP_ExtensionHeader):
> +    fields_desc = [ByteField("length", 0x40),
> +                   ShortField("udp_port", None),
> +                   ByteEnumField("next_ex", 0, ExtensionHeadersTypes),
> +]
> +
> +
> +class GTP_PDCP_PDU_ExtensionHeader(GTP_ExtensionHeader):
> +    fields_desc = [ByteField("length", 0x01),
> +                   ShortField("pdcp_pdu", None),
> +                   ByteEnumField("next_ex", 0, ExtensionHeadersTypes),
> +]
> +
> +
> +class GTPHeader(Packet):
> +    # 3GPP TS 29.060 V9.1.0 (2009-12)
> +    name = "GTP-C Header"
> +    fields_desc = [BitField("version", 1, 3),
> +                   BitField("PT", 1, 1),
> +                   BitField("reserved", 0, 1),
> +                   BitField("E", 0, 1),
> +                   BitField("S", 0, 1),
> +                   BitField("PN", 0, 1),
> +                   ByteEnumField("gtp_type", None, GTPmessageType),
> +                   ShortField("length", None),
> +                   IntField("teid", 0),
> +                   ConditionalField(XBitField("seq", 0, 16), lambda pkt:pkt.E == 1 or
> pkt.S == 1 or pkt.PN == 1),  # noqa: E501
> +                   ConditionalField(ByteField("npdu", 0), lambda pkt:pkt.E == 1 or
> pkt.S == 1 or pkt.PN == 1),  # noqa: E501
> +                   ConditionalField(ByteEnumField("next_ex", 0,
> +ExtensionHeadersTypes), lambda pkt:pkt.E == 1 or pkt.S == 1 or pkt.PN
> +== 1), ]  # noqa: E501
> +
> +    def post_build(self, p, pay):
> +        p += pay
> +        if self.length is None:
> +            tmp_len = len(p) - 8
> +            p = p[:2] + struct.pack("!H", tmp_len) + p[4:]
> +        return p
> +
> +    def hashret(self):
> +        return struct.pack("B", self.version) + self.payload.hashret()
> +
> +    def answers(self, other):
> +        return (isinstance(other, GTPHeader) and
> +                self.version == other.version and
> +                self.payload.answers(other.payload))
> +
> +    @classmethod
> +    def dispatch_hook(cls, _pkt=None, *args, **kargs):
> +        if _pkt and len(_pkt) >= 1:
> +            if (orb(_pkt[0]) >> 5) & 0x7 == 2:
> +                from . import gtp_v2
> +                return gtp_v2.GTPHeader
> +        if _pkt and len(_pkt) >= 8:
> +            _gtp_type = orb(_pkt[1:2])
> +            return GTPforcedTypes.get(_gtp_type, GTPHeader)
> +        return cls
> +
> +
> +class GTP_U_Header(GTPHeader):
> +    # 3GPP TS 29.060 V9.1.0 (2009-12)
> +    name = "GTP-U Header"
> +    # GTP-U protocol is used to transmit T-PDUs between GSN pairs (or
> between an SGSN and an RNC in UMTS),  # noqa: E501
> +    # encapsulated in G-PDUs. A G-PDU is a packet including a GTP-U header
> and a T-PDU. The Path Protocol  # noqa: E501
> +    # defines the path and the GTP-U header defines the tunnel. Several
> +tunnels may be multiplexed on a single path.  # noqa: E501
> +
> +
> +# Some gtp_types have to be associated with a certain type of header
> +GTPforcedTypes = {
> +    16: GTPHeader,
> +    17: GTPHeader,
> +    18: GTPHeader,
> +    19: GTPHeader,
> +    20: GTPHeader,
> +    21: GTPHeader,
> +    26: GTP_U_Header,
> +    27: GTPHeader,
> +    254: GTP_U_Header,
> +    255: GTP_U_Header
> +}
> +
> +
> +class GTPEchoRequest(Packet):
> +    # 3GPP TS 29.060 V9.1.0 (2009-12)
> +    name = "GTP Echo Request"
> +
> +    def hashret(self):
> +        return struct.pack("H", self.seq)
> +
> +
> +class IE_Base(Packet):
> +
> +    def extract_padding(self, pkt):
> +        return "", pkt
> +
> +
> +class IE_Cause(IE_Base):
> +    name = "Cause"
> +    fields_desc = [ByteEnumField("ietype", 1, IEType),
> +                   ByteEnumField("CauseValue", None, CauseValues)]
> +
> +
> +class IE_IMSI(IE_Base):
> +    name = "IMSI - Subscriber identity of the MS"
> +    fields_desc = [ByteEnumField("ietype", 2, IEType),
> +                   TBCDByteField("imsi", str(RandNum(0,
> +999999999999999)), 8)]
> +
> +
> +class IE_Routing(IE_Base):
> +    name = "Routing Area Identity"
> +    fields_desc = [ByteEnumField("ietype", 3, IEType),
> +                   TBCDByteField("MCC", "", 2),
> +                   # MNC: if the third digit of MCC is 0xf,
> +                   # then the length of MNC is 1 byte
> +                   TBCDByteField("MNC", "", 1),
> +                   ShortField("LAC", None),
> +                   ByteField("RAC", None)]
> +
> +
> +class IE_ReorderingRequired(IE_Base):
> +    name = "Recovery"
> +    fields_desc = [ByteEnumField("ietype", 8, IEType),
> +                   ByteEnumField("reordering_required", 254,
> +TrueFalse_value)]
> +
> +
> +class IE_Recovery(IE_Base):
> +    name = "Recovery"
> +    fields_desc = [ByteEnumField("ietype", 14, IEType),
> +                   ByteField("restart_counter", 24)]
> +
> +
> +class IE_SelectionMode(IE_Base):
> +    # Indicates the origin of the APN in the message
> +    name = "Selection Mode"
> +    fields_desc = [ByteEnumField("ietype", 15, IEType),
> +                   BitEnumField("SelectionMode", "MS or APN",
> +                                8, Selection_Mode)]
> +
> +
> +class IE_TEIDI(IE_Base):
> +    name = "Tunnel Endpoint Identifier Data"
> +    fields_desc = [ByteEnumField("ietype", 16, IEType),
> +                   XIntField("TEIDI", RandInt())]
> +
> +
> +class IE_TEICP(IE_Base):
> +    name = "Tunnel Endpoint Identifier Control Plane"
> +    fields_desc = [ByteEnumField("ietype", 17, IEType),
> +                   XIntField("TEICI", RandInt())]
> +
> +
> +class IE_Teardown(IE_Base):
> +    name = "Teardown Indicator"
> +    fields_desc = [ByteEnumField("ietype", 19, IEType),
> +                   ByteEnumField("indicator", "True", TrueFalse_value)]
> +
> +
> +class IE_NSAPI(IE_Base):
> +    # Identifies a PDP context in a mobility management context specified by
> TEICP  # noqa: E501
> +    name = "NSAPI"
> +    fields_desc = [ByteEnumField("ietype", 20, IEType),
> +                   XBitField("sparebits", 0x0000, 4),
> +                   XBitField("NSAPI", RandNum(0, 15), 4)]
> +
> +
> +class IE_ChargingCharacteristics(IE_Base):
> +    # Way of informing both the SGSN and GGSN of the rules for
> +    name = "Charging Characteristics"
> +    fields_desc = [ByteEnumField("ietype", 26, IEType),
> +                   # producing charging information based on operator configured
> triggers.  # noqa: E501
> +                   #    0000 .... .... .... : spare
> +                   #    .... 1... .... .... : normal charging
> +                   #    .... .0.. .... .... : prepaid charging
> +                   #    .... ..0. .... .... : flat rate charging
> +                   #    .... ...0 .... .... : hot billing charging
> +                   #    .... .... 0000 0000 : reserved
> +                   XBitField("Ch_ChSpare", None, 4),
> +                   XBitField("normal_charging", None, 1),
> +                   XBitField("prepaid_charging", None, 1),
> +                   XBitField("flat_rate_charging", None, 1),
> +                   XBitField("hot_billing_charging", None, 1),
> +                   XBitField("Ch_ChReserved", 0, 8)]
> +
> +
> +class IE_TraceReference(IE_Base):
> +    # Identifies a record or a collection of records for a particular trace.
> +    name = "Trace Reference"
> +    fields_desc = [ByteEnumField("ietype", 27, IEType),
> +                   XBitField("Trace_reference", None, 16)]
> +
> +
> +class IE_TraceType(IE_Base):
> +    # Indicates the type of the trace
> +    name = "Trace Type"
> +    fields_desc = [ByteEnumField("ietype", 28, IEType),
> +                   XBitField("Trace_type", None, 16)]
> +
> +
> +class IE_ChargingId(IE_Base):
> +    name = "Charging ID"
> +    fields_desc = [ByteEnumField("ietype", 127, IEType),
> +                   XIntField("Charging_id", RandInt())]
> +
> +
> +class IE_EndUserAddress(IE_Base):
> +    # Supply protocol specific information of the external packet
> +    name = "End User Address"
> +    fields_desc = [ByteEnumField("ietype", 128, IEType),
> +                   #         data network accessed by the GGPRS subscribers.
> +                   #            - Request
> +                   #                1    Type (1byte)
> +                   #                2-3    Length (2bytes) - value 2
> +                   #                4    Spare + PDP Type Organization
> +                   #                5    PDP Type Number
> +                   #            - Response
> +                   #                6-n    PDP Address
> +                   ShortField("length", 2),
> +                   BitField("SPARE", 15, 4),
> +                   BitField("PDPTypeOrganization", 1, 4),
> +                   XByteField("PDPTypeNumber", None),
> +                   ConditionalField(IPField("PDPAddress", RandIP()),
> +                                    lambda pkt: pkt.length == 6 or pkt.length == 22),  # noqa:
> E501
> +                   ConditionalField(IP6Field("IPv6_PDPAddress", '::1'),
> +                                    lambda pkt: pkt.length == 18 or
> +pkt.length == 22)]  # noqa: E501
> +
> +
> +class APNStrLenField(StrLenField):
> +    # Inspired by DNSStrField
> +    def m2i(self, pkt, s):
> +        ret_s = b""
> +        tmp_s = s
> +        while tmp_s:
> +            tmp_len = orb(tmp_s[0]) + 1
> +            if tmp_len > len(tmp_s):
> +                warning("APN prematured end of character-string (size=%i,
> remaining bytes=%i)" % (tmp_len, len(tmp_s)))  # noqa: E501
> +            ret_s += tmp_s[1:tmp_len]
> +            tmp_s = tmp_s[tmp_len:]
> +            if len(tmp_s):
> +                ret_s += b"."
> +        s = ret_s
> +        return s
> +
> +    def i2m(self, pkt, s):
> +        s = b"".join(chb(len(x)) + x for x in s.split("."))
> +        return s
> +
> +
> +class IE_AccessPointName(IE_Base):
> +    # Sent by SGSN or by GGSN as defined in 3GPP TS 23.060
> +    name = "Access Point Name"
> +    fields_desc = [ByteEnumField("ietype", 131, IEType),
> +                   ShortField("length", None),
> +                   APNStrLenField("APN", "nternet", length_from=lambda
> +x: x.length)]  # noqa: E501
> +
> +    def post_build(self, p, pay):
> +        if self.length is None:
> +            tmp_len = len(p) - 3
> +            p = p[:2] + struct.pack("!B", tmp_len) + p[3:]
> +        return p
> +
> +
> +class IE_ProtocolConfigurationOptions(IE_Base):
> +    name = "Protocol Configuration Options"
> +    fields_desc = [ByteEnumField("ietype", 132, IEType),
> +                   ShortField("length", 4),
> +                   StrLenField("Protocol_Configuration", "",
> +                               length_from=lambda x: x.length)]
> +
> +
> +class IE_GSNAddress(IE_Base):
> +    name = "GSN Address"
> +    fields_desc = [ByteEnumField("ietype", 133, IEType),
> +                   ShortField("length", 4),
> +                   IPField("address", RandIP())]
> +
> +
> +class IE_MSInternationalNumber(IE_Base):
> +    name = "MS International Number"
> +    fields_desc = [ByteEnumField("ietype", 134, IEType),
> +                   ShortField("length", None),
> +                   FlagsField("flags", 0x91, 8, ["Extension", "", "", "International
> Number", "", "", "", "ISDN numbering"]),  # noqa: E501
> +                   TBCDByteField("digits", "33607080910",
> +length_from=lambda x: x.length - 1)]  # noqa: E501
> +
> +
> +class QoS_Profile(IE_Base):
> +    name = "QoS profile"
> +    fields_desc = [ByteField("qos_ei", 0),
> +                   ByteField("length", None),
> +                   XBitField("spare", 0x00, 2),
> +                   XBitField("delay_class", 0x000, 3),
> +                   XBitField("reliability_class", 0x000, 3),
> +                   XBitField("peak_troughput", 0x0000, 4),
> +                   BitField("spare", 0, 1),
> +                   XBitField("precedence_class", 0x000, 3),
> +                   XBitField("spare", 0x000, 3),
> +                   XBitField("mean_troughput", 0x00000, 5),
> +                   XBitField("traffic_class", 0x000, 3),
> +                   XBitField("delivery_order", 0x00, 2),
> +                   XBitField("delivery_of_err_sdu", 0x000, 3),
> +                   ByteField("max_sdu_size", None),
> +                   ByteField("max_bitrate_up", None),
> +                   ByteField("max_bitrate_down", None),
> +                   XBitField("redidual_ber", 0x0000, 4),
> +                   XBitField("sdu_err_ratio", 0x0000, 4),
> +                   XBitField("transfer_delay", 0x00000, 5),
> +                   XBitField("traffic_handling_prio", 0x000, 3),
> +                   ByteField("guaranteed_bit_rate_up", None),
> +                   ByteField("guaranteed_bit_rate_down", None)]
> +
> +
> +class IE_QoS(IE_Base):
> +    name = "QoS"
> +    fields_desc = [ByteEnumField("ietype", 135, IEType),
> +                   ShortField("length", None),
> +                   ByteField("allocation_retention_prioiry", 1),
> +
> +                   ConditionalField(XBitField("spare", 0x00, 2),
> +                                    lambda pkt: pkt.length > 1),
> +                   ConditionalField(XBitField("delay_class", 0x000, 3),
> +                                    lambda pkt: pkt.length > 1),
> +                   ConditionalField(XBitField("reliability_class", 0x000, 3),
> +                                    lambda pkt: pkt.length > 1),
> +
> +                   ConditionalField(XBitField("peak_troughput", 0x0000, 4),
> +                                    lambda pkt: pkt.length > 2),
> +                   ConditionalField(BitField("spare", 0, 1),
> +                                    lambda pkt: pkt.length > 2),
> +                   ConditionalField(XBitField("precedence_class", 0x000, 3),
> +                                    lambda pkt: pkt.length > 2),
> +
> +                   ConditionalField(XBitField("spare", 0x000, 3),
> +                                    lambda pkt: pkt.length > 3),
> +                   ConditionalField(XBitField("mean_troughput", 0x00000, 5),
> +                                    lambda pkt: pkt.length > 3),
> +
> +                   ConditionalField(XBitField("traffic_class", 0x000, 3),
> +                                    lambda pkt: pkt.length > 4),
> +                   ConditionalField(XBitField("delivery_order", 0x00, 2),
> +                                    lambda pkt: pkt.length > 4),
> +                   ConditionalField(XBitField("delivery_of_err_sdu", 0x000, 3),
> +                                    lambda pkt: pkt.length > 4),
> +
> +                   ConditionalField(ByteField("max_sdu_size", None),
> +                                    lambda pkt: pkt.length > 5),
> +                   ConditionalField(ByteField("max_bitrate_up", None),
> +                                    lambda pkt: pkt.length > 6),
> +                   ConditionalField(ByteField("max_bitrate_down", None),
> +                                    lambda pkt: pkt.length > 7),
> +
> +                   ConditionalField(XBitField("redidual_ber", 0x0000, 4),
> +                                    lambda pkt: pkt.length > 8),
> +                   ConditionalField(XBitField("sdu_err_ratio", 0x0000, 4),
> +                                    lambda pkt: pkt.length > 8),
> +                   ConditionalField(XBitField("transfer_delay", 0x00000, 6),
> +                                    lambda pkt: pkt.length > 9),
> +                   ConditionalField(XBitField("traffic_handling_prio",
> +                                              0x000,
> +                                              2),
> +                                    lambda pkt: pkt.length > 9),
> +
> +                   ConditionalField(ByteField("guaranteed_bit_rate_up", None),
> +                                    lambda pkt: pkt.length > 10),
> +                   ConditionalField(ByteField("guaranteed_bit_rate_down",
> +                                              None),
> +                                    lambda pkt: pkt.length > 11),
> +
> +                   ConditionalField(XBitField("spare", 0x000, 3),
> +                                    lambda pkt: pkt.length > 12),
> +                   ConditionalField(BitField("signaling_indication", 0, 1),
> +                                    lambda pkt: pkt.length > 12),
> +                   ConditionalField(XBitField("source_stats_desc", 0x0000, 4),
> +                                    lambda pkt: pkt.length > 12),
> +
> +                   ConditionalField(ByteField("max_bitrate_down_ext", None),
> +                                    lambda pkt: pkt.length > 13),
> +                   ConditionalField(ByteField("guaranteed_bitrate_down_ext",
> +                                              None),
> +                                    lambda pkt: pkt.length > 14),
> +                   ConditionalField(ByteField("max_bitrate_up_ext", None),
> +                                    lambda pkt: pkt.length > 15),
> +                   ConditionalField(ByteField("guaranteed_bitrate_up_ext",
> +                                              None),
> +                                    lambda pkt: pkt.length > 16),
> +                   ConditionalField(ByteField("max_bitrate_down_ext2", None),
> +                                    lambda pkt: pkt.length > 17),
> +                   ConditionalField(ByteField("guaranteed_bitrate_down_ext2",
> +                                              None),
> +                                    lambda pkt: pkt.length > 18),
> +                   ConditionalField(ByteField("max_bitrate_up_ext2", None),
> +                                    lambda pkt: pkt.length > 19),
> +                   ConditionalField(ByteField("guaranteed_bitrate_up_ext2",
> +                                              None),
> +                                    lambda pkt: pkt.length > 20)]
> +
> +
> +class IE_CommonFlags(IE_Base):
> +    name = "Common Flags"
> +    fields_desc = [ByteEnumField("ietype", 148, IEType),
> +                   ShortField("length", None),
> +                   BitField("dual_addr_bearer_fl", 0, 1),
> +                   BitField("upgrade_qos_supported", 0, 1),
> +                   BitField("nrsn", 0, 1),
> +                   BitField("no_qos_nego", 0, 1),
> +                   BitField("mbms_cnting_info", 0, 1),
> +                   BitField("ran_procedure_ready", 0, 1),
> +                   BitField("mbms_service_type", 0, 1),
> +                   BitField("prohibit_payload_compression", 0, 1)]
> +
> +
> +class IE_APNRestriction(IE_Base):
> +    name = "APN Restriction"
> +    fields_desc = [ByteEnumField("ietype", 149, IEType),
> +                   ShortField("length", 1),
> +                   ByteField("restriction_type_value", 0)]
> +
> +
> +class IE_RATType(IE_Base):
> +    name = "Rat Type"
> +    fields_desc = [ByteEnumField("ietype", 151, IEType),
> +                   ShortField("length", 1),
> +                   ByteEnumField("RAT_Type", None, RATType)]
> +
> +
> +class IE_UserLocationInformation(IE_Base):
> +    name = "User Location Information"
> +    fields_desc = [ByteEnumField("ietype", 152, IEType),
> +                   ShortField("length", None),
> +                   ByteField("type", 1),
> +                   # Only type 1 is currently supported
> +                   TBCDByteField("MCC", "", 2),
> +                   # MNC: if the third digit of MCC is 0xf, then the length of MNC is 1
> byte  # noqa: E501
> +                   TBCDByteField("MNC", "", 1),
> +                   ShortField("LAC", None),
> +                   ShortField("SAC", None)]
> +
> +
> +class IE_MSTimeZone(IE_Base):
> +    name = "MS Time Zone"
> +    fields_desc = [ByteEnumField("ietype", 153, IEType),
> +                   ShortField("length", None),
> +                   ByteField("timezone", 0),
> +                   BitField("Spare", 0, 1),
> +                   BitField("Spare", 0, 1),
> +                   BitField("Spare", 0, 1),
> +                   BitField("Spare", 0, 1),
> +                   BitField("Spare", 0, 1),
> +                   BitField("Spare", 0, 1),
> +                   XBitField("daylight_saving_time", 0x00, 2)]
> +
> +
> +class IE_IMEI(IE_Base):
> +    name = "IMEI"
> +    fields_desc = [ByteEnumField("ietype", 154, IEType),
> +                   ShortField("length", None),
> +                   TBCDByteField("IMEI", "", length_from=lambda x:
> +x.length)]
> +
> +
> +class IE_MSInfoChangeReportingAction(IE_Base):
> +    name = "MS Info Change Reporting Action"
> +    fields_desc = [ByteEnumField("ietype", 181, IEType),
> +                   ShortField("length", 1),
> +                   ByteField("Action", 0)]
> +
> +
> +class IE_DirectTunnelFlags(IE_Base):
> +    name = "Direct Tunnel Flags"
> +    fields_desc = [ByteEnumField("ietype", 182, IEType),
> +                   ShortField("length", 1),
> +                   BitField("Spare", 0, 1),
> +                   BitField("Spare", 0, 1),
> +                   BitField("Spare", 0, 1),
> +                   BitField("Spare", 0, 1),
> +                   BitField("Spare", 0, 1),
> +                   BitField("EI", 0, 1),
> +                   BitField("GCSI", 0, 1),
> +                   BitField("DTI", 0, 1)]
> +
> +
> +class IE_BearerControlMode(IE_Base):
> +    name = "Bearer Control Mode"
> +    fields_desc = [ByteEnumField("ietype", 184, IEType),
> +                   ShortField("length", 1),
> +                   ByteField("bearer_control_mode", 0)]
> +
> +
> +class IE_EvolvedAllocationRetentionPriority(IE_Base):
> +    name = "Evolved Allocation/Retention Priority"
> +    fields_desc = [ByteEnumField("ietype", 191, IEType),
> +                   ShortField("length", 1),
> +                   BitField("Spare", 0, 1),
> +                   BitField("PCI", 0, 1),
> +                   XBitField("PL", 0x0000, 4),
> +                   BitField("Spare", 0, 1),
> +                   BitField("PVI", 0, 1)]
> +
> +
> +class IE_CharginGatewayAddress(IE_Base):
> +    name = "Chargin Gateway Address"
> +    fields_desc = [ByteEnumField("ietype", 251, IEType),
> +                   ShortField("length", 4),
> +                   ConditionalField(IPField("ipv4_address", "127.0.0.1"),
> +                                    lambda
> +                                    pkt: pkt.length == 4),
> +                   ConditionalField(IP6Field("ipv6_address", "::1"), lambda
> +                                    pkt: pkt.length == 16)]
> +
> +
> +class IE_PrivateExtension(IE_Base):
> +    name = "Private Extension"
> +    fields_desc = [ByteEnumField("ietype", 255, IEType),
> +                   ShortField("length", 1),
> +                   ByteField("extension identifier", 0),
> +                   StrLenField("extention_value", "",
> +                               length_from=lambda x: x.length)]
> +
> +
> +class IE_ExtensionHeaderList(IE_Base):
> +    name = "Extension Header List"
> +    fields_desc = [ByteEnumField("ietype", 141, IEType),
> +                   FieldLenField("length", None, length_of="extension_headers"),  #
> noqa: E501
> +                   FieldListField("extension_headers", [64, 192],
> +ByteField("", 0))]  # noqa: E501
> +
> +
> +class IE_NotImplementedTLV(Packet):
> +    name = "IE not implemented"
> +    fields_desc = [ByteEnumField("ietype", 0, IEType),
> +                   ShortField("length", None),
> +                   StrLenField("data", "", length_from=lambda x:
> +x.length)]
> +
> +    def extract_padding(self, pkt):
> +        return "", pkt
> +
> +
> +ietypecls = {1: IE_Cause,
> +             2: IE_IMSI,
> +             3: IE_Routing,
> +             8: IE_ReorderingRequired,
> +             14: IE_Recovery,
> +             15: IE_SelectionMode,
> +             16: IE_TEIDI,
> +             17: IE_TEICP,
> +             19: IE_Teardown,
> +             20: IE_NSAPI,
> +             26: IE_ChargingCharacteristics,
> +             27: IE_TraceReference,
> +             28: IE_TraceType,
> +             127: IE_ChargingId,
> +             128: IE_EndUserAddress,
> +             131: IE_AccessPointName,
> +             132: IE_ProtocolConfigurationOptions,
> +             133: IE_GSNAddress,
> +             134: IE_MSInternationalNumber,
> +             135: IE_QoS,
> +             141: IE_ExtensionHeaderList,
> +             148: IE_CommonFlags,
> +             149: IE_APNRestriction,
> +             151: IE_RATType,
> +             152: IE_UserLocationInformation,
> +             153: IE_MSTimeZone,
> +             154: IE_IMEI,
> +             181: IE_MSInfoChangeReportingAction,
> +             182: IE_DirectTunnelFlags,
> +             184: IE_BearerControlMode,
> +             191: IE_EvolvedAllocationRetentionPriority,
> +             251: IE_CharginGatewayAddress,
> +             255: IE_PrivateExtension}
> +
> +
> +def IE_Dispatcher(s):
> +    """Choose the correct Information Element class."""
> +    if len(s) < 1:
> +        return Raw(s)
> +    # Get the IE type
> +    ietype = orb(s[0])
> +    cls = ietypecls.get(ietype, Raw)
> +
> +    # if ietype greater than 128 are TLVs
> +    if cls == Raw and ietype & 128 == 128:
> +        cls = IE_NotImplementedTLV
> +    return cls(s)
> +
> +
> +class GTPEchoResponse(Packet):
> +    # 3GPP TS 29.060 V9.1.0 (2009-12)
> +    name = "GTP Echo Response"
> +    fields_desc = [PacketListField("IE_list", [], IE_Dispatcher)]
> +
> +    def hashret(self):
> +        return struct.pack("H", self.seq)
> +
> +    def answers(self, other):
> +        return self.seq == other.seq
> +
> +
> +class GTPCreatePDPContextRequest(Packet):
> +    # 3GPP TS 29.060 V9.1.0 (2009-12)
> +    name = "GTP Create PDP Context Request"
> +    fields_desc = [PacketListField("IE_list", [IE_TEIDI(), IE_NSAPI(),
> IE_GSNAddress(),  # noqa: E501
> +                                               IE_GSNAddress(),
> +                                               IE_NotImplementedTLV(ietype=135, length=15,
> data=RandString(15))],  # noqa: E501
> +                                   IE_Dispatcher)]
> +
> +    def hashret(self):
> +        return struct.pack("H", self.seq)
> +
> +
> +class GTPCreatePDPContextResponse(Packet):
> +    # 3GPP TS 29.060 V9.1.0 (2009-12)
> +    name = "GTP Create PDP Context Response"
> +    fields_desc = [PacketListField("IE_list", [], IE_Dispatcher)]
> +
> +    def hashret(self):
> +        return struct.pack("H", self.seq)
> +
> +    def answers(self, other):
> +        return self.seq == other.seq
> +
> +
> +class GTPUpdatePDPContextRequest(Packet):
> +    # 3GPP TS 29.060 V9.1.0 (2009-12)
> +    name = "GTP Update PDP Context Request"
> +    fields_desc = [PacketListField("IE_list", [
> +        IE_Cause(),
> +        IE_Recovery(),
> +        IE_TEIDI(),
> +        IE_TEICP(),
> +        IE_ChargingId(),
> +        IE_ProtocolConfigurationOptions(),
> +        IE_GSNAddress(),
> +        IE_GSNAddress(),
> +        IE_GSNAddress(),
> +        IE_GSNAddress(),
> +        IE_QoS(),
> +        IE_CharginGatewayAddress(),
> +        IE_CharginGatewayAddress(),
> +        IE_CommonFlags(),
> +        IE_APNRestriction(),
> +        IE_BearerControlMode(),
> +        IE_MSInfoChangeReportingAction(),
> +        IE_EvolvedAllocationRetentionPriority(),
> +        IE_PrivateExtension()],
> +        IE_Dispatcher)]
> +
> +    def hashret(self):
> +        return struct.pack("H", self.seq)
> +
> +
> +class GTPUpdatePDPContextResponse(Packet):
> +    # 3GPP TS 29.060 V9.1.0 (2009-12)
> +    name = "GTP Update PDP Context Response"
> +    fields_desc = [PacketListField("IE_list", None, IE_Dispatcher)]
> +
> +    def hashret(self):
> +        return struct.pack("H", self.seq)
> +
> +
> +class GTPErrorIndication(Packet):
> +    # 3GPP TS 29.060 V9.1.0 (2009-12)
> +    name = "GTP Error Indication"
> +    fields_desc = [PacketListField("IE_list", [], IE_Dispatcher)]
> +
> +
> +class GTPDeletePDPContextRequest(Packet):
> +    # 3GPP TS 29.060 V9.1.0 (2009-12)
> +    name = "GTP Delete PDP Context Request"
> +    fields_desc = [PacketListField("IE_list", [], IE_Dispatcher)]
> +
> +
> +class GTPDeletePDPContextResponse(Packet):
> +    # 3GPP TS 29.060 V9.1.0 (2009-12)
> +    name = "GTP Delete PDP Context Response"
> +    fields_desc = [PacketListField("IE_list", [], IE_Dispatcher)]
> +
> +
> +class GTPPDUNotificationRequest(Packet):
> +    # 3GPP TS 29.060 V9.1.0 (2009-12)
> +    name = "GTP PDU Notification Request"
> +    fields_desc = [PacketListField("IE_list", [IE_IMSI(),
> +                                               IE_TEICP(TEICI=RandInt()),
> +                                               IE_EndUserAddress(PDPTypeNumber=0x21),  #
> noqa: E501
> +                                               IE_AccessPointName(),
> +                                               IE_GSNAddress(address="127.0.0.1"),  # noqa:
> E501
> +                                               ], IE_Dispatcher)]
> +
> +
> +class GTPSupportedExtensionHeadersNotification(Packet):
> +    name = "GTP Supported Extension Headers Notification"
> +    fields_desc = [PacketListField("IE_list", [IE_ExtensionHeaderList(),
> +                                               ], IE_Dispatcher)]
> +
> +
> +class GTPmorethan1500(Packet):
> +    # 3GPP TS 29.060 V9.1.0 (2009-12)
> +    name = "GTP More than 1500"
> +    fields_desc = [ByteEnumField("IE_Cause", "Cause", IEType),
> +                   BitField("IE", 1, 12000), ]
> +
> +
> +# Bind GTP-C
> +bind_layers(UDP, GTPHeader, dport=2123) bind_layers(UDP, GTPHeader,
> +sport=2123) bind_layers(GTPHeader, GTPEchoRequest, gtp_type=1, S=1)
> +bind_layers(GTPHeader, GTPEchoResponse, gtp_type=2, S=1)
> +bind_layers(GTPHeader, GTPCreatePDPContextRequest, gtp_type=16)
> +bind_layers(GTPHeader, GTPCreatePDPContextResponse, gtp_type=17)
> +bind_layers(GTPHeader, GTPUpdatePDPContextRequest, gtp_type=18)
> +bind_layers(GTPHeader, GTPUpdatePDPContextResponse, gtp_type=19)
> +bind_layers(GTPHeader, GTPDeletePDPContextRequest, gtp_type=20)
> +bind_layers(GTPHeader, GTPDeletePDPContextResponse, gtp_type=21)
> +bind_layers(GTPHeader, GTPPDUNotificationRequest, gtp_type=27)
> +bind_layers(GTPHeader, GTPSupportedExtensionHeadersNotification,
> +gtp_type=31, S=1)  # noqa: E501 bind_layers(GTPHeader,
> +GTP_UDPPort_ExtensionHeader, next_ex=64, E=1) bind_layers(GTPHeader,
> +GTP_PDCP_PDU_ExtensionHeader, next_ex=192, E=1)
> +
> +# Bind GTP-U
> +bind_layers(UDP, GTP_U_Header, dport=2152) bind_layers(UDP,
> +GTP_U_Header, sport=2152) bind_layers(GTP_U_Header,
> GTPErrorIndication,
> +gtp_type=26, S=1) bind_layers(GTP_U_Header, IP, gtp_type=255)
> --
> 1.8.3.1


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, back to index

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-12-31 12:07 [dts] [PATCH V1 1/2] dep/add gtp for the advanced rss feature support gtp packets in CVL zhiwei.he
2019-12-31 12:07 ` [dts] [PATCH V1 2/2] dep/add gtp_v2 for the advanced rss feature to support gtp_v2 " zhiwei.he
2020-01-02  5:32 ` [dts] [PATCH V1 1/2] dep/add gtp for the advanced rss feature support gtp " Tu, Lijuan

test suite reviews and discussions

Archives are clonable:
	git clone --mirror http://inbox.dpdk.org/dts/0 dts/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 dts dts/ http://inbox.dpdk.org/dts \
		dts@dpdk.org
	public-inbox-index dts


Newsgroup available over NNTP:
	nntp://inbox.dpdk.org/inbox.dpdk.dts


AGPL code for this site: git clone https://public-inbox.org/ public-inbox