ifc_utils.c revision dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0
1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Copyright 2008, The Android Open Source Project 3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * you may not use this file except in compliance with the License. 6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * You may obtain a copy of the License at 7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * See the License for the specific language governing permissions and 14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * limitations under the License. 15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdio.h> 18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdlib.h> 19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <unistd.h> 20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <string.h> 21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <errno.h> 22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/socket.h> 24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/select.h> 25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/types.h> 26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <netinet/in.h> 27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <arpa/inet.h> 28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <linux/if.h> 30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <linux/sockios.h> 31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <linux/route.h> 32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <linux/wireless.h> 33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef ANDROID 35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define LOG_TAG "NetUtils" 36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <cutils/log.h> 37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <cutils/properties.h> 38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else 39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdio.h> 40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <string.h> 41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define LOGD printf 42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define LOGW printf 43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int ifc_ctl_sock = -1; 46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid printerr(char *fmt, ...); 47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic const char *ipaddr_to_string(uint32_t addr) 49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct in_addr in_addr; 51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project in_addr.s_addr = addr; 53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return inet_ntoa(in_addr); 54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint ifc_init(void) 57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ifc_ctl_sock == -1) { 59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ifc_ctl_sock = socket(AF_INET, SOCK_DGRAM, 0); 60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ifc_ctl_sock < 0) { 61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project printerr("socket() failed: %s\n", strerror(errno)); 62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return ifc_ctl_sock < 0 ? -1 : 0; 65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid ifc_close(void) 68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ifc_ctl_sock != -1) { 70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project (void)close(ifc_ctl_sock); 71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ifc_ctl_sock = -1; 72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void ifc_init_ifr(const char *name, struct ifreq *ifr) 76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memset(ifr, 0, sizeof(struct ifreq)); 78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strncpy(ifr->ifr_name, name, IFNAMSIZ); 79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ifr->ifr_name[IFNAMSIZ - 1] = 0; 80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint ifc_get_hwaddr(const char *name, void *ptr) 83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int r; 85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct ifreq ifr; 86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ifc_init_ifr(name, &ifr); 87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project r = ioctl(ifc_ctl_sock, SIOCGIFHWADDR, &ifr); 89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(r < 0) return -1; 90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memcpy(ptr, &ifr.ifr_hwaddr.sa_data, 6); 92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint ifc_get_ifindex(const char *name, int *if_indexp) 96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int r; 98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct ifreq ifr; 99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ifc_init_ifr(name, &ifr); 100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project r = ioctl(ifc_ctl_sock, SIOCGIFINDEX, &ifr); 102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(r < 0) return -1; 103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *if_indexp = ifr.ifr_ifindex; 105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int ifc_set_flags(const char *name, unsigned set, unsigned clr) 109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct ifreq ifr; 111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ifc_init_ifr(name, &ifr); 112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(ioctl(ifc_ctl_sock, SIOCGIFFLAGS, &ifr) < 0) return -1; 114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ifr.ifr_flags = (ifr.ifr_flags & (~clr)) | set; 115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return ioctl(ifc_ctl_sock, SIOCSIFFLAGS, &ifr); 116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint ifc_up(const char *name) 119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return ifc_set_flags(name, IFF_UP, 0); 121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint ifc_down(const char *name) 124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return ifc_set_flags(name, 0, IFF_UP); 126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void init_sockaddr_in(struct sockaddr *sa, in_addr_t addr) 129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct sockaddr_in *sin = (struct sockaddr_in *) sa; 131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sin->sin_family = AF_INET; 132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sin->sin_port = 0; 133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sin->sin_addr.s_addr = addr; 134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint ifc_set_addr(const char *name, in_addr_t addr) 137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct ifreq ifr; 139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ifc_init_ifr(name, &ifr); 141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project init_sockaddr_in(&ifr.ifr_addr, addr); 142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return ioctl(ifc_ctl_sock, SIOCSIFADDR, &ifr); 144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint ifc_set_mask(const char *name, in_addr_t mask) 147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct ifreq ifr; 149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ifc_init_ifr(name, &ifr); 151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project init_sockaddr_in(&ifr.ifr_addr, mask); 152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return ioctl(ifc_ctl_sock, SIOCSIFNETMASK, &ifr); 154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint ifc_get_info(const char *name, in_addr_t *addr, in_addr_t *mask, unsigned *flags) 157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct ifreq ifr; 159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ifc_init_ifr(name, &ifr); 160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (addr != NULL) { 162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(ioctl(ifc_ctl_sock, SIOCGIFADDR, &ifr) < 0) { 163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *addr = 0; 164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *addr = ((struct sockaddr_in*) &ifr.ifr_addr)->sin_addr.s_addr; 166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (mask != NULL) { 170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(ioctl(ifc_ctl_sock, SIOCGIFNETMASK, &ifr) < 0) { 171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *mask = 0; 172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *mask = ((struct sockaddr_in*) &ifr.ifr_addr)->sin_addr.s_addr; 174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (flags != NULL) { 178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(ioctl(ifc_ctl_sock, SIOCGIFFLAGS, &ifr) < 0) { 179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *flags = 0; 180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *flags = ifr.ifr_flags; 182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint ifc_create_default_route(const char *name, in_addr_t addr) 190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct rtentry rt; 192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memset(&rt, 0, sizeof(rt)); 194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project rt.rt_dst.sa_family = AF_INET; 196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project rt.rt_flags = RTF_UP | RTF_GATEWAY; 197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project rt.rt_dev = (void*) name; 198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project init_sockaddr_in(&rt.rt_genmask, 0); 199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project init_sockaddr_in(&rt.rt_gateway, addr); 200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return ioctl(ifc_ctl_sock, SIOCADDRT, &rt); 202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint ifc_add_host_route(const char *name, in_addr_t addr) 205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct rtentry rt; 207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int result; 208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memset(&rt, 0, sizeof(rt)); 210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project rt.rt_dst.sa_family = AF_INET; 212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project rt.rt_flags = RTF_UP | RTF_HOST; 213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project rt.rt_dev = (void*) name; 214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project init_sockaddr_in(&rt.rt_dst, addr); 215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project init_sockaddr_in(&rt.rt_genmask, 0); 216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project init_sockaddr_in(&rt.rt_gateway, 0); 217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ifc_init(); 219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project result = ioctl(ifc_ctl_sock, SIOCADDRT, &rt); 220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (result < 0 && errno == EEXIST) { 221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project result = 0; 222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ifc_close(); 224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return result; 225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint ifc_disable(const char *ifname) 228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int result; 230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ifc_init(); 232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project result = ifc_down(ifname); 233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ifc_set_addr(ifname, 0); 234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ifc_close(); 235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return result; 236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint ifc_reset_connections(const char *ifname) 239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef HAVE_ANDROID_OS 241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int result; 242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project in_addr_t myaddr; 243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct ifreq ifr; 244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ifc_init(); 246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ifc_get_info(ifname, &myaddr, NULL, NULL); 247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ifc_init_ifr(ifname, &ifr); 248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project init_sockaddr_in(&ifr.ifr_addr, myaddr); 249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project result = ioctl(ifc_ctl_sock, SIOCKILLADDR, &ifr); 250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ifc_close(); 251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return result; 253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else 254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Remove the routes associated with the named interface. 260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint ifc_remove_host_routes(const char *name) 262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char ifname[64]; 264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project in_addr_t dest, gway, mask; 265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int flags, refcnt, use, metric, mtu, win, irtt; 266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct rtentry rt; 267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project FILE *fp; 268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct in_addr addr; 269dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fp = fopen("/proc/net/route", "r"); 271dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fp == NULL) 272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* Skip the header line */ 274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fscanf(fp, "%*[^\n]\n") < 0) { 275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fclose(fp); 276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 277dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ifc_init(); 279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (;;) { 280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int nread = fscanf(fp, "%63s%X%X%X%d%d%d%X%d%d%d\n", 281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ifname, &dest, &gway, &flags, &refcnt, &use, &metric, &mask, 282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project &mtu, &win, &irtt); 283dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (nread != 11) { 284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((flags & (RTF_UP|RTF_HOST)) != (RTF_UP|RTF_HOST) 287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project || strcmp(ifname, name) != 0) { 288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memset(&rt, 0, sizeof(rt)); 291dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project rt.rt_dev = (void *)name; 292dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project init_sockaddr_in(&rt.rt_dst, dest); 293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project init_sockaddr_in(&rt.rt_gateway, gway); 294dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project init_sockaddr_in(&rt.rt_genmask, mask); 295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project addr.s_addr = dest; 296dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ioctl(ifc_ctl_sock, SIOCDELRT, &rt) < 0) { 297dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project LOGD("failed to remove route for %s to %s: %s", 298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ifname, inet_ntoa(addr), strerror(errno)); 299dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 301dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fclose(fp); 302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ifc_close(); 303dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 304dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 306dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 307dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Return the address of the default gateway 308dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 309dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * TODO: factor out common code from this and remove_host_routes() 310dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * so that we only scan /proc/net/route in one place. 311dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 312dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint ifc_get_default_route(const char *ifname) 313dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 314dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char name[64]; 315dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project in_addr_t dest, gway, mask; 316dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int flags, refcnt, use, metric, mtu, win, irtt; 317dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int result; 318dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project FILE *fp; 319dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 320dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fp = fopen("/proc/net/route", "r"); 321dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fp == NULL) 322dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 323dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* Skip the header line */ 324dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fscanf(fp, "%*[^\n]\n") < 0) { 325dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fclose(fp); 326dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 327dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 328dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ifc_init(); 329dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project result = 0; 330dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (;;) { 331dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int nread = fscanf(fp, "%63s%X%X%X%d%d%d%X%d%d%d\n", 332dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project name, &dest, &gway, &flags, &refcnt, &use, &metric, &mask, 333dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project &mtu, &win, &irtt); 334dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (nread != 11) { 335dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 336dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 337dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((flags & (RTF_UP|RTF_GATEWAY)) == (RTF_UP|RTF_GATEWAY) 338dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project && dest == 0 339dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project && strcmp(ifname, name) == 0) { 340dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project result = gway; 341dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 342dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 343dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 344dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fclose(fp); 345dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ifc_close(); 346dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return result; 347dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 348dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 349dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 350dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Sets the specified gateway as the default route for the named interface. 351dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 352dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint ifc_set_default_route(const char *ifname, in_addr_t gateway) 353dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 354dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct in_addr addr; 355dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int result; 356dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 357dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ifc_init(); 358dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project addr.s_addr = gateway; 359dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((result = ifc_create_default_route(ifname, gateway)) < 0) { 360dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project LOGD("failed to add %s as default route for %s: %s", 361dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project inet_ntoa(addr), ifname, strerror(errno)); 362dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 363dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ifc_close(); 364dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return result; 365dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 366dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 367dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 368dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Removes the default route for the named interface. 369dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 370dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint ifc_remove_default_route(const char *ifname) 371dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 372dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct rtentry rt; 373dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int result; 374dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 375dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ifc_init(); 376dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memset(&rt, 0, sizeof(rt)); 377dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project rt.rt_dev = (void *)ifname; 378dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project rt.rt_flags = RTF_UP|RTF_GATEWAY; 379dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project init_sockaddr_in(&rt.rt_dst, 0); 380dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((result = ioctl(ifc_ctl_sock, SIOCDELRT, &rt)) < 0) { 381dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project LOGD("failed to remove default route for %s: %s", ifname, strerror(errno)); 382dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 383dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ifc_close(); 384dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return result; 385dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 386dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 387dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint 388dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectifc_configure(const char *ifname, 389dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project in_addr_t address, 390dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project in_addr_t netmask, 391dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project in_addr_t gateway, 392dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project in_addr_t dns1, 393dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project in_addr_t dns2) { 394dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 395dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char dns_prop_name[PROPERTY_KEY_MAX]; 396dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 397dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ifc_init(); 398dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 399dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ifc_up(ifname)) { 400dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project printerr("failed to turn on interface %s: %s\n", ifname, strerror(errno)); 401dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ifc_close(); 402dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 403dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 404dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ifc_set_addr(ifname, address)) { 405dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project printerr("failed to set ipaddr %s: %s\n", ipaddr_to_string(address), strerror(errno)); 406dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ifc_close(); 407dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 408dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 409dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ifc_set_mask(ifname, netmask)) { 410dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project printerr("failed to set netmask %s: %s\n", ipaddr_to_string(netmask), strerror(errno)); 411dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ifc_close(); 412dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 413dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 414dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ifc_create_default_route(ifname, gateway)) { 415dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project printerr("failed to set default route %s: %s\n", ipaddr_to_string(gateway), strerror(errno)); 416dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ifc_close(); 417dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 418dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 419dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 420dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ifc_close(); 421dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 422dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project snprintf(dns_prop_name, sizeof(dns_prop_name), "dhcp.%s.dns1", ifname); 423dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project property_set(dns_prop_name, dns1 ? ipaddr_to_string(dns1) : ""); 424dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project snprintf(dns_prop_name, sizeof(dns_prop_name), "dhcp.%s.dns2", ifname); 425dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project property_set(dns_prop_name, dns2 ? ipaddr_to_string(dns2) : ""); 426dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 427dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 428dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 429