def get_ip_header(self, data=None, data_type='Protocol'): if not data: data = self.receive_data() unpacked_data = struct.unpack('!BBHHHBBH4s4s', data[:20]) if data_type == 'Version': return unpacked_data[0] >> 4 if data_type == 'IHL': return unpacked_data[0] & 0xf if data_type == 'Differentiated Services': return unpacked_data[1] if data_type == 'Total Length': return unpacked_data[2] if data_type == 'Identification': return unpacked_data[3] if data_type == 'Flags': return unpacked_data[4] if data_type == 'Fragment Offset': return unpacked_data[4] & 0x1FFF if data_type == 'TTL': return unpacked_data[5] if data_type == 'Protocol': return unpacked_data[6] if data_type == 'Header Checksum': return unpacked_data[7] if data_type == 'Source IP': return socket.inet_ntoa(unpacked_data[8]) if data_type == 'Destination IP': return socket.inet_ntoa(unpacked_data[9])
def discover_homekit_devices(max_seconds=10): """ This method discovers all HomeKit Accessories. It browses for devices in the _hap._tcp.local. domain and checks if all required fields are set in the text record. It one field is missing, it will be excluded from the result list. :param max_seconds: the number of seconds we will wait for the devices to be discovered :return: a list of dicts containing all fields as described in table 5.7 page 69 """ zeroconf = Zeroconf() listener = CollectingListener() ServiceBrowser(zeroconf, '_hap._tcp.local.', listener) sleep(max_seconds) tmp = [] for info in listener.get_data(): # from Bonjour discovery d = { 'name': info.name, 'address': inet_ntoa(info.address), 'port': info.port } logging.debug('candidate data %s', info.properties) d.update( parse_discovery_properties( decode_discovery_properties(info.properties))) if 'c#' not in d or 'md' not in d: continue logging.debug('found Homekit IP accessory %s', d) tmp.append(d) zeroconf.close() return tmp
def find_device_ip_and_port(device_id: str, max_seconds=10): """ Try to find a HomeKit Accessory via Bonjour. The process is time boxed by the second parameter which sets an upper limit of `max_seconds` before it times out. The runtime of the function may be longer because of the Bonjour handling code. :param device_id: the Accessory's pairing id :param max_seconds: the number of seconds to wait for the accessory to be found :return: a dict with ip and port if the accessory was found or None """ result = None zeroconf = Zeroconf() listener = CollectingListener() ServiceBrowser(zeroconf, '_hap._tcp.local.', listener) counter = 0 while result is None and counter < max_seconds: sleep(1) data = listener.get_data() for info in data: if info.properties[b'id'].decode() == device_id: result = {'ip': inet_ntoa(info.address), 'port': info.port} break counter += 1 zeroconf.close() return result
def split_nodes(nodes): length = len(nodes) if (length % 26) != 0: return for i in range(0, length, 26): nid = nodes[i:i + 20] ip = inet_ntoa(nodes[i + 20:i + 24]) port = unpack("!H", nodes[i + 24:i + 26])[0] yield nid, ip, port
def decode_nodes(nodes): n = [] length = len(nodes) if (length % 26) != 0: return n for i in range(0, length, 26): nid = nodes[i:i + 20] ip = inet_ntoa(nodes[i + 20:i + 24]) port = unpack('!H', nodes[i + 24:i + 26])[0] n.append((nid, ip, port)) return n
def parse_nodes(data): nodes = [] if data: length = len(data) # 每个node信息,20:nid 4:ip 2:port for i in range(0, length, COMPACT_NODE_INFO_LENGTH): nid = data[i:i + 20] ip = inet_ntoa(data[i + 20:i + 24]) port = unpack("!H", data[i + 24:i + 26])[0] nodes.append((nid, ip, port)) return nodes
def decode_nodes(nodes): nodes = nodes if isinstance(nodes, bytes) else nodes.encode('latin1') n = {} length = len(nodes) if (length % 26) != 0: return n.values() for i in range(0, length, 26): nid = nodes[i:i + 20] ip = inet_ntoa(nodes[i + 20:i + 24]) port = unpack('!H', nodes[i + 24:i + 26])[0] n[nid] = (nid, ip, port) return n.values()
def _build_data_from_service_info(service_info) -> dict[str, Any]: """Construct data from service_info.""" # from Bonjour discovery data = { "name": service_info.name, "address": inet_ntoa(service_info.addresses[0]), "port": service_info.port, } logging.debug("candidate data %s", service_info.properties) data.update( parse_discovery_properties( decode_discovery_properties(service_info.properties))) return data
def _ulong2ip(ip): '''unsigned long -> 点分十进制 ''' return _socket.inet_ntoa(pack('>L', ip))
HOST = socket.gethostbyname(socket.gethostname()) s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_IP) s.bind((HOST, 0)) s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1) s.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON) data = receiveData(s) unpackedDataIP = struct.unpack('!BBHHHBBH4s4s', data[0:20]) version_IHL = unpackedDataIP[0] # =69=0x45 IHL = version_IHL & 0xF totalLength = unpackedDataIP[2] ID = unpackedDataIP[3] # identification fragmentOffset = unpackedDataIP[4] & 0x1FFF protocolNr = unpackedDataIP[6] sourceAddress = inet_ntoa(unpackedDataIP[8]) destinationAddress = inet_ntoa(unpackedDataIP[9]) count += 1 print "Package " + str(count) print "An IP packet with the size %i was captured." % (unpackedDataIP[2]) print "Raw data: " + data print "\nParsed data" print "Header Length:\t\t" + str(IHL * 4) + " bytes" print "ID:\t\t\t" + str(hex(ID)) + " (" + str(ID) + ")" print "Length:\t\t\t" + str(totalLength) print "Protocol:\t\t" + getProtocol(protocolNr) if protocolNr == 6: print "Source:\t\t\t" + sourceAddress print "Destination:\t\t" + destinationAddress unpackedDataTCP = struct.unpack('!HH', data[20:24]) destinationPort = unpackedDataTCP[1]
def getter(self): mcast, iface = struct.unpack(format, self._sock.getsockopt(level, option, size)) return _socket.inet_ntoa(mcast), _socket.inet_ntoa(iface)
def discover_homekit_devices(max_seconds=10): """ This method discovers all HomeKit Accessories. It browses for devices in the _hap._tcp.local. domain and checks if all required fields are set in the text record. It one field is missing, it will be excluded from the result list. :param max_seconds: the number of seconds we will wait for the devices to be discovered :return: a list of dicts containing all fields as described in table 5.7 page 69 """ zeroconf = Zeroconf() listener = CollectingListener() ServiceBrowser(zeroconf, '_hap._tcp.local.', listener) sleep(max_seconds) tmp = [] for info in listener.get_data(): # from Bonjour discovery d = { 'name': info.name, 'address': inet_ntoa(info.address), 'port': info.port } props = info.properties # stuff taken from the Bonjour TXT record (see table 5-7 on page 69) conf_number = get_from_properties(props, b'c#', case_sensitive=False) if conf_number: d['c#'] = conf_number else: continue ff = get_from_properties(props, b'ff', case_sensitive=False) if ff: flags = int(ff) else: flags = 0 d['ff'] = flags d['flags'] = FeatureFlags[flags] id = get_from_properties(props, b'id', case_sensitive=False) if id: d['id'] = id md = get_from_properties(props, b'md', case_sensitive=False) if md: d['md'] = md else: continue pv = get_from_properties(props, b'pv', case_sensitive=False, default='1.0') if pv: d['pv'] = pv s = get_from_properties(props, b's#', case_sensitive=False) if s: d['s#'] = s sf = get_from_properties(props, b'sf', case_sensitive=False) if sf: d['sf'] = sf d['statusflags'] = IpStatusFlags[int(sf)] ci = get_from_properties(props, b'ci', case_sensitive=False) if ci: category = info.properties[b'ci'].decode() d['ci'] = category d['category'] = Categories[int(category)] # append device, it has all data tmp.append(d) zeroconf.close() return tmp
def getter(self): mcast, iface = struct.unpack( format, self._sock.getsockopt(level, option, size)) return _socket.inet_ntoa(mcast), _socket.inet_ntoa(iface)
def _unpack_ip(ip_addr): return inet_ntoa(struct.pack(">I", ip_addr))
def _ulong2ip(ip): """unsigned long -> 点分十进制 """ return _socket.inet_ntoa(pack(">L", ip))
def _ulong2ip(ip): return _socket.inet_ntoa(pack('>L', ip))