9#include <libmnl/libmnl.h>
11#include <linux/if_link.h>
12#include <linux/rtnetlink.h>
14static int data_attr_cb2(
const struct nlattr *attr,
void *data)
16 const struct nlattr **tb = data;
23 perror(
"mnl_attr_validate");
31static void attributes_show_ipv4(
struct nlattr *tb[])
38 printf(
"dst=%s ", inet_ntoa(*addr));
42 printf(
"src=%s ", inet_ntoa(*addr));
50 if (tb[RTA_PREFSRC]) {
52 printf(
"prefsrc=%s ", inet_ntoa(*addr));
54 if (tb[RTA_GATEWAY]) {
56 printf(
"gw=%s ", inet_ntoa(*addr));
58 if (tb[RTA_PRIORITY]) {
61 if (tb[RTA_METRICS]) {
63 struct nlattr *tbx[RTAX_MAX+1] = {};
67 for (i=0; i<RTAX_MAX; i++) {
69 printf(
"metrics[%d]=%u ",
77static 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));
84static void attributes_show_ipv6(
struct nlattr *tb[])
91 printf(
"dst=%s ", inet6_ntoa(*addr));
95 printf(
"src=%s ", inet6_ntoa(*addr));
103 if (tb[RTA_PREFSRC]) {
105 printf(
"prefsrc=%s ", inet6_ntoa(*addr));
107 if (tb[RTA_GATEWAY]) {
109 printf(
"gw=%s ", inet6_ntoa(*addr));
111 if (tb[RTA_PRIORITY]) {
114 if (tb[RTA_METRICS]) {
116 struct nlattr *tbx[RTAX_MAX+1] = {};
120 for (i=0; i<RTAX_MAX; i++) {
122 printf(
"metrics[%d]=%u ",
129static int data_ipv4_attr_cb(
const struct nlattr *attr,
void *data)
131 const struct nlattr **tb = data;
148 perror(
"mnl_attr_validate");
154 perror(
"mnl_attr_validate");
163static int data_ipv6_attr_cb(
const struct nlattr *attr,
void *data)
165 const struct nlattr **tb = data;
178 perror(
"mnl_attr_validate");
187 sizeof(
struct in6_addr)) < 0) {
188 perror(
"mnl_attr_validate2");
194 perror(
"mnl_attr_validate");
203static int data_cb(
const struct nlmsghdr *nlh,
void *data)
205 struct nlattr *tb[RTA_MAX+1] = {};
209 printf(
"family=%u ", rm->rtm_family);
212 printf(
"dst_len=%u ", rm->rtm_dst_len);
215 printf(
"src_len=%u ", rm->rtm_src_len);
218 printf(
"tos=%u ", rm->rtm_tos);
233 printf(
"table=%u ", rm->rtm_table);
250 printf(
"type=%u ", rm->rtm_type);
262 printf(
"scope=%u ", rm->rtm_scope);
274 printf(
"proto=%u ", rm->rtm_protocol);
282 printf(
"flags=%x ", rm->rtm_flags);
284 switch(rm->rtm_family) {
287 attributes_show_ipv4(tb);
291 attributes_show_ipv6(tb);
299int main(
int argc,
char *argv[])
301 char buf[MNL_SOCKET_DUMP_SIZE];
302 unsigned int seq, portid;
303 struct mnl_socket *nl;
304 struct nlmsghdr *nlh;
309 fprintf(stderr,
"Usage: %s <inet|inet6>\n", argv[0]);
314 nlh->nlmsg_type = RTM_GETROUTE;
315 nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
316 nlh->nlmsg_seq = seq = time(NULL);
319 if (strcmp(argv[1],
"inet") == 0)
320 rtm->rtm_family = AF_INET;
321 else if (strcmp(argv[1],
"inet6") == 0)
322 rtm->rtm_family = AF_INET6;
326 perror(
"mnl_socket_open");
331 perror(
"mnl_socket_bind");
337 perror(
"mnl_socket_sendto");
343 ret =
mnl_cb_run(buf, ret, seq, portid, data_cb, NULL);
344 if (ret <= MNL_CB_STOP)
int mnl_attr_parse_nested(const struct nlattr *nested, mnl_attr_cb_t cb, void *data)
void * mnl_attr_get_payload(const struct nlattr *attr)
int mnl_attr_validate(const struct nlattr *attr, enum mnl_attr_data_type type)
int mnl_attr_parse(const struct nlmsghdr *nlh, unsigned int offset, mnl_attr_cb_t cb, void *data)
int mnl_attr_type_valid(const struct nlattr *attr, uint16_t max)
uint16_t mnl_attr_get_type(const struct nlattr *attr)
int mnl_attr_validate2(const struct nlattr *attr, enum mnl_attr_data_type type, size_t exp_len)
uint32_t mnl_attr_get_u32(const struct nlattr *attr)
int mnl_cb_run(const void *buf, size_t numbytes, unsigned int seq, unsigned int portid, mnl_cb_t cb_data, void *data)
void * mnl_nlmsg_get_payload(const struct nlmsghdr *nlh)
struct nlmsghdr * mnl_nlmsg_put_header(void *buf)
void * mnl_nlmsg_put_extra_header(struct nlmsghdr *nlh, size_t size)
int mnl_socket_close(struct mnl_socket *nl)
unsigned int mnl_socket_get_portid(const struct mnl_socket *nl)
struct mnl_socket * mnl_socket_open(int bus)
ssize_t mnl_socket_recvfrom(const struct mnl_socket *nl, void *buf, size_t bufsiz)
int mnl_socket_bind(struct mnl_socket *nl, unsigned int groups, pid_t pid)
ssize_t mnl_socket_sendto(const struct mnl_socket *nl, const void *buf, size_t len)