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