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 ofSIOCGIFADDR
, 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.- Generally interfaces are easy to find in
proc
, but actual addresses are very rarely used except where explicitly part of some connection. - There's a system call called
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.
hers a fancy one i found somewhere in the internet. minorly fixed it up to fit and correctly output tun (vpn) devices.
cat /proc/net/tcp
Get the second column, with the heading "local_address", e.g. "CF00A8C0:0203"
The part after ":" is a port number.
From the rest use the last two (C0) as a hex number, e.g. C0 is 192, which is the start of the address in this example.
Took the following into my notes a while ago, from some smart point in the net:
The IP address is displayed as a little-endian four-byte hexadecimal number; that is, the least significant byte is listed first, so you'll need to reverse the order of the bytes to convert it to an IP address.
The port number is a simple two-byte hexadecimal number.
You may find the output of
ip addr show
easier to parse than output from other tools:Another option is the file
/proc/net/tcp
. It shows all currently-open TCP sessions, which is different than what you asked for, but might be Good Enough.My IP is
192.168.0.121
; note the funny arithmetic to make it come out right. :)It's bass-ackwards and I probably am forgetting a corner case, but if you look at /proc/1/net/route, that has your routing table. If you select lines for which the gateway is 0.0.0.0, the first column is the interface and the second column is the hex representation of your IP address, in network byte order (and the third column is the gateway ip you want to filter on).
My solution to retrieve IPv4 network config, using
/proc
only:Unfortunately, this is bash (bash only and without any fork), not python. But I hope this will be readable:
There is a sample of output:
Explanation:
I use integer value of IPV4 in order to check
IP & MASK == NETWORK
.I read first
/proc/net/route
to find routing configurations, searching for routes reachable without any gateway (gw==000000
).For such a route, I search in all connections (TCP, than UDP if not found in TCP) for connection using this route, the first end point is my host address.
Nota: This won't work with PPP connections
Nota2: This won't work on a totally quiet host without any opened network connection. You could do something like
echo -ne '' | nc -q 0 -w 1 8.8.8.8 80 & sleep .2 && ./retrieveIp.sh
for ensuring that something where found in/proc/net/tcp
.Nota3, 2016-09.23: New bash version use
>(command)
syntax formultiple inline pipe
feature. This implie a bug at line 18: a space must be present between>
and(
!!New version with gateway
There is a little patch: Once you create a file called
getIPv4.sh
by copying previous script, you could paste the following to the command:patch -p0
End with Ctrld, this may output:
And maybe
Then re-run your script: