1#!/usr/bin/env python3 2# BlueKitchen GmbH (c) 2014 3 4# Report SM Pairing Random packets with value zero 5 6 7import re 8import sys 9import time 10import datetime 11 12packet_types = [ "CMD =>", "EVT <=", "ACL =>", "ACL <="] 13 14def read_net_32(f): 15 a = f.read(1) 16 if a == '': 17 return -1 18 b = f.read(1) 19 if b == '': 20 return -1 21 c = f.read(1) 22 if c == '': 23 return -1 24 d = f.read(1) 25 if d == '': 26 return -1 27 return ord(a) << 24 | ord(b) << 16 | ord(c) << 8 | ord(d) 28 29def as_hex(data): 30 str_list = [] 31 for byte in data: 32 str_list.append("{0:02x} ".format(ord(byte))) 33 return ''.join(str_list) 34 35def check_file(infile): 36 with open (infile, 'rb') as fin: 37 pos = 0 38 warning = True 39 try: 40 while True: 41 len = read_net_32(fin) 42 if len < 0: 43 break 44 ts_sec = read_net_32(fin) 45 ts_usec = read_net_32(fin) 46 type = ord(fin.read(1)) 47 packet_len = len - 9; 48 if (packet_len > 66000): 49 print ("Error parsing pklg at offset %u (%x)." % (pos, pos)) 50 break 51 packet = fin.read(packet_len) 52 pos = pos + 4 + len 53 time = "[%s.%03u]" % (datetime.datetime.fromtimestamp(ts_sec).strftime("%Y-%m-%d %H:%M:%S"), ts_usec / 1000) 54 if type not in [0x02, 0x03]: 55 continue 56 packet_boundary_flags = (ord(packet[1]) >> 4) & 3 57 if packet_boundary_flags not in [0x00, 0x02]: 58 continue 59 channel = ord(packet[6]) | (ord(packet[7]) << 8) 60 if channel != 0x06: 61 continue 62 smp_command = ord(packet[8]) 63 if smp_command != 4: 64 continue 65 random = [ ord(i) for i in packet[9:25] ] 66 num_zeros = random.count(0) 67 if num_zeros != 16: 68 continue 69 if warning: 70 print("%s contains SM Pairing Random command with Zeroes:" % infile) 71 warning = False 72 print (time, packet_types[type], as_hex(packet)) 73 74 if not warning: 75 print("") 76 77 except TypeError: 78 print ("Error parsing pklg at offset %u (%x)." % (pos, pos)) 79 80if len(sys.argv) == 1: 81 print ('Usage: ' + sys.argv[0] + ' hci_dump.pklg') 82 exit(0) 83 84for infile in sys.argv[2:]: 85 check_file(infile) 86 87infile = sys.argv[1] 88 89