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] = {};
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) {
296 attributes_show_ipv4(tb);
300 attributes_show_ipv6(tb);
308int main(
int argc,
char *argv[])
310 struct mnl_socket *nl;
311 char buf[MNL_SOCKET_BUFFER_SIZE];
316 perror(
"mnl_socket_open");
321 MNL_SOCKET_AUTOPID) < 0) {
322 perror(
"mnl_socket_bind");
328 ret =
mnl_cb_run(buf, ret, 0, 0, data_cb, NULL);
329 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)
int mnl_socket_close(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)