libmnl  1.0.3
rtnl-route-add.c
1 /* This example is placed in the public domain. */
2 #include <netinet/in.h>
3 #include <arpa/inet.h>
4 #include <time.h>
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <unistd.h>
8 #include <strings.h>
9 #include <net/if.h>
10 
11 #include <libmnl/libmnl.h>
12 #include <linux/if_link.h>
13 #include <linux/rtnetlink.h>
14 
15 int main(int argc, char *argv[])
16 {
17  if (argc <= 3) {
18  printf("Usage: %s iface destination cidr [gateway]\n", argv[0]);
19  printf("Example: %s eth0 10.0.1.12 32 10.0.1.11\n", argv[0]);
20  exit(EXIT_FAILURE);
21  }
22 
23  int iface;
24  iface = if_nametoindex(argv[1]);
25  if (iface == 0) {
26  printf("Bad interface name\n");
27  exit(EXIT_FAILURE);
28  }
29 
30  in_addr_t dst;
31  if (!inet_pton(AF_INET, argv[2], &dst)) {
32  printf("Bad destination\n");
33  exit(EXIT_FAILURE);
34  }
35 
36  uint32_t mask;
37  if (sscanf(argv[3], "%u", &mask) == 0) {
38  printf("Bad CIDR\n");
39  exit(EXIT_FAILURE);
40  }
41 
42  in_addr_t gw;
43  if (argc >= 5 && !inet_pton(AF_INET, argv[4], &gw)) {
44  printf("Bad gateway\n");
45  exit(EXIT_FAILURE);
46  }
47 
48  struct mnl_socket *nl;
49  char buf[MNL_SOCKET_BUFFER_SIZE];
50  struct nlmsghdr *nlh;
51  struct rtmsg *rtm;
52 
53  nlh = mnl_nlmsg_put_header(buf);
54  nlh->nlmsg_type = RTM_NEWROUTE;
55  nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE;
56  nlh->nlmsg_seq = time(NULL);
57 
58  rtm = mnl_nlmsg_put_extra_header(nlh, sizeof(struct rtmsg));
59  rtm->rtm_family = AF_INET;
60  rtm->rtm_dst_len = mask;
61  rtm->rtm_src_len = 0;
62  rtm->rtm_tos = 0;
63  rtm->rtm_protocol = RTPROT_BOOT;
64  rtm->rtm_table = RT_TABLE_MAIN;
65  rtm->rtm_type = RTN_UNICAST;
66  /* is there any gateway? */
67  rtm->rtm_scope = (argc == 4) ? RT_SCOPE_LINK : RT_SCOPE_UNIVERSE;
68  rtm->rtm_flags = 0;
69 
70  mnl_attr_put_u32(nlh, RTA_DST, dst);
71  mnl_attr_put_u32(nlh, RTA_OIF, iface);
72  if (argc >= 5)
73  mnl_attr_put_u32(nlh, RTA_GATEWAY, gw);
74 
75  nl = mnl_socket_open(NETLINK_ROUTE);
76  if (nl == NULL) {
77  perror("mnl_socket_open");
78  exit(EXIT_FAILURE);
79  }
80 
81  if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) {
82  perror("mnl_socket_bind");
83  exit(EXIT_FAILURE);
84  }
85 
86  if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
87  perror("mnl_socket_send");
88  exit(EXIT_FAILURE);
89  }
90 
91  mnl_socket_close(nl);
92 
93  return 0;
94 }