What is the most efficient way to get all of the external ip address of a machine with multiple nics, using python? I understand that an external server is neeeded (I have one available) but am un able to find a way to find a good way to specify the nic to use for the connection (So I can use a for loop to iterate through the various nics). Any advice about the best way to go about this?
-
Why would you need to specify the NIC to use? If you open a connection to another machine your OS will automagically use the correct interface. If not, you have to fix your machine setup, not your program. – hochl Nov 26 '11 at 20:49
-
If a machine had multiple external ip address (though various nics) The OS would always use the same nic, resulting in the same ip. I'm looking to find all external ips, the only way I could think of would be to specify the nic. If there is a better way, please do tell. – Trcx Nov 26 '11 at 21:07
-
On example of this could be in a hosting environment with many nics, each corresponding to a different virtual server. – Trcx Nov 26 '11 at 21:10
5 Answers
You should use netifaces. It is designed to be cross-platform on Mac OS X, Linux, and Windows.
>>> import netifaces as ni
>>> ni.interfaces()
['lo', 'eth0', 'eth1', 'vboxnet0', 'dummy1']
>>> ni.ifaddresses('eth0')
{17: [{'broadcast': 'ff:ff:ff:ff:ff:ff', 'addr': '00:02:55:7b:b2:f6'}], 2: [{'broadcast': '24.19.161.7', 'netmask': '255.255.255.248', 'addr': '24.19.161.6'}], 10: [{'netmask': 'ffff:ffff:ffff:ffff::', 'addr': 'fe80::202:55ff:fe7b:b2f6%eth0'}]}
>>>
>>> ni.ifaddresses.__doc__
'Obtain information about the specified network interface.\n\nReturns a dict whose keys are equal to the address family constants,\ne.g. netifaces.AF_INET, and whose values are a list of addresses in\nthat family that are attached to the network interface.'
>>> # for the IPv4 address of eth0
>>> ni.ifaddresses('eth0')[2][0]['addr']
'24.19.161.6'
The numbers used to index protocols are from /usr/include/linux/socket.h
(in Linux)...
#define AF_INET 2 /* Internet IP Protocol */
#define AF_INET6 10 /* IP version 6 */
#define AF_PACKET 17 /* Packet family */

- 41,899
- 19
- 136
- 174
-
Wow Perfect! Thank you. I now can also see additional ways to rewrite my code to utilize this! Thank you! – Trcx Nov 28 '11 at 01:01
-
`ni.ifaddresses('eth0')[2][0]['addr']` this line will give you your `local IP address`, not `external IP address` if you are behind a router/NAT. – weefwefwqg3 Mar 11 '18 at 05:52
Required: WMI / PyWin32 (https://sourceforge.net/projects/pywin32/)
Use the following snippet to get the IP of the network card(s) on Windows.
import wmi
c = wmi.WMI()
for interface in c.Win32_NetworkAdapterConfiguration(IPEnabled=1):
print("Description: " + interface.Description)
print("IP: " + str(interface.IPAddress[0]))
print("MAC: " + str(interface.IPAddress[1]))
For more information on what parameters you can provide Win32_NetworkAdapterConfiguration
with visit: https://msdn.microsoft.com/en-us/library/aa394217(v=vs.85).aspx

- 3,613
- 2
- 31
- 30
For the general case, there is no solution. Consider the case where the local machine is behind a machine with two IP addresses doing NAT. You can change your local interface to anything you like, but it's unlikely that you'll convince the NAT machine to make a different routing decision on its outgoing connections.

- 47,755
- 6
- 94
- 122
Get address of all NICs without any external package
import socket
print socket.gethostbyname_ex(socket.gethostname())[2]

- 2,464
- 3
- 30
- 47
-
This solution as well, will not give an EXTERNAL IP. Look at Jean-Paul Calderone's answer. – weefwefwqg3 Mar 11 '18 at 05:53
Use the subprocess module to connect to your usual systems tools like ifconfig or netstat:
>>> import subprocess
>>> print subprocess.check_output(['ifconfig'])

- 216,523
- 63
- 388
- 485
-
But ifconfig on displays the local ip address, correct? Not sure about netstat, but I think it's the same issue. :( – Trcx Nov 26 '11 at 21:29
-
@Raymond Hettinger, FYI, Linux has deprecated `ifconfig` in favor of `ip link show` / `ip addr show` (10 years ago!)... sadly, most distros still leave `ifconfig` there for fear of breaking old scripts – Mike Pennington Nov 27 '11 at 20:51
-
@MikePennington Since *ip* never made it to the Mac OS, I tend to forget it's there :-) – Raymond Hettinger Nov 28 '11 at 07:56