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