Windows-compatible IPv6-minded cleanup of recaddr.

* Made shared.{,un}packNetworkAddress() Windows-compatible.
* Removes superfluous break statement.
This commit is contained in:
Gregor Robinson 2013-07-22 16:19:35 +01:00
parent 90771f377c
commit bf8177c148
2 changed files with 49 additions and 17 deletions

View File

@ -31,7 +31,6 @@ class AddressMessageParser:
break break
if not hostDetails: if not hostDetails:
continue continue
break
timestamp, stream, services, host, port = hostDetails timestamp, stream, services, host, port = hostDetails
yield hostDetails yield hostDetails

View File

@ -78,24 +78,57 @@ def isInSqlInventory(hash):
return True return True
def packNetworkAddress(address): def packNetworkAddress(address):
try: # For windows, we need to avoid socket.inet_pton()
# Matches IPV4-style address. if sys.platform == 'win32':
if ':' not in address and address.count('.') == 3: try:
return socket.inet_pton(socket.AF_INET6, '::ffff:' + address) # Matches IPV4-style address.
# Matches IPV4-mapped IPV6 and plain IPV6. if ':' not in address and address.count('.') == 3:
else: # Already in IPv6 format; no address curtailing needed.
return socket.inet_pton(socket.AF_INET6, address) pass
except OSError: elif address.lower().startswith('::ffff:'):
logger.error('Failed to pack address "%s".' % (address)) # Chop off the IPv4-mapped IPv6 prefix from the standard-form address.
raise 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): def unpackNetworkAddress(packedAddress):
try: # For windows, we need to avoid socket.inet_ntop()
address = socket.inet_ntop(socket.AF_INET6, packedAddress) if sys.platform == 'win32':
return address try:
except: if not packedAddress.startswith('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF'):
logger.error('Failed to unpack address %s.' % repr(packedAddress)) raise Exception('IPv6 not supported by unpackNetworkAddress on Windows.')
raise 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): def assembleVersionMessage(remoteHost, remotePort, myStreamNumber):
payload = '' payload = ''