1845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/* 2845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * WPA Supplicant - wired Ethernet driver interface 3845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Copyright (c) 2005-2007, Jouni Malinen <j@w1.fi> 4845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * 5845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * This program is free software; you can redistribute it and/or modify 6845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * it under the terms of the GNU General Public License version 2 as 7845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * published by the Free Software Foundation. 8845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * 9845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Alternatively, this software may be distributed under the terms of BSD 10845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * license. 11845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * 12845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * See README and COPYING for more details. 13845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 14845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 15845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#include "includes.h" 16845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#include <sys/ioctl.h> 17845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#include <net/if.h> 18845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#ifdef __linux__ 19845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#include <netpacket/packet.h> 20845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#endif /* __linux__ */ 21845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#ifdef __FreeBSD__ 22845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#include <net/if_dl.h> 23845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#endif /* __FreeBSD__ */ 24845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 25845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#include "common.h" 26845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#include "driver.h" 27845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#include "wpa_supplicant.h" 28845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 29845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 30845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic const u8 pae_group_addr[ETH_ALEN] = 31845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 0x01, 0x80, 0xc2, 0x00, 0x00, 0x03 }; 32845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 33845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 34845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstruct wpa_driver_wired_data { 35845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project void *ctx; 36845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project int pf_sock; 37845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project char ifname[IFNAMSIZ + 1]; 38845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project int membership, multi, iff_allmulti, iff_up; 39845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project}; 40845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 41845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 42845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic int wpa_driver_wired_get_ssid(void *priv, u8 *ssid) 43845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 44845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project ssid[0] = 0; 45845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return 0; 46845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 47845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 48845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 49845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic int wpa_driver_wired_get_bssid(void *priv, u8 *bssid) 50845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 51845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project /* Report PAE group address as the "BSSID" for wired connection. */ 52845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memcpy(bssid, pae_group_addr, ETH_ALEN); 53845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return 0; 54845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 55845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 56845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 57845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic int wpa_driver_wired_get_ifflags(const char *ifname, int *flags) 58845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 59845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct ifreq ifr; 60845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project int s; 61845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 62845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project s = socket(PF_INET, SOCK_DGRAM, 0); 63845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (s < 0) { 64845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project perror("socket"); 65845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 66845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 67845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 68845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memset(&ifr, 0, sizeof(ifr)); 69845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_strncpy(ifr.ifr_name, ifname, IFNAMSIZ); 70845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) { 71845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project perror("ioctl[SIOCGIFFLAGS]"); 72845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project close(s); 73845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 74845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 75845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project close(s); 76845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *flags = ifr.ifr_flags & 0xffff; 77845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return 0; 78845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 79845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 80845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 81845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic int wpa_driver_wired_set_ifflags(const char *ifname, int flags) 82845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 83845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct ifreq ifr; 84845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project int s; 85845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 86845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project s = socket(PF_INET, SOCK_DGRAM, 0); 87845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (s < 0) { 88845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project perror("socket"); 89845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 90845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 91845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 92845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memset(&ifr, 0, sizeof(ifr)); 93845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_strncpy(ifr.ifr_name, ifname, IFNAMSIZ); 94845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project ifr.ifr_flags = flags & 0xffff; 95845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (ioctl(s, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) { 96845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project perror("ioctl[SIOCSIFFLAGS]"); 97845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project close(s); 98845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 99845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 100845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project close(s); 101845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return 0; 102845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 103845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 104845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 105845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic int wpa_driver_wired_multi(const char *ifname, const u8 *addr, int add) 106845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 107845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct ifreq ifr; 108845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project int s; 109845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 110845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project s = socket(PF_INET, SOCK_DGRAM, 0); 111845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (s < 0) { 112845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project perror("socket"); 113845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 114845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 115845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 116845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memset(&ifr, 0, sizeof(ifr)); 117845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_strncpy(ifr.ifr_name, ifname, IFNAMSIZ); 118845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#ifdef __linux__ 119845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project ifr.ifr_hwaddr.sa_family = AF_UNSPEC; 120845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memcpy(ifr.ifr_hwaddr.sa_data, addr, ETH_ALEN); 121845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#endif /* __linux__ */ 122845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#ifdef __FreeBSD__ 123845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project { 124845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct sockaddr_dl *dlp; 125845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project dlp = (struct sockaddr_dl *) &ifr.ifr_addr; 126845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project dlp->sdl_len = sizeof(struct sockaddr_dl); 127845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project dlp->sdl_family = AF_LINK; 128845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project dlp->sdl_index = 0; 129845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project dlp->sdl_nlen = 0; 130845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project dlp->sdl_alen = ETH_ALEN; 131845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project dlp->sdl_slen = 0; 132845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memcpy(LLADDR(dlp), addr, ETH_ALEN); 133845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 134845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#endif /* __FreeBSD__ */ 135845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 136845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (ioctl(s, add ? SIOCADDMULTI : SIOCDELMULTI, (caddr_t) &ifr) < 0) { 137845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project perror("ioctl[SIOC{ADD/DEL}MULTI]"); 138845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project close(s); 139845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 140845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 141845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project close(s); 142845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return 0; 143845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 144845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 145845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 146845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic int wpa_driver_wired_membership(struct wpa_driver_wired_data *drv, 147845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const u8 *addr, int add) 148845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 149845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#ifdef __linux__ 150845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct packet_mreq mreq; 151845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 152845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (drv->pf_sock == -1) 153845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 154845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 155845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memset(&mreq, 0, sizeof(mreq)); 156845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project mreq.mr_ifindex = if_nametoindex(drv->ifname); 157845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project mreq.mr_type = PACKET_MR_MULTICAST; 158845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project mreq.mr_alen = ETH_ALEN; 159845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memcpy(mreq.mr_address, addr, ETH_ALEN); 160845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 161845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (setsockopt(drv->pf_sock, SOL_PACKET, 162845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project add ? PACKET_ADD_MEMBERSHIP : PACKET_DROP_MEMBERSHIP, 163845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project &mreq, sizeof(mreq)) < 0) { 164845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project perror("setsockopt"); 165845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 166845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 167845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return 0; 168845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#else /* __linux__ */ 169845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 170845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#endif /* __linux__ */ 171845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 172845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 173845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 174845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic void * wpa_driver_wired_init(void *ctx, const char *ifname) 175845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 176845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct wpa_driver_wired_data *drv; 177845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project int flags; 178845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 179845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project drv = os_zalloc(sizeof(*drv)); 180845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (drv == NULL) 181845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 182845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_strncpy(drv->ifname, ifname, sizeof(drv->ifname)); 183845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project drv->ctx = ctx; 184845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 185845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#ifdef __linux__ 186845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project drv->pf_sock = socket(PF_PACKET, SOCK_DGRAM, 0); 187845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (drv->pf_sock < 0) 188845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project perror("socket(PF_PACKET)"); 189845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#else /* __linux__ */ 190845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project drv->pf_sock = -1; 191845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#endif /* __linux__ */ 192845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 193845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (wpa_driver_wired_get_ifflags(ifname, &flags) == 0 && 194845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project !(flags & IFF_UP) && 195845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_driver_wired_set_ifflags(ifname, flags | IFF_UP) == 0) { 196845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project drv->iff_up = 1; 197845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 198845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 199845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (wpa_driver_wired_membership(drv, pae_group_addr, 1) == 0) { 200845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "%s: Added multicast membership with " 201845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "packet socket", __func__); 202845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project drv->membership = 1; 203845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } else if (wpa_driver_wired_multi(ifname, pae_group_addr, 1) == 0) { 204845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "%s: Added multicast membership with " 205845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "SIOCADDMULTI", __func__); 206845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project drv->multi = 1; 207845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } else if (wpa_driver_wired_get_ifflags(ifname, &flags) < 0) { 208845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_INFO, "%s: Could not get interface " 209845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "flags", __func__); 210845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_free(drv); 211845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 212845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } else if (flags & IFF_ALLMULTI) { 213845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "%s: Interface is already configured " 214845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "for multicast", __func__); 215845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } else if (wpa_driver_wired_set_ifflags(ifname, 216845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project flags | IFF_ALLMULTI) < 0) { 217845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_INFO, "%s: Failed to enable allmulti", 218845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project __func__); 219845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_free(drv); 220845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 221845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } else { 222845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "%s: Enabled allmulti mode", 223845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project __func__); 224845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project drv->iff_allmulti = 1; 225845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 226845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 227845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return drv; 228845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 229845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 230845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 231845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic void wpa_driver_wired_deinit(void *priv) 232845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 233845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct wpa_driver_wired_data *drv = priv; 234845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project int flags; 235845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 236845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (drv->membership && 237845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_driver_wired_membership(drv, pae_group_addr, 0) < 0) { 238845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "%s: Failed to remove PAE multicast " 239845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "group (PACKET)", __func__); 240845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 241845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 242845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (drv->multi && 243845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_driver_wired_multi(drv->ifname, pae_group_addr, 0) < 0) { 244845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "%s: Failed to remove PAE multicast " 245845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "group (SIOCDELMULTI)", __func__); 246845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 247845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 248845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (drv->iff_allmulti && 249845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project (wpa_driver_wired_get_ifflags(drv->ifname, &flags) < 0 || 250845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_driver_wired_set_ifflags(drv->ifname, 251845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project flags & ~IFF_ALLMULTI) < 0)) { 252845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "%s: Failed to disable allmulti mode", 253845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project __func__); 254845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 255845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 256845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (drv->iff_up && 257845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_driver_wired_get_ifflags(drv->ifname, &flags) == 0 && 258845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project (flags & IFF_UP) && 259845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_driver_wired_set_ifflags(drv->ifname, flags & ~IFF_UP) < 0) { 260845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "%s: Failed to set the interface down", 261845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project __func__); 262845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 263845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 264845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (drv->pf_sock != -1) 265845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project close(drv->pf_sock); 266845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 267845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_free(drv); 268845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 269845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 270845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 271845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectconst struct wpa_driver_ops wpa_driver_wired_ops = { 272845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project .name = "wired", 273845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project .desc = "wpa_supplicant wired Ethernet driver", 274845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project .get_ssid = wpa_driver_wired_get_ssid, 275845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project .get_bssid = wpa_driver_wired_get_bssid, 276845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project .init = wpa_driver_wired_init, 277845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project .deinit = wpa_driver_wired_deinit, 278845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project}; 279