How can I obtain the (IPv4) addresses for all network interfaces using only proc? After some extensive investigation I've discovered the following:
ifconfig
makes use of SIOCGIFADDR
, which requires open sockets and advance knowledge of all the interface names. It also isn't documented in any manual pages on Linux.proc
contains /proc/net/dev
, but this is a list of interface statistics.proc
contains /proc/net/if_inet6
, which is exactly what I need but for IPv6.proc
, but actual addresses are very rarely used except where explicitly part of some connection.getifaddrs
, which is very much a "magical" function you'd expect to see in Windows. It's also implemented on BSD. However it's not very text-oriented, which makes it difficult to use from non-C languages./proc/net/fib_trie
holds the network topography
To simply print the addresses of all adapters:
$ awk '/32 host/ { print f } {f=$2}' <<< "$(</proc/net/fib_trie)"
127.0.0.1
192.168.0.5
192.168.1.14
To determine the adapter of those addresses (a) consult the adapters' destination networks from /proc/net/route
, (b) match those networks with the ones of /proc/net/fib_trie
and (c) print the corresponding /32 host addresses listed under those networks.
Again no python
unfortunately, but a quite awky bash
approach:
#!/bin/bash
ft_local=$(awk '$1=="Local:" {flag=1} flag' <<< "$(</proc/net/fib_trie)")
for IF in $(ls /sys/class/net/); do
networks=$(awk '$1=="'$IF'" && $3=="00000000" && $8!="FFFFFFFF" {printf $2 $8 "\n"}' <<< "$(</proc/net/route)" )
for net_hex in $networks; do
net_dec=$(awk '{gsub(/../, "0x& "); printf "%d.%d.%d.%d\n", $4, $3, $2, $1}' <<< $net_hex)
mask_dec=$(awk '{gsub(/../, "0x& "); printf "%d.%d.%d.%d\n", $8, $7, $6, $5}' <<< $net_hex)
awk '/'$net_dec'/{flag=1} /32 host/{flag=0} flag {a=$2} END {print "'$IF':\t" a "\n\t'$mask_dec'\n"}' <<< "$ft_local"
done
done
exit 0
output:
eth0: 192.168.0.5
255.255.255.0
lo: 127.0.0.1
255.0.0.0
wlan0: 192.168.1.14
255.255.255.0
Known limitation:
This approach does not work reliably for host addresses that share the network with other host addresses. This loss of network uniqueness makes it impossible to determine the correct host address from fib_trie as the order of those addresses does not necessarily match the order of networks of route.
Having said that, I'm not sure why you would want multiple host addresses belonging to the same network in first place. So in most use cases this approach should work just fine.