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{ 5347ddb515b7d59b29d83628c1b4e48642dc0e49baLorenzo Colitti unsigned addr, flags; 5497186a9c3d1874ac79f94676dc9f0df1f0815e1fDmitry Shmidt unsigned char hwbuf[ETH_ALEN]; 5547ddb515b7d59b29d83628c1b4e48642dc0e49baLorenzo Colitti int prefixLength; 5697186a9c3d1874ac79f94676dc9f0df1f0815e1fDmitry Shmidt 57177ca7cd76a9245818b99f1dd6700c276511fcc0Robert Greenwalt if(ifc_get_info(name, &addr, &prefixLength, &flags)) { 58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project printf("%-8s %s ", name, flags & 1 ? "UP " : "DOWN"); 62177ca7cd76a9245818b99f1dd6700c276511fcc0Robert Greenwalt printf("%40s", ipaddr(addr)); 63177ca7cd76a9245818b99f1dd6700c276511fcc0Robert Greenwalt printf("/%-4d", prefixLength); 6497186a9c3d1874ac79f94676dc9f0df1f0815e1fDmitry Shmidt printf("0x%08x ", flags); 6597186a9c3d1874ac79f94676dc9f0df1f0815e1fDmitry Shmidt if (!ifc_get_hwaddr(name, hwbuf)) { 6697186a9c3d1874ac79f94676dc9f0df1f0815e1fDmitry Shmidt int i; 6797186a9c3d1874ac79f94676dc9f0df1f0815e1fDmitry Shmidt for(i=0; i < (ETH_ALEN-1); i++) 6897186a9c3d1874ac79f94676dc9f0df1f0815e1fDmitry Shmidt printf("%02x:", hwbuf[i]); 6997186a9c3d1874ac79f94676dc9f0df1f0815e1fDmitry Shmidt printf("%02x\n", hwbuf[i]); 7097186a9c3d1874ac79f94676dc9f0df1f0815e1fDmitry Shmidt } else { 7197186a9c3d1874ac79f94676dc9f0df1f0815e1fDmitry Shmidt printf("\n"); 7297186a9c3d1874ac79f94676dc9f0df1f0815e1fDmitry Shmidt } 73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint dump_interfaces(void) 77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project DIR *d; 79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct dirent *de; 8097186a9c3d1874ac79f94676dc9f0df1f0815e1fDmitry Shmidt 81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project d = opendir("/sys/class/net"); 82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(d == 0) return -1; 8397186a9c3d1874ac79f94676dc9f0df1f0815e1fDmitry Shmidt 84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while((de = readdir(d))) { 85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(de->d_name[0] == '.') continue; 86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dump_interface(de->d_name); 87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project closedir(d); 89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 928c85a00db6da092ec3766facd49132fa4fc319a1Szymon Jakubczakint set_hwaddr(const char *name, const char *asc) { 938c85a00db6da092ec3766facd49132fa4fc319a1Szymon Jakubczak struct ether_addr *addr = ether_aton(asc); 948c85a00db6da092ec3766facd49132fa4fc319a1Szymon Jakubczak if (!addr) { 958c85a00db6da092ec3766facd49132fa4fc319a1Szymon Jakubczak printf("Failed to parse '%s'\n", asc); 968c85a00db6da092ec3766facd49132fa4fc319a1Szymon Jakubczak return -1; 978c85a00db6da092ec3766facd49132fa4fc319a1Szymon Jakubczak } 988c85a00db6da092ec3766facd49132fa4fc319a1Szymon Jakubczak return ifc_set_hwaddr(name, addr->ether_addr_octet); 998c85a00db6da092ec3766facd49132fa4fc319a1Szymon Jakubczak} 1008c85a00db6da092ec3766facd49132fa4fc319a1Szymon Jakubczak 101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct 102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const char *name; 104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int nargs; 105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project void *func; 106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} CMDS[] = { 107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { "dhcp", 1, do_dhcp }, 108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { "up", 1, ifc_up }, 109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { "down", 1, ifc_down }, 110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { "flhosts", 1, ifc_remove_host_routes }, 111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { "deldefault", 1, ifc_remove_default_route }, 1128c85a00db6da092ec3766facd49132fa4fc319a1Szymon Jakubczak { "hwaddr", 2, set_hwaddr }, 113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { 0, 0, 0 }, 114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}; 115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int call_func(void *_func, unsigned nargs, char **args) 117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project switch(nargs){ 119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 1: { 120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int (*func)(char *a0) = _func; 121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return func(args[0]); 122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 2: { 124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int (*func)(char *a0, char *a1) = _func; 125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return func(args[0], args[1]); 126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 3: { 128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int (*func)(char *a0, char *a1, char *a2) = _func; 129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return func(args[0], args[1], args[2]); 130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project default: 132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint main(int argc, char **argv) 137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *iname; 139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int n; 140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(ifc_init()) { 142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project die("Cannot perform requested operation"); 143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(argc == 1) { 146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int result = dump_interfaces(); 147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ifc_close(); 148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return result; 149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(argc < 3) usage(); 152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project iname = argv[1]; 154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(strlen(iname) > 16) usage(); 155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project argc -= 2; 157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project argv += 2; 158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while(argc > 0) { 159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for(n = 0; CMDS[n].name; n++){ 160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(!strcmp(argv[0], CMDS[n].name)) { 161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *cmdname = argv[0]; 162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int nargs = CMDS[n].nargs; 163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project argv[0] = iname; 165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(argc < nargs) { 166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr, "not enough arguments for '%s'\n", cmdname); 167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ifc_close(); 168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(1); 169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(call_func(CMDS[n].func, nargs, argv)) { 171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr, "action '%s' failed (%s)\n", cmdname, strerror(errno)); 172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ifc_close(); 173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(1); 174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project argc -= nargs; 176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project argv += nargs; 177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto done; 178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"no such action '%s'\n", argv[0]); 181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project usage(); 182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project done: 183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ; 184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ifc_close(); 186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 189