netcfg.c revision 177ca7cd76a9245818b99f1dd6700c276511fcc0
1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* system/bin/netcfg/netcfg.c 2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** 3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Copyright 2006, The Android Open Source Project 4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** 5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License"); 6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** you may not use this file except in compliance with the License. 7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** You may obtain a copy of the License at 8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** 9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** http://www.apache.org/licenses/LICENSE-2.0 10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** 11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Unless required by applicable law or agreed to in writing, software 12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** distributed under the License is distributed on an "AS IS" BASIS, 13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** See the License for the specific language governing permissions and 15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** limitations under the License. 16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project*/ 17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdio.h> 19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdlib.h> 20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <errno.h> 21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <dirent.h> 228c85a00db6da092ec3766facd49132fa4fc319a1Szymon Jakubczak#include <netinet/ether.h> 2397186a9c3d1874ac79f94676dc9f0df1f0815e1fDmitry Shmidt#include <netinet/if_ether.h> 248c85a00db6da092ec3766facd49132fa4fc319a1Szymon Jakubczak 258c85a00db6da092ec3766facd49132fa4fc319a1Szymon Jakubczak#include <netutils/ifc.h> 268c85a00db6da092ec3766facd49132fa4fc319a1Szymon Jakubczak#include <netutils/dhcp.h> 27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int verbose = 0; 29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid die(const char *reason) 32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project perror(reason); 34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(1); 35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 378c85a00db6da092ec3766facd49132fa4fc319a1Szymon Jakubczakconst char *ipaddr(in_addr_t addr) 38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 398c85a00db6da092ec3766facd49132fa4fc319a1Szymon Jakubczak struct in_addr in_addr; 408c85a00db6da092ec3766facd49132fa4fc319a1Szymon Jakubczak 418c85a00db6da092ec3766facd49132fa4fc319a1Szymon Jakubczak in_addr.s_addr = addr; 428c85a00db6da092ec3766facd49132fa4fc319a1Szymon Jakubczak return inet_ntoa(in_addr); 43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid usage(void) 46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"usage: netcfg [<interface> {dhcp|up|down}]\n"); 4897186a9c3d1874ac79f94676dc9f0df1f0815e1fDmitry Shmidt exit(1); 49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint dump_interface(const char *name) 52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 53177ca7cd76a9245818b99f1dd6700c276511fcc0Robert Greenwalt unsigned addr, prefixLength, flags; 5497186a9c3d1874ac79f94676dc9f0df1f0815e1fDmitry Shmidt unsigned char hwbuf[ETH_ALEN]; 5597186a9c3d1874ac79f94676dc9f0df1f0815e1fDmitry Shmidt 56177ca7cd76a9245818b99f1dd6700c276511fcc0Robert Greenwalt if(ifc_get_info(name, &addr, &prefixLength, &flags)) { 57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project printf("%-8s %s ", name, flags & 1 ? "UP " : "DOWN"); 61177ca7cd76a9245818b99f1dd6700c276511fcc0Robert Greenwalt printf("%40s", ipaddr(addr)); 62177ca7cd76a9245818b99f1dd6700c276511fcc0Robert Greenwalt printf("/%-4d", prefixLength); 6397186a9c3d1874ac79f94676dc9f0df1f0815e1fDmitry Shmidt printf("0x%08x ", flags); 6497186a9c3d1874ac79f94676dc9f0df1f0815e1fDmitry Shmidt if (!ifc_get_hwaddr(name, hwbuf)) { 6597186a9c3d1874ac79f94676dc9f0df1f0815e1fDmitry Shmidt int i; 6697186a9c3d1874ac79f94676dc9f0df1f0815e1fDmitry Shmidt for(i=0; i < (ETH_ALEN-1); i++) 6797186a9c3d1874ac79f94676dc9f0df1f0815e1fDmitry Shmidt printf("%02x:", hwbuf[i]); 6897186a9c3d1874ac79f94676dc9f0df1f0815e1fDmitry Shmidt printf("%02x\n", hwbuf[i]); 6997186a9c3d1874ac79f94676dc9f0df1f0815e1fDmitry Shmidt } else { 7097186a9c3d1874ac79f94676dc9f0df1f0815e1fDmitry Shmidt printf("\n"); 7197186a9c3d1874ac79f94676dc9f0df1f0815e1fDmitry Shmidt } 72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint dump_interfaces(void) 76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project DIR *d; 78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct dirent *de; 7997186a9c3d1874ac79f94676dc9f0df1f0815e1fDmitry Shmidt 80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project d = opendir("/sys/class/net"); 81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(d == 0) return -1; 8297186a9c3d1874ac79f94676dc9f0df1f0815e1fDmitry Shmidt 83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while((de = readdir(d))) { 84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(de->d_name[0] == '.') continue; 85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dump_interface(de->d_name); 86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project closedir(d); 88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 918c85a00db6da092ec3766facd49132fa4fc319a1Szymon Jakubczakint set_hwaddr(const char *name, const char *asc) { 928c85a00db6da092ec3766facd49132fa4fc319a1Szymon Jakubczak struct ether_addr *addr = ether_aton(asc); 938c85a00db6da092ec3766facd49132fa4fc319a1Szymon Jakubczak if (!addr) { 948c85a00db6da092ec3766facd49132fa4fc319a1Szymon Jakubczak printf("Failed to parse '%s'\n", asc); 958c85a00db6da092ec3766facd49132fa4fc319a1Szymon Jakubczak return -1; 968c85a00db6da092ec3766facd49132fa4fc319a1Szymon Jakubczak } 978c85a00db6da092ec3766facd49132fa4fc319a1Szymon Jakubczak return ifc_set_hwaddr(name, addr->ether_addr_octet); 988c85a00db6da092ec3766facd49132fa4fc319a1Szymon Jakubczak} 998c85a00db6da092ec3766facd49132fa4fc319a1Szymon Jakubczak 100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct 101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const char *name; 103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int nargs; 104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project void *func; 105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} CMDS[] = { 106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { "dhcp", 1, do_dhcp }, 107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { "up", 1, ifc_up }, 108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { "down", 1, ifc_down }, 109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { "flhosts", 1, ifc_remove_host_routes }, 110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { "deldefault", 1, ifc_remove_default_route }, 1118c85a00db6da092ec3766facd49132fa4fc319a1Szymon Jakubczak { "hwaddr", 2, set_hwaddr }, 112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { 0, 0, 0 }, 113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}; 114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int call_func(void *_func, unsigned nargs, char **args) 116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project switch(nargs){ 118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 1: { 119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int (*func)(char *a0) = _func; 120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return func(args[0]); 121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 2: { 123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int (*func)(char *a0, char *a1) = _func; 124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return func(args[0], args[1]); 125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 3: { 127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int (*func)(char *a0, char *a1, char *a2) = _func; 128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return func(args[0], args[1], args[2]); 129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project default: 131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint main(int argc, char **argv) 136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *iname; 138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int n; 139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(ifc_init()) { 141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project die("Cannot perform requested operation"); 142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(argc == 1) { 145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int result = dump_interfaces(); 146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ifc_close(); 147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return result; 148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(argc < 3) usage(); 151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project iname = argv[1]; 153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(strlen(iname) > 16) usage(); 154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project argc -= 2; 156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project argv += 2; 157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while(argc > 0) { 158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for(n = 0; CMDS[n].name; n++){ 159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(!strcmp(argv[0], CMDS[n].name)) { 160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *cmdname = argv[0]; 161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int nargs = CMDS[n].nargs; 162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project argv[0] = iname; 164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(argc < nargs) { 165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr, "not enough arguments for '%s'\n", cmdname); 166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ifc_close(); 167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(1); 168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(call_func(CMDS[n].func, nargs, argv)) { 170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr, "action '%s' failed (%s)\n", cmdname, strerror(errno)); 171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ifc_close(); 172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(1); 173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project argc -= nargs; 175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project argv += nargs; 176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto done; 177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"no such action '%s'\n", argv[0]); 180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project usage(); 181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project done: 182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ; 183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ifc_close(); 185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 188