6

Is it possible to choose specific network interface to transmit data in Python? And I'm on Linux. I'm trying to transmit data through my active interfaces (first over eth0, then wlan0 etc...). Thanks.

mau5
  • 179
  • 1
  • 3
  • 8

2 Answers2

9

If we're talking about tcp/udp, then (like in any other langauge) the socket interface allows you to bind a specific ip address to it, so you do that by binding the interface's address.

People have the misconception that binding is only for listening on a socket, but this is also true for connecting, and its just that in normal usage the binding is chosen for you. Try this:

import socket
s = socket.socket()
s.bind(('192.168.1.111', 0))
s.connect(('www.google.com', 80))

Here we use the ip from interface eth0 (mine is 192.168.1.111) with a system-chosen source port to connect to google's web server. (You can also choose the source port if you want by replacing the 0)

EDIT: To get the IP address that is used for a specific interface you can use this recipe (linux only) - http://code.activestate.com/recipes/439094-get-the-ip-address-associated-with-a-network-inter/

(if you have multiple IPs on the same interface I'm not sure that it'll work. I assume it will return one of them)

itai
  • 1,566
  • 1
  • 12
  • 25
  • That's listening on a specific interface not transmitting from it. Unless of course there is a way I don't know about in which case please share the code! :) – nettux May 27 '14 at 10:57
  • Note that you might need another method to determine the ip address for the interface you want. This recipe worked for me (linux only) - http://code.activestate.com/recipes/439094-get-the-ip-address-associated-with-a-network-inter/ – itai May 27 '14 at 11:03
  • Yes, TCP/UDP of course. But, I hope you are not talking about bind to port address while listening, Thanks :) – mau5 May 27 '14 at 11:05
  • Indeed not for listening, but for connecting. – itai May 27 '14 at 11:06
  • Also note I've discovered you can use 0 as the port number in order to let the system choose the source port for you! I've changed my answer to reflect this. – itai May 27 '14 at 11:08
  • I think you are choosing and binding source port, not the interface. If I go like this, I'd still have no idea what interface my OS has chosen to connect to google.com as in the example. – mau5 May 27 '14 at 11:15
  • I am binding the IP ADDRESS not the interface, and leaving the source port for the system to choose automatically (though as I've mentioned it can be also bound manually). To get the ip address that is set for an interface use the recipe I've posted a link to in my first comment. – itai May 27 '14 at 12:08
  • Thanks, I guess I can choose interface by binding it's IP address. – mau5 May 28 '14 at 13:59
  • I believe the solution to this question should be to use `setsockopt(socket.SOL_SOCKET, IN.SO_BINDTODEVICE, "eth0")` where you will have to `import IN`. see [here](http://stackoverflow.com/questions/7221577/how-to-bind-socket-to-an-interface-in-python-socket-so-bindtodevice-missing) for more – jcchuks Nov 09 '16 at 16:39
  • Also see another example in the [python](https://mail.python.org/pipermail/python-list/2004-April/257493.html) mail thread – jcchuks Nov 09 '16 at 16:46
0

I needed to do this in ruby on linux and wrote an answer here I think you will find helpful. As itai pointed out you do need to bind to the IP address of the network interface, but on a linux machine you will also need source based routing rules. Check out my answer for more information.

hkparker
  • 121
  • 7