xref: /aosp_15_r20/external/ethtool/libmnl/examples/rtnl/rtnl-link-event.c (revision 1b481fc3bb1b45d4cf28d1ec12969dc1055f555d)
1 /* This example is placed in the public domain. */
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <unistd.h>
5 
6 #include <libmnl/libmnl.h>
7 #include <linux/if.h>
8 #include <linux/if_link.h>
9 #include <linux/rtnetlink.h>
10 
data_attr_cb(const struct nlattr * attr,void * data)11 static int data_attr_cb(const struct nlattr *attr, void *data)
12 {
13 	const struct nlattr **tb = data;
14 	int type = mnl_attr_get_type(attr);
15 
16 	/* skip unsupported attribute in user-space */
17 	if (mnl_attr_type_valid(attr, IFLA_MAX) < 0)
18 		return MNL_CB_OK;
19 
20 	switch(type) {
21 	case IFLA_MTU:
22 		if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
23 			perror("mnl_attr_validate");
24 			return MNL_CB_ERROR;
25 		}
26 		break;
27 	case IFLA_IFNAME:
28 		if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0) {
29 			perror("mnl_attr_validate");
30 			return MNL_CB_ERROR;
31 		}
32 		break;
33 	}
34 	tb[type] = attr;
35 	return MNL_CB_OK;
36 }
37 
data_cb(const struct nlmsghdr * nlh,void * data)38 static int data_cb(const struct nlmsghdr *nlh, void *data)
39 {
40 	struct nlattr *tb[IFLA_MAX+1] = {};
41 	struct ifinfomsg *ifm = mnl_nlmsg_get_payload(nlh);
42 
43 	printf("index=%d type=%d flags=%d family=%d ",
44 		ifm->ifi_index, ifm->ifi_type,
45 		ifm->ifi_flags, ifm->ifi_family);
46 
47 	if (ifm->ifi_flags & IFF_RUNNING)
48 		printf("[RUNNING] ");
49 	else
50 		printf("[NOT RUNNING] ");
51 
52 	mnl_attr_parse(nlh, sizeof(*ifm), data_attr_cb, tb);
53 	if (tb[IFLA_MTU]) {
54 		printf("mtu=%d ", mnl_attr_get_u32(tb[IFLA_MTU]));
55 	}
56 	if (tb[IFLA_IFNAME]) {
57 		printf("name=%s", mnl_attr_get_str(tb[IFLA_IFNAME]));
58 	}
59 	printf("\n");
60 	return MNL_CB_OK;
61 }
62 
main(void)63 int main(void)
64 {
65 	struct mnl_socket *nl;
66 	char buf[MNL_SOCKET_BUFFER_SIZE];
67 	int ret;
68 
69 	nl = mnl_socket_open(NETLINK_ROUTE);
70 	if (nl == NULL) {
71 		perror("mnl_socket_open");
72 		exit(EXIT_FAILURE);
73 	}
74 
75 	if (mnl_socket_bind(nl, RTMGRP_LINK, MNL_SOCKET_AUTOPID) < 0) {
76 		perror("mnl_socket_bind");
77 		exit(EXIT_FAILURE);
78 	}
79 
80 	ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
81 	while (ret > 0) {
82 		ret = mnl_cb_run(buf, ret, 0, 0, data_cb, NULL);
83 		if (ret <= 0)
84 			break;
85 		ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
86 	}
87 	if (ret == -1) {
88 		perror("error");
89 		exit(EXIT_FAILURE);
90 	}
91 
92 	mnl_socket_close(nl);
93 
94 	return 0;
95 }
96