Example #1
0
    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])
Example #2
0
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
Example #3
0
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
Example #4
0
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
Example #5
0
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
Example #6
0
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
Example #7
0
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()
Example #8
0
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
Example #9
0
def _ulong2ip(ip):
    '''unsigned long -> 点分十进制
    '''
    return _socket.inet_ntoa(pack('>L', ip))
Example #10
0
    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]
Example #11
0
 def getter(self):
     mcast, iface = struct.unpack(format, self._sock.getsockopt(level,
         option, size))
     return _socket.inet_ntoa(mcast), _socket.inet_ntoa(iface)
Example #12
0
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
Example #13
0
 def getter(self):
     mcast, iface = struct.unpack(
         format, self._sock.getsockopt(level, option, size))
     return _socket.inet_ntoa(mcast), _socket.inet_ntoa(iface)
Example #14
0
 def _unpack_ip(ip_addr):
     return inet_ntoa(struct.pack(">I", ip_addr))
Example #15
0
def _ulong2ip(ip):
    """unsigned long -> 点分十进制
  """
    return _socket.inet_ntoa(pack(">L", ip))
Example #16
0
def _ulong2ip(ip):
    '''unsigned long -> 点分十进制
  '''
    return _socket.inet_ntoa(pack('>L', ip))
Example #17
0
def _ulong2ip(ip):
  return _socket.inet_ntoa(pack('>L', ip))