Home | History | Annotate | Download | only in netcfg
      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