route.c revision dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0
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>
5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <errno.h>
7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <string.h>
8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <ctype.h>
9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/socket.h>
11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <netinet/in.h>
12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <linux/if.h>
13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <linux/sockios.h>
14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <arpa/inet.h>
15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <linux/route.h>
16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void die(const char *s)
18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fprintf(stderr,"error: %s (%s)\n", s, strerror(errno));
20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    exit(-1);
21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic inline void init_sockaddr_in(struct sockaddr_in *sin, const char *addr)
24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	sin->sin_family = AF_INET;
26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	sin->sin_port = 0;
27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	sin->sin_addr.s_addr = inet_addr(addr);
28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define ADVANCE(argc, argv) do { argc--, argv++; } while(0)
31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define EXPECT_NEXT(argc, argv) do {        \
32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ADVANCE(argc, argv);                    \
33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (0 == argc) {  						\
34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		errno = EINVAL;                     \
35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		die("expecting one more argument"); \
36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}                                       \
37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} while(0)
38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* current support two kinds of usage */
40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* route add default dev wlan0 */
41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* route add default gw 192.168.20.1 dev wlan0 */
42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint route_main(int argc, char *argv[])
44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct ifreq ifr;
46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int s,i;
47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	struct rtentry rt;
48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	struct sockaddr_in ina;
49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(argc == 0) return 0;
51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    strncpy(ifr.ifr_name, argv[0], IFNAMSIZ);
53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ifr.ifr_name[IFNAMSIZ-1] = 0;
54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	ADVANCE(argc, argv);
55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        die("cannot open control socket\n");
58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    while(argc > 0){
61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(!strcmp(argv[0], "add")) {
62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			EXPECT_NEXT(argc, argv);
63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if(!strcmp(argv[0], "default")) {
64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				EXPECT_NEXT(argc, argv);
65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				memset((char *) &rt, 0, sizeof(struct rtentry));
66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				rt.rt_dst.sa_family = AF_INET;
67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				if(!strcmp(argv[0], "dev")) {
68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				  EXPECT_NEXT(argc, argv);
69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				  rt.rt_flags = RTF_UP | RTF_HOST;
70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				  rt.rt_dev = argv[0];
71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				  if (ioctl(s, SIOCADDRT, &rt) < 0) die("SIOCADDRT");
72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				}else if(!strcmp(argv[0], "gw")) {
73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				  EXPECT_NEXT(argc, argv);
74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				  rt.rt_flags = RTF_UP | RTF_GATEWAY;
75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				  init_sockaddr_in((struct sockaddr_in *)&(rt.rt_genmask), "0.0.0.0");
76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				  if(isdigit(argv[0][0])){
77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					init_sockaddr_in((struct sockaddr_in *)&(rt.rt_gateway), argv[0]);
78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				  }else{
79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					die("expecting an IP address for parameter \"gw\"");
80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				  }
81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				  EXPECT_NEXT(argc, argv);
82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				  if(!strcmp(argv[0], "dev")) {
83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					EXPECT_NEXT(argc, argv);
84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					rt.rt_dev = argv[0];
85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					if (ioctl(s, SIOCADDRT, &rt) < 0){
86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					  die("SIOCADDRT");
87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					}
88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				  }
89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				}
90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			}
91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		ADVANCE(argc, argv);
93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
98