driver_wired_common.c revision abb90a3fc1917e628167827cb14e742000605332
1abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt/* 2abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt * Common functions for Wired Ethernet driver interfaces 3abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt * Copyright (c) 2005-2009, Jouni Malinen <j@w1.fi> 4abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt * Copyright (c) 2004, Gunter Burchardt <tira@isx.de> 5abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt * 6abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 7abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt * See README for more details. 8abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt */ 9abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt 10abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt#include "includes.h" 11abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt 12abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt#include "common.h" 13abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt#include "eloop.h" 14abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt#include "driver.h" 15abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt#include "driver_wired_common.h" 16abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt 17abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt#include <sys/ioctl.h> 18abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt#include <net/if.h> 19abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt#ifdef __linux__ 20abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt#include <netpacket/packet.h> 21abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt#include <net/if_arp.h> 22abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt#include <net/if.h> 23abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt#endif /* __linux__ */ 24abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) 25abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt#include <net/if_dl.h> 26abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt#include <net/if_media.h> 27abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt#endif /* defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) */ 28abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt#ifdef __sun__ 29abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt#include <sys/sockio.h> 30abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt#endif /* __sun__ */ 31abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt 32abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt 33abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidtstatic int driver_wired_get_ifflags(const char *ifname, int *flags) 34abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt{ 35abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt struct ifreq ifr; 36abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt int s; 37abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt 38abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt s = socket(PF_INET, SOCK_DGRAM, 0); 39abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt if (s < 0) { 40abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt wpa_printf(MSG_ERROR, "socket: %s", strerror(errno)); 41abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt return -1; 42abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt } 43abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt 44abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt os_memset(&ifr, 0, sizeof(ifr)); 45abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ); 46abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt if (ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) { 47abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt wpa_printf(MSG_ERROR, "ioctl[SIOCGIFFLAGS]: %s", 48abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt strerror(errno)); 49abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt close(s); 50abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt return -1; 51abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt } 52abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt close(s); 53abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt *flags = ifr.ifr_flags & 0xffff; 54abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt return 0; 55abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt} 56abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt 57abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt 58abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidtstatic int driver_wired_set_ifflags(const char *ifname, int flags) 59abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt{ 60abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt struct ifreq ifr; 61abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt int s; 62abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt 63abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt s = socket(PF_INET, SOCK_DGRAM, 0); 64abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt if (s < 0) { 65abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt wpa_printf(MSG_ERROR, "socket: %s", strerror(errno)); 66abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt return -1; 67abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt } 68abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt 69abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt os_memset(&ifr, 0, sizeof(ifr)); 70abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ); 71abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt ifr.ifr_flags = flags & 0xffff; 72abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt if (ioctl(s, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) { 73abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt wpa_printf(MSG_ERROR, "ioctl[SIOCSIFFLAGS]: %s", 74abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt strerror(errno)); 75abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt close(s); 76abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt return -1; 77abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt } 78abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt close(s); 79abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt return 0; 80abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt} 81abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt 82abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt 83abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidtstatic int driver_wired_multi(const char *ifname, const u8 *addr, int add) 84abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt{ 85abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt struct ifreq ifr; 86abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt int s; 87abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt 88abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt#ifdef __sun__ 89abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt return -1; 90abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt#endif /* __sun__ */ 91abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt 92abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt s = socket(PF_INET, SOCK_DGRAM, 0); 93abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt if (s < 0) { 94abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt wpa_printf(MSG_ERROR, "socket: %s", strerror(errno)); 95abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt return -1; 96abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt } 97abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt 98abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt os_memset(&ifr, 0, sizeof(ifr)); 99abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ); 100abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt#ifdef __linux__ 101abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt ifr.ifr_hwaddr.sa_family = AF_UNSPEC; 102abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt os_memcpy(ifr.ifr_hwaddr.sa_data, addr, ETH_ALEN); 103abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt#endif /* __linux__ */ 104abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) 105abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt { 106abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt struct sockaddr_dl *dlp; 107abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt 108abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt dlp = (struct sockaddr_dl *) &ifr.ifr_addr; 109abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt dlp->sdl_len = sizeof(struct sockaddr_dl); 110abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt dlp->sdl_family = AF_LINK; 111abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt dlp->sdl_index = 0; 112abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt dlp->sdl_nlen = 0; 113abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt dlp->sdl_alen = ETH_ALEN; 114abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt dlp->sdl_slen = 0; 115abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt os_memcpy(LLADDR(dlp), addr, ETH_ALEN); 116abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt } 117abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt#endif /* defined(__FreeBSD__) || defined(__DragonFly__) || defined(FreeBSD_kernel__) */ 118abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt#if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__APPLE__) 119abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt { 120abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt struct sockaddr *sap; 121abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt 122abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt sap = (struct sockaddr *) &ifr.ifr_addr; 123abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt sap->sa_len = sizeof(struct sockaddr); 124abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt sap->sa_family = AF_UNSPEC; 125abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt os_memcpy(sap->sa_data, addr, ETH_ALEN); 126abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt } 127abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt#endif /* defined(__NetBSD__) || defined(__OpenBSD__) || defined(__APPLE__) */ 128abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt 129abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt if (ioctl(s, add ? SIOCADDMULTI : SIOCDELMULTI, (caddr_t) &ifr) < 0) { 130abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt wpa_printf(MSG_ERROR, "ioctl[SIOC{ADD/DEL}MULTI]: %s", 131abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt strerror(errno)); 132abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt close(s); 133abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt return -1; 134abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt } 135abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt close(s); 136abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt return 0; 137abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt} 138abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt 139abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt 140abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidtint wired_multicast_membership(int sock, int ifindex, const u8 *addr, int add) 141abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt{ 142abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt#ifdef __linux__ 143abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt struct packet_mreq mreq; 144abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt 145abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt if (sock < 0) 146abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt return -1; 147abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt 148abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt os_memset(&mreq, 0, sizeof(mreq)); 149abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt mreq.mr_ifindex = ifindex; 150abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt mreq.mr_type = PACKET_MR_MULTICAST; 151abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt mreq.mr_alen = ETH_ALEN; 152abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt os_memcpy(mreq.mr_address, addr, ETH_ALEN); 153abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt 154abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt if (setsockopt(sock, SOL_PACKET, 155abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt add ? PACKET_ADD_MEMBERSHIP : PACKET_DROP_MEMBERSHIP, 156abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt &mreq, sizeof(mreq)) < 0) { 157abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt wpa_printf(MSG_ERROR, "setsockopt: %s", strerror(errno)); 158abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt return -1; 159abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt } 160abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt return 0; 161abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt#else /* __linux__ */ 162abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt return -1; 163abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt#endif /* __linux__ */ 164abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt} 165abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt 166abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt 167abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidtint driver_wired_get_ssid(void *priv, u8 *ssid) 168abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt{ 169abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt ssid[0] = 0; 170abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt return 0; 171abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt} 172abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt 173abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt 174abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidtint driver_wired_get_bssid(void *priv, u8 *bssid) 175abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt{ 176abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt /* Report PAE group address as the "BSSID" for wired connection. */ 177abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt os_memcpy(bssid, pae_group_addr, ETH_ALEN); 178abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt return 0; 179abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt} 180abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt 181abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt 182abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidtint driver_wired_get_capa(void *priv, struct wpa_driver_capa *capa) 183abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt{ 184abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt os_memset(capa, 0, sizeof(*capa)); 185abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt capa->flags = WPA_DRIVER_FLAGS_WIRED; 186abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt return 0; 187abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt} 188abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt 189abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt 190abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) 191abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidtstatic int driver_wired_get_ifstatus(const char *ifname, int *status) 192abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt{ 193abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt struct ifmediareq ifmr; 194abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt int s; 195abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt 196abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt s = socket(PF_INET, SOCK_DGRAM, 0); 197abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt if (s < 0) { 198abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt wpa_printf(MSG_ERROR, "socket: %s", strerror(errno)); 199abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt return -1; 200abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt } 201abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt 202abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt os_memset(&ifmr, 0, sizeof(ifmr)); 203abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt os_strlcpy(ifmr.ifm_name, ifname, IFNAMSIZ); 204abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt if (ioctl(s, SIOCGIFMEDIA, (caddr_t) &ifmr) < 0) { 205abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt wpa_printf(MSG_ERROR, "ioctl[SIOCGIFMEDIA]: %s", 206abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt strerror(errno)); 207abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt close(s); 208abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt return -1; 209abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt } 210abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt close(s); 211abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt *status = (ifmr.ifm_status & (IFM_ACTIVE | IFM_AVALID)) == 212abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt (IFM_ACTIVE | IFM_AVALID); 213abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt 214abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt return 0; 215abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt} 216abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt#endif /* defined(__FreeBSD__) || defined(__DragonFly__) || defined(FreeBSD_kernel__) */ 217abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt 218abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt 219abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidtint driver_wired_init_common(struct driver_wired_common_data *common, 220abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt const char *ifname, void *ctx) 221abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt{ 222abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt int flags; 223abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt 224abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt os_strlcpy(common->ifname, ifname, sizeof(common->ifname)); 225abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt common->ctx = ctx; 226abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt 227abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt#ifdef __linux__ 228abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt common->pf_sock = socket(PF_PACKET, SOCK_DGRAM, 0); 229abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt if (common->pf_sock < 0) 230abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt wpa_printf(MSG_ERROR, "socket(PF_PACKET): %s", strerror(errno)); 231abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt#else /* __linux__ */ 232abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt common->pf_sock = -1; 233abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt#endif /* __linux__ */ 234abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt 235abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt if (driver_wired_get_ifflags(ifname, &flags) == 0 && 236abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt !(flags & IFF_UP) && 237abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt driver_wired_set_ifflags(ifname, flags | IFF_UP) == 0) 238abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt common->iff_up = 1; 239abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt 240abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt if (wired_multicast_membership(common->pf_sock, 241abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt if_nametoindex(common->ifname), 242abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt pae_group_addr, 1) == 0) { 243abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt wpa_printf(MSG_DEBUG, 244abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt "%s: Added multicast membership with packet socket", 245abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt __func__); 246abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt common->membership = 1; 247abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt } else if (driver_wired_multi(ifname, pae_group_addr, 1) == 0) { 248abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt wpa_printf(MSG_DEBUG, 249abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt "%s: Added multicast membership with SIOCADDMULTI", 250abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt __func__); 251abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt common->multi = 1; 252abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt } else if (driver_wired_get_ifflags(ifname, &flags) < 0) { 253abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt wpa_printf(MSG_INFO, "%s: Could not get interface flags", 254abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt __func__); 255abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt return -1; 256abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt } else if (flags & IFF_ALLMULTI) { 257abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt wpa_printf(MSG_DEBUG, 258abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt "%s: Interface is already configured for multicast", 259abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt __func__); 260abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt } else if (driver_wired_set_ifflags(ifname, 261abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt flags | IFF_ALLMULTI) < 0) { 262abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt wpa_printf(MSG_INFO, "%s: Failed to enable allmulti", __func__); 263abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt return -1; 264abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt } else { 265abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: Enabled allmulti mode", __func__); 266abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt common->iff_allmulti = 1; 267abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt } 268abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) 269abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt { 270abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt int status; 271abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt 272abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: waiting for link to become active", 273abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt __func__); 274abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt while (driver_wired_get_ifstatus(ifname, &status) == 0 && 275abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt status == 0) 276abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt sleep(1); 277abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt } 278abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt#endif /* defined(__FreeBSD__) || defined(__DragonFly__) || defined(FreeBSD_kernel__) */ 279abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt 280abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt return 0; 281abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt} 282abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt 283abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt 284abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidtvoid driver_wired_deinit_common(struct driver_wired_common_data *common) 285abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt{ 286abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt int flags; 287abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt 288abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt if (common->membership && 289abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt wired_multicast_membership(common->pf_sock, 290abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt if_nametoindex(common->ifname), 291abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt pae_group_addr, 0) < 0) { 292abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt wpa_printf(MSG_DEBUG, 293abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt "%s: Failed to remove PAE multicast group (PACKET)", 294abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt __func__); 295abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt } 296abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt 297abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt if (common->multi && 298abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt driver_wired_multi(common->ifname, pae_group_addr, 0) < 0) { 299abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt wpa_printf(MSG_DEBUG, 300abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt "%s: Failed to remove PAE multicast group (SIOCDELMULTI)", 301abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt __func__); 302abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt } 303abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt 304abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt if (common->iff_allmulti && 305abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt (driver_wired_get_ifflags(common->ifname, &flags) < 0 || 306abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt driver_wired_set_ifflags(common->ifname, 307abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt flags & ~IFF_ALLMULTI) < 0)) { 308abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: Failed to disable allmulti mode", 309abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt __func__); 310abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt } 311abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt 312abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt if (common->iff_up && 313abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt driver_wired_get_ifflags(common->ifname, &flags) == 0 && 314abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt (flags & IFF_UP) && 315abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt driver_wired_set_ifflags(common->ifname, flags & ~IFF_UP) < 0) { 316abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: Failed to set the interface down", 317abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt __func__); 318abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt } 319abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt 320abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt if (common->pf_sock != -1) 321abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt close(common->pf_sock); 322abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt} 323