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