Question

This is a little hard to explain, so bear with me.

In python, I want to send a UDP message:

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(('0.0.0.0', 5011))
dest = ('foo.horse', 5011)
# attact the source address to the message
...

sock.sendto(msg, dest)

But before I send that message, I want to determine the address of the interface that it will be sent over based on the destination address, so that I can include it in the message.

For example, if the destination is a WAN address, it would be the address of the LAN interface (because I am behind a NAT). If the destination is 'localhost', then the address would be '127.0.0.1'. If it's an address on the VPN, then it would be my VPN address.

UPDATE:

It looks like I can use: $ ip route get <destination> and it will tell me the src address
https://stackoverflow.com/a/5557459/334632

I ended up digging into the iproute2 source code, but I don't see what it is using that I can shortcut to. https://git.kernel.org/cgit/linux/kernel/git/shemminger/iproute2.git/tree/ip/iproute.c#n1376

I may end up just creating a subprocess and parsing the result, but I would like to avoid that if possible.

Was it helpful?

Solution

If you don't care about anything other than linux, you could use the pyroute2 module. For example, to get the routing information for a particular IP address:

>>> import pprint
>>> import pyroute2
>>> import socket
>>> ip = pyroute2.IPRoute()
>>> pprint.pprint(ip.get_routes(family=socket.AF_INET, dst='127.0.0.6'))
[{'attrs': [['RTA_TABLE', 254],
            ['RTA_DST', '127.0.0.6'],
            ['RTA_OIF', 1],
            ['RTA_PREFSRC', '127.0.0.1'],
            ['RTA_CACHEINFO',
             {'rta_clntref': 1,
              'rta_error': 0,
              'rta_expires': 0,
              'rta_id': 0,
              'rta_lastuse': 0,
              'rta_ts': 0,
              'rta_tsage': 0,
              'rta_used': 1}]],
  'dst_len': 32,
  'event': 'RTM_NEWROUTE',
  'family': 2,
  'flags': 2147484160,
  'proto': 0,
  'scope': 0,
  'src_len': 0,
  'table': 254,
  'tos': 0,
  'type': 2}]

Unfortunately, this doesn't work with the latest version of pyroute2 that's on pypi; I had to install from source in order to get these results.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top