netcfg.c revision 47ddb515b7d59b29d83628c1b4e48642dc0e49ba
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 28static int verbose = 0; 29 30 31void die(const char *reason) 32{ 33 perror(reason); 34 exit(1); 35} 36 37const 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 45void usage(void) 46{ 47 fprintf(stderr,"usage: netcfg [<interface> {dhcp|up|down}]\n"); 48 exit(1); 49} 50 51int 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 76int 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 92int 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 101struct 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 116static 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 136int 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