Get Local Network Interface Addresses Using Only Proc

Get local network interface addresses using only proc?

There is no IPv4 analog of /proc/net/if_inet6

ifconfig does:

fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP)
ioctl(fd, SIOCGIFCONF, ...)

You'll get something like this:

ioctl(4, SIOCGIFCONF, {120, {{"lo", {AF_INET, inet_addr("127.0.0.1")}}, {"eth0", {AF_INET, inet_addr("10.6.23.69")}}, {"tun0", {AF_INET, inet_addr("10.253.10.151")}}}})

How to get interface name from IPv4 ip address using only fs and bash in Linux?

I think you have sufficient information there. The /proc/net/route file doesn't really list addresses. It's supposed to tell you how to route packets. But you can glean information about the interfaces from it. On my system (ubuntu 14 so different interface name format but otherwise should be similar), it shows this:

Iface   Destination Gateway     Flags   RefCnt  Use Metric  Mask        MTU Window  IRTT
eth0 00000000 0100A8C0 0003 0 0 0 00000000 0 0 0
eth0 0000A8C0 00000000 0001 0 0 1 00FFFFFF 0 0 0
eth1 0028A8C0 00000000 0001 0 0 1 00FFFFFF 0 0 0

The destination and mask fields are in hexadecimal -- and byte-reversed on little-endian machine -- and give you the range of the network. Interpretation is:

  • Anything destined for the 192.168.0.0/24 network (0000A8C0 + 00FFFFFF) goes to eth0 with no gateway needed (in other words, it's on the same subnet as this machine).
  • Anything destined for 192.168.40.0/24 (0028A8C0 + 00FFFFFF) goes to eth1 with no gateway needed.
  • Packets destined for any other address (00000000 + 00000000) go to the default gateway 192.168.0.1.
    (Not sure; it's possible that the extra flag bit or the "metric" value in this line marks this as a default gateway. But in any case, if it doesn't have a non-zero mask or is in the 0.0.0.0 address range, it's not going to be useful for routing in the real world.)

From this I can infer that my system has IP addresses in the 192.168.0.0/24 and 192.168.40.0/24 networks. The output from the grep command on /proc/net/fib_trie shows on my system:

           |-- 127.0.0.1
/32 host LOCAL
|-- 192.168.0.104
/32 host LOCAL
|-- 192.168.40.129
/32 host LOCAL

So that makes it clear that my local IP addresses are 192.168.0.104 (eth0) and 192.168.40.129 (eth1). (We can ignore 127.0.0.1; it's always the loopback interface.)

Get network interface name from IPv4 address

#include <windows.h>
#include <iphlpapi.h>
#include <stdio.h>

#pragma comment(lib, "iphlpapi.lib")

int
main(int argc, char** argv) {
PIP_ADAPTER_INFO pAdapterInfo;
pAdapterInfo = (IP_ADAPTER_INFO *) malloc(sizeof(IP_ADAPTER_INFO));
ULONG buflen = sizeof(IP_ADAPTER_INFO);

if(GetAdaptersInfo(pAdapterInfo, &buflen) == ERROR_BUFFER_OVERFLOW) {
free(pAdapterInfo);
pAdapterInfo = (IP_ADAPTER_INFO *) malloc(buflen);
}

if(GetAdaptersInfo(pAdapterInfo, &buflen) == NO_ERROR) {
PIP_ADAPTER_INFO pAdapter = pAdapterInfo;
while (pAdapter) {
printf("\tAdapter Name: \t%s\n", pAdapter->AdapterName);
printf("\tAdapter Desc: \t%s\n", pAdapter->Description);
printf("\tAdapter Addr: \t%ld\n", pAdapter->Address);
printf("\tIP Address: \t%s\n", pAdapter->IpAddressList.IpAddress.String);
printf("\tIP Mask: \t%s\n", pAdapter->IpAddressList.IpMask.String);
printf("\tGateway: \t%s\n", pAdapter->GatewayList.IpAddress.String);
if(pAdapter->DhcpEnabled) {
printf("\tDHCP Enabled: Yes\n");
printf("\t\tDHCP Server: \t%s\n", pAdapter->DhcpServer.IpAddress.String);
printf("\tLease Obtained: %ld\n", pAdapter->LeaseObtained);
} else {
printf("\tDHCP Enabled: No\n");
}
if(pAdapter->HaveWins) {
printf("\tHave Wins: Yes\n");
printf("\t\tPrimary Wins Server: \t%s\n", pAdapter->PrimaryWinsServer.IpAddress.String);
printf("\t\tSecondary Wins Server: \t%s\n", pAdapter->SecondaryWinsServer.IpAddress.String);
} else {
printf("\tHave Wins: No\n");
}
pAdapter = pAdapter->Next;
}
} else {
printf("Call to GetAdaptersInfo failed.\n");
}
}

As @sonyisda1 mentioned, this is taken from MSDN.

How to check whether an ethernet interface is up with some IP or not in LINUX only using sysfs?

There is nothing in sysfs that will tell you IP addresses. The network system has always been a bit different, e.g. network interfaces aren't device nodes, and it doesn't use sysfs. Networking hardware, yes, but the network layer, not so much.

The list of interfaces in /sys/class/net is about all you'll get it. The information there is all device related and doesn't have networking, protocols, and non-hardware addresses.

There is more in /proc, but not exactly what you want. You can get a list of interfaces in /proc/net/dev. It doesn't tell you if the interface is up or has an address assigned.

If an interface appears in /proc/net/route, then it's in the routing table. Generally any interface that has been assigned an IP address will appear in the routing table and the route will be created at the same time the IP is assigned. But it's not required that an interface with an IP appear in the routing table. With IPv4LL, it's even possible for an interface with no routes to send and receive packets.

In /proc/net/if_inet6 there is a list of every interface assigned an IPv6 address, along with the address in hex. But this is IPv6 only and not IPv4.

If you want to be notified of addresses being assigned or removed, then the better way to do it is via a netlink socket. You need to write code to use this. A netlink datagram will be sent to your processes over the netlink socket when an interface has an address added, changed, or removed. The datagram will contain such things as the interface name and address.

This is a much better way to monitor, since your process can just sleep on the netlink socket waiting for a packet. When an address is changed, you'll get immediately woken. This will respond faster and is much more efficient than continuously polling files in sysfs. You also don't have to worry about missing something if it changes multiple times, e.g. addressed added and then removed, between polls. And it preserves the order of events.

If the system is running NetworkManager, or something compatible, then monitoring via dbus can be done. The signal org.freedesktop.NetworkManager.DeviceAdded can be monitored for new devices, and on each device, e.g. /org/freedesktop/NetworkManager/Devices/1, the signal org.freedesktop.NetworkManager.Device.StateChanged can be monitored to see when the device enters/leaves NM_DEVICE_STATE_ACTIVATED.

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


Related Topics



Leave a reply



Submit