1f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project/* 2f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * dhcpcd - DHCP client daemon 3a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt * Copyright (c) 2006-2012 Roy Marples <roy@marples.name> 4f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * All rights reserved 5f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 6f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * Redistribution and use in source and binary forms, with or without 7f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * modification, are permitted provided that the following conditions 8f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * are met: 9f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * 1. Redistributions of source code must retain the above copyright 10f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * notice, this list of conditions and the following disclaimer. 11f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright 12f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * notice, this list of conditions and the following disclaimer in the 13f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * documentation and/or other materials provided with the distribution. 14f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * 15f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * SUCH DAMAGE. 26f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project */ 27f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 28f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#include <sys/ioctl.h> 29f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#include <sys/param.h> 30e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <sys/socket.h> 31e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <sys/stat.h> 32e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <sys/sysctl.h> 33e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <sys/types.h> 34f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 35f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#include <arpa/inet.h> 36e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <net/if.h> 37f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#include <net/if_dl.h> 38f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#include <net/route.h> 39f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#include <netinet/in.h> 40e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#ifdef __DragonFly__ 41e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt# include <netproto/802_11/ieee80211_ioctl.h> 42e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#elif __APPLE__ 43e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt /* FIXME: Add apple includes so we can work out SSID */ 44e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#else 45e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt# include <net80211/ieee80211_ioctl.h> 46e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#endif 47f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 48f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#include <errno.h> 49e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <fnmatch.h> 50f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#include <stddef.h> 51f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#include <stdio.h> 52f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#include <stdlib.h> 53f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#include <string.h> 54e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <syslog.h> 55f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#include <unistd.h> 56f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 57f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#include "config.h" 58f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#include "common.h" 59e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "configure.h" 60f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#include "dhcp.h" 61e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "if-options.h" 62f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#include "net.h" 63f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 64a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt#ifndef RT_ROUNDUP 65a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt#define RT_ROUNDUP(a) \ 66e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) 67a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt#define RT_ADVANCE(x, n) (x += RT_ROUNDUP((n)->sa_len)) 68a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt#endif 69e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 70e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt/* FIXME: Why do we need to check for sa_family 255 */ 71e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#define COPYOUT(sin, sa) \ 72e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt sin.s_addr = ((sa) != NULL) ? \ 73e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt (((struct sockaddr_in *)(void *)sa)->sin_addr).s_addr : 0 74e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 75e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtstatic int r_fd = -1; 76e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtstatic char *link_buf; 77e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtstatic ssize_t link_buflen; 78e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 79e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtint 80e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtif_init(_unused struct interface *iface) 81e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{ 82e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt /* BSD promotes secondary address by default */ 83e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return 0; 84e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt} 85e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 86e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtint 87e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtif_conf(_unused struct interface *iface) 88e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{ 89e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt /* No extra checks needed on BSD */ 90e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return 0; 91e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt} 92e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 93a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt#ifdef DEBUG_MEMORY 94a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidtstatic void 95a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidtcleanup(void) 96a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt{ 97a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt 98a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt free(link_buf); 99a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt} 100a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt#endif 101a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt 102e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtint 103e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtinit_sockets(void) 104e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{ 105e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if ((socket_afnet = socket(AF_INET, SOCK_DGRAM, 0)) == -1) 106e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return -1; 107e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt set_cloexec(socket_afnet); 108e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if ((r_fd = socket(PF_ROUTE, SOCK_RAW, 0)) == -1) 109e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return -1; 110e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt set_cloexec(r_fd); 111e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return 0; 112e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt} 113e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 114e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtint 115e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtgetifssid(const char *ifname, char *ssid) 116e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{ 117e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt int retval = -1; 118e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#if defined(SIOCG80211NWID) 119e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt struct ifreq ifr; 120e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt struct ieee80211_nwid nwid; 121e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#elif defined(IEEE80211_IOC_SSID) 122e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt struct ieee80211req ireq; 123e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt char nwid[IEEE80211_NWID_LEN + 1]; 124f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#endif 125f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 126e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#if defined(SIOCG80211NWID) /* NetBSD */ 127e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt memset(&ifr, 0, sizeof(ifr)); 128e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); 129e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt memset(&nwid, 0, sizeof(nwid)); 130e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifr.ifr_data = (void *)&nwid; 131e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (ioctl(socket_afnet, SIOCG80211NWID, &ifr) == 0) { 132e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt retval = nwid.i_len; 133e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt memcpy(ssid, nwid.i_nwid, nwid.i_len); 134e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ssid[nwid.i_len] = '\0'; 135e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 136e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#elif defined(IEEE80211_IOC_SSID) /* FreeBSD */ 137e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt memset(&ireq, 0, sizeof(ireq)); 138e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt strlcpy(ireq.i_name, ifname, sizeof(ireq.i_name)); 139e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ireq.i_type = IEEE80211_IOC_SSID; 140e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ireq.i_val = -1; 141a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt memset(nwid, 0, sizeof(nwid)); 142e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ireq.i_data = &nwid; 143e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (ioctl(socket_afnet, SIOCG80211, &ireq) == 0) { 144e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt retval = ireq.i_len; 145e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt memcpy(ssid, nwid, ireq.i_len); 146e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ssid[ireq.i_len] = '\0'; 147e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 148e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#endif 149e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return retval; 150e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt} 151e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 152f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Projectint 153e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtif_address(const struct interface *iface, const struct in_addr *address, 154e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt const struct in_addr *netmask, const struct in_addr *broadcast, 155e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt int action) 156f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project{ 157f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project int retval; 158f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project struct ifaliasreq ifa; 159f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project union { 160f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project struct sockaddr *sa; 161f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project struct sockaddr_in *sin; 162f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project } _s; 163f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 164f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project memset(&ifa, 0, sizeof(ifa)); 165e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt strlcpy(ifa.ifra_name, iface->name, sizeof(ifa.ifra_name)); 166f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 167e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#define ADDADDR(_var, _addr) { \ 168e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt _s.sa = &_var; \ 169e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt _s.sin->sin_family = AF_INET; \ 170e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt _s.sin->sin_len = sizeof(*_s.sin); \ 171e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt memcpy(&_s.sin->sin_addr, _addr, sizeof(_s.sin->sin_addr)); \ 172e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 173f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 174f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project ADDADDR(ifa.ifra_addr, address); 175f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project ADDADDR(ifa.ifra_mask, netmask); 176e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (action >= 0 && broadcast) { 177f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project ADDADDR(ifa.ifra_broadaddr, broadcast); 178f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project } 179f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#undef ADDADDR 180f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 181f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project if (action < 0) 182e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt retval = ioctl(socket_afnet, SIOCDIFADDR, &ifa); 183f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project else 184e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt retval = ioctl(socket_afnet, SIOCAIFADDR, &ifa); 185f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project return retval; 186f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project} 187f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 188e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt/* ARGSUSED4 */ 189f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Projectint 190a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidtif_route(const struct rt *rt, int action) 191f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project{ 192f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project union sockunion { 193f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project struct sockaddr sa; 194f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project struct sockaddr_in sin; 195f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#ifdef INET6 196f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project struct sockaddr_in6 sin6; 197f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#endif 198f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project struct sockaddr_dl sdl; 199f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project struct sockaddr_storage ss; 200f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project } su; 201f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project struct rtm 202f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project { 203f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project struct rt_msghdr hdr; 204938bc384f44031877543765a9ae18c764f5da9c8Dmitry Shmidt char buffer[sizeof(su) * 4]; 205f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project } rtm; 206a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt char *bp = rtm.buffer; 207f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project size_t l; 208f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project int retval = 0; 209f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 210e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#define ADDSU(_su) { \ 211a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt l = RT_ROUNDUP(_su.sa.sa_len); \ 212e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt memcpy(bp, &(_su), l); \ 213e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt bp += l; \ 214e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 215e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#define ADDADDR(_a) { \ 216e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt memset (&su, 0, sizeof(su)); \ 217e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt su.sin.sin_family = AF_INET; \ 218e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt su.sin.sin_len = sizeof(su.sin); \ 219e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt memcpy (&su.sin.sin_addr, _a, sizeof(su.sin.sin_addr)); \ 220e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ADDSU(su); \ 221e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 222f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 223f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project memset(&rtm, 0, sizeof(rtm)); 224f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project rtm.hdr.rtm_version = RTM_VERSION; 225938bc384f44031877543765a9ae18c764f5da9c8Dmitry Shmidt rtm.hdr.rtm_seq = 1; 226f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project if (action == 0) 227f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project rtm.hdr.rtm_type = RTM_CHANGE; 228f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project else if (action > 0) 229f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project rtm.hdr.rtm_type = RTM_ADD; 230f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project else 231f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project rtm.hdr.rtm_type = RTM_DELETE; 232938bc384f44031877543765a9ae18c764f5da9c8Dmitry Shmidt rtm.hdr.rtm_flags = RTF_UP; 233938bc384f44031877543765a9ae18c764f5da9c8Dmitry Shmidt /* None interface subnet routes are static. */ 234a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt if (rt->gate.s_addr != INADDR_ANY || 235a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt rt->net.s_addr != rt->iface->net.s_addr || 236a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt rt->dest.s_addr != (rt->iface->addr.s_addr & rt->iface->net.s_addr)) 237938bc384f44031877543765a9ae18c764f5da9c8Dmitry Shmidt rtm.hdr.rtm_flags |= RTF_STATIC; 238938bc384f44031877543765a9ae18c764f5da9c8Dmitry Shmidt rtm.hdr.rtm_addrs = RTA_DST | RTA_GATEWAY; 239a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt if (rt->dest.s_addr == rt->gate.s_addr && 240a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt rt->net.s_addr == INADDR_BROADCAST) 241f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project rtm.hdr.rtm_flags |= RTF_HOST; 242938bc384f44031877543765a9ae18c764f5da9c8Dmitry Shmidt else { 243938bc384f44031877543765a9ae18c764f5da9c8Dmitry Shmidt rtm.hdr.rtm_addrs |= RTA_NETMASK; 244938bc384f44031877543765a9ae18c764f5da9c8Dmitry Shmidt if (rtm.hdr.rtm_flags & RTF_STATIC) 245938bc384f44031877543765a9ae18c764f5da9c8Dmitry Shmidt rtm.hdr.rtm_flags |= RTF_GATEWAY; 246938bc384f44031877543765a9ae18c764f5da9c8Dmitry Shmidt if (action >= 0) 247938bc384f44031877543765a9ae18c764f5da9c8Dmitry Shmidt rtm.hdr.rtm_addrs |= RTA_IFA; 248938bc384f44031877543765a9ae18c764f5da9c8Dmitry Shmidt } 249f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 250a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt ADDADDR(&rt->dest); 251938bc384f44031877543765a9ae18c764f5da9c8Dmitry Shmidt if (rtm.hdr.rtm_flags & RTF_HOST || 252938bc384f44031877543765a9ae18c764f5da9c8Dmitry Shmidt !(rtm.hdr.rtm_flags & RTF_STATIC)) 253938bc384f44031877543765a9ae18c764f5da9c8Dmitry Shmidt { 254938bc384f44031877543765a9ae18c764f5da9c8Dmitry Shmidt /* Make us a link layer socket for the host gateway */ 255f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project memset(&su, 0, sizeof(su)); 256938bc384f44031877543765a9ae18c764f5da9c8Dmitry Shmidt su.sdl.sdl_len = sizeof(struct sockaddr_dl); 257a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt link_addr(rt->iface->name, &su.sdl); 258938bc384f44031877543765a9ae18c764f5da9c8Dmitry Shmidt ADDSU(su); 259938bc384f44031877543765a9ae18c764f5da9c8Dmitry Shmidt } else 260a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt ADDADDR(&rt->gate); 261938bc384f44031877543765a9ae18c764f5da9c8Dmitry Shmidt 262a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt if (rtm.hdr.rtm_addrs & RTA_NETMASK) 263a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt ADDADDR(&rt->net); 264f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 265938bc384f44031877543765a9ae18c764f5da9c8Dmitry Shmidt if (rtm.hdr.rtm_addrs & RTA_IFA) 266a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt ADDADDR(&rt->iface->addr); 267f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 268f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project rtm.hdr.rtm_msglen = l = bp - (char *)&rtm; 269e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (write(r_fd, &rtm, l) == -1) 270f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project retval = -1; 271f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project return retval; 272f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project} 273f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 274f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Projectint 275e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtopen_link_socket(void) 276f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project{ 277f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project int fd; 278f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 279a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt#ifdef DEBUG_MEMORY 280a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt if (link_buf == NULL) 281a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt atexit(cleanup); 282a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt#endif 283a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt 284f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project fd = socket(PF_ROUTE, SOCK_RAW, 0); 285e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (fd != -1) { 286e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt set_cloexec(fd); 287e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt set_nonblock(fd); 288e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 289e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return fd; 290e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt} 291e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 292e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtstatic void 293e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtget_addrs(int type, char *cp, struct sockaddr **sa) 294e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{ 295e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt int i; 296e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 297e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt for (i = 0; i < RTAX_MAX; i++) { 298e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (type & (1 << i)) { 299e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt sa[i] = (struct sockaddr *)cp; 300e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#ifdef DEBUG 301e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt printf ("got %d %d %s\n", i, sa[i]->sa_family, 302e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt inet_ntoa(((struct sockaddr_in *)sa[i])-> 303e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt sin_addr)); 304e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#endif 305a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt RT_ADVANCE(cp, sa[i]); 306e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } else 307e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt sa[i] = NULL; 308e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 309f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project} 310f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 311f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Projectint 312e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtmanage_link(int fd) 313f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project{ 314e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt char *p, *e, *cp; 315e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt char ifname[IF_NAMESIZE]; 316f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project ssize_t bytes; 317f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project struct rt_msghdr *rtm; 318e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt struct if_announcemsghdr *ifan; 319f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project struct if_msghdr *ifm; 320e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt struct ifa_msghdr *ifam; 321e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt struct rt rt; 322e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt struct sockaddr *sa, *rti_info[RTAX_MAX]; 323e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt int len; 324e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#ifdef RTM_CHGADDR 325e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt struct sockaddr_dl sdl; 326e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt unsigned char *hwaddr; 327e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#endif 328f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project 329f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project for (;;) { 330e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (ioctl(fd, FIONREAD, &len) == -1) 331e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return -1; 332e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (link_buflen < len) { 333e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt p = realloc(link_buf, len); 334e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (p == NULL) 335e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return -1; 336e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt link_buf = p; 337e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt link_buflen = len; 338e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 339e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt bytes = read(fd, link_buf, link_buflen); 340f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project if (bytes == -1) { 341f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project if (errno == EAGAIN) 342f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project return 0; 343f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project if (errno == EINTR) 344f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project continue; 345f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project return -1; 346f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project } 347e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt e = link_buf + bytes; 348e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt for (p = link_buf; p < e; p += rtm->rtm_msglen) { 349e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt rtm = (struct rt_msghdr *)(void *)p; 350e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt switch(rtm->rtm_type) { 351e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#ifdef RTM_IFANNOUNCE 352e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case RTM_IFANNOUNCE: 353e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifan = (struct if_announcemsghdr *)(void *)p; 354e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt switch(ifan->ifan_what) { 355e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case IFAN_ARRIVAL: 356e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt handle_interface(1, ifan->ifan_name); 357e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 358e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case IFAN_DEPARTURE: 359e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt handle_interface(-1, ifan->ifan_name); 360e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 361e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 362e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 363e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#endif 364e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case RTM_IFINFO: 365e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifm = (struct if_msghdr *)(void *)p; 366e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt memset(ifname, 0, sizeof(ifname)); 367a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt if (!(if_indextoname(ifm->ifm_index, ifname))) 368a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt break; 369a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt switch (ifm->ifm_data.ifi_link_state) { 370a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt case LINK_STATE_DOWN: 371a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt len = -1; 372a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt break; 373a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt case LINK_STATE_UP: 374a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt len = 1; 375a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt break; 376a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt default: 377a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt /* handle_carrier will re-load 378a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt * the interface flags and check for 379a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt * IFF_RUNNING as some drivers that 380a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt * don't handle link state also don't 381a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt * set IFF_RUNNING when this routing 382a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt * message is generated. 383a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt * As such, it is a race ...*/ 384a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt len = 0; 385a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt break; 386a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt } 387a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt handle_carrier(len, ifm->ifm_flags, ifname); 388e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 389e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case RTM_DELETE: 390a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt if (~rtm->rtm_addrs & 391a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt (RTA_DST | RTA_GATEWAY | RTA_NETMASK)) 392e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 393e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (rtm->rtm_pid == getpid()) 394e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 395e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt cp = (char *)(void *)(rtm + 1); 396e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt sa = (struct sockaddr *)(void *)cp; 397e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (sa->sa_family != AF_INET) 398e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 399e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt get_addrs(rtm->rtm_addrs, cp, rti_info); 400e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt rt.iface = NULL; 401e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt rt.next = NULL; 402e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt COPYOUT(rt.dest, rti_info[RTAX_DST]); 403e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt COPYOUT(rt.net, rti_info[RTAX_NETMASK]); 404e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt COPYOUT(rt.gate, rti_info[RTAX_GATEWAY]); 405e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt route_deleted(&rt); 406e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 407e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#ifdef RTM_CHGADDR 408e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case RTM_CHGADDR: /* FALLTHROUGH */ 409e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#endif 410e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case RTM_DELADDR: /* FALLTHROUGH */ 411e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case RTM_NEWADDR: 412e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ifam = (struct ifa_msghdr *)(void *)p; 413e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (!if_indextoname(ifam->ifam_index, ifname)) 414e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 415e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt cp = (char *)(void *)(ifam + 1); 416e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt get_addrs(ifam->ifam_addrs, cp, rti_info); 417e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (rti_info[RTAX_IFA] == NULL) 418e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 419e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt switch (rti_info[RTAX_IFA]->sa_family) { 420e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#ifdef RTM_CHGADDR 421e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case AF_LINK: 422e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (rtm->rtm_type != RTM_CHGADDR) 423e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 424e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt memcpy(&sdl, rti_info[RTAX_IFA], 425e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt rti_info[RTAX_IFA]->sa_len); 426e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt hwaddr = xmalloc(sdl.sdl_alen); 427e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt memcpy(hwaddr, LLADDR(&sdl), 428e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt sdl.sdl_alen); 429e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt handle_hwaddr(ifname, hwaddr, 430e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt sdl.sdl_alen); 431e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 432e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#endif 433e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case AF_INET: 434e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case 255: /* FIXME: Why 255? */ 435e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt COPYOUT(rt.dest, rti_info[RTAX_IFA]); 436e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt COPYOUT(rt.net, rti_info[RTAX_NETMASK]); 437e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt COPYOUT(rt.gate, rti_info[RTAX_BRD]); 438e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt handle_ifa(rtm->rtm_type, ifname, 439e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt &rt.dest, &rt.net, &rt.gate); 440e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 441e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 442e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 443e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 444f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project } 445f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project } 446f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project} 447