class ResetPacket(Packet): name = "Reset" fields_desc = [ LEShortField("id", 0xDEAC), ByteField("type", 0x0), LEShortField("nodes", None), LEShortField("rkeys", None) ]
class CadencePayload(Packet): fields_desc = [ BitField('page_change_toggle', 0, 1), BitField('data_page_number', None, 7), # ignore differences between page types FieldListField('data', None, XByteField('x', 0), count_from=lambda p: 3), LEShortField('cadence_event_time', 0), LEShortField('cadence_rev_count', 0), ]
class Metadata(Packet): name = "Metadata" fields_desc = [ LEShortField("pkt_len", 0), BitField("src_port", 0, 8), BitField("dst_port", 0, 8), LEShortField("bp_count", 0), BitField("q_id", 0, 8), BitField("rank_op", 0, 8), LEShortField("srpt_rank", 0), BitField("log_pkt", 0, 8), BitField("unused", 0, 40) ] def mysummary(self): return self.sprintf("pkt_len=%pkt_len% src_port=%src_port% dst_port=%dst_port% bp_count=%bp_count% q_id=%q_id% rank_op=%rank_op% srpt_rank=%srpt_rank% log_pkt=%log_pkt%")
class STFQ_Metadata(Packet): name = "STFQ_Metadata" fields_desc = [ LEShortField("pkt_len", 0), BitField("src_port", 0, 8), BitField("dst_port", 0, 8), LEShortField("rank", 0), LEShortField("bp_count", 0), LEIntField("q_id", 0), LEIntField("start_time", 0) ] def mysummary(self): return self.sprintf( "pkt_len=%pkt_len% src_port=%src_port% dst_port=%dst_port% rank=%rank% q_id=%q_id% start_time=%start_time%" )
class CoLoR_Data(Packet): name = 'CoLoR_Data' fields_desc = [ BitField("Version", 7, 4, tot_size=1), BitField("Package", 3, 4, end_tot_size=1), ByteField("TTL", 64), LEShortField("pkg_length", None), XShortField("checksum", None), ByteField("header_length", None), ByteField("PID_pt", None), FieldLenField("PID_num", None, fmt="B", count_of="PIDs", adjust=lambda pkt, x: x - (pkt.Flags.R == True)), FlagsField("Flags", 0, 8, "rSCQMRBF"), ConditionalField(ShortField("Minimal_PID_CP", None), lambda pkt: pkt.Flags.M), StrFixedLenField("N_sid", "", 16), StrFixedLenField("L_sid", "", 20), StrFixedLenField("nid_cus", "", 16), ConditionalField( StrFixedLenField("nid_pro", "", 16), lambda pkt: pkt.Flags.B == False and pkt.Flags.R == True), ConditionalField( FieldLenField("QoS_len", None, fmt="B", length_of="QoS_requirements"), lambda pkt: pkt.Flags.Q == True), ConditionalField( StrLenField("QoS_requirements", "", length_from=lambda pkt: pkt.QoS_len), lambda pkt: pkt.Flags.Q == True), ConditionalField(IntField("HMAC", None), lambda pkt: pkt.Flags.C == True), ConditionalField(IntField("Seg_ID", None), lambda pkt: pkt.Flags.S == True), FieldListField("PIDs", [""], StrFixedLenField("", "", 4), count_from=lambda pkt: pkt.PID_num + (pkt.Flags.R == True)) ] def post_build(self, pkt, pay): if self.header_length is None: self.header_length = len(pkt) pkt = pkt[:6] + int2Bytes(self.header_length, 1) + pkt[7:] if self.pkg_length is None: self.pkg_length = len(pkt) + len(pay) pkt = pkt[:2] + int2BytesLE(self.pkg_length, 2) + pkt[4:] if self.checksum is None: self.checksum = CalcChecksum(pkt) pkt = pkt[:4] + int2Bytes(self.checksum, 2) + pkt[6:] # print(self.pkg_length, self.header_length, self.checksum) return pkt + pay
class FitnessControlPage(Packet): fields_desc = [ByteField('data_page_number', None)] + [ ConditionalField(f, lambda p: p.data_page_number == 51) for f in [ FieldListField( 'reserved', 0, ByteField('x', 0), count_from=lambda p: 4), LEShortField('grade', 0), ByteField('coeff_roll', 0), ] ]
class Metadata(Packet): name = "Metadata" fields_desc = [ LEShortField("pkt_len", 0), BitField("src_port", 0, 8), BitField("dst_port", 0, 8), LEIntField("rank", 0), BitField("unused", 0, 64) ] def mysummary(self): return self.sprintf("pkt_len=%pkt_len% src_port=%src_port% dst_port=%dst_port% rank=%rank%")
class CoLoR_Ann(Packet): name = "CoLoR_Ann" fields_desc = [ BitField("Version", 7, 4, tot_size=1), BitField("Package", 1, 4, end_tot_size=1), ByteField("TTL", 64), LEShortField("pkg_length", None), XShortField("checksum", None), FlagsField("Flags", 0, 8, "rrrrrPKF"), BitField("unit_num", None, 4, tot_size=1), BitField("PX_num", None, 4, end_tot_size=1), PacketListField("Announce_unit_list", None, Ann_unit, count_from=lambda pkt: pkt.unit_num), ConditionalField( FieldLenField("Public_key_len", None, fmt="H", length_of="Public_key"), lambda pkt: pkt.Flags.K == True), ConditionalField( StrLenField("Public_key", "", length_from=lambda pkt: pkt.Public_key_len), lambda pkt: pkt.Flags.K == True), ConditionalField( FieldLenField("AS_PATH_len", None, fmt="B", count_of="AID_list"), lambda pkt: pkt.Flags.P == True), ConditionalField( FieldListField("AID_list", None, StrFixedLenField("", "", 1), count_from=lambda pkt: pkt.AS_PATH_len), lambda pkt: pkt.Flags.P == True), FieldListField("PX_list", None, StrFixedLenField("", "", 2), count_from=lambda pkt: pkt.PX_num) ] def post_build(self, pkt, pay): if self.pkg_length is None: self.pkg_length = len(pkt) pkt = pkt[:2] + int2BytesLE(self.pkg_length, 2) + pkt[4:] if self.checksum is None: self.checksum = CalcChecksum(pkt) pkt = pkt[:4] + int2Bytes(self.checksum, 2) + pkt[6:] if self.unit_num is None and self.PX_num is None: self.unit_num = len(self.Announce_unit_list) self.PX_num = len(self.PX_list) pkt = pkt[:7] + int2Bytes(self.unit_num << 4 | self.PX_num, 1) + pkt[8:] return pkt + pay
class CoLoR_Get(Packet): name = "CoLoR_Get" fields_desc = [ BitField("Version", 7, 4, tot_size=1), BitField("Package", 2, 4, end_tot_size=1), ByteField("TTL", 64), LEShortField("pkg_length", None), XShortField("checksum", None), ShortField("MTU", None), FieldLenField("PID_num", None, fmt="B", count_of="PIDs"), FlagsField("Flags", 8, 8, "rrrASQKF"), ShortField("Minimal_PID_CP", None), StrFixedLenField("N_sid", "", 16), StrFixedLenField("L_sid", "", 20), StrFixedLenField("nid", "", 16), ConditionalField( FieldLenField("Public_key_len", None, fmt="H", length_of="Public_key"), lambda pkt: pkt.Flags.K == True), ConditionalField( StrLenField("Public_key", "", length_from=lambda pkt: pkt.Public_key_len), lambda pkt: pkt.Flags.K == True), ConditionalField( FieldLenField("QoS_len", None, fmt="B", length_of="QoS_requirements"), lambda pkt: pkt.Flags.Q == True), ConditionalField( StrLenField("QoS_requirements", "", length_from=lambda pkt: pkt.QoS_len), lambda pkt: pkt.Flags.Q == True), ConditionalField(IntField("Seg_ID", None), lambda pkt: pkt.Flags.S == True), FieldListField("PIDs", None, StrFixedLenField("", "", 4), count_from=lambda pkt: pkt.PID_num) ] def post_build(self, pkt, pay): if self.pkg_length is None: self.pkg_length = len(pkt) pkt = pkt[:2] + int2BytesLE(self.pkg_length, 2) + pkt[4:] if self.checksum is None: self.checksum = CalcChecksum(pkt) pkt = pkt[:4] + int2Bytes(self.checksum, 2) + pkt[6:] return pkt + pay
class Metadata(Packet): name = "Metadata" fields_desc = [ LEShortField("pkt_len", 0), BitField("src_port", 0, 8), BitField("dst_port", 0, 8), LEIntField("enq_data", 0), LEIntField("deq_data", 0), LEIntField("drop_data", 0) ] def mysummary(self): return self.sprintf( "pkt_len=%pkt_len% src_port=%src_port% dst_port=%dst_port% enq_data=%enq_data% deq_data=%deq_data% drop_data=%drop_data%" )
class Dot11EltRSN(Packet): """The enc, cipher, and auth members contain the decoded 'security' details""" name = '802.11 RSN Information Element' cipher_suites = { '\x00\x0f\xac\x00': 'GROUP', '\x00\x0f\xac\x01': 'WEP', '\x00\x0f\xac\x02': 'TKIP', '\x00\x0f\xac\x04': 'CCMP', '\x00\x0f\xac\x05': 'WEP' } auth_suites = {'\x00\x0f\xac\x01': 'MGT', '\x00\x0f\xac\x02': 'PSK'} fields_desc = [ ByteField('ID', 0), FieldLenField("len", None, "info", "B"), LEShortField('version', 1), StrFixedLenField('group_cipher_suite', '', length=4), LEFieldLenField('pairwise_cipher_suite_count', 1, count_of='pairwise_cipher_suite'), FieldListField('pairwise_cipher_suite', None, StrFixedLenField('', '', length=4), count_from=lambda pkt: pkt.pairwise_cipher_suite_count), LEFieldLenField('auth_cipher_suite_count', 1, count_of='auth_cipher_suite'), FieldListField('auth_cipher_suite', None, StrFixedLenField('', '', length=4), count_from=lambda pkt: pkt.auth_cipher_suite_count), BitField('rsn_cap_pre_auth', 0, 1), BitField('rsn_cap_no_pairwise', 0, 1), BitField('rsn_cap_ptksa_replay_counter', 0, 2), BitField('rsn_cap_gtksa_replay_counter', 0, 2), BitField('rsn_cap_mgmt_frame_protect_required', 0, 1), BitField('rsn_cap_mgmt_frame_protect_capable', 0, 1), BitField('rsn_cap_reserved_1', 0, 1), BitField('rsn_cap_peer_key_enabled', 0, 1), BitField('rsn_cap_reserved_2', 0, 6), ] def post_dissection(self, pkt): """Parse cipher suites to determine encryption, cipher, and authentication methods""" self.enc = 'WPA2' # Everything is assumed to be WPA self.cipher = '' self.auth = '' ciphers = [ self.cipher_suites.get(pairwise_cipher) for pairwise_cipher in self.getfieldval('pairwise_cipher_suite') ] if 'GROUP' in ciphers: ciphers = [ self.cipher_suites.get(group_cipher, '') for group_cipher in self.getfieldval('group_cipher_suite') ] for cipher in ['CCMP', 'TKIP', 'WEP']: if cipher in ciphers: self.cipher = cipher break if 'WEP' == self.cipher: self.enc = 'WEP' for auth_cipher in self.getfieldval('auth_cipher_suite'): self.auth = self.auth_suites.get(auth_cipher, '') break
class PresentFlagField(ConditionalField): """Utility field for use by RadioTap""" def __init__(self, field, flag_name): ConditionalField.__init__( self, field, lambda pkt: pkt.hasflag('present', flag_name)) # TODO(ivanlei): This fields_desc does not cover chained present flags decode will fail in this cases scapy.layers.dot11.RadioTap.name = '802.11 RadioTap' # Greatly improved fields_desc for RadioTap which parses known present flags scapy.layers.dot11.RadioTap.fields_desc = [ ByteField('version', 0), ByteField('pad', 0), LEShortField('RadioTap_len', 0), FlagsField('present', None, -32, [ 'TSFT', 'Flags', 'Rate', 'Channel', 'FHSS', 'dBm_AntSignal', 'dBm_AntNoise', 'Lock_Quality', 'TX_Attenuation', 'dB_TX_Attenuation', 'dBm_TX_Power', 'Antenna', 'dB_AntSignal', 'dB_AntNoise', 'b14', 'b15', 'b16', 'b17', 'b18', 'b19', 'b20', 'b21', 'b22', 'b23', 'b24', 'b25', 'b26', 'b27', 'b28', 'b29', 'b30', 'Ext' ]), PresentFlagField(LELongField('TSFT', 0), 'TSFT'), PresentFlagField(ByteField('Flags', 0), 'Flags'), PresentFlagField(ByteField('Rate', 0), 'Rate'), PresentFlagField(ChannelFromMhzField('Channel', 0), 'Channel'), PresentFlagField(LEShortField('Channel_flags', 0), 'Channel'), PresentFlagField(ByteField('FHSS_hop_set', 0), 'FHSS'), PresentFlagField(ByteField('FHSS_hop_pattern', 0), 'FHSS'), PresentFlagField(SignedByteField('dBm_AntSignal', 0), 'dBm_AntSignal'),
class FitnessPayload(OptionalExtended): fields_desc = ([ByteField('data_page_number', None)] + [ ConditionalField(f, lambda p: p.data_page_number == 16) for f in [ ByteEnumField('equip_type', 0, {}), ByteField('elapsed_time', 0), ByteField('distance_traveled', 0), LEShortField('speed', 0), ByteField('heart_rate', 0), BitField('capabilities', 0, 4), BitField('fe_status', 0, 4), ] ] + [ ConditionalField(f, lambda p: p.data_page_number == 17) for f in [ ByteField('reserved_1', 0), ByteField('reserved_2', 0), ByteField('cycle_length', 0), LEShortField('incline', 0), ByteField('resistance_level', 0), BitField('capabilities', 0, 4), BitField('fe_status', 0, 4), ] ] + [ ConditionalField(f, lambda p: p.data_page_number == 25) for f in [ ByteField('update_event_count', 0), ByteField('instant_cadence', 0), LEShortField('accum_power', 0), InstantPowerField('instant_power', 0), TSBField('trainer_status', 0), BitEnumField( 'target_power', 0, 2, { 0x0: 'at_target_power', 0x1: 'speed_too_low', 0x2: 'speed_too_high', 0x3: 'undetermined', }, ), BitField('reserved', 0, 2), BitEnumField( 'hr_data_source', 0, 2, { 0x0: 'invalid', 0x1: 'ANT+', 0x2: 'HRM', 0x3: 'Contact Sensor' }, ), BitEnumField('distance_traveled_enabled', 0, 1, { 0x0: 'no', 0x1: 'yes' }), BitEnumField('speed_flag', 0, 1, { 0x0: 'real_speed', 0x1: 'virtual_speed' }), ] ] + [ ConditionalField(f, lambda p: p.data_page_number == 26) for f in [ ByteField('update_event_count', 0), ByteField('wheel_ticks', 0), LEShortField('wheel_period', 0), LEShortField('accum_torque', 0), BitField('capabilities', 0, 4), BitField('fe_status', 0, 4), ] ] + [ ConditionalField(f, lambda p: p.data_page_number == 80) for f in [ ByteField('reserved1', 0xFF), ByteField('reserved2', 0xFF), ByteField('hw_revision', 0), LEShortField('manufacturer_id', 0), LEShortField('model_number', 0), ] ] + [ ConditionalField(f, lambda p: p.data_page_number == 81) for f in [ ByteField('reserved', 0xFF), ByteField('sw_revision_supplemental', 0), ByteField('sw_revision', 0), LEIntField('serial_number', 0), ] ]) def post_dissection(self, pkt): if self.data_page_number not in [16, 17, 25, 26, 80, 81]: msg = f'Unknown fitness data page {self.data_page_number}' log.error(msg)