From 4f6e8d7a00cbeda1e70cc15be9c4af1018bdad53 Mon Sep 17 00:00:00 2001 From: The Android Open Source Project Date: Tue, 21 Oct 2008 07:00:00 -0700 Subject: Initial Contribution --- toolbox/route.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 toolbox/route.c (limited to 'toolbox/route.c') diff --git a/toolbox/route.c b/toolbox/route.c new file mode 100644 index 0000000..adf5c69 --- /dev/null +++ b/toolbox/route.c @@ -0,0 +1,97 @@ + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +static void die(const char *s) +{ + fprintf(stderr,"error: %s (%s)\n", s, strerror(errno)); + exit(-1); +} + +static inline void init_sockaddr_in(struct sockaddr_in *sin, const char *addr) +{ + sin->sin_family = AF_INET; + sin->sin_port = 0; + sin->sin_addr.s_addr = inet_addr(addr); +} + +#define ADVANCE(argc, argv) do { argc--, argv++; } while(0) +#define EXPECT_NEXT(argc, argv) do { \ + ADVANCE(argc, argv); \ + if (0 == argc) { \ + errno = EINVAL; \ + die("expecting one more argument"); \ + } \ +} while(0) + +/* current support two kinds of usage */ +/* route add default dev wlan0 */ +/* route add default gw 192.168.20.1 dev wlan0 */ + +int route_main(int argc, char *argv[]) +{ + struct ifreq ifr; + int s,i; + struct rtentry rt; + struct sockaddr_in ina; + + if(argc == 0) return 0; + + strncpy(ifr.ifr_name, argv[0], IFNAMSIZ); + ifr.ifr_name[IFNAMSIZ-1] = 0; + ADVANCE(argc, argv); + + if((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + die("cannot open control socket\n"); + } + + while(argc > 0){ + if(!strcmp(argv[0], "add")) { + EXPECT_NEXT(argc, argv); + if(!strcmp(argv[0], "default")) { + EXPECT_NEXT(argc, argv); + memset((char *) &rt, 0, sizeof(struct rtentry)); + rt.rt_dst.sa_family = AF_INET; + if(!strcmp(argv[0], "dev")) { + EXPECT_NEXT(argc, argv); + rt.rt_flags = RTF_UP | RTF_HOST; + rt.rt_dev = argv[0]; + if (ioctl(s, SIOCADDRT, &rt) < 0) die("SIOCADDRT"); + }else if(!strcmp(argv[0], "gw")) { + EXPECT_NEXT(argc, argv); + rt.rt_flags = RTF_UP | RTF_GATEWAY; + init_sockaddr_in((struct sockaddr_in *)&(rt.rt_genmask), "0.0.0.0"); + if(isdigit(argv[0][0])){ + init_sockaddr_in((struct sockaddr_in *)&(rt.rt_gateway), argv[0]); + }else{ + die("expecting an IP address for parameter \"gw\""); + } + EXPECT_NEXT(argc, argv); + if(!strcmp(argv[0], "dev")) { + EXPECT_NEXT(argc, argv); + rt.rt_dev = argv[0]; + if (ioctl(s, SIOCADDRT, &rt) < 0){ + die("SIOCADDRT"); + } + } + } + } + } + ADVANCE(argc, argv); + } + + return 0; +} + -- cgit v1.1