diff --git a/bin/UTscapy.bat b/bin/UTscapy.bat
index 3bccb69a072dd0c8ce5861b2b37f343325f84031..d9c277f26424c712fb9bed8eac26be2d4530a484 100755
--- a/bin/UTscapy.bat
+++ b/bin/UTscapy.bat
@@ -1,4 +1,4 @@
-@echo off
-REM Use Python to run the UTscapy script from the current directory, passing all parameters
-title UTscapy
-python "%~dp0\UTscapy" %*
+@echo off
+REM Use Python to run the UTscapy script from the current directory, passing all parameters
+title UTscapy
+python "%~dp0\UTscapy" %*
diff --git a/bin/scapy.bat b/bin/scapy.bat
index cbb17445abb0577f3eceb4541ea332855265b80e..23e43cba51c72900b636898326358df46e6805af 100755
--- a/bin/scapy.bat
+++ b/bin/scapy.bat
@@ -1,4 +1,4 @@
-@echo off
-REM Use Python to run the Scapy script from the current directory, passing all parameters
-title scapy
-python "%~dp0\scapy" %*
+@echo off
+REM Use Python to run the Scapy script from the current directory, passing all parameters
+title scapy
+python "%~dp0\scapy" %*
diff --git a/run_scapy.bat b/run_scapy.bat
index ef1273f7c58128568606cd743d7cc4fc87589eec..ba0774288ea073cc391ad8f84414562b7f61f757 100644
--- a/run_scapy.bat
+++ b/run_scapy.bat
@@ -1,6 +1,6 @@
-@echo off
-set PYTHONPATH=%cd%
-python -m scapy.__init__
-if errorlevel 1 (
- PAUSE
-)
+@echo off
+set PYTHONPATH=%cd%
+python -m scapy.__init__
+if errorlevel 1 (
+ PAUSE
+)
diff --git a/scapy/contrib/gtp.py b/scapy/contrib/gtp.py
index 4fef6c023c24a371a745665c7785cdfa3d70204f..8e40b17be71341e4bd8fc934a9e8412df83a7411 100644
--- a/scapy/contrib/gtp.py
+++ b/scapy/contrib/gtp.py
@@ -1,198 +1,198 @@
-#! /usr/bin/env python
-
-## Copyright (C) 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 = GTP
-# scapy.contrib.status = loads
-
-import time
-import logging
-
-from scapy.packet import *
-from scapy.fields import *
-from scapy.layers.inet import IP, UDP
-from scapy.layers.inet6 import IP6Field
-from scapy.error import warning
-
-# 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",
- 255: "gtp_u_header" }
-
-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",
- 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"}
-
-
-class TBCDByteField(StrFixedLenField):
-
- def i2h(self, pkt, val):
- return val
-
- def i2repr(self, pkt, x):
- return repr(self.i2h(pkt,x))
-
- def m2i(self, pkt, val):
- ret = []
- for v in val:
- byte = ord(v)
- left = byte >> 4
- right = byte & 0xf
- if left == 0xf:
- ret += [TBCD_TO_ASCII[right]]
- else:
- ret += [TBCD_TO_ASCII[right], TBCD_TO_ASCII[left]]
- return "".join(ret)
-
- def i2m(self, pkt, val):
- val = str(val)
- ret_string = ""
- for i in xrange(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 = "0123456789*#abc"
-
-
-class GTPHeader(Packet):
- # 3GPP TS 29.060 V9.1.0 (2009-12)
- name = "GTP Header"
- fields_desc=[ BitField("version", 1, 3),
- BitField("PT", 1, 1),
- BitField("reserved", 0, 1),
- BitField("E", 0, 1),
- BitField("S", 1, 1),
- BitField("PN", 0, 1),
- ByteEnumField("gtp_type", None, GTPmessageType),
- ShortField("length", None),
- IntField("teid", 0) ]
-
- def post_build(self, p, pay):
- p += pay
- if self.length is None:
- l = len(p)-8
- p = p[:2] + struct.pack("!H", l)+ 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))
-
+#! /usr/bin/env python
+
+## Copyright (C) 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 = GTP
+# scapy.contrib.status = loads
+
+import time
+import logging
+
+from scapy.packet import *
+from scapy.fields import *
+from scapy.layers.inet import IP, UDP
+from scapy.layers.inet6 import IP6Field
+from scapy.error import warning
+
+# 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",
+ 255: "gtp_u_header" }
+
+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",
+ 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"}
+
+
+class TBCDByteField(StrFixedLenField):
+
+ def i2h(self, pkt, val):
+ return val
+
+ def i2repr(self, pkt, x):
+ return repr(self.i2h(pkt,x))
+
+ def m2i(self, pkt, val):
+ ret = []
+ for v in val:
+ byte = ord(v)
+ left = byte >> 4
+ right = byte & 0xf
+ if left == 0xf:
+ ret += [TBCD_TO_ASCII[right]]
+ else:
+ ret += [TBCD_TO_ASCII[right], TBCD_TO_ASCII[left]]
+ return "".join(ret)
+
+ def i2m(self, pkt, val):
+ val = str(val)
+ ret_string = ""
+ for i in xrange(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 = "0123456789*#abc"
+
+
+class GTPHeader(Packet):
+ # 3GPP TS 29.060 V9.1.0 (2009-12)
+ name = "GTP Header"
+ fields_desc=[ BitField("version", 1, 3),
+ BitField("PT", 1, 1),
+ BitField("reserved", 0, 1),
+ BitField("E", 0, 1),
+ BitField("S", 1, 1),
+ BitField("PN", 0, 1),
+ ByteEnumField("gtp_type", None, GTPmessageType),
+ ShortField("length", None),
+ IntField("teid", 0) ]
+
+ def post_build(self, p, pay):
+ p += pay
+ if self.length is None:
+ l = len(p)-8
+ p = p[:2] + struct.pack("!H", l)+ 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:
@@ -200,675 +200,675 @@ class GTPHeader(Packet):
import gtp_v2
return gtp_v2.GTPHeader
return GTPHeader
-
-
-class GTPEchoRequest(Packet):
- # 3GPP TS 29.060 V9.1.0 (2009-12)
- name = "GTP Echo Request"
- fields_desc = [ XBitField("seq", 0, 16),
- ByteField("npdu", 0),
- ByteField("next_ex", 0),]
-
- 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
- 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.
- # 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 Addresss"
- 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 > 2)]
-
-
-class APNStrLenField(StrLenField):
- # Inspired by DNSStrField
- def m2i(self, pkt, s):
- ret_s = ""
- tmp_s = s
- while tmp_s:
- tmp_len = struct.unpack("!B", tmp_s[0])[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)))
- ret_s += tmp_s[1:tmp_len]
- tmp_s = tmp_s[tmp_len:]
- if len(tmp_s) :
- ret_s += "."
- s = ret_s
- return s
- def i2m(self, pkt, s):
- s = "".join(map(lambda x: chr(len(x))+x, 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) ]
-
- def post_build(self, p, pay):
- if self.length is None:
- l = len(p)-3
- p = p[:2] + struct.pack("!B", l)+ 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"]),
- TBCDByteField("digits", "33607080910", length_from=lambda x: x.length-1) ]
-
-
-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
- 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_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,
- 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 = ord(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 = [ XBitField("seq", 0, 16),
- ByteField("npdu", 0),
- ByteField("next_ex", 0),
- 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 = [ ShortField("seq", RandShort()),
- ByteField("npdu", 0),
- ByteField("next_ex", 0),
- PacketListField("IE_list", [ IE_TEIDI(), IE_NSAPI(), IE_GSNAddress(),
- IE_GSNAddress(),
- IE_NotImplementedTLV(ietype=135, length=15,data=RandString(15)) ],
- 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 = [ ShortField("seq", RandShort()),
- ByteField("npdu", 0),
- ByteField("next_ex", 0),
- 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 = [ShortField("seq", RandShort()),
- ByteField("npdu", 0),
- ByteField("next_ex", 0),
- 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 = [ShortField("seq", RandShort()),
- ByteField("npdu", 0),
- ByteField("next_ex", 0),
- 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 = [ XBitField("seq", 0, 16),
- ByteField("npdu", 0),
- ByteField("next_ex",0),
- 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 = [ XBitField("seq", 0, 16),
- ByteField("npdu", 0),
- ByteField("next_ex", 0),
- 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 = [ XBitField("seq", 0, 16),
- ByteField("npdu", 0),
- ByteField("next_ex",0),
- PacketListField("IE_list", [], IE_Dispatcher) ]
-
-class GTPPDUNotificationRequest(Packet):
- # 3GPP TS 29.060 V9.1.0 (2009-12)
- name = "GTP PDU Notification Request"
- fields_desc = [ XBitField("seq", 0, 16),
- ByteField("npdu", 0),
- ByteField("next_ex", 0),
- PacketListField("IE_list", [ IE_IMSI(),
- IE_TEICP(TEICI=RandInt()),
- IE_EndUserAddress(PDPTypeNumber=0x21),
- IE_AccessPointName(),
- IE_GSNAddress(address="127.0.0.1"),
- ], IE_Dispatcher) ]
-
-class GTP_U_Header(Packet):
- # 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),
- # encapsulated in G-PDUs. A G-PDU is a packet including a GTP-U header and a T-PDU. The Path Protocol
- # defines the path and the GTP-U header defines the tunnel. Several tunnels may be multiplexed on a single path.
- 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),
- BitField("length", None, 16),
- XBitField("TEID", 0, 32),
- ConditionalField(XBitField("seq", 0, 16), lambda pkt:pkt.E==1 or pkt.S==1 or pkt.PN==1),
- ConditionalField(ByteField("npdu", 0), lambda pkt:pkt.E==1 or pkt.S==1 or pkt.PN==1),
- ConditionalField(ByteField("next_ex", 0), lambda pkt:pkt.E==1 or pkt.S==1 or pkt.PN==1),
- ]
-
- def post_build(self, p, pay):
- p += pay
- if self.length is None:
- l = len(p)-8
- p = p[:2] + struct.pack("!H", l)+ p[4:]
- return p
-
-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)
-bind_layers(GTPHeader, GTPEchoResponse, gtp_type=2)
-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 GTP-U
-bind_layers(UDP, GTP_U_Header, dport = 2152)
-bind_layers(UDP, GTP_U_Header, sport = 2152)
-bind_layers(GTP_U_Header, IP, gtp_type = 255)
-
-if __name__ == "__main__":
- from scapy.all import *
- interact(mydict=globals(), mybanner="GTPv1 add-on")
+
+
+class GTPEchoRequest(Packet):
+ # 3GPP TS 29.060 V9.1.0 (2009-12)
+ name = "GTP Echo Request"
+ fields_desc = [ XBitField("seq", 0, 16),
+ ByteField("npdu", 0),
+ ByteField("next_ex", 0),]
+
+ 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
+ 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.
+ # 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 Addresss"
+ 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 > 2)]
+
+
+class APNStrLenField(StrLenField):
+ # Inspired by DNSStrField
+ def m2i(self, pkt, s):
+ ret_s = ""
+ tmp_s = s
+ while tmp_s:
+ tmp_len = struct.unpack("!B", tmp_s[0])[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)))
+ ret_s += tmp_s[1:tmp_len]
+ tmp_s = tmp_s[tmp_len:]
+ if len(tmp_s) :
+ ret_s += "."
+ s = ret_s
+ return s
+ def i2m(self, pkt, s):
+ s = "".join(map(lambda x: chr(len(x))+x, 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) ]
+
+ def post_build(self, p, pay):
+ if self.length is None:
+ l = len(p)-3
+ p = p[:2] + struct.pack("!B", l)+ 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"]),
+ TBCDByteField("digits", "33607080910", length_from=lambda x: x.length-1) ]
+
+
+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
+ 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_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,
+ 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 = ord(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 = [ XBitField("seq", 0, 16),
+ ByteField("npdu", 0),
+ ByteField("next_ex", 0),
+ 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 = [ ShortField("seq", RandShort()),
+ ByteField("npdu", 0),
+ ByteField("next_ex", 0),
+ PacketListField("IE_list", [ IE_TEIDI(), IE_NSAPI(), IE_GSNAddress(),
+ IE_GSNAddress(),
+ IE_NotImplementedTLV(ietype=135, length=15,data=RandString(15)) ],
+ 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 = [ ShortField("seq", RandShort()),
+ ByteField("npdu", 0),
+ ByteField("next_ex", 0),
+ 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 = [ShortField("seq", RandShort()),
+ ByteField("npdu", 0),
+ ByteField("next_ex", 0),
+ 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 = [ShortField("seq", RandShort()),
+ ByteField("npdu", 0),
+ ByteField("next_ex", 0),
+ 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 = [ XBitField("seq", 0, 16),
+ ByteField("npdu", 0),
+ ByteField("next_ex",0),
+ 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 = [ XBitField("seq", 0, 16),
+ ByteField("npdu", 0),
+ ByteField("next_ex", 0),
+ 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 = [ XBitField("seq", 0, 16),
+ ByteField("npdu", 0),
+ ByteField("next_ex",0),
+ PacketListField("IE_list", [], IE_Dispatcher) ]
+
+class GTPPDUNotificationRequest(Packet):
+ # 3GPP TS 29.060 V9.1.0 (2009-12)
+ name = "GTP PDU Notification Request"
+ fields_desc = [ XBitField("seq", 0, 16),
+ ByteField("npdu", 0),
+ ByteField("next_ex", 0),
+ PacketListField("IE_list", [ IE_IMSI(),
+ IE_TEICP(TEICI=RandInt()),
+ IE_EndUserAddress(PDPTypeNumber=0x21),
+ IE_AccessPointName(),
+ IE_GSNAddress(address="127.0.0.1"),
+ ], IE_Dispatcher) ]
+
+class GTP_U_Header(Packet):
+ # 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),
+ # encapsulated in G-PDUs. A G-PDU is a packet including a GTP-U header and a T-PDU. The Path Protocol
+ # defines the path and the GTP-U header defines the tunnel. Several tunnels may be multiplexed on a single path.
+ 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),
+ BitField("length", None, 16),
+ XBitField("TEID", 0, 32),
+ ConditionalField(XBitField("seq", 0, 16), lambda pkt:pkt.E==1 or pkt.S==1 or pkt.PN==1),
+ ConditionalField(ByteField("npdu", 0), lambda pkt:pkt.E==1 or pkt.S==1 or pkt.PN==1),
+ ConditionalField(ByteField("next_ex", 0), lambda pkt:pkt.E==1 or pkt.S==1 or pkt.PN==1),
+ ]
+
+ def post_build(self, p, pay):
+ p += pay
+ if self.length is None:
+ l = len(p)-8
+ p = p[:2] + struct.pack("!H", l)+ p[4:]
+ return p
+
+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)
+bind_layers(GTPHeader, GTPEchoResponse, gtp_type=2)
+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 GTP-U
+bind_layers(UDP, GTP_U_Header, dport = 2152)
+bind_layers(UDP, GTP_U_Header, sport = 2152)
+bind_layers(GTP_U_Header, IP, gtp_type = 255)
+
+if __name__ == "__main__":
+ from scapy.all import *
+ interact(mydict=globals(), mybanner="GTPv1 add-on")
diff --git a/scapy/contrib/mqtt.uts b/scapy/contrib/mqtt.uts
index 17d92c2d3b90095a2404ec15f8feb0d70306f0c0..0b3f456eede72c88dd0c3c6468d0aa219b194942 100644
--- a/scapy/contrib/mqtt.uts
+++ b/scapy/contrib/mqtt.uts
@@ -1,110 +1,110 @@
-# MQTT layer unit tests
-# Copyright (C) Santiago Hernandez Ramos <shramos@protonmail.com>
-#
-# Type the following command to launch start the tests:
-# $ test/run_tests -P "load_contrib('mqtt')" -t scapy/contrib/mqtt.uts
-
-+ Syntax check
-= Import the MQTT layer
-from scapy.contrib.mqtt import *
-
-
-+ MQTT protocol test
-
-= MQTTPublish, packet instanciation
-p = MQTT()/MQTTPublish(topic='test1',value='test2')
-assert(p.type == 3)
-assert(p.topic == 'test1')
-assert(p.value == 'test2')
-assert(p.len == None)
-assert(p.length == None)
-
-= Fixed header and MQTTPublish, packet dissection
-s = b'0\n\x00\x04testtest'
-publish = MQTT(s)
-assert(publish.type == 3)
-assert(publish.QOS == 0)
-assert(publish.DUP == 0)
-assert(publish.RETAIN == 0)
-assert(publish.len == 10)
-assert(publish[MQTTPublish].length == 4)
-assert(publish[MQTTPublish].topic == 'test')
-assert(publish[MQTTPublish].value == 'test')
-
-
-= MQTTConnect, packet instanciation
-c = MQTT()/MQTTConnect(clientIdlen=5, clientId='newid')
-assert(c.type == 1)
-assert(c.clientId == 'newid')
-assert(c.clientIdlen == 5)
-
-= MQTTConnect, packet dissection
-s = b'\x10\x1f\x00\x06MQIsdp\x03\x02\x00<\x00\x11mosqpub/1440-kali'
-connect = MQTT(s)
-assert(connect.length == 6)
-assert(connect.protoname == 'MQIsdp')
-assert(connect.protolevel == 3)
-assert(connect.usernameflag == 0)
-assert(connect.passwordflag == 0)
-assert(connect.willretainflag == 0)
-assert(connect.willQOSflag == 0)
-assert(connect.willflag == 0)
-assert(connect.cleansess == 1)
-assert(connect.reserved == 0)
-assert(connect.klive == 60)
-assert(connect.clientIdlen == 17)
-assert(connect.clientId == 'mosqpub/1440-kali')
-
-
-=MQTTConnack, packet instanciation
-ck = MQTT()/MQTTConnack(sessPresentFlag=1,retcode=0)
-assert(ck.type == 2)
-assert(ck.sessPresentFlag == 1)
-assert(ck.retcode == 0)
-
-= MQTTConnack, packet dissection
-s = b' \x02\x00\x00'
-connack = MQTT(s)
-assert(connack.sessPresentFlag == 0)
-assert(connack.retcode == 0)
-
-
-= MQTTSubscribe, packet instanciation
-sb = MQTT()/MQTTSubscribe(msgid=1,topic='newtopic',QOS=0,length=0)
-assert(sb.type == 8)
-assert(sb.msgid == 1)
-assert(sb.topic == 'newtopic')
-assert(sb.length == 0)
-assert(sb[MQTTSubscribe].QOS == 0)
-
-= MQTTSubscribe, packet dissection
-s = b'\x82\t\x00\x01\x00\x04test\x00'
-subscribe = MQTT(s)
-assert(subscribe.msgid == 1)
-assert(subscribe.length == 4)
-assert(subscribe.topic == 'test')
-assert(subscribe.QOS == 1)
-
-
-= MQTTSuback, packet instanciation
-sk = MQTT()/MQTTSuback(msgid=1, retcode=0)
-assert(sk.type == 9)
-assert(sk.msgid == 1)
-assert(sk.retcode == 0)
-
-= MQTTSuback, packet dissection
-s = b'\x90\x03\x00\x01\x00'
-suback = MQTT(s)
-assert(suback.msgid == 1)
-assert(suback.retcode == 0)
-
-
-= MQTTPubrec, packet instanciation
-pc = MQTT()/MQTTPubrec(msgid=1)
-assert(pc.type == 5)
-assert(pc.msgid == 1)
-
-= MQTTPubrec packet dissection
-s = b'P\x02\x00\x01'
-pubrec = MQTT(s)
-assert(pubrec.msgid == 1)
+# MQTT layer unit tests
+# Copyright (C) Santiago Hernandez Ramos <shramos@protonmail.com>
+#
+# Type the following command to launch start the tests:
+# $ test/run_tests -P "load_contrib('mqtt')" -t scapy/contrib/mqtt.uts
+
++ Syntax check
+= Import the MQTT layer
+from scapy.contrib.mqtt import *
+
+
++ MQTT protocol test
+
+= MQTTPublish, packet instanciation
+p = MQTT()/MQTTPublish(topic='test1',value='test2')
+assert(p.type == 3)
+assert(p.topic == 'test1')
+assert(p.value == 'test2')
+assert(p.len == None)
+assert(p.length == None)
+
+= Fixed header and MQTTPublish, packet dissection
+s = b'0\n\x00\x04testtest'
+publish = MQTT(s)
+assert(publish.type == 3)
+assert(publish.QOS == 0)
+assert(publish.DUP == 0)
+assert(publish.RETAIN == 0)
+assert(publish.len == 10)
+assert(publish[MQTTPublish].length == 4)
+assert(publish[MQTTPublish].topic == 'test')
+assert(publish[MQTTPublish].value == 'test')
+
+
+= MQTTConnect, packet instanciation
+c = MQTT()/MQTTConnect(clientIdlen=5, clientId='newid')
+assert(c.type == 1)
+assert(c.clientId == 'newid')
+assert(c.clientIdlen == 5)
+
+= MQTTConnect, packet dissection
+s = b'\x10\x1f\x00\x06MQIsdp\x03\x02\x00<\x00\x11mosqpub/1440-kali'
+connect = MQTT(s)
+assert(connect.length == 6)
+assert(connect.protoname == 'MQIsdp')
+assert(connect.protolevel == 3)
+assert(connect.usernameflag == 0)
+assert(connect.passwordflag == 0)
+assert(connect.willretainflag == 0)
+assert(connect.willQOSflag == 0)
+assert(connect.willflag == 0)
+assert(connect.cleansess == 1)
+assert(connect.reserved == 0)
+assert(connect.klive == 60)
+assert(connect.clientIdlen == 17)
+assert(connect.clientId == 'mosqpub/1440-kali')
+
+
+=MQTTConnack, packet instanciation
+ck = MQTT()/MQTTConnack(sessPresentFlag=1,retcode=0)
+assert(ck.type == 2)
+assert(ck.sessPresentFlag == 1)
+assert(ck.retcode == 0)
+
+= MQTTConnack, packet dissection
+s = b' \x02\x00\x00'
+connack = MQTT(s)
+assert(connack.sessPresentFlag == 0)
+assert(connack.retcode == 0)
+
+
+= MQTTSubscribe, packet instanciation
+sb = MQTT()/MQTTSubscribe(msgid=1,topic='newtopic',QOS=0,length=0)
+assert(sb.type == 8)
+assert(sb.msgid == 1)
+assert(sb.topic == 'newtopic')
+assert(sb.length == 0)
+assert(sb[MQTTSubscribe].QOS == 0)
+
+= MQTTSubscribe, packet dissection
+s = b'\x82\t\x00\x01\x00\x04test\x00'
+subscribe = MQTT(s)
+assert(subscribe.msgid == 1)
+assert(subscribe.length == 4)
+assert(subscribe.topic == 'test')
+assert(subscribe.QOS == 1)
+
+
+= MQTTSuback, packet instanciation
+sk = MQTT()/MQTTSuback(msgid=1, retcode=0)
+assert(sk.type == 9)
+assert(sk.msgid == 1)
+assert(sk.retcode == 0)
+
+= MQTTSuback, packet dissection
+s = b'\x90\x03\x00\x01\x00'
+suback = MQTT(s)
+assert(suback.msgid == 1)
+assert(suback.retcode == 0)
+
+
+= MQTTPubrec, packet instanciation
+pc = MQTT()/MQTTPubrec(msgid=1)
+assert(pc.type == 5)
+assert(pc.msgid == 1)
+
+= MQTTPubrec packet dissection
+s = b'P\x02\x00\x01'
+pubrec = MQTT(s)
+assert(pubrec.msgid == 1)
diff --git a/scapy/contrib/ppi.py b/scapy/contrib/ppi.py
index 95d39ed454f820016bbcda9fbb2451f8fd61c050..13945a33faec1247a1b997e51e182611fb5abf5a 100644
--- a/scapy/contrib/ppi.py
+++ b/scapy/contrib/ppi.py
@@ -1,97 +1,97 @@
-# 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/>.
-
-# author: <jellch@harris.com>
-
-# scapy.contrib.description = PPI
-# scapy.contrib.status = loads
-
-
-"""
-PPI (Per-Packet Information).
-"""
-import logging,struct
-from scapy.config import conf
-from scapy.packet import *
-from scapy.fields import *
-from scapy.layers.l2 import Ether
-from scapy.layers.dot11 import Dot11
-
-# Dictionary to map the TLV type to the class name of a sub-packet
-_ppi_types = {}
-def addPPIType(id, value):
- _ppi_types[id] = value
-def getPPIType(id, default="default"):
- return _ppi_types.get(id, _ppi_types.get(default, None))
-
-
-# Default PPI Field Header
-class PPIGenericFldHdr(Packet):
- name = "PPI Field Header"
- fields_desc = [ LEShortField('pfh_type', 0),
- FieldLenField('pfh_length', None, length_of="value", fmt='<H', adjust=lambda p,x:x+4),
- StrLenField("value", "", length_from=lambda p:p.pfh_length) ]
-
- def extract_padding(self, p):
- return "",p
-
-def _PPIGuessPayloadClass(p, **kargs):
- """ This function tells the PacketListField how it should extract the
- TLVs from the payload. We pass cls only the length string
- pfh_len says it needs. If a payload is returned, that means
- part of the sting was unused. This converts to a Raw layer, and
- the remainder of p is added as Raw's payload. If there is no
- payload, the remainder of p is added as out's payload.
- """
- if len(p) >= 4:
- t,pfh_len = struct.unpack("<HH", p[:4])
- # Find out if the value t is in the dict _ppi_types.
- # If not, return the default TLV class
- cls = getPPIType(t, "default")
- pfh_len += 4
- out = cls(p[:pfh_len], **kargs)
- if (out.payload):
- out.payload = conf.raw_layer(out.payload.load)
- if (len(p) > pfh_len):
- out.payload.payload = conf.padding_layer(p[pfh_len:])
- elif (len(p) > pfh_len):
- out.payload = conf.padding_layer(p[pfh_len:])
-
- else:
- out = conf.raw_layer(p, **kargs)
- return out
-
-
-
-
-class PPI(Packet):
- name = "PPI Packet Header"
- fields_desc = [ ByteField('pph_version', 0),
- ByteField('pph_flags', 0),
- FieldLenField('pph_len', None, length_of="PPIFieldHeaders", fmt="<H", adjust=lambda p,x:x+8 ),
- LEIntField('dlt', None),
- PacketListField("PPIFieldHeaders", [], _PPIGuessPayloadClass, length_from=lambda p:p.pph_len-8,) ]
- def guess_payload_class(self,payload):
- return conf.l2types.get(self.dlt, Packet.guess_payload_class(self, payload))
-
-#Register PPI
-addPPIType("default", PPIGenericFldHdr)
-
-conf.l2types.register(192, PPI)
-conf.l2types.register_num2layer(192, PPI)
-
-bind_layers(PPI, Dot11, dlt=conf.l2types.get(Dot11))
-bind_layers(Dot11, PPI)
-bind_layers(PPI, Ether, dlt=conf.l2types.get(Ether))
-bind_layers(Dot11, Ether)
+# 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/>.
+
+# author: <jellch@harris.com>
+
+# scapy.contrib.description = PPI
+# scapy.contrib.status = loads
+
+
+"""
+PPI (Per-Packet Information).
+"""
+import logging,struct
+from scapy.config import conf
+from scapy.packet import *
+from scapy.fields import *
+from scapy.layers.l2 import Ether
+from scapy.layers.dot11 import Dot11
+
+# Dictionary to map the TLV type to the class name of a sub-packet
+_ppi_types = {}
+def addPPIType(id, value):
+ _ppi_types[id] = value
+def getPPIType(id, default="default"):
+ return _ppi_types.get(id, _ppi_types.get(default, None))
+
+
+# Default PPI Field Header
+class PPIGenericFldHdr(Packet):
+ name = "PPI Field Header"
+ fields_desc = [ LEShortField('pfh_type', 0),
+ FieldLenField('pfh_length', None, length_of="value", fmt='<H', adjust=lambda p,x:x+4),
+ StrLenField("value", "", length_from=lambda p:p.pfh_length) ]
+
+ def extract_padding(self, p):
+ return "",p
+
+def _PPIGuessPayloadClass(p, **kargs):
+ """ This function tells the PacketListField how it should extract the
+ TLVs from the payload. We pass cls only the length string
+ pfh_len says it needs. If a payload is returned, that means
+ part of the sting was unused. This converts to a Raw layer, and
+ the remainder of p is added as Raw's payload. If there is no
+ payload, the remainder of p is added as out's payload.
+ """
+ if len(p) >= 4:
+ t,pfh_len = struct.unpack("<HH", p[:4])
+ # Find out if the value t is in the dict _ppi_types.
+ # If not, return the default TLV class
+ cls = getPPIType(t, "default")
+ pfh_len += 4
+ out = cls(p[:pfh_len], **kargs)
+ if (out.payload):
+ out.payload = conf.raw_layer(out.payload.load)
+ if (len(p) > pfh_len):
+ out.payload.payload = conf.padding_layer(p[pfh_len:])
+ elif (len(p) > pfh_len):
+ out.payload = conf.padding_layer(p[pfh_len:])
+
+ else:
+ out = conf.raw_layer(p, **kargs)
+ return out
+
+
+
+
+class PPI(Packet):
+ name = "PPI Packet Header"
+ fields_desc = [ ByteField('pph_version', 0),
+ ByteField('pph_flags', 0),
+ FieldLenField('pph_len', None, length_of="PPIFieldHeaders", fmt="<H", adjust=lambda p,x:x+8 ),
+ LEIntField('dlt', None),
+ PacketListField("PPIFieldHeaders", [], _PPIGuessPayloadClass, length_from=lambda p:p.pph_len-8,) ]
+ def guess_payload_class(self,payload):
+ return conf.l2types.get(self.dlt, Packet.guess_payload_class(self, payload))
+
+#Register PPI
+addPPIType("default", PPIGenericFldHdr)
+
+conf.l2types.register(192, PPI)
+conf.l2types.register_num2layer(192, PPI)
+
+bind_layers(PPI, Dot11, dlt=conf.l2types.get(Dot11))
+bind_layers(Dot11, PPI)
+bind_layers(PPI, Ether, dlt=conf.l2types.get(Ether))
+bind_layers(Dot11, Ether)
diff --git a/scapy/contrib/ppi_cace.py b/scapy/contrib/ppi_cace.py
index 9fc63d25b8d27617f698e327d4b8d6d7c73a72a6..b1896be21e6f209be331f5a84b1ee25278972223 100644
--- a/scapy/contrib/ppi_cace.py
+++ b/scapy/contrib/ppi_cace.py
@@ -1,98 +1,98 @@
-# 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/>.
-
-# author: <jellch@harris.com>
-
-# scapy.contrib.description = PPI CACE
-# scapy.contrib.status = loads
-
-"""
-CACE PPI types
-"""
-import logging,struct
-from scapy.config import conf
-from scapy.packet import *
-from scapy.fields import *
-from scapy.layers.l2 import Ether
-from scapy.layers.dot11 import Dot11
-from scapy.contrib.ppi import *
-
-PPI_DOT11COMMON = 2
-PPI_DOT11NMAC = 3
-PPI_DOT11NMACPHY = 4
-PPI_SPECTRUMMAP = 5
-PPI_PROCESSINFO = 6
-PPI_CAPTUREINFO = 7
-PPI_AGGREGATION = 8
-PPI_DOT3 = 9
-
-# PPI 802.11 Common Field Header Fields
-class dBmByteField(Field):
- def __init__(self, name, default):
- Field.__init__(self, name, default, "b")
- def i2repr(self, pkt, val):
- if (val != None):
- val = "%4d dBm" % val
- return val
-
-class PPITSFTField(LELongField):
- def i2h(self, pkt, val):
- flags = 0
- if (pkt):
- flags = pkt.getfieldval("Pkt_Flags")
- if not flags:
- flags = 0
- if (flags & 0x02):
- scale = 1e-3
- else:
- scale = 1e-6
- tout = scale * float(val)
- return tout
- def h2i(self, pkt, val):
- scale = 1e6
- if pkt:
- flags = pkt.getfieldval("Pkt_Flags")
- if flags:
- if (flags & 0x02):
- scale = 1e3
- tout = int((scale * val) + 0.5)
- return tout
-
-_PPIDot11CommonChFlags = ['','','','','Turbo','CCK','OFDM','2GHz','5GHz',
- 'PassiveOnly','Dynamic CCK-OFDM','GSFK']
-
-_PPIDot11CommonPktFlags = ['FCS','TSFT_ms','FCS_Invalid','PHY_Error']
-
-# PPI 802.11 Common Field Header
-class Dot11Common(Packet):
- name = "PPI 802.11-Common"
- fields_desc = [ LEShortField('pfh_type',PPI_DOT11COMMON),
- LEShortField('pfh_length', 20),
- PPITSFTField('TSF_Timer', 0),
- FlagsField('Pkt_Flags',0, -16, _PPIDot11CommonPktFlags),
- LEShortField('Rate',0),
- LEShortField('Ch_Freq',0),
- FlagsField('Ch_Flags', 0, -16, _PPIDot11CommonChFlags),
- ByteField('FHSS_Hop',0),
- ByteField('FHSS_Pat',0),
- dBmByteField('Antsignal',-128),
- dBmByteField('Antnoise',-128)]
-
- def extract_padding(self, p):
- return "",p
-#Hopefully other CACE defined types will be added here.
-
-#Add the dot11common layer to the PPI array
-addPPIType(PPI_DOT11COMMON, Dot11Common)
-
+# 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/>.
+
+# author: <jellch@harris.com>
+
+# scapy.contrib.description = PPI CACE
+# scapy.contrib.status = loads
+
+"""
+CACE PPI types
+"""
+import logging,struct
+from scapy.config import conf
+from scapy.packet import *
+from scapy.fields import *
+from scapy.layers.l2 import Ether
+from scapy.layers.dot11 import Dot11
+from scapy.contrib.ppi import *
+
+PPI_DOT11COMMON = 2
+PPI_DOT11NMAC = 3
+PPI_DOT11NMACPHY = 4
+PPI_SPECTRUMMAP = 5
+PPI_PROCESSINFO = 6
+PPI_CAPTUREINFO = 7
+PPI_AGGREGATION = 8
+PPI_DOT3 = 9
+
+# PPI 802.11 Common Field Header Fields
+class dBmByteField(Field):
+ def __init__(self, name, default):
+ Field.__init__(self, name, default, "b")
+ def i2repr(self, pkt, val):
+ if (val != None):
+ val = "%4d dBm" % val
+ return val
+
+class PPITSFTField(LELongField):
+ def i2h(self, pkt, val):
+ flags = 0
+ if (pkt):
+ flags = pkt.getfieldval("Pkt_Flags")
+ if not flags:
+ flags = 0
+ if (flags & 0x02):
+ scale = 1e-3
+ else:
+ scale = 1e-6
+ tout = scale * float(val)
+ return tout
+ def h2i(self, pkt, val):
+ scale = 1e6
+ if pkt:
+ flags = pkt.getfieldval("Pkt_Flags")
+ if flags:
+ if (flags & 0x02):
+ scale = 1e3
+ tout = int((scale * val) + 0.5)
+ return tout
+
+_PPIDot11CommonChFlags = ['','','','','Turbo','CCK','OFDM','2GHz','5GHz',
+ 'PassiveOnly','Dynamic CCK-OFDM','GSFK']
+
+_PPIDot11CommonPktFlags = ['FCS','TSFT_ms','FCS_Invalid','PHY_Error']
+
+# PPI 802.11 Common Field Header
+class Dot11Common(Packet):
+ name = "PPI 802.11-Common"
+ fields_desc = [ LEShortField('pfh_type',PPI_DOT11COMMON),
+ LEShortField('pfh_length', 20),
+ PPITSFTField('TSF_Timer', 0),
+ FlagsField('Pkt_Flags',0, -16, _PPIDot11CommonPktFlags),
+ LEShortField('Rate',0),
+ LEShortField('Ch_Freq',0),
+ FlagsField('Ch_Flags', 0, -16, _PPIDot11CommonChFlags),
+ ByteField('FHSS_Hop',0),
+ ByteField('FHSS_Pat',0),
+ dBmByteField('Antsignal',-128),
+ dBmByteField('Antnoise',-128)]
+
+ def extract_padding(self, p):
+ return "",p
+#Hopefully other CACE defined types will be added here.
+
+#Add the dot11common layer to the PPI array
+addPPIType(PPI_DOT11COMMON, Dot11Common)
+
diff --git a/scapy/contrib/ppi_geotag.py b/scapy/contrib/ppi_geotag.py
index 47b3d83f35526248e7da04ca37ac7a1893a1cdfb..23fe38b0cc84561ba48f5c8c9b1c4c6f92f7eaf8 100644
--- a/scapy/contrib/ppi_geotag.py
+++ b/scapy/contrib/ppi_geotag.py
@@ -1,459 +1,459 @@
-# 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/>.
-
-# author: <jellch@harris.com>
-
-# scapy.contrib.description = PPI GEOLOCATION
-# scapy.contrib.status = loads
-
-
-"""
-PPI-GEOLOCATION tags
-"""
-import struct, time
-from scapy.packet import *
-from scapy.fields import *
-from scapy.contrib.ppi import PPIGenericFldHdr,addPPIType
-from scapy.error import warning
-
-CURR_GEOTAG_VER = 2 #Major revision of specification
-
-PPI_GPS = 30002
-PPI_VECTOR = 30003
-PPI_SENSOR = 30004
-PPI_ANTENNA = 30005
-#The FixedX_Y Fields are used to store fixed point numbers in a variety of fields in the GEOLOCATION-TAGS specification
-class Fixed3_6Field(LEIntField):
- def i2h(self, pkt, x):
- if x is not None:
- if (x < 0):
- warning("Fixed3_6: Internal value too negative: %d" % x)
- x = 0
- elif (x > 999999999):
- warning("Fixed3_6: Internal value too positive: %d" % x)
- x = 999999999
- x = x * 1e-6
- return x
- def h2i(self, pkt, x):
- if x is not None:
- if (x <= -0.5e-6):
- warning("Fixed3_6: Input value too negative: %.7f" % x)
- x = 0
- elif (x >= 999.9999995):
- warning("Fixed3_6: Input value too positive: %.7f" % x)
- x = 999.999999
- x = int(round(x * 1e6))
- return x
- def i2m(self, pkt, x):
- """Convert internal value to machine value"""
- if x is None:
- #Try to return zero if undefined
- x = self.h2i(pkt, 0)
- return x
-
- def i2repr(self,pkt,x):
- if x is None:
- y=0
- else:
- y=self.i2h(pkt,x)
- return "%3.6f"%(y)
-class Fixed3_7Field(LEIntField):
- def i2h(self, pkt, x):
- if x is not None:
- if (x < 0):
- warning("Fixed3_7: Internal value too negative: %d" % x)
- x = 0
- elif (x > 3600000000):
- warning("Fixed3_7: Internal value too positive: %d" % x)
- x = 3600000000
- x = (x - 1800000000) * 1e-7
- return x
- def h2i(self, pkt, x):
- if x is not None:
- if (x <= -180.00000005):
- warning("Fixed3_7: Input value too negative: %.8f" % x)
- x = -180.0
- elif (x >= 180.00000005):
- warning("Fixed3_7: Input value too positive: %.8f" % x)
- x = 180.0
- x = int(round((x + 180.0) * 1e7))
- return x
- def i2m(self, pkt, x):
- """Convert internal value to machine value"""
- if x is None:
- #Try to return zero if undefined
- x = self.h2i(pkt, 0)
- return x
- def i2repr(self,pkt,x):
- if x is None:
- y=0
- else:
- y=self.i2h(pkt,x)
- return "%3.7f"%(y)
-
-class Fixed6_4Field(LEIntField):
- def i2h(self, pkt, x):
- if x is not None:
- if (x < 0):
- warning("Fixed6_4: Internal value too negative: %d" % x)
- x = 0
- elif (x > 3600000000):
- warning("Fixed6_4: Internal value too positive: %d" % x)
- x = 3600000000
- x = (x - 1800000000) * 1e-4
- return x
- def h2i(self, pkt, x):
- if x is not None:
- if (x <= -180000.00005):
- warning("Fixed6_4: Input value too negative: %.5f" % x)
- x = -180000.0
- elif (x >= 180000.00005):
- warning("Fixed6_4: Input value too positive: %.5f" % x)
- x = 180000.0
- x = int(round((x + 180000.0) * 1e4))
- return x
- def i2m(self, pkt, x):
- """Convert internal value to machine value"""
- if x is None:
- #Try to return zero if undefined
- x = self.h2i(pkt, 0)
- return x
- def i2repr(self,pkt,x):
- if x is None:
- y=0
- else:
- y=self.i2h(pkt,x)
- return "%6.4f"%(y)
-#The GPS timestamps fractional time counter is stored in a 32-bit unsigned ns counter.
-#The ept field is as well,
-class NSCounter_Field(LEIntField):
- def i2h(self, pkt, x): #converts nano-seconds to seconds for output
- if x is not None:
- if (x < 0):
- warning("NSCounter_Field: Internal value too negative: %d" % x)
- x = 0
- elif (x >= 2**32):
- warning("NSCounter_Field: Internal value too positive: %d" % x)
- x = 2**32-1
- x = (x / 1e9)
- return x
- def h2i(self, pkt, x): #converts input in seconds into nano-seconds for storage
- if x is not None:
- if (x < 0):
- warning("NSCounter_Field: Input value too negative: %.10f" % x)
- x = 0
- elif (x >= (2**32) / 1e9):
- warning("NSCounter_Field: Input value too positive: %.10f" % x)
- x = (2**32-1) / 1e9
- x = int(round((x * 1e9)))
- return x
- def i2repr(self,pkt,x):
- if x is None:
- y=0
- else:
- y=self.i2h(pkt,x)
- return "%1.9f"%(y)
-
-class LETimeField(UTCTimeField,LEIntField):
- __slots__ = ["epoch", "delta", "strf"]
- def __init__(self, name, default, epoch=None, strf="%a, %d %b %Y %H:%M:%S +0000"):
- LEIntField.__init__(self, name, default)
- UTCTimeField.__init__(self, name, default, epoch=epoch, strf=strf)
-
-class SignedByteField(Field):
- def __init__(self, name, default):
- Field.__init__(self, name, default, "b")
- def randval(self):
- return RandSByte()
-
-class XLEShortField(LEShortField,XShortField):
- def i2repr(self, pkt, x):
- return XShortField.i2repr(self, pkt, x)
-
-class XLEIntField(LEIntField,XIntField):
- def i2repr(self, pkt, x):
- return XIntField.i2repr(self, pkt, x)
-
-class GPSTime_Field(LETimeField):
- def __init__(self, name, default):
- return LETimeField.__init__(self, name, default, strf="%a, %d %b %Y %H:%M:%S UTC")
-
-class VectorFlags_Field(XLEIntField):
- """Represents te VectorFlags field. Handles the RelativeTo:sub-field"""
- _fwdstr = "DefinesForward"
- _resmask = 0xfffffff8
- _relmask = 0x6
- _relnames = ["RelativeToForward", "RelativeToEarth", "RelativeToCurrent", "RelativeToReserved"]
- _relvals = [0x00, 0x02, 0x04, 0x06]
- def i2repr(self, pkt, x):
- if x is None:
- return str(x)
- r = []
- if (x & 0x1):
- r.append(self._fwdstr)
- i = (x & self._relmask) >> 1
- r.append(self._relnames[i])
- i = x & self._resmask
- if (i):
- r.append("ReservedBits:%08X" % i)
- sout = "+".join(r)
- return sout
- def any2i(self, pkt, x):
- if isinstance(x, str):
- r = x.split("+")
- y = 0
- for value in r:
- if (value == self._fwdstr):
- y |= 0x1
- elif (value in self._relnames):
- i = self._relnames.index(value)
- y &= (~self._relmask)
- y |= self._relvals[i]
- else:
- #logging.warning("Unknown VectorFlags Argument: %s" % value)
- pass
- else:
- y = x
- #print "any2i: %s --> %s" % (str(x), str(y))
- return y
-
-class HCSIFlagsField(FlagsField):
- """ A FlagsField where each bit/flag turns a conditional field on or off.
- If the value is None when building a packet, i2m() will check the value of
- every field in self.names. If the field's value is not None, the corresponding
- flag will be set. """
- def i2m(self, pkt, val):
- if val is None:
- val = 0
- if (pkt):
- for i, name in enumerate(self.names):
- value = pkt.getfieldval(name)
- if value is not None:
- val |= 1 << i
- return val
-
-class HCSINullField(StrFixedLenField):
- def __init__(self, name, default):
- return StrFixedLenField.__init__(self, name, default, length=0)
-
-class HCSIDescField(StrFixedLenField):
- def __init__(self, name, default):
- return StrFixedLenField.__init__(self, name, default, length=32)
-
-class HCSIAppField(StrFixedLenField):
- def __init__(self, name, default):
- return StrFixedLenField.__init__(self, name, default, length=60)
-
-def _FlagsList(myfields):
- flags = ["Reserved%02d" % i for i in xrange(32)]
- for i, value in myfields.iteritems():
- flags[i] = value
- return flags
-
-# Define all geolocation-tag flags lists
-_hcsi_gps_flags = _FlagsList({0:"No Fix Available", 1:"GPS", 2:"Differential GPS",
- 3:"Pulse Per Second", 4:"Real Time Kinematic",
- 5:"Float Real Time Kinematic", 6:"Estimated (Dead Reckoning)",
- 7:"Manual Input", 8:"Simulation"})
-
-#_hcsi_vector_flags = _FlagsList({0:"ForwardFrame", 1:"RotationsAbsoluteXYZ", 5:"OffsetFromGPS_XYZ"})
-#This has been replaced with the VectorFlags_Field class, in order to handle the RelativeTo:subfield
-
-_hcsi_vector_char_flags = _FlagsList({0:"Antenna", 1:"Direction of Travel",
- 2:"Front of Vehicle", 3:"Angle of Arrival", 4:"Transmitter Position",
- 8:"GPS Derived", 9:"INS Derived", 10:"Compass Derived",
- 11:"Acclerometer Derived", 12:"Human Derived"})
-
-_hcsi_antenna_flags = _FlagsList({ 1:"Horizontal Polarization", 2:"Vertical Polarization",
- 3:"Circular Polarization Left", 4:"Circular Polarization Right",
- 16:"Electronically Steerable", 17:"Mechanically Steerable"})
-
-""" HCSI PPI Fields are similar to RadioTap. A mask field called "present" specifies if each field
-is present. All other fields are conditional. When dissecting a packet, each field is present if
-"present" has the corresponding bit set. When building a packet, if "present" is None, the mask is
-set to include every field that does not have a value of None. Otherwise, if the mask field is
-not None, only the fields specified by "present" will be added to the packet.
-
-To build each Packet type, build a list of the fields normally, excluding the present bitmask field.
-The code will then construct conditional versions of each field and add the present field.
-See GPS_Fields as an example. """
-
-# Conditional test for all HCSI Fields
-def _HCSITest(pkt, ibit, name):
- if pkt.present is None:
- return (pkt.getfieldval(name) is not None)
- return pkt.present & ibit
-
-# Wrap optional fields in ConditionalField, add HCSIFlagsField
-def _HCSIBuildFields(fields):
- names = [f.name for f in fields]
- cond_fields = [HCSIFlagsField('present', None, -len(names), names)]
- for i, name in enumerate(names):
- ibit = 1 << i
- seval = "lambda pkt:_HCSITest(pkt,%s,'%s')" % (ibit, name)
- test = eval(seval)
- cond_fields.append(ConditionalField(fields[i], test))
- return cond_fields
-
-class HCSIPacket(Packet):
- name = "PPI HCSI"
- fields_desc = [ LEShortField('pfh_type', None),
- LEShortField('pfh_length', None),
- ByteField('geotag_ver', CURR_GEOTAG_VER),
- ByteField('geotag_pad', 0),
- LEShortField('geotag_len', None)]
- def post_build(self, p, pay):
- if self.pfh_length is None:
- l = len(p) - 4
- sl = struct.pack('<H',l)
- p = p[:2] + sl + p[4:]
- if self.geotag_len is None:
- l_g = len(p) - 4
- sl_g = struct.pack('<H',l_g)
- p = p[:6] + sl_g + p[8:]
- p += pay
- return p
- def extract_padding(self, p):
- return "",p
-
-#GPS Fields
-GPS_Fields = [FlagsField("GPSFlags", None, -32, _hcsi_gps_flags),
- Fixed3_7Field("Latitude", None),
- Fixed3_7Field("Longitude", None), Fixed6_4Field("Altitude", None),
- Fixed6_4Field("Altitude_g", None), GPSTime_Field("GPSTime", None),
- NSCounter_Field("FractionalTime", None), Fixed3_6Field("eph", None),
- Fixed3_6Field("epv", None), NSCounter_Field("ept", None),
- HCSINullField("Reserved10", None), HCSINullField("Reserved11", None),
- HCSINullField("Reserved12", None), HCSINullField("Reserved13", None),
- HCSINullField("Reserved14", None), HCSINullField("Reserved15", None),
- HCSINullField("Reserved16", None), HCSINullField("Reserved17", None),
- HCSINullField("Reserved18", None), HCSINullField("Reserved19", None),
- HCSINullField("Reserved20", None), HCSINullField("Reserved21", None),
- HCSINullField("Reserved22", None), HCSINullField("Reserved23", None),
- HCSINullField("Reserved24", None), HCSINullField("Reserved25", None),
- HCSINullField("Reserved26", None), HCSINullField("Reserved27", None),
- HCSIDescField("DescString", None), XLEIntField("AppId", None),
- HCSIAppField("AppData", None), HCSINullField("Extended", None)]
-
-class GPS(HCSIPacket):
- name = "PPI GPS"
- fields_desc = [ LEShortField('pfh_type', PPI_GPS), #pfh_type
- LEShortField('pfh_length', None), #pfh_len
- ByteField('geotag_ver', CURR_GEOTAG_VER), #base_geotag_header.ver
- ByteField('geotag_pad', 0), #base_geotag_header.pad
- LEShortField('geotag_len', None)] + _HCSIBuildFields(GPS_Fields)
-
-
-#Vector Fields
-VEC_Fields = [VectorFlags_Field("VectorFlags", None),
- FlagsField("VectorChars", None, -32, _hcsi_vector_char_flags),
- Fixed3_6Field("Pitch", None), Fixed3_6Field("Roll", None),
- Fixed3_6Field("Heading", None), Fixed6_4Field("Off_X", None),
- Fixed6_4Field("Off_Y", None), Fixed6_4Field("Off_Z", None),
- HCSINullField("Reserved08", None), HCSINullField("Reserved09", None),
- HCSINullField("Reserved10", None), HCSINullField("Reserved11", None),
- HCSINullField("Reserved12", None), HCSINullField("Reserved13", None),
- HCSINullField("Reserved14", None), HCSINullField("Reserved15", None),
- Fixed3_6Field("Err_Rot", None), Fixed6_4Field("Err_Off", None),
- HCSINullField("Reserved18", None), HCSINullField("Reserved19", None),
- HCSINullField("Reserved20", None), HCSINullField("Reserved21", None),
- HCSINullField("Reserved22", None), HCSINullField("Reserved23", None),
- HCSINullField("Reserved24", None), HCSINullField("Reserved25", None),
- HCSINullField("Reserved26", None), HCSINullField("Reserved27", None),
- HCSIDescField("DescString", None), XLEIntField("AppId", None),
- HCSIAppField("AppData", None), HCSINullField("Extended", None)]
-
-class Vector(HCSIPacket):
- name = "PPI Vector"
- fields_desc = [ LEShortField('pfh_type', PPI_VECTOR), #pfh_type
- LEShortField('pfh_length', None), #pfh_len
- ByteField('geotag_ver', CURR_GEOTAG_VER), #base_geotag_header.ver
- ByteField('geotag_pad', 0), #base_geotag_header.pad
- LEShortField('geotag_len', None)] + _HCSIBuildFields(VEC_Fields)
-
-#Sensor Fields
-# http://www.iana.org/assignments/icmp-parameters
-sensor_types= { 1 : "Velocity",
- 2 : "Acceleration",
- 3 : "Jerk",
- 100 : "Rotation",
- 101 : "Magnetic",
- 1000: "Temperature",
- 1001: "Barometer",
- 1002: "Humidity",
- 2000: "TDOA_Clock",
- 2001: "Phase"
- }
-SENS_Fields = [ LEShortEnumField('SensorType', None, sensor_types),
- SignedByteField('ScaleFactor', None),
- Fixed6_4Field('Val_X', None),
- Fixed6_4Field('Val_Y', None),
- Fixed6_4Field('Val_Z', None),
- Fixed6_4Field('Val_T', None),
- Fixed6_4Field('Val_E', None),
- HCSINullField("Reserved07", None), HCSINullField("Reserved08", None),
- HCSINullField("Reserved09", None), HCSINullField("Reserved10", None),
- HCSINullField("Reserved11", None), HCSINullField("Reserved12", None),
- HCSINullField("Reserved13", None), HCSINullField("Reserved14", None),
- HCSINullField("Reserved15", None), HCSINullField("Reserved16", None),
- HCSINullField("Reserved17", None), HCSINullField("Reserved18", None),
- HCSINullField("Reserved19", None), HCSINullField("Reserved20", None),
- HCSINullField("Reserved21", None), HCSINullField("Reserved22", None),
- HCSINullField("Reserved23", None), HCSINullField("Reserved24", None),
- HCSINullField("Reserved25", None), HCSINullField("Reserved26", None),
- HCSINullField("Reserved27", None),
- HCSIDescField("DescString", None), XLEIntField("AppId", None),
- HCSIAppField("AppData", None), HCSINullField("Extended", None)]
-
-
-
-class Sensor(HCSIPacket):
- name = "PPI Sensor"
- fields_desc = [ LEShortField('pfh_type', PPI_SENSOR), #pfh_type
- LEShortField('pfh_length', None), #pfh_len
- ByteField('geotag_ver', CURR_GEOTAG_VER ), #base_geotag_header.ver
- ByteField('geotag_pad', 0), #base_geotag_header.pad
- LEShortField('geotag_len', None)] + _HCSIBuildFields(SENS_Fields)
-
-# HCSIAntenna Fields
-ANT_Fields = [FlagsField("AntennaFlags", None, -32, _hcsi_antenna_flags),
- ByteField("Gain", None),
- Fixed3_6Field("HorizBw", None), Fixed3_6Field("VertBw", None),
- Fixed3_6Field("PrecisionGain",None), XLEShortField("BeamID", None),
- HCSINullField("Reserved06", None), HCSINullField("Reserved07", None),
- HCSINullField("Reserved08", None), HCSINullField("Reserved09", None),
- HCSINullField("Reserved10", None), HCSINullField("Reserved11", None),
- HCSINullField("Reserved12", None), HCSINullField("Reserved13", None),
- HCSINullField("Reserved14", None), HCSINullField("Reserved15", None),
- HCSINullField("Reserved16", None), HCSINullField("Reserved17", None),
- HCSINullField("Reserved18", None), HCSINullField("Reserved19", None),
- HCSINullField("Reserved20", None), HCSINullField("Reserved21", None),
- HCSINullField("Reserved22", None), HCSINullField("Reserved23", None),
- HCSINullField("Reserved24", None), HCSINullField("Reserved25", None),
- HCSIDescField("SerialNumber", None), HCSIDescField("ModelName", None),
- HCSIDescField("DescString", None), XLEIntField("AppId", None),
- HCSIAppField("AppData", None), HCSINullField("Extended", None)]
-
-class Antenna(HCSIPacket):
- name = "PPI Antenna"
- fields_desc = [ LEShortField('pfh_type', PPI_ANTENNA), #pfh_type
- LEShortField('pfh_length', None), #pfh_len
- ByteField('geotag_ver', CURR_GEOTAG_VER), #base_geotag_header.ver
- ByteField('geotag_pad', 0), #base_geotag_header.pad
- LEShortField('geotag_len', None)] + _HCSIBuildFields(ANT_Fields)
-
-addPPIType(PPI_GPS, GPS)
-addPPIType(PPI_VECTOR, Vector)
-addPPIType(PPI_SENSOR, Sensor)
-addPPIType(PPI_ANTENNA,Antenna)
+# 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/>.
+
+# author: <jellch@harris.com>
+
+# scapy.contrib.description = PPI GEOLOCATION
+# scapy.contrib.status = loads
+
+
+"""
+PPI-GEOLOCATION tags
+"""
+import struct, time
+from scapy.packet import *
+from scapy.fields import *
+from scapy.contrib.ppi import PPIGenericFldHdr,addPPIType
+from scapy.error import warning
+
+CURR_GEOTAG_VER = 2 #Major revision of specification
+
+PPI_GPS = 30002
+PPI_VECTOR = 30003
+PPI_SENSOR = 30004
+PPI_ANTENNA = 30005
+#The FixedX_Y Fields are used to store fixed point numbers in a variety of fields in the GEOLOCATION-TAGS specification
+class Fixed3_6Field(LEIntField):
+ def i2h(self, pkt, x):
+ if x is not None:
+ if (x < 0):
+ warning("Fixed3_6: Internal value too negative: %d" % x)
+ x = 0
+ elif (x > 999999999):
+ warning("Fixed3_6: Internal value too positive: %d" % x)
+ x = 999999999
+ x = x * 1e-6
+ return x
+ def h2i(self, pkt, x):
+ if x is not None:
+ if (x <= -0.5e-6):
+ warning("Fixed3_6: Input value too negative: %.7f" % x)
+ x = 0
+ elif (x >= 999.9999995):
+ warning("Fixed3_6: Input value too positive: %.7f" % x)
+ x = 999.999999
+ x = int(round(x * 1e6))
+ return x
+ def i2m(self, pkt, x):
+ """Convert internal value to machine value"""
+ if x is None:
+ #Try to return zero if undefined
+ x = self.h2i(pkt, 0)
+ return x
+
+ def i2repr(self,pkt,x):
+ if x is None:
+ y=0
+ else:
+ y=self.i2h(pkt,x)
+ return "%3.6f"%(y)
+class Fixed3_7Field(LEIntField):
+ def i2h(self, pkt, x):
+ if x is not None:
+ if (x < 0):
+ warning("Fixed3_7: Internal value too negative: %d" % x)
+ x = 0
+ elif (x > 3600000000):
+ warning("Fixed3_7: Internal value too positive: %d" % x)
+ x = 3600000000
+ x = (x - 1800000000) * 1e-7
+ return x
+ def h2i(self, pkt, x):
+ if x is not None:
+ if (x <= -180.00000005):
+ warning("Fixed3_7: Input value too negative: %.8f" % x)
+ x = -180.0
+ elif (x >= 180.00000005):
+ warning("Fixed3_7: Input value too positive: %.8f" % x)
+ x = 180.0
+ x = int(round((x + 180.0) * 1e7))
+ return x
+ def i2m(self, pkt, x):
+ """Convert internal value to machine value"""
+ if x is None:
+ #Try to return zero if undefined
+ x = self.h2i(pkt, 0)
+ return x
+ def i2repr(self,pkt,x):
+ if x is None:
+ y=0
+ else:
+ y=self.i2h(pkt,x)
+ return "%3.7f"%(y)
+
+class Fixed6_4Field(LEIntField):
+ def i2h(self, pkt, x):
+ if x is not None:
+ if (x < 0):
+ warning("Fixed6_4: Internal value too negative: %d" % x)
+ x = 0
+ elif (x > 3600000000):
+ warning("Fixed6_4: Internal value too positive: %d" % x)
+ x = 3600000000
+ x = (x - 1800000000) * 1e-4
+ return x
+ def h2i(self, pkt, x):
+ if x is not None:
+ if (x <= -180000.00005):
+ warning("Fixed6_4: Input value too negative: %.5f" % x)
+ x = -180000.0
+ elif (x >= 180000.00005):
+ warning("Fixed6_4: Input value too positive: %.5f" % x)
+ x = 180000.0
+ x = int(round((x + 180000.0) * 1e4))
+ return x
+ def i2m(self, pkt, x):
+ """Convert internal value to machine value"""
+ if x is None:
+ #Try to return zero if undefined
+ x = self.h2i(pkt, 0)
+ return x
+ def i2repr(self,pkt,x):
+ if x is None:
+ y=0
+ else:
+ y=self.i2h(pkt,x)
+ return "%6.4f"%(y)
+#The GPS timestamps fractional time counter is stored in a 32-bit unsigned ns counter.
+#The ept field is as well,
+class NSCounter_Field(LEIntField):
+ def i2h(self, pkt, x): #converts nano-seconds to seconds for output
+ if x is not None:
+ if (x < 0):
+ warning("NSCounter_Field: Internal value too negative: %d" % x)
+ x = 0
+ elif (x >= 2**32):
+ warning("NSCounter_Field: Internal value too positive: %d" % x)
+ x = 2**32-1
+ x = (x / 1e9)
+ return x
+ def h2i(self, pkt, x): #converts input in seconds into nano-seconds for storage
+ if x is not None:
+ if (x < 0):
+ warning("NSCounter_Field: Input value too negative: %.10f" % x)
+ x = 0
+ elif (x >= (2**32) / 1e9):
+ warning("NSCounter_Field: Input value too positive: %.10f" % x)
+ x = (2**32-1) / 1e9
+ x = int(round((x * 1e9)))
+ return x
+ def i2repr(self,pkt,x):
+ if x is None:
+ y=0
+ else:
+ y=self.i2h(pkt,x)
+ return "%1.9f"%(y)
+
+class LETimeField(UTCTimeField,LEIntField):
+ __slots__ = ["epoch", "delta", "strf"]
+ def __init__(self, name, default, epoch=None, strf="%a, %d %b %Y %H:%M:%S +0000"):
+ LEIntField.__init__(self, name, default)
+ UTCTimeField.__init__(self, name, default, epoch=epoch, strf=strf)
+
+class SignedByteField(Field):
+ def __init__(self, name, default):
+ Field.__init__(self, name, default, "b")
+ def randval(self):
+ return RandSByte()
+
+class XLEShortField(LEShortField,XShortField):
+ def i2repr(self, pkt, x):
+ return XShortField.i2repr(self, pkt, x)
+
+class XLEIntField(LEIntField,XIntField):
+ def i2repr(self, pkt, x):
+ return XIntField.i2repr(self, pkt, x)
+
+class GPSTime_Field(LETimeField):
+ def __init__(self, name, default):
+ return LETimeField.__init__(self, name, default, strf="%a, %d %b %Y %H:%M:%S UTC")
+
+class VectorFlags_Field(XLEIntField):
+ """Represents te VectorFlags field. Handles the RelativeTo:sub-field"""
+ _fwdstr = "DefinesForward"
+ _resmask = 0xfffffff8
+ _relmask = 0x6
+ _relnames = ["RelativeToForward", "RelativeToEarth", "RelativeToCurrent", "RelativeToReserved"]
+ _relvals = [0x00, 0x02, 0x04, 0x06]
+ def i2repr(self, pkt, x):
+ if x is None:
+ return str(x)
+ r = []
+ if (x & 0x1):
+ r.append(self._fwdstr)
+ i = (x & self._relmask) >> 1
+ r.append(self._relnames[i])
+ i = x & self._resmask
+ if (i):
+ r.append("ReservedBits:%08X" % i)
+ sout = "+".join(r)
+ return sout
+ def any2i(self, pkt, x):
+ if isinstance(x, str):
+ r = x.split("+")
+ y = 0
+ for value in r:
+ if (value == self._fwdstr):
+ y |= 0x1
+ elif (value in self._relnames):
+ i = self._relnames.index(value)
+ y &= (~self._relmask)
+ y |= self._relvals[i]
+ else:
+ #logging.warning("Unknown VectorFlags Argument: %s" % value)
+ pass
+ else:
+ y = x
+ #print "any2i: %s --> %s" % (str(x), str(y))
+ return y
+
+class HCSIFlagsField(FlagsField):
+ """ A FlagsField where each bit/flag turns a conditional field on or off.
+ If the value is None when building a packet, i2m() will check the value of
+ every field in self.names. If the field's value is not None, the corresponding
+ flag will be set. """
+ def i2m(self, pkt, val):
+ if val is None:
+ val = 0
+ if (pkt):
+ for i, name in enumerate(self.names):
+ value = pkt.getfieldval(name)
+ if value is not None:
+ val |= 1 << i
+ return val
+
+class HCSINullField(StrFixedLenField):
+ def __init__(self, name, default):
+ return StrFixedLenField.__init__(self, name, default, length=0)
+
+class HCSIDescField(StrFixedLenField):
+ def __init__(self, name, default):
+ return StrFixedLenField.__init__(self, name, default, length=32)
+
+class HCSIAppField(StrFixedLenField):
+ def __init__(self, name, default):
+ return StrFixedLenField.__init__(self, name, default, length=60)
+
+def _FlagsList(myfields):
+ flags = ["Reserved%02d" % i for i in xrange(32)]
+ for i, value in myfields.iteritems():
+ flags[i] = value
+ return flags
+
+# Define all geolocation-tag flags lists
+_hcsi_gps_flags = _FlagsList({0:"No Fix Available", 1:"GPS", 2:"Differential GPS",
+ 3:"Pulse Per Second", 4:"Real Time Kinematic",
+ 5:"Float Real Time Kinematic", 6:"Estimated (Dead Reckoning)",
+ 7:"Manual Input", 8:"Simulation"})
+
+#_hcsi_vector_flags = _FlagsList({0:"ForwardFrame", 1:"RotationsAbsoluteXYZ", 5:"OffsetFromGPS_XYZ"})
+#This has been replaced with the VectorFlags_Field class, in order to handle the RelativeTo:subfield
+
+_hcsi_vector_char_flags = _FlagsList({0:"Antenna", 1:"Direction of Travel",
+ 2:"Front of Vehicle", 3:"Angle of Arrival", 4:"Transmitter Position",
+ 8:"GPS Derived", 9:"INS Derived", 10:"Compass Derived",
+ 11:"Acclerometer Derived", 12:"Human Derived"})
+
+_hcsi_antenna_flags = _FlagsList({ 1:"Horizontal Polarization", 2:"Vertical Polarization",
+ 3:"Circular Polarization Left", 4:"Circular Polarization Right",
+ 16:"Electronically Steerable", 17:"Mechanically Steerable"})
+
+""" HCSI PPI Fields are similar to RadioTap. A mask field called "present" specifies if each field
+is present. All other fields are conditional. When dissecting a packet, each field is present if
+"present" has the corresponding bit set. When building a packet, if "present" is None, the mask is
+set to include every field that does not have a value of None. Otherwise, if the mask field is
+not None, only the fields specified by "present" will be added to the packet.
+
+To build each Packet type, build a list of the fields normally, excluding the present bitmask field.
+The code will then construct conditional versions of each field and add the present field.
+See GPS_Fields as an example. """
+
+# Conditional test for all HCSI Fields
+def _HCSITest(pkt, ibit, name):
+ if pkt.present is None:
+ return (pkt.getfieldval(name) is not None)
+ return pkt.present & ibit
+
+# Wrap optional fields in ConditionalField, add HCSIFlagsField
+def _HCSIBuildFields(fields):
+ names = [f.name for f in fields]
+ cond_fields = [HCSIFlagsField('present', None, -len(names), names)]
+ for i, name in enumerate(names):
+ ibit = 1 << i
+ seval = "lambda pkt:_HCSITest(pkt,%s,'%s')" % (ibit, name)
+ test = eval(seval)
+ cond_fields.append(ConditionalField(fields[i], test))
+ return cond_fields
+
+class HCSIPacket(Packet):
+ name = "PPI HCSI"
+ fields_desc = [ LEShortField('pfh_type', None),
+ LEShortField('pfh_length', None),
+ ByteField('geotag_ver', CURR_GEOTAG_VER),
+ ByteField('geotag_pad', 0),
+ LEShortField('geotag_len', None)]
+ def post_build(self, p, pay):
+ if self.pfh_length is None:
+ l = len(p) - 4
+ sl = struct.pack('<H',l)
+ p = p[:2] + sl + p[4:]
+ if self.geotag_len is None:
+ l_g = len(p) - 4
+ sl_g = struct.pack('<H',l_g)
+ p = p[:6] + sl_g + p[8:]
+ p += pay
+ return p
+ def extract_padding(self, p):
+ return "",p
+
+#GPS Fields
+GPS_Fields = [FlagsField("GPSFlags", None, -32, _hcsi_gps_flags),
+ Fixed3_7Field("Latitude", None),
+ Fixed3_7Field("Longitude", None), Fixed6_4Field("Altitude", None),
+ Fixed6_4Field("Altitude_g", None), GPSTime_Field("GPSTime", None),
+ NSCounter_Field("FractionalTime", None), Fixed3_6Field("eph", None),
+ Fixed3_6Field("epv", None), NSCounter_Field("ept", None),
+ HCSINullField("Reserved10", None), HCSINullField("Reserved11", None),
+ HCSINullField("Reserved12", None), HCSINullField("Reserved13", None),
+ HCSINullField("Reserved14", None), HCSINullField("Reserved15", None),
+ HCSINullField("Reserved16", None), HCSINullField("Reserved17", None),
+ HCSINullField("Reserved18", None), HCSINullField("Reserved19", None),
+ HCSINullField("Reserved20", None), HCSINullField("Reserved21", None),
+ HCSINullField("Reserved22", None), HCSINullField("Reserved23", None),
+ HCSINullField("Reserved24", None), HCSINullField("Reserved25", None),
+ HCSINullField("Reserved26", None), HCSINullField("Reserved27", None),
+ HCSIDescField("DescString", None), XLEIntField("AppId", None),
+ HCSIAppField("AppData", None), HCSINullField("Extended", None)]
+
+class GPS(HCSIPacket):
+ name = "PPI GPS"
+ fields_desc = [ LEShortField('pfh_type', PPI_GPS), #pfh_type
+ LEShortField('pfh_length', None), #pfh_len
+ ByteField('geotag_ver', CURR_GEOTAG_VER), #base_geotag_header.ver
+ ByteField('geotag_pad', 0), #base_geotag_header.pad
+ LEShortField('geotag_len', None)] + _HCSIBuildFields(GPS_Fields)
+
+
+#Vector Fields
+VEC_Fields = [VectorFlags_Field("VectorFlags", None),
+ FlagsField("VectorChars", None, -32, _hcsi_vector_char_flags),
+ Fixed3_6Field("Pitch", None), Fixed3_6Field("Roll", None),
+ Fixed3_6Field("Heading", None), Fixed6_4Field("Off_X", None),
+ Fixed6_4Field("Off_Y", None), Fixed6_4Field("Off_Z", None),
+ HCSINullField("Reserved08", None), HCSINullField("Reserved09", None),
+ HCSINullField("Reserved10", None), HCSINullField("Reserved11", None),
+ HCSINullField("Reserved12", None), HCSINullField("Reserved13", None),
+ HCSINullField("Reserved14", None), HCSINullField("Reserved15", None),
+ Fixed3_6Field("Err_Rot", None), Fixed6_4Field("Err_Off", None),
+ HCSINullField("Reserved18", None), HCSINullField("Reserved19", None),
+ HCSINullField("Reserved20", None), HCSINullField("Reserved21", None),
+ HCSINullField("Reserved22", None), HCSINullField("Reserved23", None),
+ HCSINullField("Reserved24", None), HCSINullField("Reserved25", None),
+ HCSINullField("Reserved26", None), HCSINullField("Reserved27", None),
+ HCSIDescField("DescString", None), XLEIntField("AppId", None),
+ HCSIAppField("AppData", None), HCSINullField("Extended", None)]
+
+class Vector(HCSIPacket):
+ name = "PPI Vector"
+ fields_desc = [ LEShortField('pfh_type', PPI_VECTOR), #pfh_type
+ LEShortField('pfh_length', None), #pfh_len
+ ByteField('geotag_ver', CURR_GEOTAG_VER), #base_geotag_header.ver
+ ByteField('geotag_pad', 0), #base_geotag_header.pad
+ LEShortField('geotag_len', None)] + _HCSIBuildFields(VEC_Fields)
+
+#Sensor Fields
+# http://www.iana.org/assignments/icmp-parameters
+sensor_types= { 1 : "Velocity",
+ 2 : "Acceleration",
+ 3 : "Jerk",
+ 100 : "Rotation",
+ 101 : "Magnetic",
+ 1000: "Temperature",
+ 1001: "Barometer",
+ 1002: "Humidity",
+ 2000: "TDOA_Clock",
+ 2001: "Phase"
+ }
+SENS_Fields = [ LEShortEnumField('SensorType', None, sensor_types),
+ SignedByteField('ScaleFactor', None),
+ Fixed6_4Field('Val_X', None),
+ Fixed6_4Field('Val_Y', None),
+ Fixed6_4Field('Val_Z', None),
+ Fixed6_4Field('Val_T', None),
+ Fixed6_4Field('Val_E', None),
+ HCSINullField("Reserved07", None), HCSINullField("Reserved08", None),
+ HCSINullField("Reserved09", None), HCSINullField("Reserved10", None),
+ HCSINullField("Reserved11", None), HCSINullField("Reserved12", None),
+ HCSINullField("Reserved13", None), HCSINullField("Reserved14", None),
+ HCSINullField("Reserved15", None), HCSINullField("Reserved16", None),
+ HCSINullField("Reserved17", None), HCSINullField("Reserved18", None),
+ HCSINullField("Reserved19", None), HCSINullField("Reserved20", None),
+ HCSINullField("Reserved21", None), HCSINullField("Reserved22", None),
+ HCSINullField("Reserved23", None), HCSINullField("Reserved24", None),
+ HCSINullField("Reserved25", None), HCSINullField("Reserved26", None),
+ HCSINullField("Reserved27", None),
+ HCSIDescField("DescString", None), XLEIntField("AppId", None),
+ HCSIAppField("AppData", None), HCSINullField("Extended", None)]
+
+
+
+class Sensor(HCSIPacket):
+ name = "PPI Sensor"
+ fields_desc = [ LEShortField('pfh_type', PPI_SENSOR), #pfh_type
+ LEShortField('pfh_length', None), #pfh_len
+ ByteField('geotag_ver', CURR_GEOTAG_VER ), #base_geotag_header.ver
+ ByteField('geotag_pad', 0), #base_geotag_header.pad
+ LEShortField('geotag_len', None)] + _HCSIBuildFields(SENS_Fields)
+
+# HCSIAntenna Fields
+ANT_Fields = [FlagsField("AntennaFlags", None, -32, _hcsi_antenna_flags),
+ ByteField("Gain", None),
+ Fixed3_6Field("HorizBw", None), Fixed3_6Field("VertBw", None),
+ Fixed3_6Field("PrecisionGain",None), XLEShortField("BeamID", None),
+ HCSINullField("Reserved06", None), HCSINullField("Reserved07", None),
+ HCSINullField("Reserved08", None), HCSINullField("Reserved09", None),
+ HCSINullField("Reserved10", None), HCSINullField("Reserved11", None),
+ HCSINullField("Reserved12", None), HCSINullField("Reserved13", None),
+ HCSINullField("Reserved14", None), HCSINullField("Reserved15", None),
+ HCSINullField("Reserved16", None), HCSINullField("Reserved17", None),
+ HCSINullField("Reserved18", None), HCSINullField("Reserved19", None),
+ HCSINullField("Reserved20", None), HCSINullField("Reserved21", None),
+ HCSINullField("Reserved22", None), HCSINullField("Reserved23", None),
+ HCSINullField("Reserved24", None), HCSINullField("Reserved25", None),
+ HCSIDescField("SerialNumber", None), HCSIDescField("ModelName", None),
+ HCSIDescField("DescString", None), XLEIntField("AppId", None),
+ HCSIAppField("AppData", None), HCSINullField("Extended", None)]
+
+class Antenna(HCSIPacket):
+ name = "PPI Antenna"
+ fields_desc = [ LEShortField('pfh_type', PPI_ANTENNA), #pfh_type
+ LEShortField('pfh_length', None), #pfh_len
+ ByteField('geotag_ver', CURR_GEOTAG_VER), #base_geotag_header.ver
+ ByteField('geotag_pad', 0), #base_geotag_header.pad
+ LEShortField('geotag_len', None)] + _HCSIBuildFields(ANT_Fields)
+
+addPPIType(PPI_GPS, GPS)
+addPPIType(PPI_VECTOR, Vector)
+addPPIType(PPI_SENSOR, Sensor)
+addPPIType(PPI_ANTENNA,Antenna)
diff --git a/scapy/contrib/rsvp.py b/scapy/contrib/rsvp.py
index b8d8d7f4fc629409bcef98f869cdc739c0b7330c..3908546c5b9459609152a875544eaae7aa7d8d57 100644
--- a/scapy/contrib/rsvp.py
+++ b/scapy/contrib/rsvp.py
@@ -1,200 +1,200 @@
-## RSVP layer
-
-# 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 = RSVP
-# scapy.contrib.status = loads
-
-from scapy.packet import *
-from scapy.fields import *
-from scapy.layers.inet import IP
-
-rsvpmsgtypes = { 0x01 : "Path",
- 0x02 : "Reservation request",
- 0x03 : "Path error",
- 0x04 : "Reservation request error",
- 0x05 : "Path teardown",
- 0x06 : "Reservation teardown",
- 0x07 : "Reservation request acknowledgment"
-}
-
-class RSVP(Packet):
- name = "RSVP"
- fields_desc = [ BitField("Version",1,4),
- BitField("Flags",1,4),
- ByteEnumField("Class",0x01, rsvpmsgtypes),
- XShortField("chksum", None),
- ByteField("TTL",1),
- XByteField("dataofs", 0),
- ShortField("Length",None)]
- def post_build(self, p, pay):
- p += pay
- if self.Length is None:
- l = len(p)
- p = p[:6]+chr((l>>8)&0xff)+chr(l&0xff)+p[8:]
- if self.chksum is None:
- ck = checksum(p)
- p = p[:2]+chr(ck>>8)+chr(ck&0xff)+p[4:]
- return p
-
-rsvptypes = { 0x01 : "Session",
- 0x03 : "HOP",
- 0x04 : "INTEGRITY",
- 0x05 : "TIME_VALUES",
- 0x06 : "ERROR_SPEC",
- 0x07 : "SCOPE",
- 0x08 : "STYLE",
- 0x09 : "FLOWSPEC",
- 0x0A : "FILTER_SPEC",
- 0x0B : "SENDER_TEMPLATE",
- 0x0C : "SENDER_TSPEC",
- 0x0D : "ADSPEC",
- 0x0E : "POLICY_DATA",
- 0x0F : "RESV_CONFIRM",
- 0x10 : "RSVP_LABEL",
- 0x11 : "HOP_COUNT",
- 0x12 : "STRICT_SOURCE_ROUTE",
- 0x13 : "LABEL_REQUEST",
- 0x14 : "EXPLICIT_ROUTE",
- 0x15 : "ROUTE_RECORD",
- 0x16 : "HELLO",
- 0x17 : "MESSAGE_ID",
- 0x18 : "MESSAGE_ID_ACK",
- 0x19 : "MESSAGE_ID_LIST",
- 0x1E : "DIAGNOSTIC",
- 0x1F : "ROUTE",
- 0x20 : "DIAG_RESPONSE",
- 0x21 : "DIAG_SELECT",
- 0x22 : "RECOVERY_LABEL",
- 0x23 : "UPSTREAM_LABEL",
- 0x24 : "LABEL_SET",
- 0x25 : "PROTECTION",
- 0x26 : "PRIMARY PATH ROUTE",
- 0x2A : "DSBM IP ADDRESS",
- 0x2B : "SBM_PRIORITY",
- 0x2C : "DSBM TIMER INTERVALS",
- 0x2D : "SBM_INFO",
- 0x32 : "S2L_SUB_LSP",
- 0x3F : "DETOUR",
- 0x40 : "CHALLENGE",
- 0x41 : "DIFF-SERV",
- 0x42 : "CLASSTYPE",
- 0x43 : "LSP_REQUIRED_ATTRIBUTES",
- 0x80 : "NODE_CHAR",
- 0x81 : "SUGGESTED_LABEL",
- 0x82 : "ACCEPTABLE_LABEL_SET",
- 0x83 : "RESTART_CA",
- 0x84 : "SESSION-OF-INTEREST",
- 0x85 : "LINK_CAPABILITY",
- 0x86 : "Capability Object",
- 0xA1 : "RSVP_HOP_L2",
- 0xA2 : "LAN_NHOP_L2",
- 0xA3 : "LAN_NHOP_L3",
- 0xA4 : "LAN_LOOPBACK",
- 0xA5 : "TCLASS",
- 0xC0 : "TUNNEL",
- 0xC1 : "LSP_TUNNEL_INTERFACE_ID",
- 0xC2 : "USER_ERROR_SPEC",
- 0xC3 : "NOTIFY_REQUEST",
- 0xC4 : "ADMIN-STATUS",
- 0xC5 : "LSP_ATTRIBUTES",
- 0xC6 : "ALARM_SPEC",
- 0xC7 : "ASSOCIATION",
- 0xC8 : "SECONDARY_EXPLICIT_ROUTE",
- 0xC9 : "SECONDARY_RECORD_ROUTE",
- 0xCD : "FAST_REROUTE",
- 0xCF : "SESSION_ATTRIBUTE",
- 0xE1 : "DCLASS",
- 0xE2 : "PACKETCABLE EXTENSIONS",
- 0xE3 : "ATM_SERVICECLASS",
- 0xE4 : "CALL_OPS (ASON)",
- 0xE5 : "GENERALIZED_UNI",
- 0xE6 : "CALL_ID",
- 0xE7 : "3GPP2_Object",
- 0xE8 : "EXCLUDE_ROUTE"
-}
-
-class RSVP_Object(Packet):
- name = "RSVP_Object"
- fields_desc = [ ShortField("Length",4),
- ByteEnumField("Class",0x01, rsvptypes),
- ByteField("C-Type",1)]
- def guess_payload_class(self, payload):
- if self.Class == 0x03:
- return RSVP_HOP
- elif self.Class == 0x05:
- return RSVP_Time
- elif self.Class == 0x0c:
- return RSVP_SenderTSPEC
- elif self.Class == 0x13:
- return RSVP_LabelReq
- elif self.Class == 0xCF:
- return RSVP_SessionAttrb
- else:
- return RSVP_Data
-
-
-
-class RSVP_Data(Packet):
- name = "Data"
- fields_desc = [StrLenField("Data","",length_from= lambda pkt:pkt.underlayer.Length - 4)]
- def default_payload_class(self, payload):
- return RSVP_Object
-
-class RSVP_HOP(Packet):
- name = "HOP"
- fields_desc = [ IPField("neighbor","0.0.0.0"),
- BitField("inface",1,32)]
- def default_payload_class(self, payload):
- return RSVP_Object
-
-class RSVP_Time(Packet):
- name = "Time Val"
- fields_desc = [ BitField("refresh",1,32)]
- def default_payload_class(self, payload):
- return RSVP_Object
-
-class RSVP_SenderTSPEC(Packet):
- name = "Sender_TSPEC"
- fields_desc = [ ByteField("Msg_Format",0),
- ByteField("reserve",0),
- ShortField("Data_Length",4),
- ByteField("Srv_hdr",1),
- ByteField("reserve2",0),
- ShortField("Srv_Length",4),
- StrLenField("Tokens","",length_from= lambda pkt:pkt.underlayer.Length - 12) ]
- def default_payload_class(self, payload):
- return RSVP_Object
-
-class RSVP_LabelReq(Packet):
- name = "Lable Req"
- fields_desc = [ ShortField("reserve",1),
- ShortField("L3PID",1)]
- def default_payload_class(self, payload):
- return RSVP_Object
-
-class RSVP_SessionAttrb(Packet):
- name = "Session_Attribute"
- fields_desc = [ ByteField("Setup_priority",1),
- ByteField("Hold_priority",1),
- ByteField("flags",1),
- ByteField("Name_length",1),
- StrLenField("Name","",length_from= lambda pkt:pkt.underlayer.Length - 8),
- ]
- def default_payload_class(self, payload):
- return RSVP_Object
-
-bind_layers( IP, RSVP, { "proto" : 46} )
-bind_layers( RSVP, RSVP_Object, {})
+## RSVP layer
+
+# 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 = RSVP
+# scapy.contrib.status = loads
+
+from scapy.packet import *
+from scapy.fields import *
+from scapy.layers.inet import IP
+
+rsvpmsgtypes = { 0x01 : "Path",
+ 0x02 : "Reservation request",
+ 0x03 : "Path error",
+ 0x04 : "Reservation request error",
+ 0x05 : "Path teardown",
+ 0x06 : "Reservation teardown",
+ 0x07 : "Reservation request acknowledgment"
+}
+
+class RSVP(Packet):
+ name = "RSVP"
+ fields_desc = [ BitField("Version",1,4),
+ BitField("Flags",1,4),
+ ByteEnumField("Class",0x01, rsvpmsgtypes),
+ XShortField("chksum", None),
+ ByteField("TTL",1),
+ XByteField("dataofs", 0),
+ ShortField("Length",None)]
+ def post_build(self, p, pay):
+ p += pay
+ if self.Length is None:
+ l = len(p)
+ p = p[:6]+chr((l>>8)&0xff)+chr(l&0xff)+p[8:]
+ if self.chksum is None:
+ ck = checksum(p)
+ p = p[:2]+chr(ck>>8)+chr(ck&0xff)+p[4:]
+ return p
+
+rsvptypes = { 0x01 : "Session",
+ 0x03 : "HOP",
+ 0x04 : "INTEGRITY",
+ 0x05 : "TIME_VALUES",
+ 0x06 : "ERROR_SPEC",
+ 0x07 : "SCOPE",
+ 0x08 : "STYLE",
+ 0x09 : "FLOWSPEC",
+ 0x0A : "FILTER_SPEC",
+ 0x0B : "SENDER_TEMPLATE",
+ 0x0C : "SENDER_TSPEC",
+ 0x0D : "ADSPEC",
+ 0x0E : "POLICY_DATA",
+ 0x0F : "RESV_CONFIRM",
+ 0x10 : "RSVP_LABEL",
+ 0x11 : "HOP_COUNT",
+ 0x12 : "STRICT_SOURCE_ROUTE",
+ 0x13 : "LABEL_REQUEST",
+ 0x14 : "EXPLICIT_ROUTE",
+ 0x15 : "ROUTE_RECORD",
+ 0x16 : "HELLO",
+ 0x17 : "MESSAGE_ID",
+ 0x18 : "MESSAGE_ID_ACK",
+ 0x19 : "MESSAGE_ID_LIST",
+ 0x1E : "DIAGNOSTIC",
+ 0x1F : "ROUTE",
+ 0x20 : "DIAG_RESPONSE",
+ 0x21 : "DIAG_SELECT",
+ 0x22 : "RECOVERY_LABEL",
+ 0x23 : "UPSTREAM_LABEL",
+ 0x24 : "LABEL_SET",
+ 0x25 : "PROTECTION",
+ 0x26 : "PRIMARY PATH ROUTE",
+ 0x2A : "DSBM IP ADDRESS",
+ 0x2B : "SBM_PRIORITY",
+ 0x2C : "DSBM TIMER INTERVALS",
+ 0x2D : "SBM_INFO",
+ 0x32 : "S2L_SUB_LSP",
+ 0x3F : "DETOUR",
+ 0x40 : "CHALLENGE",
+ 0x41 : "DIFF-SERV",
+ 0x42 : "CLASSTYPE",
+ 0x43 : "LSP_REQUIRED_ATTRIBUTES",
+ 0x80 : "NODE_CHAR",
+ 0x81 : "SUGGESTED_LABEL",
+ 0x82 : "ACCEPTABLE_LABEL_SET",
+ 0x83 : "RESTART_CA",
+ 0x84 : "SESSION-OF-INTEREST",
+ 0x85 : "LINK_CAPABILITY",
+ 0x86 : "Capability Object",
+ 0xA1 : "RSVP_HOP_L2",
+ 0xA2 : "LAN_NHOP_L2",
+ 0xA3 : "LAN_NHOP_L3",
+ 0xA4 : "LAN_LOOPBACK",
+ 0xA5 : "TCLASS",
+ 0xC0 : "TUNNEL",
+ 0xC1 : "LSP_TUNNEL_INTERFACE_ID",
+ 0xC2 : "USER_ERROR_SPEC",
+ 0xC3 : "NOTIFY_REQUEST",
+ 0xC4 : "ADMIN-STATUS",
+ 0xC5 : "LSP_ATTRIBUTES",
+ 0xC6 : "ALARM_SPEC",
+ 0xC7 : "ASSOCIATION",
+ 0xC8 : "SECONDARY_EXPLICIT_ROUTE",
+ 0xC9 : "SECONDARY_RECORD_ROUTE",
+ 0xCD : "FAST_REROUTE",
+ 0xCF : "SESSION_ATTRIBUTE",
+ 0xE1 : "DCLASS",
+ 0xE2 : "PACKETCABLE EXTENSIONS",
+ 0xE3 : "ATM_SERVICECLASS",
+ 0xE4 : "CALL_OPS (ASON)",
+ 0xE5 : "GENERALIZED_UNI",
+ 0xE6 : "CALL_ID",
+ 0xE7 : "3GPP2_Object",
+ 0xE8 : "EXCLUDE_ROUTE"
+}
+
+class RSVP_Object(Packet):
+ name = "RSVP_Object"
+ fields_desc = [ ShortField("Length",4),
+ ByteEnumField("Class",0x01, rsvptypes),
+ ByteField("C-Type",1)]
+ def guess_payload_class(self, payload):
+ if self.Class == 0x03:
+ return RSVP_HOP
+ elif self.Class == 0x05:
+ return RSVP_Time
+ elif self.Class == 0x0c:
+ return RSVP_SenderTSPEC
+ elif self.Class == 0x13:
+ return RSVP_LabelReq
+ elif self.Class == 0xCF:
+ return RSVP_SessionAttrb
+ else:
+ return RSVP_Data
+
+
+
+class RSVP_Data(Packet):
+ name = "Data"
+ fields_desc = [StrLenField("Data","",length_from= lambda pkt:pkt.underlayer.Length - 4)]
+ def default_payload_class(self, payload):
+ return RSVP_Object
+
+class RSVP_HOP(Packet):
+ name = "HOP"
+ fields_desc = [ IPField("neighbor","0.0.0.0"),
+ BitField("inface",1,32)]
+ def default_payload_class(self, payload):
+ return RSVP_Object
+
+class RSVP_Time(Packet):
+ name = "Time Val"
+ fields_desc = [ BitField("refresh",1,32)]
+ def default_payload_class(self, payload):
+ return RSVP_Object
+
+class RSVP_SenderTSPEC(Packet):
+ name = "Sender_TSPEC"
+ fields_desc = [ ByteField("Msg_Format",0),
+ ByteField("reserve",0),
+ ShortField("Data_Length",4),
+ ByteField("Srv_hdr",1),
+ ByteField("reserve2",0),
+ ShortField("Srv_Length",4),
+ StrLenField("Tokens","",length_from= lambda pkt:pkt.underlayer.Length - 12) ]
+ def default_payload_class(self, payload):
+ return RSVP_Object
+
+class RSVP_LabelReq(Packet):
+ name = "Lable Req"
+ fields_desc = [ ShortField("reserve",1),
+ ShortField("L3PID",1)]
+ def default_payload_class(self, payload):
+ return RSVP_Object
+
+class RSVP_SessionAttrb(Packet):
+ name = "Session_Attribute"
+ fields_desc = [ ByteField("Setup_priority",1),
+ ByteField("Hold_priority",1),
+ ByteField("flags",1),
+ ByteField("Name_length",1),
+ StrLenField("Name","",length_from= lambda pkt:pkt.underlayer.Length - 8),
+ ]
+ def default_payload_class(self, payload):
+ return RSVP_Object
+
+bind_layers( IP, RSVP, { "proto" : 46} )
+bind_layers( RSVP, RSVP_Object, {})
diff --git a/test/run_tests.bat b/test/run_tests.bat
index 8c4200d867fe76d9df2814d942cdb145b18fee85..fce8e76ec211e621da2abb2352058932f50b4e77 100644
--- a/test/run_tests.bat
+++ b/test/run_tests.bat
@@ -1,10 +1,10 @@
-@echo off
-title UTscapy - All tests
-set MYDIR=%cd%\..
-set PYTHONPATH=%MYDIR%
-if [%1]==[] (
- python "%MYDIR%\scapy\tools\UTscapy.py" -c configs\\windows2.utsc -T bpf.uts -o scapy_regression_test_%date:~6,4%_%date:~3,2%_%date:~0,2%.html
-) else (
- python "%MYDIR%\scapy\tools\UTscapy.py" %@
-)
-PAUSE
+@echo off
+title UTscapy - All tests
+set MYDIR=%cd%\..
+set PYTHONPATH=%MYDIR%
+if [%1]==[] (
+ python "%MYDIR%\scapy\tools\UTscapy.py" -c configs\\windows2.utsc -T bpf.uts -o scapy_regression_test_%date:~6,4%_%date:~3,2%_%date:~0,2%.html
+) else (
+ python "%MYDIR%\scapy\tools\UTscapy.py" %@
+)
+PAUSE