ip из iproute2. Стандартно полез гуглить исходники и уж было начал их курить... В общем, не знаю, почему мне пришло это в голову только сейчас, но... Куда быстрее просто обернуть вызов ip в strace:strace -e trace=network,file ip addr
execve("/usr/sbin/ip", ["ip", "addr"], [/* 35 vars */]) = 0
...
socket(AF_NETLINK, SOCK_RAW|SOCK_CLOEXEC, NETLINK_ROUTE) = 3
setsockopt(3, SOL_SOCKET, SO_SNDBUF, [32768], 4) = 0
setsockopt(3, SOL_SOCKET, SO_RCVBUF, [1048576], 4) = 0
setsockopt(3, SOL_NETLINK, 11, [1], 4) = -1 ENOPROTOOPT (Protocol not available)
bind(3, {sa_family=AF_NETLINK, pid=0, groups=00000000}, 12) = 0
getsockname(3, {sa_family=AF_NETLINK, pid=4727, groups=00000000}, [12]) = 0
sendto(3, ..., 40, 0, NULL, 0) = 40
recvmsg(3, ..., MSG_PEEK|MSG_TRUNC) = 3752
...
open("/etc/iproute2/group", O_RDONLY) = 4
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 52:54:00:26:10:60 brd ff:ff:ff:ff:ff:ff
inet 10.0.2.15/24 brd 10.0.2.255 scope global noprefixroute dynamic eth0
valid_lft 76662sec preferred_lft 76662sec
inet6 fe80::5054:ff:fe26:1060/64 scope link
valid_lft forever preferred_lft forever
Вот так за 5 секунд мы узнали, что пора читать про AF_NETLINK сокеты https://en.wikipedia.org/wiki/Netlink.