9 #include <libmnl/libmnl.h>
11 #include <linux/if_link.h>
12 #include <linux/rtnetlink.h>
14 static int data_attr_cb2(
const struct nlattr *attr,
void *data)
16 const struct nlattr **tb = data;
19 if (mnl_attr_type_valid(attr, RTAX_MAX) < 0)
22 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
23 perror(
"mnl_attr_validate");
27 tb[mnl_attr_get_type(attr)] = attr;
31 static void attributes_show_ipv4(
struct nlattr *tb[])
34 printf(
"table=%u ", mnl_attr_get_u32(tb[RTA_TABLE]));
37 struct in_addr *addr = mnl_attr_get_payload(tb[RTA_DST]);
38 printf(
"dst=%s ", inet_ntoa(*addr));
41 struct in_addr *addr = mnl_attr_get_payload(tb[RTA_SRC]);
42 printf(
"src=%s ", inet_ntoa(*addr));
45 printf(
"oif=%u ", mnl_attr_get_u32(tb[RTA_OIF]));
48 printf(
"flow=%u ", mnl_attr_get_u32(tb[RTA_FLOW]));
50 if (tb[RTA_PREFSRC]) {
51 struct in_addr *addr = mnl_attr_get_payload(tb[RTA_PREFSRC]);
52 printf(
"prefsrc=%s ", inet_ntoa(*addr));
54 if (tb[RTA_GATEWAY]) {
55 struct in_addr *addr = mnl_attr_get_payload(tb[RTA_GATEWAY]);
56 printf(
"gw=%s ", inet_ntoa(*addr));
58 if (tb[RTA_PRIORITY]) {
59 printf(
"prio=%u ", mnl_attr_get_u32(tb[RTA_PRIORITY]));
61 if (tb[RTA_METRICS]) {
63 struct nlattr *tbx[RTAX_MAX+1] = {};
65 mnl_attr_parse_nested(tb[RTA_METRICS], data_attr_cb2, tbx);
67 for (i=0; i<RTAX_MAX; i++) {
69 printf(
"metrics[%d]=%u ",
70 i, mnl_attr_get_u32(tbx[i]));
77 static const char *inet6_ntoa(
struct in6_addr in6)
79 static char buf[INET6_ADDRSTRLEN];
81 return inet_ntop(AF_INET6, &in6.s6_addr, buf,
sizeof(buf));
84 static void attributes_show_ipv6(
struct nlattr *tb[])
87 printf(
"table=%u ", mnl_attr_get_u32(tb[RTA_TABLE]));
90 struct in6_addr *addr = mnl_attr_get_payload(tb[RTA_DST]);
91 printf(
"dst=%s ", inet6_ntoa(*addr));
94 struct in6_addr *addr = mnl_attr_get_payload(tb[RTA_SRC]);
95 printf(
"src=%s ", inet6_ntoa(*addr));
98 printf(
"oif=%u ", mnl_attr_get_u32(tb[RTA_OIF]));
101 printf(
"flow=%u ", mnl_attr_get_u32(tb[RTA_FLOW]));
103 if (tb[RTA_PREFSRC]) {
104 struct in6_addr *addr = mnl_attr_get_payload(tb[RTA_PREFSRC]);
105 printf(
"prefsrc=%s ", inet6_ntoa(*addr));
107 if (tb[RTA_GATEWAY]) {
108 struct in6_addr *addr = mnl_attr_get_payload(tb[RTA_GATEWAY]);
109 printf(
"gw=%s ", inet6_ntoa(*addr));
111 if (tb[RTA_PRIORITY]) {
112 printf(
"prio=%u ", mnl_attr_get_u32(tb[RTA_PRIORITY]));
114 if (tb[RTA_METRICS]) {
116 struct nlattr *tbx[RTAX_MAX+1] = {};
118 mnl_attr_parse_nested(tb[RTA_METRICS], data_attr_cb2, tbx);
120 for (i=0; i<RTAX_MAX; i++) {
122 printf(
"metrics[%d]=%u ",
123 i, mnl_attr_get_u32(tbx[i]));
129 static int data_ipv4_attr_cb(
const struct nlattr *attr,
void *data)
131 const struct nlattr **tb = data;
132 int type = mnl_attr_get_type(attr);
135 if (mnl_attr_type_valid(attr, RTA_MAX) < 0)
147 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
148 perror(
"mnl_attr_validate");
153 if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0) {
154 perror(
"mnl_attr_validate");
163 static int data_ipv6_attr_cb(
const struct nlattr *attr,
void *data)
165 const struct nlattr **tb = data;
166 int type = mnl_attr_get_type(attr);
169 if (mnl_attr_type_valid(attr, RTA_MAX) < 0)
177 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
178 perror(
"mnl_attr_validate");
186 if (mnl_attr_validate2(attr, MNL_TYPE_BINARY,
187 sizeof(
struct in6_addr)) < 0) {
188 perror(
"mnl_attr_validate2");
193 if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0) {
194 perror(
"mnl_attr_validate");
203 static int data_cb(
const struct nlmsghdr *nlh,
void *data)
205 struct nlattr *tb[RTA_MAX+1] = {};
206 struct rtmsg *rm = mnl_nlmsg_get_payload(nlh);
208 switch(nlh->nlmsg_type) {
218 printf(
"family=%u ", rm->rtm_family);
221 printf(
"dst_len=%u ", rm->rtm_dst_len);
224 printf(
"src_len=%u ", rm->rtm_src_len);
227 printf(
"tos=%u ", rm->rtm_tos);
242 printf(
"table=%u ", rm->rtm_table);
259 printf(
"type=%u ", rm->rtm_type);
271 printf(
"scope=%u ", rm->rtm_scope);
283 printf(
"proto=%u ", rm->rtm_protocol);
291 printf(
"flags=%x ", rm->rtm_flags);
293 switch(rm->rtm_family) {
295 mnl_attr_parse(nlh,
sizeof(*rm), data_ipv4_attr_cb, tb);
296 attributes_show_ipv4(tb);
299 mnl_attr_parse(nlh,
sizeof(*rm), data_ipv6_attr_cb, tb);
300 attributes_show_ipv6(tb);
308 int main(
int argc,
char *argv[])
311 char buf[MNL_SOCKET_BUFFER_SIZE];
314 nl = mnl_socket_open(NETLINK_ROUTE);
316 perror(
"mnl_socket_open");
320 if (mnl_socket_bind(nl, RTMGRP_IPV4_ROUTE | RTMGRP_IPV6_ROUTE,
321 MNL_SOCKET_AUTOPID) < 0) {
322 perror(
"mnl_socket_bind");
326 ret = mnl_socket_recvfrom(nl, buf,
sizeof(buf));
328 ret = mnl_cb_run(buf, ret, 0, 0, data_cb, NULL);
329 if (ret <= MNL_CB_STOP)
331 ret = mnl_socket_recvfrom(nl, buf,
sizeof(buf));
338 mnl_socket_close(nl);