class UDS_CCPR(Packet): name = 'CommunicationControlPositiveResponse' fields_desc = [ ByteEnumField('controlType', 0, UDS_CC.controlTypes) ]
class IE_ChargingId(IE_Base): name = "Charging ID" fields_desc = [ ByteEnumField("ietype", 127, IEType), XIntField("Charging_id", RandInt()) ]
class PCO_IPv4(PCO_Option): name = "IPv4" fields_desc = [ByteEnumField("type", None, PCO_OPTION_TYPES), ByteField("length", 0), IPField("address", RandIP())]
class IE_Recovery(IE_Base): name = "Recovery" fields_desc = [ ByteEnumField("ietype", 14, IEType), ByteField("restart_counter", 24) ]
class IE_TEICP(IE_Base): name = "Tunnel Endpoint Identifier Control Plane" fields_desc = [ ByteEnumField("ietype", 17, IEType), XIntField("TEICI", RandInt()) ]
class GTPPDUSessionContainer(Packet): name = "GTP PDU Session Container" fields_desc = [ ByteField("ExtHdrLen", None), BitField("type", 0, 4), BitField("qmp", 0, 1), ConditionalField(BitField("dlDelayInd", 0, 1), lambda pkt: pkt.type == 1), ConditionalField(BitField("ulDelayInd", 0, 1), lambda pkt: pkt.type == 1), ConditionalField(BitField("spareUl1", 0, 1), lambda pkt: pkt.type == 1), ConditionalField(XBitField("spareDl1", 0, 3), lambda pkt: pkt.type == 0), ConditionalField(BitField("P", 0, 1), lambda pkt: pkt.type == 0), ConditionalField(BitField("R", 0, 1), lambda pkt: pkt.type == 0), ConditionalField(XBitField("spareUl2", 0, 2), lambda pkt: pkt.type == 1), BitField("QFI", 0, 6), ConditionalField(XBitField("PPI", 0, 3), lambda pkt: pkt.type == 0 and pkt.P == 1), ConditionalField(XBitField("spareDl2", 0, 5), lambda pkt: pkt.type == 0 and pkt.P == 1), ConditionalField(XBitField("dlSendTime", 0, 32), lambda pkt: pkt.type == 0 and pkt.qmp == 1), ConditionalField(XBitField("dlSendTimeRpt", 0, 32), lambda pkt: pkt.type == 1 and pkt.qmp == 1), ConditionalField(XBitField("dlRecvTime", 0, 32), lambda pkt: pkt.type == 1 and pkt.qmp == 1), ConditionalField(XBitField("ulSendTime", 0, 32), lambda pkt: pkt.type == 1 and pkt.qmp == 1), ConditionalField(XBitField("dlDelayRslt", 0, 32), lambda pkt: pkt.type == 1 and pkt.dlDelayInd == 1), ConditionalField(XBitField("ulDelayRslt", 0, 32), lambda pkt: pkt.type == 1 and pkt.ulDelayInd == 1), ByteEnumField("NextExtHdr", 0, ExtensionHeadersTypes), ConditionalField( StrLenField("extraPadding", "", length_from=lambda pkt: 4 * (pkt.ExtHdrLen) - 5), lambda pkt: pkt.ExtHdrLen and pkt.ExtHdrLen > 1 and pkt.type == 0 and pkt.P == 1 and pkt.NextExtHdr == 0) ] def guess_payload_class(self, payload): if self.NextExtHdr == 0: sub_proto = orb(payload[0]) if sub_proto >= 0x45 and sub_proto <= 0x4e: return IP elif (sub_proto & 0xf0) == 0x60: return IPv6 else: return PPP return GTPHeader.guess_payload_class(self, payload) def post_build(self, p, pay): p += pay if self.ExtHdrLen is None: if self.P == 1: hdr_len = 2 else: hdr_len = 1 p = struct.pack("!B", hdr_len) + p[1:] return p
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 PPP_LCP_MRU_Option(PPP_LCP_Option): fields_desc = [ ByteEnumField("type", 1, _PPP_lcp_optiontypes), FieldLenField("len", 4, fmt="B", adjust=lambda p, x: 4), ShortField("max_recv_unit", 1500) ]
class PPP_LCP_ACCM_Option(PPP_LCP_Option): fields_desc = [ ByteEnumField("type", 2, _PPP_lcp_optiontypes), FieldLenField("len", 6, fmt="B"), BitField("accm", 0x00000000, 32) ]
class ASDU(Packet): name = 'IEC 60870-5-104-ASDU' fields_desc = [ ByteEnumField('TypeId', None, TYPEID_ASDU), ByteEnumField('SQ', None, SQ_ENUM), ByteField('NumIx', 0), ByteEnumField('CauseTx', None, CAUSE_OF_TX), ByteEnumField('PN', 0x00, PN_ENUM), ByteField('Test', None), ByteField('OA', None), LEShortField('Addr', None), PacketListField('IOA', None) ] def do_dissect(self, s): self.TypeId = s[0] self.SQ = s[1] & 0x80 self.NumIx = s[1] & 0x7f self.CauseTx = s[2] & 0x3F self.PN = s[2] & 0x40 self.Test = s[2] & 0x80 self.OA = s[3] self.Addr = unpack('<H', s[4:6])[0] # self.Addr = s[4] # NOTE: For Malformed Packets TypeId = 13 flag = True list_IOA = list() remain = s[6:] # remain = s[5:] # NOTE: For Malformed Packets TypeId = 13 idx = 6 # idx=5 # NOTE: For Malformed Packets TypeId = 13 i = 1 typeIOA = IOAS[self.TypeId] lenIOA = IOALEN[self.TypeId] j = 0 if self.SQ: for i in range(1, self.NumIx + 1): if flag: list_IOA.append(typeIOA(remain[:lenIOA])) offset = list_IOA[0].IOA remain = remain[lenIOA:] idx = idx + lenIOA lenIOA = lenIOA - 3 else: offsetIOA = pack( "<H", (i - 1) + offset) + b'\x00' # See 7.2.2.1 of IEC 60870-5-101 remain2 = offsetIOA + remain[:lenIOA] list_IOA.append(typeIOA(remain2)) remain = remain[lenIOA:] idx = idx + lenIOA flag = False else: list_IOA = [ typeIOA(remain[(x * lenIOA):(x * lenIOA) + lenIOA]) for x in range(self.NumIx) ] idx += lenIOA * self.NumIx # for i in range(1,self.NumIx+1): # list_IOA.append(typeIOA(remain[:lenIOA])) # remain = remain[lenIOA:] # idx = idx+lenIOA self.IOA = list_IOA return s[idx:] def do_build(self): s = bytearray() s.append(self.TypeId) s.append(self.SQ | self.NumIx) s.append(self.Test | self.PN | self.CauseTx) s.append(self.OA) s.append(int(self.Addr) & 0xff) s.append(int(self.Addr) >> 8) s = bytes(s) if self.IOA is not None: for i in self.IOA: s += i.build() return s
class APCI(Packet): name = 'IEC 60870-5-104-APCI' fields_desc = [ XByteField('START', 0x68), ByteField('ApduLen', 4), ByteEnumField('Type', 0x00, TYPE_APCI), ConditionalField(XByteField('UType', None), lambda pkt: pkt.Type == 0x03), ConditionalField(ShortField('Tx', 0x00), lambda pkt: pkt.Type == 0x00), ConditionalField(ShortField('Rx', 0x00), lambda pkt: pkt.Type < 3), ] def do_dissect(self, s): self.START = s[0] self.ApduLen = s[1] self.Type = s[2] & 0x03 if bool(s[2] & 0x01) else 0x00 if self.Type == 3: self.UType = (s[2] & 0xfc) >> 2 else: if self.Type == 0: self.Tx = (s[3] << 7) | (s[2] >> 1) self.Rx = (s[5] << 7) | (s[4] >> 1) return s[6:] def dissect(self, s): s = self.pre_dissect(s) s = self.do_dissect(s) s = self.post_dissect(s) payl, pad = self.extract_padding(s) self.do_dissect_payload(payl) if pad and conf.padding: self.add_payload(Padding(pad)) def do_build(self): s = list(range(6)) s[0] = 0x68 s[1] = self.ApduLen if self.Type == 0x03: s[2] = ((self.UType << 2) & 0xfc) | self.Type s[3] = 0 s[4] = 0 s[5] = 0 else: if self.Type == 0x00: s[2] = ((self.Tx << 1) & 0x00fe) | self.Type s[3] = ((self.Tx << 1) & 0xff00) >> 8 else: s[2] = self.Type s[3] = 0 s[4] = (self.Rx << 1) & 0x00fe s[5] = ((self.Rx << 1) & 0xff00) >> 8 s = bytes(s) if self.haslayer('ASDU'): s += self.payload.build() return s def extract_padding(self, s): if self.Type == 0x00 and self.ApduLen > 4: return s[:self.ApduLen - 4], s[self.ApduLen - 4:] return None, s def do_dissect_payload(self, s): if s is not None: p = ASDU(s, _internal=1, _underlayer=self) self.add_payload(p)
class LLTD(Packet): name = "LLTD" answer_hashret = { # (tos, function) tuple mapping (answer -> query), used by # .hashret() (1, 1): (0, 0), (0, 12): (0, 11), } fields_desc = [ ByteField("version", 1), ByteEnumField("tos", 0, { 0: "Topology discovery", 1: "Quick discovery", 2: "QoS diagnostics", }), ByteField("reserved", 0), MultiEnumField("function", 0, { 0: { 0: "Discover", 1: "Hello", 2: "Emit", 3: "Train", 4: "Probe", 5: "Ack", 6: "Query", 7: "QueryResp", 8: "Reset", 9: "Charge", 10: "Flat", 11: "QueryLargeTlv", 12: "QueryLargeTlvResp", }, 1: { 0: "Discover", 1: "Hello", 8: "Reset", }, 2: { 0: "QosInitializeSink", 1: "QosReady", 2: "QosProbe", 3: "QosQuery", 4: "QosQueryResp", 5: "QosReset", 6: "QosError", 7: "QosAck", 8: "QosCounterSnapshot", 9: "QosCounterResult", 10: "QosCounterLease", }, }, depends_on=lambda pkt: pkt.tos, fmt="B"), MACField("real_dst", None), MACField("real_src", None), ConditionalField(ShortField("xid", 0), lambda pkt: pkt.function in [0, 8]), ConditionalField(ShortField("seq", 0), lambda pkt: pkt.function not in [0, 8]), ] def post_build(self, pkt, pay): if (self.real_dst is None or self.real_src is None) and \ isinstance(self.underlayer, Ether): eth = self.underlayer if self.real_dst is None: pkt = (pkt[:4] + eth.fields_desc[0].i2m(eth, eth.dst) + pkt[10:]) if self.real_src is None: pkt = (pkt[:10] + eth.fields_desc[1].i2m(eth, eth.src) + pkt[16:]) return pkt + pay def mysummary(self): if isinstance(self.underlayer, Ether): return self.underlayer.sprintf( 'LLTD %src% > %dst% %LLTD.tos% - %LLTD.function%') else: return self.sprintf('LLTD %tos% - %function%') def hashret(self): tos, function = self.tos, self.function return "%c%c" % self.answer_hashret.get((tos, function), (tos, function)) def answers(self, other): if not isinstance(other, LLTD): return False if self.tos == 0: if self.function == 0 and isinstance(self.payload, LLTDDiscover) \ and len(self[LLTDDiscover].stations_list) == 1: # "Topology discovery - Discover" with one MAC address # discovered answers a "Quick discovery - Hello" return other.tos == 1 and \ other.function == 1 and \ LLTDAttributeHostID in other and \ other[LLTDAttributeHostID].mac == \ self[LLTDDiscover].stations_list[0] elif self.function == 12: # "Topology discovery - QueryLargeTlvResp" answers # "Topology discovery - QueryLargeTlv" with same .seq # value return other.tos == 0 and other.function == 11 \ and other.seq == self.seq elif self.tos == 1: if self.function == 1 and isinstance(self.payload, LLTDHello): # "Quick discovery - Hello" answers a "Topology # discovery - Discover" return other.tos == 0 and other.function == 0 and \ other.real_src == self.current_mapper_address return False
class UDS_LCPR(Packet): name = 'LinkControlPositiveResponse' fields_desc = [ ByteEnumField('linkControlType', 0, UDS_LC.linkControlTypes) ]
class UDS_CDTCSPR(Packet): name = 'ControlDTCSettingPositiveResponse' fields_desc = [ ByteEnumField('DTCSettingType', 0, UDS_CDTCS.DTCSettingTypes) ]
class GTP_UDPPort_ExtensionHeader(GTP_ExtensionHeader): fields_desc = [ ByteField("length", 0x40), ShortField("udp_port", None), ByteEnumField("next_ex", 0, ExtensionHeadersTypes), ]
class PPP_LCP_Magic_Number_Option(PPP_LCP_Option): fields_desc = [ ByteEnumField("type", 5, _PPP_lcp_optiontypes), FieldLenField("len", 6, fmt="B", adjust=lambda p, x: 6), IntField("magic_number", None) ]
class GTP_PDCP_PDU_ExtensionHeader(GTP_ExtensionHeader): fields_desc = [ ByteField("length", 0x01), ShortField("pdcp_pdu", None), ByteEnumField("next_ex", 0, ExtensionHeadersTypes), ]
class RPLOptPad1(_RPLGuessOption): """ Control Option: Pad 1 byte """ name = "Pad1" fields_desc = [ByteEnumField("otype", 0x00, RPLOPTSSTR)]
class IE_Cause(IE_Base): name = "Cause" fields_desc = [ ByteEnumField("ietype", 1, IEType), ByteEnumField("CauseValue", None, CauseValues) ]
41: IPField("NIS_server", "0.0.0.0"), 42: IPField("NTP_server", "0.0.0.0"), 43: "vendor_specific", 44: IPField("NetBIOS_server", "0.0.0.0"), 45: IPField("NetBIOS_dist_server", "0.0.0.0"), 50: IPField("requested_addr", "0.0.0.0"), 51: IntField("lease_time", 43200), 53: ByteEnumField("message-type", 1, DHCPTypes), 54: IPField("server_id", "0.0.0.0"), 55: _DHCPParamReqFieldListField("param_req_list", [], ByteField("opcode", 0), length_from=lambda x: 1), # noqa: E501 56: "error_message", 57: ShortField("max_dhcp_size", 1500), 58: IntField("renewal_time", 21600), 59: IntField("rebinding_time", 37800), 60:
class IE_ReorderingRequired(IE_Base): name = "Recovery" fields_desc = [ ByteEnumField("ietype", 8, IEType), ByteEnumField("reordering_required", 254, TrueFalse_value) ]
class ProfinetDCP(Packet): """ Profinet DCP Packet Requests are handled via ConditionalField because here only 1 Block is used qevery time Ŕesoinse can contain 1..n Blocks, for that you have to use one ProfinetDCP Layer with one or multiple DCP*Block Layers ProfinetDCP / DCPNameOfStationBlock / DCPDeviceIDBlock ... Example for a DCP Identify All Request: Ether(dst="01:0e:cf:00:00:00") / ProfinetIO(frameID=DCP_IDENTIFY_REQUEST_FRAME_ID) / ProfinetDCP(service_id=DCP_SERVICE_ID_IDENTIFY, service_type=DCP_REQUEST, option=255, sub_option=255, dcp_data_length=4) Example for a DCP Identify Response: Ether(dst=dst_mac) / ProfinetIO(frameID=DCP_IDENTIFY_RESPONSE_FRAME_ID) / ProfinetDCP( service_id=DCP_SERVICE_ID_IDENTIFY, service_type=DCP_RESPONSE) / DCPNameOfStationBlock(name_of_station="device1") Example for a DCP Set Request: Ether(dst=mac) / ProfinetIO(frameID=DCP_GET_SET_FRAME_ID) / ProfinetDCP(service_id=DCP_SERVICE_ID_SET, service_type=DCP_REQUEST, option=2, sub_option=2, dcp_data_length=14, dcp_block_length=10, name_of_station=name, reserved=0) """ name = "Profinet DCP" # a DCP PDU consists of some fields and 1..n DCP Blocks fields_desc = [ ByteEnumField("service_id", 5, DCP_SERVICE_ID), ByteEnumField("service_type", 0, DCP_SERVICE_TYPE), XIntField("xid", 0x01000001), # XShortField('reserved', 0), ShortField('reserved', 0), LenField("dcp_data_length", None), # DCP REQUEST specific ConditionalField(ByteEnumField("option", 2, DCP_OPTIONS), lambda pkt: pkt.service_type == 0), ConditionalField( MultiEnumField("sub_option", 3, DCP_SUBOPTIONS, fmt='B', depends_on=lambda p: p.option), lambda pkt: pkt.service_type == 0), # calculate the len fields - workaround ConditionalField(LenField("dcp_block_length", 0), lambda pkt: pkt.service_type == 0), # DCP SET REQUEST # ConditionalField( ShortEnumField("block_qualifier", 1, BLOCK_QUALIFIERS), lambda pkt: pkt.service_id == 4 and pkt.service_type == 0), # Name Of Station ConditionalField( StrLenField("name_of_station", "et200sp", length_from=lambda x: x.dcp_block_length - 2), lambda pkt: pkt.service_id == 4 and pkt.service_type == 0 and pkt. option == 2 and pkt.sub_option == 2), # MAC ConditionalField( MACField("mac", "00:00:00:00:00:00"), lambda pkt: pkt.service_id == 4 and pkt.service_type == 0 and pkt.option == 1 and pkt.sub_option == 1), # IP ConditionalField( IPField("ip", "192.168.0.2"), lambda pkt: pkt.service_id == 4 and pkt.service_type == 0 and pkt.option == 1 and pkt.sub_option == 2), ConditionalField( IPField("netmask", "255.255.255.0"), lambda pkt: pkt.service_id == 4 and pkt. service_type == 0 and pkt.option == 1 and pkt.sub_option == 2), ConditionalField( IPField("gateway", "192.168.0.1"), lambda pkt: pkt.service_id == 4 and pkt. service_type == 0 and pkt.option == 1 and pkt.sub_option == 2), # DCP IDENTIFY REQUEST # # Name of station ConditionalField( StrLenField("name_of_station", "et200sp", length_from=lambda x: x.dcp_block_length), lambda pkt: pkt.service_id == 5 and pkt.service_type == 0 and pkt. option == 2 and pkt.sub_option == 2), # Alias name ConditionalField( StrLenField("alias_name", "et200sp", length_from=lambda x: x.dcp_block_length), lambda pkt: pkt.service_id == 5 and pkt.service_type == 0 and pkt. option == 2 and pkt.sub_option == 6), # implement further REQUEST fields if needed .... # DCP RESPONSE BLOCKS # ConditionalField( PacketListField("dcp_blocks", [], guess_dcp_block_class, length_from=lambda p: p.dcp_data_length), lambda pkt: pkt.service_type == 1), ] def post_build(self, pkt, pay): # add padding to ensure min packet length padding = MIN_PACKET_LENGTH - (len(pkt + pay)) pay += b"\0" * padding return Packet.post_build(self, pkt, pay)
class IE_TEIDI(IE_Base): name = "Tunnel Endpoint Identifier Data" fields_desc = [ ByteEnumField("ietype", 16, IEType), XIntField("TEIDI", RandInt()) ]
class RadioTap(Packet): name = "RadioTap dummy" fields_desc = [ByteField('version', 0), ByteField('pad', 0), LEShortField('len', None), FlagsField('present', None, -32, ['TSFT', 'Flags', 'Rate', 'Channel', 'FHSS', 'dBm_AntSignal', # noqa: E501 'dBm_AntNoise', 'Lock_Quality', 'TX_Attenuation', 'dB_TX_Attenuation', # noqa: E501 'dBm_TX_Power', 'Antenna', 'dB_AntSignal', 'dB_AntNoise', # noqa: E501 'RXFlags', 'TXFlags', 'b17', 'b18', 'ChannelPlus', 'MCS', 'A_MPDU', # noqa: E501 'VHT', 'timestamp', 'b24', 'b25', 'b26', 'b27', 'b28', 'b29', # noqa: E501 'RadiotapNS', 'VendorNS', 'Ext']), # noqa: E501 # Extended presence mask ConditionalField(PacketListField("Ext", [], next_cls_cb=_next_radiotap_extpm), lambda pkt: pkt.present and pkt.present.Ext), # noqa: E501 # Default fields ConditionalField(_RadiotapReversePadField(BitField("mac_timestamp", 0, -64)), lambda pkt: pkt.present and pkt.present.TSFT), # noqa: E501 ConditionalField( _RadiotapReversePadField( FlagsField("Flags", None, -8, ['CFP', 'ShortPreamble', 'wep', 'fragment', # noqa: E501 'FCS', 'pad', 'badFCS', 'ShortGI']) # noqa: E501 ), lambda pkt: pkt.present and pkt.present.Flags), ConditionalField(_RadiotapReversePadField(ByteField("Rate", 0)), lambda pkt: pkt.present and pkt.present.Rate), # noqa: E501 ConditionalField(_RadiotapReversePadField(LEShortField("Channel", 0)), lambda pkt: pkt.present and pkt.present.Channel), # noqa: E501 ConditionalField( _RadiotapReversePadField( FlagsField("ChannelFlags", None, -16, ['res1', 'res2', 'res3', 'res4', 'Turbo', 'CCK', # noqa: E501 'OFDM', '2GHz', '5GHz', 'Passive', 'Dynamic_CCK_OFDM', # noqa: E501 'GFSK', 'GSM', 'StaticTurbo', '10MHz', '5MHz']) # noqa: E501 ), lambda pkt: pkt.present and pkt.present.Channel), ConditionalField(_RadiotapReversePadField(_dbmField("dBm_AntSignal", -256)), lambda pkt: pkt.present and pkt.present.dBm_AntSignal), # noqa: E501 ConditionalField(_RadiotapReversePadField(_dbmField("dBm_AntNoise", -256)), lambda pkt: pkt.present and pkt.present.dBm_AntNoise), # noqa: E501 ConditionalField(_RadiotapReversePadField(ByteField("Antenna", 0)), lambda pkt: pkt.present and pkt.present.Antenna), # noqa: E501 # RX Flags ConditionalField(_RadiotapReversePadField(FlagsField("RXFlags", None, -16, ["res1", "BAD_PLCP", "res2"])), # noqa: E501 lambda pkt: pkt.present and pkt.present.RXFlags), # noqa: E501# # TX Flags ConditionalField(_RadiotapReversePadField(FlagsField("TXFlags", None, -16, ["TX_FAIL", "CTS", "RTS", "NOACK", "NOSEQ"])), # noqa: E501 lambda pkt: pkt.present and pkt.present.TXFlags), # noqa: E501 # ChannelPlus ConditionalField( _RadiotapReversePadField( FlagsField("ChannelFlags2", None, -32, ['res1', 'res2', 'res3', 'res4', 'Turbo', 'CCK', # noqa: E501 'OFDM', '2GHz', '5GHz', 'Passive', 'Dynamic_CCK_OFDM', # noqa: E501 'GFSK', 'GSM', 'StaticTurbo', '10MHz', '5MHz', # noqa: E501 '20MHz', '40MHz_ext_channel_above', '40MHz_ext_channel_below', # noqa: E501 'res5', 'res6', 'res7', 'res8', 'res9']) # noqa: E501 ), lambda pkt: pkt.present and pkt.present.ChannelPlus), ConditionalField(_RadiotapReversePadField(LEShortField("ChannelFrequency", 0)), lambda pkt: pkt.present and pkt.present.ChannelPlus), # noqa: E501 ConditionalField(_RadiotapReversePadField(ByteField("ChannelNumber", 0)), lambda pkt: pkt.present and pkt.present.ChannelPlus), # noqa: E501 # MCS ConditionalField( _RadiotapReversePadField(FlagsField("knownMCS", None, -8, ['bandwidth', 'MCS_index', 'guard_interval', 'HT_format', # noqa: E501 'FEC_type', 'STBC_streams', 'Ness', 'Ness_MSB'])), # noqa: E501 lambda pkt: pkt.present and pkt.present.MCS), ConditionalField(BitEnumField("bandwidth", 0, 2, {0: "20MHz", 1: "40MHz", 2: "ht40Mhz-", 3: "ht40MHz+"}), # noqa: E501 lambda pkt: pkt.present and pkt.present.MCS), # noqa: E501 ConditionalField(BitEnumField("guard_interval", 0, 1, {0: "Long_GI", 1: "Short_GI"}), lambda pkt: pkt.present and pkt.present.MCS), # noqa: E501 ConditionalField(BitEnumField("HT_format", 0, 1, {0: "mixed", 1: "greenfield"}), lambda pkt: pkt.present and pkt.present.MCS), # noqa: E501 ConditionalField(BitEnumField("FEC_type", 0, 1, {0: "BCC", 1: "LDPC"}), lambda pkt: pkt.present and pkt.present.MCS), # noqa: E501 ConditionalField(BitField("STBC_streams", 0, 2), lambda pkt: pkt.present and pkt.present.MCS), # noqa: E501 ConditionalField(BitField("Ness_LSB", 0, 1), lambda pkt: pkt.present and pkt.present.MCS), # noqa: E501 ConditionalField(ByteField("MCS_index", 0), lambda pkt: pkt.present and pkt.present.MCS), # noqa: E501 # A_MPDU ConditionalField(_RadiotapReversePadField(LEIntField("A_MPDU_ref", 0)), lambda pkt: pkt.present and pkt.present.A_MPDU), # noqa: E501 ConditionalField( _RadiotapReversePadField( FlagsField("A_MPDU_flags", None, -32, ['Report0Subframe', 'Is0Subframe', 'KnownLastSubframe', # noqa: E501 'LastSubframe', 'CRCerror', 'EOFsubframe', 'KnownEOF', # noqa: E501 'res1', 'res2', 'res3', 'res4', 'res5', 'res6', 'res7', 'res8']) # noqa: E501 ), lambda pkt: pkt.present and pkt.present.A_MPDU), # VHT ConditionalField( _RadiotapReversePadField( FlagsField("KnownVHT", None, -16, ['STBC', 'TXOP_PS_NOT_ALLOWED', 'GuardInterval', 'SGINsysmDis', # noqa: E501 'LDPCextraOFDM', 'Beamformed', 'Bandwidth', 'GroupID', 'PartialAID', # noqa: E501 'res1', 'res2', 'res3', 'res4', 'res5', 'res6', 'res7']) # noqa: E501 ), lambda pkt: pkt.present and pkt.present.VHT), ConditionalField( _RadiotapReversePadField( FlagsField("PresentVHT", None, -8, ['STBC', 'TXOP_PS_NOT_ALLOWED', 'GuardInterval', 'SGINsysmDis', # noqa: E501 'LDPCextraOFDM', 'Beamformed', 'res1', 'res2']) # noqa: E501 ), lambda pkt: pkt.present and pkt.present.VHT), ConditionalField(_RadiotapReversePadField(ByteEnumField("bandwidth", 0, _vht_bandwidth)), lambda pkt: pkt.present and pkt.present.VHT), # noqa: E501 ConditionalField(_RadiotapReversePadField(StrFixedLenField("mcs_nss", 0, length=5)), lambda pkt: pkt.present and pkt.present.VHT), # noqa: E501 ConditionalField(_RadiotapReversePadField(ByteField("GroupID", 0)), lambda pkt: pkt.present and pkt.present.VHT), # noqa: E501 ConditionalField(_RadiotapReversePadField(ShortField("PartialAID", 0)), lambda pkt: pkt.present and pkt.present.VHT), # noqa: E501 StrLenField('notdecoded', "", length_from=lambda pkt: pkt.len - pkt._tmp_dissect_pos)] # noqa: E501 def guess_payload_class(self, payload): if self.present and self.present.Flags and self.Flags.FCS: return Dot11FCS return Dot11 def post_build(self, p, pay): if self.len is None: p = p[:2] + struct.pack("!H", len(p))[::-1] + p[4:] return p + pay
class IE_Teardown(IE_Base): name = "Teardown Indicator" fields_desc = [ ByteEnumField("ietype", 19, IEType), ByteEnumField("indicator", "True", TrueFalse_value) ]
class Dot11Elt(Packet): name = "802.11 Information Element" fields_desc = [ByteEnumField("ID", 0, _dot11_info_elts_ids), FieldLenField("len", None, "info", "B"), StrLenField("info", "", length_from=lambda x: x.len, max_length=255)] def mysummary(self): if self.ID == 0: ssid = repr(self.info) if ssid[:2] in ['b"', "b'"]: ssid = ssid[1:] return "SSID=%s" % ssid, [Dot11] else: return "" registered_ies = {} @classmethod def register_variant(cls): cls.registered_ies[cls.ID.default] = cls @classmethod def dispatch_hook(cls, _pkt=None, *args, **kargs): if _pkt: _id = orb(_pkt[0]) if _id == 221: oui_a = orb(_pkt[2]) oui_b = orb(_pkt[3]) oui_c = orb(_pkt[4]) if oui_a == 0x00 and oui_b == 0x50 and oui_c == 0xf2: # MS OUI type_ = orb(_pkt[5]) if type_ == 0x01: # MS WPA IE return Dot11EltMicrosoftWPA else: return Dot11EltVendorSpecific else: return Dot11EltVendorSpecific else: return cls.registered_ies.get(_id, cls) return cls def haslayer(self, cls): if cls == "Dot11Elt": if isinstance(self, Dot11Elt): return True elif issubtype(cls, Dot11Elt): if isinstance(self, cls): return True return super(Dot11Elt, self).haslayer(cls) def getlayer(self, cls, nb=1, _track=None, _subclass=True, **flt): return super(Dot11Elt, self).getlayer(cls, nb=nb, _track=_track, _subclass=True, **flt) def post_build(self, p, pay): if self.len is None: p = p[:1] + chb(len(p) - 2) + p[2:] return p + pay
class IE_QoS(IE_Base): name = "QoS" fields_desc = [ ByteEnumField("ietype", 135, IEType), ShortField("length", None), ByteField("allocation_retention_prioiry", 1), # 3GPP TS 24.008 10.5.6.5 ConditionalField(XBitField("spare1", 0x00, 2), lambda p: p.length and p.length > 1), ConditionalField(XBitField("delay_class", 0x000, 3), lambda p: p.length and p.length > 1), ConditionalField(XBitField("reliability_class", 0x000, 3), lambda p: p.length and p.length > 1), ConditionalField(XBitField("peak_troughput", 0x0000, 4), lambda p: p.length and p.length > 2), ConditionalField(BitField("spare2", 0, 1), lambda p: p.length and p.length > 2), ConditionalField(XBitField("precedence_class", 0x000, 3), lambda p: p.length and p.length > 2), ConditionalField(XBitField("spare3", 0x000, 3), lambda p: p.length and p.length > 3), ConditionalField(XBitField("mean_troughput", 0x00000, 5), lambda p: p.length and p.length > 3), ConditionalField(XBitField("traffic_class", 0x000, 3), lambda p: p.length and p.length > 4), ConditionalField(XBitField("delivery_order", 0x00, 2), lambda p: p.length and p.length > 4), ConditionalField(XBitField("delivery_of_err_sdu", 0x000, 3), lambda p: p.length and p.length > 4), ConditionalField(ByteField("max_sdu_size", None), lambda p: p.length and p.length > 5), ConditionalField(ByteField("max_bitrate_up", None), lambda p: p.length and p.length > 6), ConditionalField(ByteField("max_bitrate_down", None), lambda p: p.length and p.length > 7), ConditionalField(XBitField("redidual_ber", 0x0000, 4), lambda p: p.length and p.length > 8), ConditionalField(XBitField("sdu_err_ratio", 0x0000, 4), lambda p: p.length and p.length > 8), ConditionalField(XBitField("transfer_delay", 0x00000, 6), lambda p: p.length and p.length > 9), ConditionalField(XBitField("traffic_handling_prio", 0x000, 2), lambda p: p.length and p.length > 9), ConditionalField(ByteField("guaranteed_bit_rate_up", None), lambda p: p.length and p.length > 10), ConditionalField(ByteField("guaranteed_bit_rate_down", None), lambda p: p.length and p.length > 11), ConditionalField(XBitField("spare4", 0x000, 3), lambda p: p.length and p.length > 12), ConditionalField(BitField("signaling_indication", 0, 1), lambda p: p.length and p.length > 12), ConditionalField(XBitField("source_stats_desc", 0x0000, 4), lambda p: p.length and p.length > 12), ConditionalField(ByteField("max_bitrate_down_ext", None), lambda p: p.length and p.length > 13), ConditionalField(ByteField("guaranteed_bitrate_down_ext", None), lambda p: p.length and p.length > 14), ConditionalField(ByteField("max_bitrate_up_ext", None), lambda p: p.length and p.length > 15), ConditionalField(ByteField("guaranteed_bitrate_up_ext", None), lambda p: p.length and p.length > 16), ConditionalField(ByteField("max_bitrate_down_ext2", None), lambda p: p.length and p.length > 17), ConditionalField(ByteField("guaranteed_bitrate_down_ext2", None), lambda p: p.length and p.length > 18), ConditionalField(ByteField("max_bitrate_up_ext2", None), lambda p: p.length and p.length > 19), ConditionalField(ByteField("guaranteed_bitrate_up_ext2", None), lambda p: p.length and p.length > 20) ]
class IGMPv3(IGMP): """IGMP Message Class for v3. This class is derived from class Packet. The fields defined below are a direct interpretation of the v3 Membership Query Message. Fields 'type' through 'qqic' are directly assignable. For 'numsrc', do not assign a value. Instead add to the 'srcaddrs' list to auto-set 'numsrc'. To assign values to 'srcaddrs', use the following methods:: c = IGMPv3() c.srcaddrs = ['1.2.3.4', '5.6.7.8'] c.srcaddrs += ['192.168.10.24'] At this point, 'c.numsrc' is three (3) 'chksum' is automagically calculated before the packet is sent. 'mrcode' is also the Advertisement Interval field """ name = "IGMPv3" igmpv3types = { 0x11: "Membership Query", 0x22: "Version 3 Membership Report", 0x30: "Multicast Router Advertisement", 0x31: "Multicast Router Solicitation", 0x32: "Multicast Router Termination" } fields_desc = [ ByteEnumField("type", 0x11, igmpv3types), ByteField("mrcode", 20), XShortField("chksum", None) ] def encode_maxrespcode(self): """Encode and replace the mrcode value to its IGMPv3 encoded time value if needed, # noqa: E501 as specified in rfc3376#section-4.1.1. If value < 128, return the value specified. If >= 128, encode as a floating # noqa: E501 point value. Value can be 0 - 31744. """ value = self.mrcode if value < 128: code = value elif value > 31743: code = 255 else: exp = 0 value >>= 3 while (value > 31): exp += 1 value >>= 1 exp <<= 4 code = 0x80 | exp | (value & 0x0F) self.mrcode = code def mysummary(self): """Display a summary of the IGMPv3 object.""" if isinstance(self.underlayer, IP): return self.underlayer.sprintf( "IGMPv3: %IP.src% > %IP.dst% %IGMPv3.type%") # noqa: E501 else: return self.sprintf("IGMPv3 %IGMPv3.type%") @classmethod def dispatch_hook(cls, _pkt=None, *args, **kargs): if _pkt and len(_pkt) >= 4: if orb(_pkt[0]) in [0x12, 0x16, 0x17]: return IGMP elif orb(_pkt[0]) == 0x11 and len(_pkt) < 12: return IGMP return IGMPv3
class PCO_Primary_NBNS(PCO_Option): name = "Primary DNS Server IP Address" fields_desc = [ByteEnumField("type", None, PCO_OPTION_TYPES), ByteField("length", 0), IPField("address", RandIP())]
class SOCKS4Reply(Packet): name = "SOCKS 4 - Reply" overload_fields = {SOCKS: {"vn": 0x0}} fields_desc = [ ByteEnumField("cd", 90, _socks4_cd_reply), ] + SOCKS4Request.fields_desc[1:-2] # Re-use dstport, dst and userid