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