Finding an Ip Address from an Interface Name

How to get interface name and IP address from this text file in Python

Don't split into lines but work with full text as single string.

If you split on empty line - \n\n (double new line) - then you should have every device as separated text.

First word in every device is interface - so it needs split(' ', 1) and [0] to get this word.

IP address is after inet addr: so you can use it to split text and get [1] to have text with IP address at the beginning - so you can use again split(' ', 1) and [0]` to get this IP.


Minimal working code.

I found that there is single space in empty line so it needs \n \n instead of \n\n.

text = '''eth0 Link encap:Ethernet HWaddr b8:ac:6f:65:31:e5 inet addr:192.168.2.100 
Bcast:192.168.2.255 Mask:255.255.255.0 inet6 addr: fe80::baac:6fff:fe65:31e5/64
Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:2697529
errors:0 dropped:0 overruns:0 frame:0 TX packets:2630541 errors:0 dropped:0
overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:2159382827 (2.0 GiB) TX
bytes:1389552776 (1.2 GiB)

eth1 Link encap:Ethernet HWaddr b8:ac:6f:65:53:e5 inet addr:10.10.2.100 Bcast:10.10.2.255
Mask:255.255.255.0 inet6 addr: fe80::baac:6fff:ff65:31e5/64 Scope:Link UP BROADCAST RUNNING
MULTICAST MTU:1500 Metric:1 RX packets:2697529 errors:0 dropped:0 overruns:0 frame:0 TX
packets:2630541 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX
bytes:2159382827 (2.0 GiB) TX bytes:1389552776 (1.2 GiB)'''

devices = text.split('\n \n')

for dev in devices:
name = dev.split(' ', 1)[0]
ip = dev.split('inet addr:')[1].split(' ', 1)[0]
print(name, ip)

Result:

eth0 192.168.2.100
eth1 10.10.2.100

BTW:

If you want to get interfaces for current computer then you can use module psutil

import psutil

interfaces = psutil.net_if_addrs()

for key, val in interfaces.items():
print(key, val[0].address)

Result on my Linux Mint 20 (based on Ubuntu 20.04)

lo 127.0.0.1
enp3s0 192.168.1.28
wlp5s0 192.168.1.31
docker0 172.17.0.1

Extracting ip address and interface name from ifconfig

Also you can extract MAC via following script:

for ifcfg in $(ifconfig -lu)
do
mac=$(ifconfig $ifcfg | grep -o -E '([[:xdigit:]]{1,2}:){5}[[:xdigit:]]{1,2}')
ifconfig $ifcfg | grep -v inet6 | awk -v ifcfg=$ifcfg,$mac '/inet6?/{print ifcfg mac "," $2}' | grep -v lo
done

Output:

em0,00:50:56:a5:42:13,192.168.1.5
em1,00:50:56:a1:62:19,172.16.16.16

Finding an IP address from an interface name


// Originally from http://www.tlug.org.za/wiki/index.php/Obtaining_your_own_IP_address

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>

/**
* getIPv4()
*
* This function takes a network identifier such as "eth0" or "eth0:0" and
* a pointer to a buffer of at least 16 bytes and then stores the IP of that
* device gets stored in that buffer.
*
* it return 0 on success or -1 on failure.
*
* Author: Jaco Kroon <jaco@kroon.co.za>
*/
int getIPv4(const char * dev, char * ipv4) {
struct ifreq ifc;
int res;
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);

if(sockfd < 0)
return -1;
strcpy(ifc.ifr_name, dev);
res = ioctl(sockfd, SIOCGIFADDR, &ifc);
close(sockfd);
if(res < 0)
return -1;
strcpy(ipv4, inet_ntoa(((struct sockaddr_in*)&ifc.ifr_addr)->sin_addr));
return 0;
}


int main() {
char ip[16];
if(getIPv4("eth0", ip) == 0)
printf("IPv4: %s\n", ip);
else
printf("No IP\n");
return 0;
}

Update: Moved dead link to a comment (for posterity) (thanks @obayhan), and added syntax highlighting.

How can I get the IP address from a NIC (network interface controller) in Python?

Two methods:

Method #1 (use external package)

You need to ask for the IP address that is bound to your eth0 interface. This is available from the netifaces package

import netifaces as ni
ip = ni.ifaddresses('eth0')[ni.AF_INET][0]['addr']
print(ip) # should print "192.168.100.37"

You can also get a list of all available interfaces via

ni.interfaces()

Method #2 (no external package)

Here's a way to get the IP address without using a python package:

import socket
import fcntl
import struct

def get_ip_address(ifname):
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
return socket.inet_ntoa(fcntl.ioctl(
s.fileno(),
0x8915, # SIOCGIFADDR
struct.pack('256s', ifname[:15])
)[20:24])

get_ip_address('eth0') # '192.168.0.110'

Note: detecting the IP address to determine what environment you are using is quite a hack. Almost all frameworks provide a very simple way to set/modify an environment variable to indicate the current environment. Try and take a look at your documentation for this. It should be as simple as doing

if app.config['ENV'] == 'production':
# send production email
else:
# send development email

Getting interface name/address from (or mapping NetworkInterface to) jpcap device paths


Platform-Independent, NetworkInterface

Here is an alternate solution that should be platform independent although only provides info for interfaces that are up. The registry solution was my first attempt, it works well, but I believe this is a better solution as long as information about down interfaces is not required.

Method

  1. PacketCapture can provide a network address and subnet mask given a device string (it's an instance method, not a static method, though). For each device string in PacketCapture.lookupDevices():
  2. Get it's network address and mask from a PacketCapture instance (capture does not need to be open).
  3. Search through all network interfaces returned by NetworkInterface.getNetworkInterfaces() and find one that has an address that is on the same network given by the network address and mask that jpcap returned for the device.
  4. That NetworkInterface (probably) corresponds to the device string.

Implementation

Prerequisites:

  • No dependencies other than jpcap. Tested with version 0.01.16.

Issues:

  • While platform-independent, unlike the registry-based solution this can only find interfaces that are up.
  • Byte ordering is weird. I can't make much sense of the jpcap discussion forum on SourceForge but somebody did seem to point it out. Therefore I suppose it's always subject to change in the future.
  • There are probably a lot of edge cases that will cause this to return incorrect results that I have not tested for.

Code

Code is below. Usage is free under SO's CC attribution-sharealike license. It's self-contained so I did not put it on github.

import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

import net.sourceforge.jpcap.capture.CaptureDeviceLookupException;
import net.sourceforge.jpcap.capture.PacketCapture;

public class JpcapInterfaceInfo {


/**
* Get a list of interface information for all devices returned by jpcap.
* @param capture An instance of PacketCapture to use for getting network address and mask info. If null,
* a new instance will be created.
* @return List of information.
* @throws CaptureDeviceLookupException
*/
public static List<InterfaceInfo> listInterfaces (PacketCapture capture) throws CaptureDeviceLookupException {

if (capture == null)
capture = new PacketCapture();

List<InterfaceInfo> infos = new ArrayList<InterfaceInfo>();
for (String device : PacketCapture.lookupDevices())
infos.add(getInterfaceInfo(capture, device));

return infos;

}


/**
* Get a list of interface information for all devices returned by jpcap.
* @return List of information.
* @throws CaptureDeviceLookupException
*/
public static List<InterfaceInfo> listInterfaces () throws CaptureDeviceLookupException {
return listInterfaces(null);
}




/**
* Utility to check if an interface address matches a jpcap network address and mask.
* @param address An InetAddress to check.
* @param jpcapAddr Network address.
* @param jpcapMask Network mask.
* @return True if address is an IPv4 address on the network given by jpcapAddr/jpcapMask,
* false otherwise.
*/
private static boolean networkMatches (InetAddress address, int jpcapAddr, int jpcapMask) {

if (!(address instanceof Inet4Address))
return false;

byte[] address4 = address.getAddress();
if (address4.length != 4)
return false;

int addr = ByteBuffer.wrap(address4).order(ByteOrder.LITTLE_ENDIAN).getInt();
return ((addr & jpcapMask) == jpcapAddr);

}


/**
* Get an InterfaceInfo that corresponds to the given jpcap device string. The interface must be
* up in order to query info about it; if it is not then the NetworkInterface in the returned
* InterfaceInfo will be null.
* @param capture A PacketCapture instance used to get network address and mask info.
* @param jpcapDeviceString String from PacketCapture.lookupDevices().
* @return InterfaceInfo.
*/
public static InterfaceInfo getInterfaceInfo (PacketCapture capture, String jpcapDeviceString) {

InterfaceInfo info = null;
String deviceName = jpcapDeviceString.replaceAll("\n.*", "").trim();

try {

int netAddress = capture.getNetwork(deviceName);
int netMask = capture.getNetmask(deviceName);

// go through all addresses of all interfaces and try to find a match.

Enumeration<NetworkInterface> e = NetworkInterface.getNetworkInterfaces();
while (e.hasMoreElements() && info == null) {
NetworkInterface iface = e.nextElement();
Enumeration<InetAddress> ae = iface.getInetAddresses();
while (ae.hasMoreElements() && info == null) {
if (networkMatches(ae.nextElement(), netAddress, netMask))
info = new InterfaceInfo(iface, deviceName);
}
}

} catch (Exception x) {

System.err.println("While querying info for " + deviceName + ":");
x.printStackTrace(System.err);

}

if (info == null)
info = new InterfaceInfo(null, deviceName);

return info;

}


/**
* Information about a network interface for jpcap, which is basically just a NetworkInterface
* with details, and the jpcap device name for use with PacketCapture.
*/
public static class InterfaceInfo {

private final NetworkInterface iface;
private final String deviceName;

InterfaceInfo (NetworkInterface iface, String deviceName) {
this.iface = iface;
this.deviceName = deviceName;
}

/**
* Get NetworkInterface for this interface.
* @return May return null if no matching NetworkInterface was found.
*/
public final NetworkInterface getIface () {
return iface;
}

/**
* Get jpcap device name for this interface. This can be passed to PacketCapture.open().
* @return Device name for interface.
*/
public final String getDeviceName () {
return deviceName;
}

@Override public final String toString () {
return deviceName + " : " + iface;
}

}


}

Example

Here is an example:

import java.util.List;

import net.sourceforge.jpcap.capture.PacketCapture;

public class JpcapInterfaceInfoTest {

public static void main (String[] args) throws Exception {

// Info can be queried from jpcap device list.
List<JpcapInterfaceInfo.InterfaceInfo> infos = JpcapInterfaceInfo.listInterfaces();

// Info can be displayed.
for (JpcapInterfaceInfo.InterfaceInfo info : infos)
System.out.println(info);

// Device names from InterfaceInfo can be passed directly to jpcap:
JpcapInterfaceInfo.InterfaceInfo selected = infos.get(0);
PacketCapture capture = new PacketCapture();
capture.open(selected.getDeviceName(), true);

}

}

On my machine (same setup as registry solution), this outputs:


\Device\NPF_{691D289D-7EE5-4BD8-B5C1-3C4729A852D5} : null
\Device\NPF_{39966C4C-3728-4368-AE92-1D36ACAF6634} : name:net5 (1x1 11b/g/n Wireless LAN PCI Express Half Mini Card Adapter)

I did not make the output as pretty as the other solution. Note that the "virtual wifi miniport adapter" (the first one) has a null NetworkInterface because, since it is not up, a match could not be found (an IP address and network address was not present).

Find Single Interface IP address (libpcap)


char myip = inet_ntoa(((struct sockaddr_in*)a->addr)->sin_addr);

inet_ntoa returns a char * (not a char), change to:

char *myip = inet_ntoa(((struct sockaddr_in*)a->addr)->sin_addr);

This line is also wrong:

if (d->name == en0) {

you want:

if (strcmp(d->name, "en0") == 0) {

Get ip address of matching interface in powershell

Starting in Windows 10 / Server 2016 you can use Get-NetIPConfiguration like so:

(Get-NetIPConfiguration -InterfaceAlias "Ethernet *").IPv4Address.IPAddress

Further details: Get-NetIPConfiguration



Related Topics



Leave a reply



Submit