How can I determine the source address before sending a message based on the destination address?

StackOverflow https://stackoverflow.com/questions/22845426

Domanda

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.

È stato utile?

Soluzione

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top