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 23static int verbose = 0; 24 25int ifc_init(); 26void ifc_close(); 27int ifc_up(char *iname); 28int ifc_down(char *iname); 29int ifc_remove_host_routes(char *iname); 30int ifc_remove_default_route(char *iname); 31int ifc_get_info(const char *name, unsigned *addr, unsigned *mask, unsigned *flags); 32int do_dhcp(char *iname); 33 34void die(const char *reason) 35{ 36 perror(reason); 37 exit(1); 38} 39 40const char *ipaddr(unsigned addr) 41{ 42 static char buf[32]; 43 44 sprintf(buf,"%d.%d.%d.%d", 45 addr & 255, 46 ((addr >> 8) & 255), 47 ((addr >> 16) & 255), 48 (addr >> 24)); 49 return buf; 50} 51 52void usage(void) 53{ 54 fprintf(stderr,"usage: netcfg [<interface> {dhcp|up|down}]\n"); 55 exit(1); 56} 57 58int dump_interface(const char *name) 59{ 60 unsigned addr, mask, flags; 61 62 if(ifc_get_info(name, &addr, &mask, &flags)) { 63 return 0; 64 } 65 66 printf("%-8s %s ", name, flags & 1 ? "UP " : "DOWN"); 67 printf("%-16s", ipaddr(addr)); 68 printf("%-16s", ipaddr(mask)); 69 printf("0x%08x\n", flags); 70 return 0; 71} 72 73int dump_interfaces(void) 74{ 75 DIR *d; 76 struct dirent *de; 77 78 d = opendir("/sys/class/net"); 79 if(d == 0) return -1; 80 81 while((de = readdir(d))) { 82 if(de->d_name[0] == '.') continue; 83 dump_interface(de->d_name); 84 } 85 closedir(d); 86 return 0; 87} 88 89struct 90{ 91 const char *name; 92 int nargs; 93 void *func; 94} CMDS[] = { 95 { "dhcp", 1, do_dhcp }, 96 { "up", 1, ifc_up }, 97 { "down", 1, ifc_down }, 98 { "flhosts", 1, ifc_remove_host_routes }, 99 { "deldefault", 1, ifc_remove_default_route }, 100 { 0, 0, 0 }, 101}; 102 103static int call_func(void *_func, unsigned nargs, char **args) 104{ 105 switch(nargs){ 106 case 1: { 107 int (*func)(char *a0) = _func; 108 return func(args[0]); 109 } 110 case 2: { 111 int (*func)(char *a0, char *a1) = _func; 112 return func(args[0], args[1]); 113 } 114 case 3: { 115 int (*func)(char *a0, char *a1, char *a2) = _func; 116 return func(args[0], args[1], args[2]); 117 } 118 default: 119 return -1; 120 } 121} 122 123int main(int argc, char **argv) 124{ 125 char *iname; 126 int n; 127 128 if(ifc_init()) { 129 die("Cannot perform requested operation"); 130 } 131 132 if(argc == 1) { 133 int result = dump_interfaces(); 134 ifc_close(); 135 return result; 136 } 137 138 if(argc < 3) usage(); 139 140 iname = argv[1]; 141 if(strlen(iname) > 16) usage(); 142 143 argc -= 2; 144 argv += 2; 145 while(argc > 0) { 146 for(n = 0; CMDS[n].name; n++){ 147 if(!strcmp(argv[0], CMDS[n].name)) { 148 char *cmdname = argv[0]; 149 int nargs = CMDS[n].nargs; 150 151 argv[0] = iname; 152 if(argc < nargs) { 153 fprintf(stderr, "not enough arguments for '%s'\n", cmdname); 154 ifc_close(); 155 exit(1); 156 } 157 if(call_func(CMDS[n].func, nargs, argv)) { 158 fprintf(stderr, "action '%s' failed (%s)\n", cmdname, strerror(errno)); 159 ifc_close(); 160 exit(1); 161 } 162 argc -= nargs; 163 argv += nargs; 164 goto done; 165 } 166 } 167 fprintf(stderr,"no such action '%s'\n", argv[0]); 168 usage(); 169 done: 170 ; 171 } 172 ifc_close(); 173 174 return 0; 175} 176