3

How to get interface name from IPv4 ip address using only filesystem like /proc, /dev, /sys and bash? Is this possible without using the commands (such as ip, ifconfig, etc.)? I am also not able to use any packages or install any tools.

Edit: The reason for this is I am trying to get host's interface names and ip addresses from within a Docker container. The container is mounted with host's root and has access to host's filesystem. However, since the container is in a separate namespace, ip commands (and other similar command such as ifconfig) will only return the container's network. Hence, I believe the only way of getting the host's interface names and ip addresses is through the host's root (/hostroot/proc, /hostroot/sys, etc.). Note that I cannot have the --net=host flag when starting the container (which tells the container to use the host's net namespace).

I tried finding all my network interface IP addresses (IPv4) from the /proc/net/fib_trie file. I read at https://regexit.com/3-ways-to-get-your-ip-on-a-linux-system/ which basically says that I can do cat /proc/net/fib_trie | grep -B 1 "32 host LOCAL" to find the IP addresses. I also see in https://stackoverflow.com/a/42082822 , that we can filter the fib_trie by pattern matching the string "32 host" to get the local network interface addresses. After getting the IP addresses from the above method (using the /proc/net/fib_trie), I try to match those IP address with the "destination" IP address in /proc/net/route to get the network interface name. However, my /proc/net/route contains multiple entry for some interfaces (such as enp0s3). For example, there are two enp0s3 entries with different IP addresss ("Destination column). Moreover, the network interfaces in route file does have ip close to what is indicated by the ip command but not exactly.

Is there a better way of getting the network interface name after getting the IP address from fib_trie?

Output I need will be all the host's network interface name and corresponding IPv4 IP addresses.

3
  • How do you intend to obtain any information at all that you do not already have if you do not use any commands? And why is that a constraint? What are you really asking? Commented Mar 30, 2017 at 17:39
  • Can you show us what you have tried with an actual command you are trying and the output you need? Commented Mar 30, 2017 at 17:44
  • Added more information to post. Thanks Commented Mar 30, 2017 at 18:10

1 Answer 1

3

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.)

Sign up to request clarification or add additional context in comments.

9 Comments

I did some more researching and came up with something very close to what you mentioned. First, we can grep for the pair of addresses in fib_trie for both "/32 link" and "/32 host" under the same branch. Second, match the address of "/32 link" to the 'destination' address in /proc/net/route. Lastly, the interface name in /proc/net/route of the matched row from step 2 is the interface name of the "/32 host" address from step 1. Is this procedure, especially matching the "/32 link" to the 'destination' address in /proc/net/route, for getting the network interface name correct?
I don't really see what additional info you are getting from the /32 link lines. The netmask info from /proc/net/route (00FFFFFF in my example) tells you the netmask is 255.255.255.0 (== /24). And the destination field gives you the "base network address" (in this case, all but the final tuple of the address). Combining that with the /32 host address from /proc/net/fib_trie already gives you a unique answer to which interface each address serves as well as its subnet range.
What I found (I am not sure if this will always hold true) but from the /proc/net/fib_trie for example one of my branch has 10.0.2.0 for /32 link and corresponding 10.0.2.15 for /32 host. I then see in my /proc/net/route I have a row with Iface=enp0s3 and Destination=0002000A (10.0.2.0). I see that 10.0.2.15 for /32 host gotten above actually does not match with any of my Ifaces's destination. However, 10.0.2.0 for /32 link matches with enp0s3's destination (10.0.2.0). Thus, I can conclude that the pair of IP from fib_trie belongs to enp0s3. (enp0s3 has IP 10.0.2.15/24 from ip addr show)
The route table already tells you about the subnets on your box (Destination + Mask); each is associated with an interface. The fib_trie "/32 Host" entries tell you your IP addresses. You then just need to figure out which subnet each IP address falls into to find the interface. For each subnet entry from the route table, test to see if the IP fits within the subnet: In other words, does IP_Address & Mask == Destination (where & is bitwise-and). If so, you've found the matching interface. 10.0.2.15 in hex (byte-flipped) is 0F02000A. (0F02000A & 00FFFFFF) == 0002000A => matches enp0s3
In case it's not clear, I'm not saying you can't use the /32 Link entries. I just don't see that they add any information you don't already have from the route entries.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.