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