xref: /aosp_15_r20/external/ethtool/libmnl/examples/rtnl/rtnl-addr-add.c (revision 1b481fc3bb1b45d4cf28d1ec12969dc1055f555d)
1*1b481fc3SMaciej Żenczykowski /* This example is placed in the public domain. */
2*1b481fc3SMaciej Żenczykowski #include <netinet/in.h>
3*1b481fc3SMaciej Żenczykowski #include <arpa/inet.h>
4*1b481fc3SMaciej Żenczykowski #include <time.h>
5*1b481fc3SMaciej Żenczykowski #include <stdio.h>
6*1b481fc3SMaciej Żenczykowski #include <stdlib.h>
7*1b481fc3SMaciej Żenczykowski #include <unistd.h>
8*1b481fc3SMaciej Żenczykowski #include <strings.h>
9*1b481fc3SMaciej Żenczykowski #include <net/if.h>
10*1b481fc3SMaciej Żenczykowski 
11*1b481fc3SMaciej Żenczykowski #include <libmnl/libmnl.h>
12*1b481fc3SMaciej Żenczykowski #include <linux/if_link.h>
13*1b481fc3SMaciej Żenczykowski #include <linux/rtnetlink.h>
14*1b481fc3SMaciej Żenczykowski 
main(int argc,char * argv[])15*1b481fc3SMaciej Żenczykowski int main(int argc, char *argv[])
16*1b481fc3SMaciej Żenczykowski {
17*1b481fc3SMaciej Żenczykowski 	struct mnl_socket *nl;
18*1b481fc3SMaciej Żenczykowski 	char buf[MNL_SOCKET_BUFFER_SIZE];
19*1b481fc3SMaciej Żenczykowski 	struct nlmsghdr *nlh;
20*1b481fc3SMaciej Żenczykowski 	struct ifaddrmsg *ifm;
21*1b481fc3SMaciej Żenczykowski 	uint32_t seq, portid;
22*1b481fc3SMaciej Żenczykowski 	union {
23*1b481fc3SMaciej Żenczykowski 		in_addr_t ip;
24*1b481fc3SMaciej Żenczykowski 		struct in6_addr ip6;
25*1b481fc3SMaciej Żenczykowski 	} addr;
26*1b481fc3SMaciej Żenczykowski 	int ret, family = AF_INET;
27*1b481fc3SMaciej Żenczykowski 
28*1b481fc3SMaciej Żenczykowski 	uint32_t prefix;
29*1b481fc3SMaciej Żenczykowski 	int iface;
30*1b481fc3SMaciej Żenczykowski 
31*1b481fc3SMaciej Żenczykowski 
32*1b481fc3SMaciej Żenczykowski 	if (argc <= 3) {
33*1b481fc3SMaciej Żenczykowski 		printf("Usage: %s iface destination cidr\n", argv[0]);
34*1b481fc3SMaciej Żenczykowski 		printf("Example: %s eth0 10.0.1.12 32\n", argv[0]);
35*1b481fc3SMaciej Żenczykowski 		printf("	 %s eth0 ffff::10.0.1.12 128\n", argv[0]);
36*1b481fc3SMaciej Żenczykowski 		exit(EXIT_FAILURE);
37*1b481fc3SMaciej Żenczykowski 	}
38*1b481fc3SMaciej Żenczykowski 
39*1b481fc3SMaciej Żenczykowski 	iface = if_nametoindex(argv[1]);
40*1b481fc3SMaciej Żenczykowski 	if (iface == 0) {
41*1b481fc3SMaciej Żenczykowski 		perror("if_nametoindex");
42*1b481fc3SMaciej Żenczykowski 		exit(EXIT_FAILURE);
43*1b481fc3SMaciej Żenczykowski 	}
44*1b481fc3SMaciej Żenczykowski 
45*1b481fc3SMaciej Żenczykowski 	if (!inet_pton(AF_INET, argv[2], &addr)) {
46*1b481fc3SMaciej Żenczykowski 		if (!inet_pton(AF_INET6, argv[2], &addr)) {
47*1b481fc3SMaciej Żenczykowski 			perror("inet_pton");
48*1b481fc3SMaciej Żenczykowski 			exit(EXIT_FAILURE);
49*1b481fc3SMaciej Żenczykowski 		}
50*1b481fc3SMaciej Żenczykowski 		family = AF_INET6;
51*1b481fc3SMaciej Żenczykowski 	}
52*1b481fc3SMaciej Żenczykowski 
53*1b481fc3SMaciej Żenczykowski 	if (sscanf(argv[3], "%u", &prefix) == 0) {
54*1b481fc3SMaciej Żenczykowski 		perror("sscanf");
55*1b481fc3SMaciej Żenczykowski 		exit(EXIT_FAILURE);
56*1b481fc3SMaciej Żenczykowski 	}
57*1b481fc3SMaciej Żenczykowski 
58*1b481fc3SMaciej Żenczykowski 	nlh = mnl_nlmsg_put_header(buf);
59*1b481fc3SMaciej Żenczykowski 	nlh->nlmsg_type	= RTM_NEWADDR;
60*1b481fc3SMaciej Żenczykowski 
61*1b481fc3SMaciej Żenczykowski 	nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_REPLACE | NLM_F_ACK;
62*1b481fc3SMaciej Żenczykowski 	nlh->nlmsg_seq = seq = time(NULL);
63*1b481fc3SMaciej Żenczykowski 
64*1b481fc3SMaciej Żenczykowski 	ifm = mnl_nlmsg_put_extra_header(nlh, sizeof(struct ifaddrmsg));
65*1b481fc3SMaciej Żenczykowski 
66*1b481fc3SMaciej Żenczykowski 	ifm->ifa_family = family;
67*1b481fc3SMaciej Żenczykowski 	ifm->ifa_prefixlen = prefix;
68*1b481fc3SMaciej Żenczykowski 	ifm->ifa_flags = IFA_F_PERMANENT;
69*1b481fc3SMaciej Żenczykowski 
70*1b481fc3SMaciej Żenczykowski 	ifm->ifa_scope = RT_SCOPE_UNIVERSE;
71*1b481fc3SMaciej Żenczykowski 	ifm->ifa_index = iface;
72*1b481fc3SMaciej Żenczykowski 
73*1b481fc3SMaciej Żenczykowski 	/*
74*1b481fc3SMaciej Żenczykowski 	 * The exact meaning of IFA_LOCAL and IFA_ADDRESS depend
75*1b481fc3SMaciej Żenczykowski 	 * on the address family being used and the device type.
76*1b481fc3SMaciej Żenczykowski 	 * For broadcast devices (like the interfaces we use),
77*1b481fc3SMaciej Żenczykowski 	 * for IPv4 we specify both and they are used interchangeably.
78*1b481fc3SMaciej Żenczykowski 	 * For IPv6, only IFA_ADDRESS needs to be set.
79*1b481fc3SMaciej Żenczykowski 	 */
80*1b481fc3SMaciej Żenczykowski 	if (family == AF_INET) {
81*1b481fc3SMaciej Żenczykowski 		mnl_attr_put_u32(nlh, IFA_LOCAL, addr.ip);
82*1b481fc3SMaciej Żenczykowski 		mnl_attr_put_u32(nlh, IFA_ADDRESS, addr.ip);
83*1b481fc3SMaciej Żenczykowski 	} else {
84*1b481fc3SMaciej Żenczykowski 		mnl_attr_put(nlh, IFA_ADDRESS, sizeof(struct in6_addr), &addr);
85*1b481fc3SMaciej Żenczykowski 	}
86*1b481fc3SMaciej Żenczykowski 
87*1b481fc3SMaciej Żenczykowski 	nl = mnl_socket_open(NETLINK_ROUTE);
88*1b481fc3SMaciej Żenczykowski 	if (nl == NULL) {
89*1b481fc3SMaciej Żenczykowski 		perror("mnl_socket_open");
90*1b481fc3SMaciej Żenczykowski 		exit(EXIT_FAILURE);
91*1b481fc3SMaciej Żenczykowski 	}
92*1b481fc3SMaciej Żenczykowski 
93*1b481fc3SMaciej Żenczykowski 	if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) {
94*1b481fc3SMaciej Żenczykowski 		perror("mnl_socket_bind");
95*1b481fc3SMaciej Żenczykowski 		exit(EXIT_FAILURE);
96*1b481fc3SMaciej Żenczykowski 	}
97*1b481fc3SMaciej Żenczykowski 	portid = mnl_socket_get_portid(nl);
98*1b481fc3SMaciej Żenczykowski 
99*1b481fc3SMaciej Żenczykowski 	if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
100*1b481fc3SMaciej Żenczykowski 		perror("mnl_socket_sendto");
101*1b481fc3SMaciej Żenczykowski 		exit(EXIT_FAILURE);
102*1b481fc3SMaciej Żenczykowski 	}
103*1b481fc3SMaciej Żenczykowski 
104*1b481fc3SMaciej Żenczykowski 	ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
105*1b481fc3SMaciej Żenczykowski 	if (ret < 0) {
106*1b481fc3SMaciej Żenczykowski 		perror("mnl_socket_recvfrom");
107*1b481fc3SMaciej Żenczykowski 		exit(EXIT_FAILURE);
108*1b481fc3SMaciej Żenczykowski 	}
109*1b481fc3SMaciej Żenczykowski 
110*1b481fc3SMaciej Żenczykowski 	ret = mnl_cb_run(buf, ret, seq, portid, NULL, NULL);
111*1b481fc3SMaciej Żenczykowski 	if (ret < 0) {
112*1b481fc3SMaciej Żenczykowski 		perror("mnl_cb_run");
113*1b481fc3SMaciej Żenczykowski 		exit(EXIT_FAILURE);
114*1b481fc3SMaciej Żenczykowski 	}
115*1b481fc3SMaciej Żenczykowski 
116*1b481fc3SMaciej Żenczykowski 	mnl_socket_close(nl);
117*1b481fc3SMaciej Żenczykowski 
118*1b481fc3SMaciej Żenczykowski 	return 0;
119*1b481fc3SMaciej Żenczykowski }
120