netlink,rtnetlink,libnetlink 三者之间的关系是:
- netlink 是Linux内核和用户空间程序消息通信的一种方法。
- rtnetlink 是 netlink 的一个子集,用于访问内核中的路由表,网口,IP地址等信息。
- libnetlink 是为了方便使用rtnetlink服务而设计的API。
为了安装libnetlink.h,执行下面命令:
$ dnf install iproute-devel
例1. 打印所有的IP地址
# cat list-addr.c
#include <stdio.h> //perror()
#include <stdlib.h> //exit()
#include <libnetlink.h> //rtnl_handle
void die(char *s)
{
perror(s);
exit(1);
}
int get_addr(const struct sockaddr_nl *who, struct nlmsghdr *h, void *arg)
{
struct ifaddrmsg * addr;
struct rtattr * attr;
int len;
addr = NLMSG_DATA(h);
len = RTM_PAYLOAD(h);
/* loop over all attributes for the NEWLINK message */
for (attr = IFLA_RTA(addr); RTA_OK(attr, len); attr = RTA_NEXT(attr, len))
{
switch (attr->rta_type)
{
case IFA_LABEL:
printf("Interface : %s\n", (char *)RTA_DATA(attr));
break;
case IFA_LOCAL:
{
int ip = *(int*)RTA_DATA(attr);
unsigned char bytes[4];
bytes[0] = ip & 0xFF;
bytes[1] = (ip >> 8) & 0xFF;
bytes[2] = (ip >> 16) & 0xFF;
bytes[3] = (ip >> 24) & 0xFF;
printf("IP Address : %d.%d.%d.%d\n", bytes[0], bytes[1], bytes[2], bytes[3]);
break;
}
default:
break;
}
}
}
int main()
{
struct rtnl_handle rth;
if (rtnl_open(&rth, 0))
{
die("rtnl_open()");
}
if (rtnl_wilddump_request(&rth, AF_INET, RTM_GETADDR) < 0) {
die("rtnl_wilddump_request()");
}
if (rtnl_dump_filter(&rth, get_addr, NULL) < 0) {
die("rtnl_dump_filter()");
}
rtnl_close( &rth );
return 0;
}
# gcc list-addr.c -lnetlink -o list-addr && ./list-addr
IP Address : 127.0.0.1
Interface : lo
IP Address : 10.254.52.242
Interface : eth0