diff --git a/src/message_parsers.py b/src/message_parsers.py index ed4bdb1f..069b8ea9 100644 --- a/src/message_parsers.py +++ b/src/message_parsers.py @@ -31,7 +31,6 @@ class AddressMessageParser: break if not hostDetails: continue - break timestamp, stream, services, host, port = hostDetails yield hostDetails diff --git a/src/shared.py b/src/shared.py index 3553c852..33f4197a 100644 --- a/src/shared.py +++ b/src/shared.py @@ -78,24 +78,57 @@ def isInSqlInventory(hash): return True def packNetworkAddress(address): - try: - # Matches IPV4-style address. - if ':' not in address and address.count('.') == 3: - return socket.inet_pton(socket.AF_INET6, '::ffff:' + address) - # Matches IPV4-mapped IPV6 and plain IPV6. - else: - return socket.inet_pton(socket.AF_INET6, address) - except OSError: - logger.error('Failed to pack address "%s".' % (address)) - raise + # For windows, we need to avoid socket.inet_pton() + if sys.platform == 'win32': + try: + # Matches IPV4-style address. + if ':' not in address and address.count('.') == 3: + # Already in IPv6 format; no address curtailing needed. + pass + elif address.lower().startswith('::ffff:'): + # Chop off the IPv4-mapped IPv6 prefix from the standard-form address. + address = address[7:] + else: + raise Exception('IPv6 not supported by packNetworkAddress on Windows.') + # Pack the standard-form IPv4 address and add prefix to make packed IPv4-mapped IPv6. + return '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF' + \ + socket.inet_aton(address) + except Exception as err: + logger.error('Failed to pack address "%s". Err: %s' % (address, err)) + raise + # Works on most modern posix distros. + else: + try: + # Matches IPV4-style address. + if ':' not in address and address.count('.') == 3: + return socket.inet_pton(socket.AF_INET6, '::ffff:' + address) + # Matches IPV4-mapped IPV6 and plain IPV6. + else: + return socket.inet_pton(socket.AF_INET6, address) + except Exception as err: + logger.error('Failed to pack address "%s". Err: %s' % (address, err)) + raise + +# Take packed IPv4-mapped IPv6 address and return unpacked IPv4-mapped IPv6 string in standard +# notation (e.g. ::ffff:127.0.0.1). def unpackNetworkAddress(packedAddress): - try: - address = socket.inet_ntop(socket.AF_INET6, packedAddress) - return address - except: - logger.error('Failed to unpack address %s.' % repr(packedAddress)) - raise + # For windows, we need to avoid socket.inet_ntop() + if sys.platform == 'win32': + try: + if not packedAddress.startswith('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF'): + raise Exception('IPv6 not supported by unpackNetworkAddress on Windows.') + return '::ffff:' + socket.inet_ntoa(packedAddress[12:]) + except: + logger.error('Failed to unpack address %s.' % repr(packedAddress)) + raise + # Works on most modern posix distros. + else: + try: + return socket.inet_ntop(socket.AF_INET6, packedAddress) + except: + logger.error('Failed to unpack address %s.' % repr(packedAddress)) + raise def assembleVersionMessage(remoteHost, remotePort, myStreamNumber): payload = ''