45

Is there a clean, simple way to get an IP address for a network interface from /proc, similar to the way I can get the MAC address for a network interface?
Ideally I would just type cat /proc/<foo>/{interface_name} and get the IPv4 address.

I'd rather not run anything other than cat.

fra-san
  • 9,931
  • 2
  • 21
  • 42
razeh
  • 569
  • 1
  • 4
  • 4

3 Answers3

58

Under the /proc directory, you can also find the IPv4 addresses in the Forwarding Information Base table, at /proc/net/fib_trie

The table is pretty intelligible doing a mere cat, first comes the Main: and then Local:

cat /proc/net/fib_trie

or to see your network, IP addresses and netmask:

cat /proc/net/fib_trie | grep "|--"   | egrep -v "0.0.0.0| 127."
       |-- 193.136.1.0
       |-- 193.136.1.2
    |-- 193.136.1.255
       |-- 193.136.1.0
       |-- 193.136.1.2
    |-- 193.136.1.255       
Rui F Ribeiro
  • 55,929
  • 26
  • 146
  • 227
  • 1
    Is there a way to get the interface for each IP address? – razeh May 15 '17 at 18:18
  • They appear in a pre-determined order; probably priority, but that can be changed; other than that, no. – Rui F Ribeiro May 15 '17 at 18:27
  • 3
    `/proc/net/fib_trie` isn't available on my RHEL 6.6 system here at work – villapx May 15 '17 at 18:47
  • 2
    @villapx fib_trie is not present on 2.6 kernels. – Rui F Ribeiro Sep 27 '18 at 15:07
  • There's no way to associate ip addresses with interface in fib_trie. – ZioByte Mar 10 '19 at 21:38
  • @ZioByte There is a pre-defined order, but from the table alone, having several interfaces, not really. Now, if you only have one like eth0.... – Rui F Ribeiro Mar 10 '19 at 21:41
  • Then it's not a valid answer. My understanding of question (and what I'm looking for) is: Is there a way to get from /proc (or /sys, i.e.: without spawning three processses) the equivalent of: `ip a show dev | awk '/inet/ {print $2}'`? – ZioByte Mar 10 '19 at 21:48
  • @ZioByte That is the best you can come up with using /proc alone afaik. There is some order to it, kind of eth0/eth1 and so on, but you will never know when an interface has several IP addresses. – Rui F Ribeiro Mar 10 '19 at 21:50
  • Any further "enhancement" is possible if we allow also /sys usage? *Background*: I'm polling in a (reasonably) tight loop to see if/when a certain device gets it's IP address, so I would like to keep overhead to a minimum. – ZioByte Mar 10 '19 at 21:54
  • @ZioByte i am always curious for that kind of stuff, unfortunately I within a few hours of entering a plane for another continent and just popping by here with access to a Linux machine the next month. I am used to abuse SNMP for this kind of stuff actually. (for monitoring purposes) – Rui F Ribeiro Mar 10 '19 at 21:56
7
$ awk '/32 host/ { print f } {f=$2}' <<< "$(</proc/net/fib_trie)"
God
  • 79
  • 1
  • 1
  • 2
    Welcome on U&L! Why `<<< "$( – fra-san May 31 '19 at 10:11
  • 3
    @fra-san: `awk '/32 host/ { print f } {f=$2}' /proc/net/fib_trie` works the same – Dominik Dorn Feb 10 '20 at 11:49
  • 3
    there is no ip command many of official docker containers, then your answer solved my problem. `awk '/32 host/ { print f } {f=$2}' /proc/net/fib_trie | sort | uniq | grep -v 127.0.0.1` – edib Jun 13 '20 at 20:10
  • 1
    @God could you pl explain the `awk` syntax? The `/32 host/` would match lines containing that `32 host`. For me, these are lines like `32 host LOCAL`. `$2` would return the 2nd field from the line... so, what does `print f` do? ... and what would be its value? Why does `f=$2` come after `print 2`. (I thought I knew `awk` enough.) – Harry Jul 24 '21 at 02:32
  • 2
    @Harry It basically does this: For every line it saves $2 in f. But if the line contains "32 host" then print `f` that was saved from the previous line. After printing f, save $2 again – Wodin Oct 19 '21 at 10:43
6

It might be possible to associate network addresses from /proc/net/fib_trie with interfaces from /proc/net/route:

  $ awk '/^[^I]/ {print $1 " " $2}' /proc/net/route
  br0 0001020A
  br0 FE01020A

..and to convert the hexadecimal network addresses with:

$ echo FE01020A | xxd -r -p | hexdump -e '/1 "%u."' | tac -s'.' | sed 's/\.$//'
10.2.1.254