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
23 static int verbose = 0;
24
25 int ifc_init();
26 void ifc_close();
27 int ifc_up(char *iname);
28 int ifc_down(char *iname);
29 int ifc_remove_host_routes(char *iname);
30 int ifc_remove_default_route(char *iname);
31 int ifc_get_info(const char *name, unsigned *addr, unsigned *mask, unsigned *flags);
32 int do_dhcp(char *iname);
33
die(const char * reason)34 void die(const char *reason)
35 {
36 perror(reason);
37 exit(1);
38 }
39
ipaddr(unsigned addr)40 const 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
usage(void)52 void usage(void)
53 {
54 fprintf(stderr,"usage: netcfg [<interface> {dhcp|up|down}]\n");
55 exit(1);
56 }
57
dump_interface(const char * name)58 int 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
dump_interfaces(void)73 int 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
89 struct
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
call_func(void * _func,unsigned nargs,char ** args)103 static 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
main(int argc,char ** argv)123 int 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