blob: 2fd71080c6b27339f3b8a794f034465480d11563 [file] [log] [blame]
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001
2#include <stdio.h>
3#include <stdlib.h>
4#include <unistd.h>
Chung-yih Wang98c297f2009-04-14 18:45:32 -07005#include <stdarg.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08006
7#include <errno.h>
8#include <string.h>
9#include <ctype.h>
10
11#include <sys/socket.h>
12#include <netinet/in.h>
13#include <linux/if.h>
14#include <linux/sockios.h>
15#include <arpa/inet.h>
16#include <linux/route.h>
17
Chung-yih Wang98c297f2009-04-14 18:45:32 -070018static void die(const char *fmt, ...)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080019{
Chung-yih Wang98c297f2009-04-14 18:45:32 -070020 va_list p;
21
22 va_start(p, fmt);
23 fprintf(stderr,"error(%s): ", strerror(errno));
24 fprintf(stderr, fmt, p);
25 va_end(p);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080026 exit(-1);
27}
28
29static inline void init_sockaddr_in(struct sockaddr_in *sin, const char *addr)
30{
31 sin->sin_family = AF_INET;
32 sin->sin_port = 0;
33 sin->sin_addr.s_addr = inet_addr(addr);
34}
35
36#define ADVANCE(argc, argv) do { argc--, argv++; } while(0)
37#define EXPECT_NEXT(argc, argv) do { \
38 ADVANCE(argc, argv); \
39 if (0 == argc) { \
40 errno = EINVAL; \
41 die("expecting one more argument"); \
42 } \
43} while(0)
44
Chung-yih Wang98c297f2009-04-14 18:45:32 -070045/* current support the following routing entries */
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080046/* route add default dev wlan0 */
47/* route add default gw 192.168.20.1 dev wlan0 */
Chung-yih Wang98c297f2009-04-14 18:45:32 -070048/* route add net 192.168.1.1 netmask 255.255.255.0 gw 172.24.192.10 */
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080049
50int route_main(int argc, char *argv[])
51{
52 struct ifreq ifr;
53 int s,i;
San Mehat83ec1812009-05-13 17:18:27 -070054 struct rtentry rt;
55 struct sockaddr_in ina;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080056
San Mehat83ec1812009-05-13 17:18:27 -070057 if (!argc)
58 return 0;
59
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080060 strncpy(ifr.ifr_name, argv[0], IFNAMSIZ);
61 ifr.ifr_name[IFNAMSIZ-1] = 0;
San Mehat83ec1812009-05-13 17:18:27 -070062 ADVANCE(argc, argv);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080063
San Mehat83ec1812009-05-13 17:18:27 -070064 if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080065 die("cannot open control socket\n");
66 }
67
68 while(argc > 0){
San Mehat83ec1812009-05-13 17:18:27 -070069 if (!strcmp(argv[0], "add")) {
70 EXPECT_NEXT(argc, argv);
71 if (!strcmp(argv[0], "default")) {
72 EXPECT_NEXT(argc, argv);
73 memset((char *) &rt, 0, sizeof(struct rtentry));
74 rt.rt_dst.sa_family = AF_INET;
75 if(!strcmp(argv[0], "dev")) {
76 EXPECT_NEXT(argc, argv);
77 rt.rt_flags = RTF_UP | RTF_HOST;
78 rt.rt_dev = argv[0];
79 if (ioctl(s, SIOCADDRT, &rt) < 0)
80 die("SIOCADDRT\n");
81 } else if (!strcmp(argv[0], "gw")) {
82 EXPECT_NEXT(argc, argv);
83 rt.rt_flags = RTF_UP | RTF_GATEWAY;
84 init_sockaddr_in((struct sockaddr_in *)&(rt.rt_genmask), "0.0.0.0");
85 if(isdigit(argv[0][0])) {
86 init_sockaddr_in((struct sockaddr_in *)&(rt.rt_gateway), argv[0]);
87 } else {
88 die("expecting an IP address for parameter \"gw\"\n");
89 }
90 EXPECT_NEXT(argc, argv);
91 if (!strcmp(argv[0], "dev")) {
92 EXPECT_NEXT(argc, argv);
93 rt.rt_dev = argv[0];
94 if (ioctl(s, SIOCADDRT, &rt) < 0) {
Chung-yih Wang98c297f2009-04-14 18:45:32 -070095 die("SIOCADDRT\n");
Chung-yih Wang98c297f2009-04-14 18:45:32 -070096 }
San Mehat83ec1812009-05-13 17:18:27 -070097 }
98 }
99 } else {
100 char keywords[3][10] = { "-net", "netmask", "gw" };
101 struct sockaddr_in *paddr[3] = { &rt.rt_dst, &rt.rt_genmask, &rt.rt_gateway };
102 int k = 0;
103
104 memset((char *) &rt, 0, sizeof(struct rtentry));
105 rt.rt_flags = RTF_UP | RTF_GATEWAY;
106 do {
107 if (!strcmp(argv[0], keywords[k])) {
108 EXPECT_NEXT(argc, argv);
109 if (isdigit(argv[0][0])) {
110 init_sockaddr_in(paddr[k], argv[0]);
111 } else {
112 die("expecting an IP/MASK address for parameter %s\n", keywords[k]);
113 }
114 if (k < 2)
115 EXPECT_NEXT(argc, argv);
116 } else {
117 die("expecting keyword(s)\n");
118 }
119 } while (++k < 3);
120
121 if (ioctl(s, SIOCADDRT, &rt) < 0) {
122 die("SIOCADDRT\n");
123 }
124 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800125 }
San Mehat83ec1812009-05-13 17:18:27 -0700126 ADVANCE(argc, argv);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800127 }
128
129 return 0;
130}