# portions extracted from ipaddresslib by Autonomous Zone Industries, LGPL (author: Greg Smith) # portions adapted from nattraverso.ipdiscover # portions authored by Brian Warner, working for Allmydata # most recent version authored by Zooko O'Whielacronx, working for Allmydata # from the Python Standard Library import re, socket, sys # from Twisted from twisted.internet import defer from twisted.internet import reactor from twisted.internet.protocol import DatagramProtocol from twisted.internet.utils import getProcessOutput from twisted.python.procutils import which def get_local_addresses_async(target='A.ROOT-SERVERS.NET'): """ Return a Deferred that fires with a list of IPv4 addresses (as dotted-quad strings) that are currently configured on this host. @param target: we want to learn an IP address they could try using to connect to us; The default value is fine, but it might help if you pass the address of a host that you are actually trying to be reachable to. """ if sys.platform == "cygwin": return _cygwin_hack(target) addresses = set() addresses.add(get_local_ip_for(target)) d = _find_addresses_via_config() def _collect(res): addresses.update(res) return addresses d.addCallback(_collect) return d def get_local_ip_for(target): """Find out what our IP address is for use by a given target. @returns: the IP address as a dotted-quad string which could be used by 'target' to connect to us. It might work for them, it might not """ target_ipaddr = socket.gethostbyname(target) udpprot = DatagramProtocol() port = reactor.listenUDP(0, udpprot) udpprot.transport.connect(target_ipaddr, 7) localip = udpprot.transport.getHost().host port.stopListening() # note, this returns a Deferred return localip # k: result of sys.platform, v: which kind of IP configuration reader we use _platform_map = { "linux-i386": "linux", # redhat "linux-ppc": "linux", # redhat "linux2": "linux", # debian "win32": "win32", "irix6-n32": "irix", "irix6-n64": "irix", "irix6": "irix", "openbsd2": "bsd", "darwin": "bsd", # Mac OS X "freebsd4": "bsd", "freebsd5": "bsd", "netbsd1": "bsd", "sunos5": "sunos", "cygwin": "cygwin", } class UnsupportedPlatformError(Exception): pass # Wow, I'm really amazed at home much mileage we've gotten out of calling # the external route.exe program on windows... It appears to work on all # versions so far. Still, the real system calls would much be preferred... # ... thus wrote Greg Smith in time immemorial... _win32_path = 'route.exe' _win32_args = ('print',) _win32_re = re.compile('^\s*\d+\.\d+\.\d+\.\d+\s.+\s(?P
\d+\.\d+\.\d+\.\d+)\s+(?P