route.c revision 98c297f2448fd8194cae16d213dfc9194180fa3f
1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdio.h>
3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdlib.h>
4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <unistd.h>
598c297f2448fd8194cae16d213dfc9194180fa3fChung-yih Wang#include <stdarg.h>
6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <errno.h>
8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <string.h>
9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <ctype.h>
10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/socket.h>
12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <netinet/in.h>
13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <linux/if.h>
14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <linux/sockios.h>
15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <arpa/inet.h>
16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <linux/route.h>
17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1898c297f2448fd8194cae16d213dfc9194180fa3fChung-yih Wangstatic void die(const char *fmt, ...)
19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
2098c297f2448fd8194cae16d213dfc9194180fa3fChung-yih Wang    va_list p;
2198c297f2448fd8194cae16d213dfc9194180fa3fChung-yih Wang
2298c297f2448fd8194cae16d213dfc9194180fa3fChung-yih Wang    va_start(p, fmt);
2398c297f2448fd8194cae16d213dfc9194180fa3fChung-yih Wang    fprintf(stderr,"error(%s): ", strerror(errno));
2498c297f2448fd8194cae16d213dfc9194180fa3fChung-yih Wang    fprintf(stderr, fmt, p);
2598c297f2448fd8194cae16d213dfc9194180fa3fChung-yih Wang    va_end(p);
26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    exit(-1);
27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic inline void init_sockaddr_in(struct sockaddr_in *sin, const char *addr)
30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	sin->sin_family = AF_INET;
32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	sin->sin_port = 0;
33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	sin->sin_addr.s_addr = inet_addr(addr);
34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define ADVANCE(argc, argv) do { argc--, argv++; } while(0)
37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define EXPECT_NEXT(argc, argv) do {        \
38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ADVANCE(argc, argv);                    \
39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (0 == argc) {  						\
40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		errno = EINVAL;                     \
41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		die("expecting one more argument"); \
42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}                                       \
43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} while(0)
44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
4598c297f2448fd8194cae16d213dfc9194180fa3fChung-yih Wang/* current support the following routing entries */
46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* route add default dev wlan0 */
47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* route add default gw 192.168.20.1 dev wlan0 */
4898c297f2448fd8194cae16d213dfc9194180fa3fChung-yih Wang/* route add net 192.168.1.1 netmask 255.255.255.0 gw 172.24.192.10 */
49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint route_main(int argc, char *argv[])
51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct ifreq ifr;
53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int s,i;
54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	struct rtentry rt;
55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	struct sockaddr_in ina;
56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(argc == 0) return 0;
58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    strncpy(ifr.ifr_name, argv[0], IFNAMSIZ);
60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ifr.ifr_name[IFNAMSIZ-1] = 0;
61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	ADVANCE(argc, argv);
62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        die("cannot open control socket\n");
65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    while(argc > 0){
68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(!strcmp(argv[0], "add")) {
69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			EXPECT_NEXT(argc, argv);
70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if(!strcmp(argv[0], "default")) {
71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				EXPECT_NEXT(argc, argv);
72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				memset((char *) &rt, 0, sizeof(struct rtentry));
73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				rt.rt_dst.sa_family = AF_INET;
74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				if(!strcmp(argv[0], "dev")) {
75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				  EXPECT_NEXT(argc, argv);
76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				  rt.rt_flags = RTF_UP | RTF_HOST;
77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				  rt.rt_dev = argv[0];
7898c297f2448fd8194cae16d213dfc9194180fa3fChung-yih Wang				  if (ioctl(s, SIOCADDRT, &rt) < 0) die("SIOCADDRT\n");
79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				}else if(!strcmp(argv[0], "gw")) {
80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				  EXPECT_NEXT(argc, argv);
81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				  rt.rt_flags = RTF_UP | RTF_GATEWAY;
82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				  init_sockaddr_in((struct sockaddr_in *)&(rt.rt_genmask), "0.0.0.0");
83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				  if(isdigit(argv[0][0])){
84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					init_sockaddr_in((struct sockaddr_in *)&(rt.rt_gateway), argv[0]);
85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				  }else{
8698c297f2448fd8194cae16d213dfc9194180fa3fChung-yih Wang					die("expecting an IP address for parameter \"gw\"\n");
87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				  }
88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				  EXPECT_NEXT(argc, argv);
89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				  if(!strcmp(argv[0], "dev")) {
90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					EXPECT_NEXT(argc, argv);
91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					rt.rt_dev = argv[0];
92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					if (ioctl(s, SIOCADDRT, &rt) < 0){
9398c297f2448fd8194cae16d213dfc9194180fa3fChung-yih Wang					  die("SIOCADDRT\n");
94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					}
95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				  }
96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				}
9798c297f2448fd8194cae16d213dfc9194180fa3fChung-yih Wang			} else  {
9898c297f2448fd8194cae16d213dfc9194180fa3fChung-yih Wang                          char keywords[3][5] = { "net", "mask", "gw" };
9998c297f2448fd8194cae16d213dfc9194180fa3fChung-yih Wang                          struct sockaddr_in *paddr[3] = { &rt.rt_dst, &rt.rt_genmask, &rt.rt_gateway };
10098c297f2448fd8194cae16d213dfc9194180fa3fChung-yih Wang                          int k = 0;
10198c297f2448fd8194cae16d213dfc9194180fa3fChung-yih Wang
10298c297f2448fd8194cae16d213dfc9194180fa3fChung-yih Wang                          memset((char *) &rt, 0, sizeof(struct rtentry));
10398c297f2448fd8194cae16d213dfc9194180fa3fChung-yih Wang                          rt.rt_flags = RTF_UP | RTF_GATEWAY;
10498c297f2448fd8194cae16d213dfc9194180fa3fChung-yih Wang                          do {
10598c297f2448fd8194cae16d213dfc9194180fa3fChung-yih Wang                            if(!strcmp(argv[0], keywords[k])) {
10698c297f2448fd8194cae16d213dfc9194180fa3fChung-yih Wang                              EXPECT_NEXT(argc, argv);
10798c297f2448fd8194cae16d213dfc9194180fa3fChung-yih Wang                              if(isdigit(argv[0][0])) {
10898c297f2448fd8194cae16d213dfc9194180fa3fChung-yih Wang                                init_sockaddr_in(paddr[k], argv[0]);
10998c297f2448fd8194cae16d213dfc9194180fa3fChung-yih Wang                              } else {
11098c297f2448fd8194cae16d213dfc9194180fa3fChung-yih Wang                                die("expecting an IP/MASK address for parameter %s\n", keywords[k]);
11198c297f2448fd8194cae16d213dfc9194180fa3fChung-yih Wang                              }
11298c297f2448fd8194cae16d213dfc9194180fa3fChung-yih Wang                              if(k < 2) EXPECT_NEXT(argc, argv);
11398c297f2448fd8194cae16d213dfc9194180fa3fChung-yih Wang                            } else {
11498c297f2448fd8194cae16d213dfc9194180fa3fChung-yih Wang                              die("expecting keyword(s)\n");
11598c297f2448fd8194cae16d213dfc9194180fa3fChung-yih Wang                            }
11698c297f2448fd8194cae16d213dfc9194180fa3fChung-yih Wang                          } while(++k < 3);
11798c297f2448fd8194cae16d213dfc9194180fa3fChung-yih Wang                          if(ioctl(s, SIOCADDRT, &rt) < 0) {
11898c297f2448fd8194cae16d213dfc9194180fa3fChung-yih Wang                            die("SIOCADDRT\n");
11998c297f2448fd8194cae16d213dfc9194180fa3fChung-yih Wang                          }
12098c297f2448fd8194cae16d213dfc9194180fa3fChung-yih Wang                        }
121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		ADVANCE(argc, argv);
123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
127