def usage() -> None: """Show usage""" l('Ubiquiti Discovery Tool\n -h Help\n -m Display mode: oneline, everything, edge\n' + ' -v Verbose\n -s Server mode\n -c Client mode\n -B Seconds since boot for server mode' )
def print_one_line(packet: UbntTLV) -> None: """Print a discovery as one line for column view""" ipv4: str = '' model: str = '' hostname: str = '' hwaddr: str = '' for t in packet.TLVs: cur_type = t.Type if cur_type == 0x0b: # hostname hostname = t.value_to_str() elif cur_type == 0x0c: # model name model = t.value_to_str() elif cur_type == 0x02: # 'MAC address and IP address' ipv4 = t.value_to_str().split('ipv4: ')[1] elif cur_type == 0x01: # 'MAC address' hwaddr = t.value_to_str() l('{:17} {:15} {:10} \''.format(hwaddr, ipv4, model) + hostname + '\'')
def server(): """Main server function""" global GLOBAL_TIMEOUT timeout: int = time() + GLOBAL_TIMEOUT try: while True: if GLOBAL_TIMEOUT != 0 and time() >= timeout: l('Timeout reached, exiting.') break try: data, came_from = SOCKET.recvfrom(2048) except socket.timeout: d('Timeout reached') break except Exception as ex: e('Could not receive incoming packets: ' + str(ex)) d('Incoming packet from ' + str(came_from)) parsed_packet: UbntTLV = None try: parsed_packet = UbntTLV(data) except Exception as r: e('Malformed packet: ' + str(r)) if parsed_packet is not None: d('Received version ' + str(parsed_packet.Version) + ', opcode ' + str(parsed_packet.Opcode)) if parsed_packet.Version == 1 and parsed_packet.Opcode == 0: l('Received query from ' + str(came_from) + '. Answering.') answer: UbntTLV = create_answer_packet() SOCKET.sendto(answer.to_byte_array(), came_from) else: d('Received non discovery request packet: \n' + str(parsed_packet)) else: d('Received malformed packet: ' + str(data)) except KeyboardInterrupt: l('Goodbye') except Exception as err: e('Uncaught exception in server mode: ' + str(err)) exit(-1)
def print_edge_detail_style(packet: UbntTLV) -> None: """Print a discovery result mimicking ERs show ubnt discovery detail output""" hostname: str = '' hwaddr: str = '' ipv4: str = '' product: str = '' fwversion: str = '' uptime: str = '' addresses: str = '' for t in packet.TLVs: cur_type: int = t.Type if cur_type == 0x0b: # hostname hostname = t.value_to_str() elif cur_type == 0x0c: # model name product = t.value_to_str() elif cur_type == 0x02: # 'MAC address and IP address' addresses += '\n ' + t.value_to_str() ipv4 = t.value_to_str().split('ipv4: ')[1] elif cur_type == 0x01: # 'MAC address' hwaddr = t.value_to_str() elif cur_type == 0x0a: # 'uptime' uptime = t.value_to_str() elif cur_type == 0x03: # 'firmware version' fwversion = t.value_to_str() l('hostname: ' + hostname) l('hwaddr: ' + hwaddr) l('ipv4: ' + ipv4) l('product: ' + product) l('fwversion: ' + fwversion) l('uptime: ' + uptime) l('addresses:' + addresses)
def print_everything(packet: UbntTLV) -> None: """Most verbose output for discovery packets""" for t in packet.TLVs: l('{:26}: {:}'.format(lookup_tlv_type(t.Type), t.value_to_str()))
def client() -> None: """Main client function""" global GLOBAL_TIMEOUT, DISPLAY_MODE discovery_request: UbntTLV = UbntTLV() d('Sending a discovery request to broadcast.') SOCKET.sendto(discovery_request.to_byte_array(), ('255.255.255.255', 10001)) d('Sent.') d('Sending a discovery request to multicast.') SOCKET.sendto(discovery_request.to_byte_array(), ('233.89.188.1', 10001)) d('Sent.') received_packets: List[UbntTLV] = [] timeout: int = time() + GLOBAL_TIMEOUT while True: data: bytearray = None came_from: Tuple[str, int] = ('', 0) try: data, came_from = SOCKET.recvfrom(2048) except socket.timeout: d('Timeout reached') break except Exception as ex: e('Could not receive incoming packets: ' + str(ex)) d('Incoming packet from ' + str(came_from)) parsed_packet: UbntTLV = None try: parsed_packet = UbntTLV(data) except Exception as r: e('Malformed packet: ' + str(r)) if parsed_packet is not None: d('Received version ' + str(parsed_packet.Version) + ', opcode ' + str(parsed_packet.Opcode)) if parsed_packet.Opcode in (0, 6) and len(parsed_packet.TLVs) > 2: received_packets.append(parsed_packet) else: d('Received non discovery response packet: \n' + str(parsed_packet)) else: d('Received malformed packet: ' + str(data)) if timeout < time(): d('Timeout reached. Exiting loop.') break received_unique_packets: List[UbntTLV] = [] for i in received_packets: found: bool = False for i2 in received_unique_packets: if i.identifier() == i2.identifier(): d('Found duplicate announcement.') found = True break if not found: received_unique_packets.append(i) l('Discovered ' + str(len(received_unique_packets)) + ' devices:') if DISPLAY_MODE == 'edge': l('----------------------------------------------------') for unique_device in received_unique_packets: print_edge_detail_style(unique_device) l('----------------------------------------------------') l('') elif DISPLAY_MODE == 'oneline': l('{:17} {:15} {:10} '.format('Hardware Address', 'IP address', 'Model') + 'hostname') for unique_device in received_unique_packets: print_one_line(unique_device) elif DISPLAY_MODE == 'everything': l('----------------------------------------------------') for unique_device in received_unique_packets: print_everything(unique_device) l('----------------------------------------------------')