]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/blob - src/allmydata/util/iputil.py
iputil: add get_local_addresses(), an attempt to enumerate all IPv4 addresses on...
[tahoe-lafs/tahoe-lafs.git] / src / allmydata / util / iputil.py
1
2 # adapted from nattraverso.ipdiscover
3
4 from cStringIO import StringIO
5 import re
6 import socket
7 from twisted.internet import reactor
8 from twisted.internet.protocol import DatagramProtocol
9 from twisted.internet.utils import getProcessOutput
10
11 def get_local_addresses():
12     """Return a Deferred that fires with a list of IPv4 addresses (as
13     dotted-quad strings) that are currently configured on this host.
14     """
15     # eventually I want to use somebody else's cross-platform library for
16     # this. For right now, I'm running ifconfig and grepping for the 'inet '
17     # lines.
18     cmd = "ifconfig"
19     d = getProcessOutput("ifconfig")
20     def _parse(output):
21         addresses = []
22         for line in StringIO(output).readlines():
23             # linux shows: "   inet addr:1.2.3.4  Bcast:1.2.3.255..."
24             # OS-X shows: "   inet 1.2.3.4 ..."
25             m = re.match("^\s+inet\s+[a-z:]*([\d\.]+)\s", line)
26             if m:
27                 addresses.append(m.group(1))
28         return addresses
29     def _fallback(f):
30         return ["127.0.0.1", get_local_ip_for()]
31     d.addCallbacks(_parse, _fallback)
32     return d
33
34
35 def get_local_ip_for(target='A.ROOT-SERVERS.NET'):
36     """Find out what our IP address is for use by a given target.
37
38     Returns a string that holds the IP address which could be used by
39     'target' to connect to us. It might work for them, it might not.
40     """
41     try:
42         target_ipaddr = socket.gethostbyname(target)
43     except socket.gaierror:
44         return "127.0.0.1"
45     udpprot = DatagramProtocol()
46     port = reactor.listenUDP(0, udpprot)
47     udpprot.transport.connect(target_ipaddr, 7)
48     localip = udpprot.transport.getHost().host
49     port.stopListening() # note, this returns a Deferred
50     return localip
51