1 /* system/bin/netcfg/netcfg.c 2 ** 3 ** Copyright 2006, The Android Open Source Project 4 ** 5 ** Licensed under the Apache License, Version 2.0 (the "License"); 6 ** you may not use this file except in compliance with the License. 7 ** You may obtain a copy of the License at 8 ** 9 ** http://www.apache.org/licenses/LICENSE-2.0 10 ** 11 ** Unless required by applicable law or agreed to in writing, software 12 ** distributed under the License is distributed on an "AS IS" BASIS, 13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 ** See the License for the specific language governing permissions and 15 ** limitations under the License. 16 */ 17 18 #include <stdio.h> 19 #include <stdlib.h> 20 #include <errno.h> 21 #include <dirent.h> 22 #include <netinet/ether.h> 23 #include <netinet/if_ether.h> 24 25 #include <netutils/ifc.h> 26 #include <netutils/dhcp.h> 27 28 static int verbose = 0; 29 30 31 void die(const char *reason) 32 { 33 perror(reason); 34 exit(1); 35 } 36 37 const char *ipaddr(in_addr_t addr) 38 { 39 struct in_addr in_addr; 40 41 in_addr.s_addr = addr; 42 return inet_ntoa(in_addr); 43 } 44 45 void usage(void) 46 { 47 fprintf(stderr,"usage: netcfg [<interface> {dhcp|up|down}]\n"); 48 exit(1); 49 } 50 51 int dump_interface(const char *name) 52 { 53 unsigned addr, flags; 54 unsigned char hwbuf[ETH_ALEN]; 55 int prefixLength; 56 57 if(ifc_get_info(name, &addr, &prefixLength, &flags)) { 58 return 0; 59 } 60 61 printf("%-8s %s ", name, flags & 1 ? "UP " : "DOWN"); 62 printf("%40s", ipaddr(addr)); 63 printf("/%-4d", prefixLength); 64 printf("0x%08x ", flags); 65 if (!ifc_get_hwaddr(name, hwbuf)) { 66 int i; 67 for(i=0; i < (ETH_ALEN-1); i++) 68 printf("%02x:", hwbuf[i]); 69 printf("%02x\n", hwbuf[i]); 70 } else { 71 printf("\n"); 72 } 73 return 0; 74 } 75 76 int dump_interfaces(void) 77 { 78 DIR *d; 79 struct dirent *de; 80 81 d = opendir("/sys/class/net"); 82 if(d == 0) return -1; 83 84 while((de = readdir(d))) { 85 if(de->d_name[0] == '.') continue; 86 dump_interface(de->d_name); 87 } 88 closedir(d); 89 return 0; 90 } 91 92 int set_hwaddr(const char *name, const char *asc) { 93 struct ether_addr *addr = ether_aton(asc); 94 if (!addr) { 95 printf("Failed to parse '%s'\n", asc); 96 return -1; 97 } 98 return ifc_set_hwaddr(name, addr->ether_addr_octet); 99 } 100 101 struct 102 { 103 const char *name; 104 int nargs; 105 void *func; 106 } CMDS[] = { 107 { "dhcp", 1, do_dhcp }, 108 { "up", 1, ifc_up }, 109 { "down", 1, ifc_down }, 110 { "flhosts", 1, ifc_remove_host_routes }, 111 { "deldefault", 1, ifc_remove_default_route }, 112 { "hwaddr", 2, set_hwaddr }, 113 { 0, 0, 0 }, 114 }; 115 116 static int call_func(void *_func, unsigned nargs, char **args) 117 { 118 switch(nargs){ 119 case 1: { 120 int (*func)(char *a0) = _func; 121 return func(args[0]); 122 } 123 case 2: { 124 int (*func)(char *a0, char *a1) = _func; 125 return func(args[0], args[1]); 126 } 127 case 3: { 128 int (*func)(char *a0, char *a1, char *a2) = _func; 129 return func(args[0], args[1], args[2]); 130 } 131 default: 132 return -1; 133 } 134 } 135 136 int main(int argc, char **argv) 137 { 138 char *iname; 139 int n; 140 141 if(ifc_init()) { 142 die("Cannot perform requested operation"); 143 } 144 145 if(argc == 1) { 146 int result = dump_interfaces(); 147 ifc_close(); 148 return result; 149 } 150 151 if(argc < 3) usage(); 152 153 iname = argv[1]; 154 if(strlen(iname) > 16) usage(); 155 156 argc -= 2; 157 argv += 2; 158 while(argc > 0) { 159 for(n = 0; CMDS[n].name; n++){ 160 if(!strcmp(argv[0], CMDS[n].name)) { 161 char *cmdname = argv[0]; 162 int nargs = CMDS[n].nargs; 163 164 argv[0] = iname; 165 if(argc < nargs) { 166 fprintf(stderr, "not enough arguments for '%s'\n", cmdname); 167 ifc_close(); 168 exit(1); 169 } 170 if(call_func(CMDS[n].func, nargs, argv)) { 171 fprintf(stderr, "action '%s' failed (%s)\n", cmdname, strerror(errno)); 172 ifc_close(); 173 exit(1); 174 } 175 argc -= nargs; 176 argv += nargs; 177 goto done; 178 } 179 } 180 fprintf(stderr,"no such action '%s'\n", argv[0]); 181 usage(); 182 done: 183 ; 184 } 185 ifc_close(); 186 187 return 0; 188 } 189