X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=src%2Fdrivers%2Fdriver_atheros.c;h=c0dd731d7f70eeb3b73ebf003079362b19cc0269;hb=0e2e565a44ab7b073491cab00847f7bc62731483;hp=ce9f98379db89c88755fcf6f5f79e04de6455246;hpb=e3bd3912ca50d4f694a459d700988ea4fdbc5af4;p=libeap.git diff --git a/src/drivers/driver_atheros.c b/src/drivers/driver_atheros.c index ce9f983..c0dd731 100644 --- a/src/drivers/driver_atheros.c +++ b/src/drivers/driver_atheros.c @@ -28,44 +28,32 @@ #endif #endif /* _BYTE_ORDER */ -#include -#include -#include - /* * Note, the ATH_WPS_IE setting must match with the driver build.. If the * driver does not include this, the IEEE80211_IOCTL_GETWPAIE ioctl will fail. */ #define ATH_WPS_IE -#include + +#include "os/linux/include/ieee80211_external.h" + #ifdef CONFIG_WPS -#ifdef IEEE80211_IOCTL_FILTERFRAME #include #ifndef ETH_P_80211_RAW #define ETH_P_80211_RAW 0x0019 #endif -#endif /* IEEE80211_IOCTL_FILTERFRAME */ #endif /* CONFIG_WPS */ -/* - * Avoid conflicts with hostapd definitions by undefining couple of defines - * from madwifi header files. - */ -#undef WPA_OUI_TYPE -#undef WME_OUI_TYPE - #include "wireless_copy.h" -#include "../hostapd/hostapd.h" -#include "../hostapd/config.h" -#include "../hostapd/sta_flags.h" #include "driver.h" #include "eloop.h" #include "priv_netlink.h" #include "l2_packet/l2_packet.h" #include "common/ieee802_11_defs.h" +#include "netlink.h" +#include "linux_ioctl.h" struct madwifi_driver_data { @@ -76,7 +64,7 @@ struct madwifi_driver_data { struct l2_packet_data *sock_xmit; /* raw packet xmit socket */ struct l2_packet_data *sock_recv; /* raw packet recv socket */ int ioctl_sock; /* socket for ioctl() use */ - int wext_sock; /* socket for wireless events */ + struct netlink_data *netlink; int we_version; u8 acct_mac[ETH_ALEN]; struct hostap_sta_driver_data acct_data; @@ -86,6 +74,109 @@ struct madwifi_driver_data { static int madwifi_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr, int reason_code); +static int madwifi_set_privacy(void *priv, int enabled); + +static const char * athr_get_ioctl_name(int op) +{ + switch (op) { + case IEEE80211_IOCTL_SETPARAM: + return "SETPARAM"; + case IEEE80211_IOCTL_GETPARAM: + return "GETPARAM"; + case IEEE80211_IOCTL_SETKEY: + return "SETKEY"; + case IEEE80211_IOCTL_SETWMMPARAMS: + return "SETWMMPARAMS"; + case IEEE80211_IOCTL_DELKEY: + return "DELKEY"; + case IEEE80211_IOCTL_GETWMMPARAMS: + return "GETWMMPARAMS"; + case IEEE80211_IOCTL_SETMLME: + return "SETMLME"; + case IEEE80211_IOCTL_GETCHANINFO: + return "GETCHANINFO"; + case IEEE80211_IOCTL_SETOPTIE: + return "SETOPTIE"; + case IEEE80211_IOCTL_GETOPTIE: + return "GETOPTIE"; + case IEEE80211_IOCTL_ADDMAC: + return "ADDMAC"; + case IEEE80211_IOCTL_DELMAC: + return "DELMAC"; + case IEEE80211_IOCTL_GETCHANLIST: + return "GETCHANLIST"; + case IEEE80211_IOCTL_SETCHANLIST: + return "SETCHANLIST"; + case IEEE80211_IOCTL_KICKMAC: + return "KICKMAC"; + case IEEE80211_IOCTL_CHANSWITCH: + return "CHANSWITCH"; + case IEEE80211_IOCTL_GETMODE: + return "GETMODE"; + case IEEE80211_IOCTL_SETMODE: + return "SETMODE"; + case IEEE80211_IOCTL_GET_APPIEBUF: + return "GET_APPIEBUF"; + case IEEE80211_IOCTL_SET_APPIEBUF: + return "SET_APPIEBUF"; + case IEEE80211_IOCTL_SET_ACPARAMS: + return "SET_ACPARAMS"; + case IEEE80211_IOCTL_FILTERFRAME: + return "FILTERFRAME"; + case IEEE80211_IOCTL_SET_RTPARAMS: + return "SET_RTPARAMS"; + case IEEE80211_IOCTL_SENDADDBA: + return "SENDADDBA"; + case IEEE80211_IOCTL_GETADDBASTATUS: + return "GETADDBASTATUS"; + case IEEE80211_IOCTL_SENDDELBA: + return "SENDDELBA"; + case IEEE80211_IOCTL_SET_MEDENYENTRY: + return "SET_MEDENYENTRY"; + case IEEE80211_IOCTL_SET_ADDBARESP: + return "SET_ADDBARESP"; + case IEEE80211_IOCTL_GET_MACADDR: + return "GET_MACADDR"; + case IEEE80211_IOCTL_SET_HBRPARAMS: + return "SET_HBRPARAMS"; + case IEEE80211_IOCTL_SET_RXTIMEOUT: + return "SET_RXTIMEOUT"; + case IEEE80211_IOCTL_STA_STATS: + return "STA_STATS"; + case IEEE80211_IOCTL_GETWPAIE: + return "GETWPAIE"; + default: + return "??"; + } +} + + +static const char * athr_get_param_name(int op) +{ + switch (op) { + case IEEE80211_IOC_MCASTCIPHER: + return "MCASTCIPHER"; + case IEEE80211_PARAM_MCASTKEYLEN: + return "MCASTKEYLEN"; + case IEEE80211_PARAM_UCASTCIPHERS: + return "UCASTCIPHERS"; + case IEEE80211_PARAM_KEYMGTALGS: + return "KEYMGTALGS"; + case IEEE80211_PARAM_RSNCAPS: + return "RSNCAPS"; + case IEEE80211_PARAM_WPA: + return "WPA"; + case IEEE80211_PARAM_AUTHMODE: + return "AUTHMODE"; + case IEEE80211_PARAM_PRIVACY: + return "PRIVACY"; + case IEEE80211_PARAM_COUNTERMEASURES: + return "COUNTERMEASURES"; + default: + return "??"; + } +} + static int set80211priv(struct madwifi_driver_data *drv, int op, void *data, int len) @@ -116,40 +207,11 @@ set80211priv(struct madwifi_driver_data *drv, int op, void *data, int len) } if (ioctl(drv->ioctl_sock, op, &iwr) < 0) { - int first = IEEE80211_IOCTL_SETPARAM; - static const char *opnames[] = { - "ioctl[IEEE80211_IOCTL_SETPARAM]", - "ioctl[IEEE80211_IOCTL_GETPARAM]", - "ioctl[IEEE80211_IOCTL_SETKEY]", - "ioctl[IEEE80211_IOCTL_SETWMMPARAMS]", - "ioctl[IEEE80211_IOCTL_DELKEY]", - "ioctl[IEEE80211_IOCTL_GETWMMPARAMS]", - "ioctl[IEEE80211_IOCTL_SETMLME]", - "ioctl[IEEE80211_IOCTL_GETCHANINFO]", - "ioctl[IEEE80211_IOCTL_SETOPTIE]", - "ioctl[IEEE80211_IOCTL_GETOPTIE]", - "ioctl[IEEE80211_IOCTL_ADDMAC]", - "ioctl[IEEE80211_IOCTL_DELMAC]", - "ioctl[IEEE80211_IOCTL_GETCHANLIST]", - "ioctl[IEEE80211_IOCTL_SETCHANLIST]", - "ioctl[IEEE80211_IOCTL_KICKMAC]", - "ioctl[IEEE80211_IOCTL_CHANSWITCH]", - "ioctl[IEEE80211_IOCTL_GETMODE]", - "ioctl[IEEE80211_IOCTL_SETMODE]", - "ioctl[IEEE80211_IOCTL_GET_APPIEBUF]", - "ioctl[IEEE80211_IOCTL_SET_APPIEBUF]", - NULL, - "ioctl[IEEE80211_IOCTL_FILTERFRAME]", - }; - int idx = op - first; - if (first <= op && - idx < (int) (sizeof(opnames) / sizeof(opnames[0])) && - opnames[idx]) - perror(opnames[idx]); - else { - perror("ioctl[unknown???]"); - wpa_printf(MSG_DEBUG, "Failed ioctl: 0x%x", op); - } + wpa_printf(MSG_DEBUG, "atheros: %s: %s: ioctl op=0x%x " + "(%s) len=%d failed: %d (%s)", + __func__, drv->iface, op, + athr_get_ioctl_name(op), + len, errno, strerror(errno)); return -1; } return 0; @@ -167,8 +229,9 @@ set80211param(struct madwifi_driver_data *drv, int op, int arg) if (ioctl(drv->ioctl_sock, IEEE80211_IOCTL_SETPARAM, &iwr) < 0) { perror("ioctl[IEEE80211_IOCTL_SETPARAM]"); - wpa_printf(MSG_DEBUG, "%s: Failed to set parameter (op %d " - "arg %d)", __func__, op, arg); + wpa_printf(MSG_DEBUG, "%s: %s: Failed to set parameter (op %d " + "(%s) arg %d)", __func__, drv->iface, op, + athr_get_param_name(op), arg); return -1; } return 0; @@ -192,13 +255,12 @@ ether_sprintf(const u8 *addr) * Configure WPA parameters. */ static int -madwifi_configure_wpa(struct madwifi_driver_data *drv) +madwifi_configure_wpa(struct madwifi_driver_data *drv, + struct wpa_bss_params *params) { - struct hostapd_data *hapd = drv->hapd; - struct hostapd_bss_config *conf = hapd->conf; int v; - switch (conf->wpa_group) { + switch (params->wpa_group) { case WPA_CIPHER_CCMP: v = IEEE80211_CIPHER_AES_CCM; break; @@ -216,7 +278,7 @@ madwifi_configure_wpa(struct madwifi_driver_data *drv) break; default: wpa_printf(MSG_ERROR, "Unknown group key cipher %u", - conf->wpa_group); + params->wpa_group); return -1; } wpa_printf(MSG_DEBUG, "%s: group key cipher=%d", __func__, v); @@ -226,7 +288,7 @@ madwifi_configure_wpa(struct madwifi_driver_data *drv) } if (v == IEEE80211_CIPHER_WEP) { /* key length is done only for specific ciphers */ - v = (conf->wpa_group == WPA_CIPHER_WEP104 ? 13 : 5); + v = (params->wpa_group == WPA_CIPHER_WEP104 ? 13 : 5); if (set80211param(drv, IEEE80211_PARAM_MCASTKEYLEN, v)) { printf("Unable to set group key length to %u\n", v); return -1; @@ -234,11 +296,11 @@ madwifi_configure_wpa(struct madwifi_driver_data *drv) } v = 0; - if (conf->wpa_pairwise & WPA_CIPHER_CCMP) + if (params->wpa_pairwise & WPA_CIPHER_CCMP) v |= 1<wpa_pairwise & WPA_CIPHER_TKIP) + if (params->wpa_pairwise & WPA_CIPHER_TKIP) v |= 1<wpa_pairwise & WPA_CIPHER_NONE) + if (params->wpa_pairwise & WPA_CIPHER_NONE) v |= 1<wpa_key_mgmt); - if (set80211param(drv, IEEE80211_PARAM_KEYMGTALGS, conf->wpa_key_mgmt)) { + __func__, params->wpa_key_mgmt); + if (set80211param(drv, IEEE80211_PARAM_KEYMGTALGS, + params->wpa_key_mgmt)) { printf("Unable to set key management algorithms to 0x%x\n", - conf->wpa_key_mgmt); + params->wpa_key_mgmt); return -1; } v = 0; - if (conf->rsn_preauth) + if (params->rsn_preauth) v |= BIT(0); wpa_printf(MSG_DEBUG, "%s: rsn capabilities=0x%x", - __func__, conf->rsn_preauth); + __func__, params->rsn_preauth); if (set80211param(drv, IEEE80211_PARAM_RSNCAPS, v)) { printf("Unable to set RSN capabilities to 0x%x\n", v); return -1; } - wpa_printf(MSG_DEBUG, "%s: enable WPA=0x%x", __func__, conf->wpa); - if (set80211param(drv, IEEE80211_PARAM_WPA, conf->wpa)) { - printf("Unable to set WPA to %u\n", conf->wpa); - return -1; - } - return 0; -} - - -static int -madwifi_set_iface_flags(void *priv, int dev_up) -{ - struct madwifi_driver_data *drv = priv; - struct ifreq ifr; - - wpa_printf(MSG_DEBUG, "%s: dev_up=%d", __func__, dev_up); - - if (drv->ioctl_sock < 0) - return -1; - - memset(&ifr, 0, sizeof(ifr)); - os_strlcpy(ifr.ifr_name, drv->iface, IFNAMSIZ); - - if (ioctl(drv->ioctl_sock, SIOCGIFFLAGS, &ifr) != 0) { - perror("ioctl[SIOCGIFFLAGS]"); - return -1; - } - - if (dev_up) - ifr.ifr_flags |= IFF_UP; - else - ifr.ifr_flags &= ~IFF_UP; - - if (ioctl(drv->ioctl_sock, SIOCSIFFLAGS, &ifr) != 0) { - perror("ioctl[SIOCSIFFLAGS]"); + wpa_printf(MSG_DEBUG, "%s: enable WPA=0x%x", __func__, params->wpa); + if (set80211param(drv, IEEE80211_PARAM_WPA, params->wpa)) { + printf("Unable to set WPA to %u\n", params->wpa); return -1; } - return 0; } @@ -309,30 +339,30 @@ static int madwifi_set_ieee8021x(void *priv, struct wpa_bss_params *params) { struct madwifi_driver_data *drv = priv; - struct hostapd_data *hapd = drv->hapd; - struct hostapd_bss_config *conf = hapd->conf; - int enabled = params->enabled; - wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled); + wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, params->enabled); - if (!enabled) { + if (!params->enabled) { /* XXX restore state */ - return set80211param(priv, IEEE80211_PARAM_AUTHMODE, - IEEE80211_AUTH_AUTO); + if (set80211param(priv, IEEE80211_PARAM_AUTHMODE, + IEEE80211_AUTH_AUTO) < 0) + return -1; + /* IEEE80211_AUTH_AUTO ends up enabling Privacy; clear that */ + return madwifi_set_privacy(drv, 0); } - if (!conf->wpa && !conf->ieee802_1x) { - hostapd_logger(hapd, NULL, HOSTAPD_MODULE_DRIVER, + if (!params->wpa && !params->ieee802_1x) { + hostapd_logger(drv->hapd, NULL, HOSTAPD_MODULE_DRIVER, HOSTAPD_LEVEL_WARNING, "No 802.1X or WPA enabled!"); return -1; } - if (conf->wpa && madwifi_configure_wpa(drv) != 0) { - hostapd_logger(hapd, NULL, HOSTAPD_MODULE_DRIVER, + if (params->wpa && madwifi_configure_wpa(drv, params) != 0) { + hostapd_logger(drv->hapd, NULL, HOSTAPD_MODULE_DRIVER, HOSTAPD_LEVEL_WARNING, "Error configuring WPA state!"); return -1; } if (set80211param(priv, IEEE80211_PARAM_AUTHMODE, - (conf->wpa ? IEEE80211_AUTH_WPA : IEEE80211_AUTH_8021X))) { - hostapd_logger(hapd, NULL, HOSTAPD_MODULE_DRIVER, + (params->wpa ? IEEE80211_AUTH_WPA : IEEE80211_AUTH_8021X))) { + hostapd_logger(drv->hapd, NULL, HOSTAPD_MODULE_DRIVER, HOSTAPD_LEVEL_WARNING, "Error enabling WPA/802.1X!"); return -1; } @@ -341,7 +371,7 @@ madwifi_set_ieee8021x(void *priv, struct wpa_bss_params *params) } static int -madwifi_set_privacy(const char *ifname, void *priv, int enabled) +madwifi_set_privacy(void *priv, int enabled) { struct madwifi_driver_data *drv = priv; @@ -376,13 +406,13 @@ madwifi_set_sta_authorized(void *priv, const u8 *addr, int authorized) } static int -madwifi_sta_set_flags(void *priv, const u8 *addr, int total_flags, - int flags_or, int flags_and) +madwifi_sta_set_flags(void *priv, const u8 *addr, + int total_flags, int flags_or, int flags_and) { /* For now, only support setting Authorized flag */ - if (flags_or & WLAN_STA_AUTHORIZED) + if (flags_or & WPA_STA_AUTHORIZED) return madwifi_set_sta_authorized(priv, addr, 1); - if (!(flags_and & WLAN_STA_AUTHORIZED)) + if (!(flags_and & WPA_STA_AUTHORIZED)) return madwifi_set_sta_authorized(priv, addr, 0); return 0; } @@ -416,9 +446,9 @@ madwifi_del_key(void *priv, const u8 *addr, int key_idx) } static int -madwifi_set_key(const char *ifname, void *priv, wpa_alg alg, const u8 *addr, - int key_idx, int set_tx, const u8 *seq, size_t seq_len, - const u8 *key, size_t key_len) +madwifi_set_key(const char *ifname, void *priv, enum wpa_alg alg, + const u8 *addr, int key_idx, int set_tx, const u8 *seq, + size_t seq_len, const u8 *key, size_t key_len) { struct madwifi_driver_data *drv = priv; struct ieee80211req_key wk; @@ -510,6 +540,9 @@ madwifi_get_seqnum(const char *ifname, void *priv, const u8 *addr, int idx, * swap it to match with the byte order used in WPA. */ int i; +#ifndef WPA_KEY_RSC_LEN +#define WPA_KEY_RSC_LEN 8 +#endif u8 tmp[WPA_KEY_RSC_LEN]; memcpy(tmp, &wk.ik_keytsc, sizeof(wk.ik_keytsc)); for (i = 0; i < WPA_KEY_RSC_LEN; i++) { @@ -591,7 +624,7 @@ madwifi_sta_clear_stats(void *priv, const u8 *addr) static int -madwifi_set_opt_ie(const char *ifname, void *priv, const u8 *ie, size_t ie_len) +madwifi_set_opt_ie(void *priv, const u8 *ie, size_t ie_len) { /* * Do nothing; we setup parameters at startup that define the @@ -654,9 +687,8 @@ static void madwifi_raw_receive(void *ctx, const u8 *src_addr, const u8 *buf, { struct madwifi_driver_data *drv = ctx; const struct ieee80211_mgmt *mgmt; - const u8 *end, *ie; u16 fc; - size_t ie_len; + union wpa_event_data event; /* Send Probe Request information to WPS processing */ @@ -669,11 +701,12 @@ static void madwifi_raw_receive(void *ctx, const u8 *src_addr, const u8 *buf, WLAN_FC_GET_STYPE(fc) != WLAN_FC_STYPE_PROBE_REQ) return; - end = buf + len; - ie = mgmt->u.probe_req.variable; - ie_len = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req)); - - hostapd_probe_req_rx(drv->hapd, mgmt->sa, ie, ie_len); + os_memset(&event, 0, sizeof(event)); + event.rx_probe_req.sa = mgmt->sa; + event.rx_probe_req.ie = mgmt->u.probe_req.variable; + event.rx_probe_req.ie_len = + len - (IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req)); + wpa_supplicant_event(drv->hapd, EVENT_RX_PROBE_REQ, &event); } #endif /* CONFIG_WPS */ @@ -704,7 +737,7 @@ static int madwifi_set_wps_ie(void *priv, const u8 *ie, size_t len, u32 frametype) { struct madwifi_driver_data *drv = priv; - u8 buf[256]; + u8 buf[500]; struct ieee80211req_getset_appiebuf *beac_ie; wpa_printf(MSG_DEBUG, "%s buflen = %lu", __func__, @@ -720,30 +753,32 @@ madwifi_set_wps_ie(void *priv, const u8 *ie, size_t len, u32 frametype) } static int -madwifi_set_wps_beacon_ie(const char *ifname, void *priv, const u8 *ie, - size_t len) +madwifi_set_ap_wps_ie(void *priv, const struct wpabuf *beacon, + const struct wpabuf *proberesp, + const struct wpabuf *assocresp) { - return madwifi_set_wps_ie(priv, ie, len, IEEE80211_APPIE_FRAME_BEACON); -} - -static int -madwifi_set_wps_probe_resp_ie(const char *ifname, void *priv, const u8 *ie, - size_t len) -{ - return madwifi_set_wps_ie(priv, ie, len, + madwifi_set_wps_ie(priv, assocresp ? wpabuf_head(assocresp) : NULL, + assocresp ? wpabuf_len(assocresp) : 0, + IEEE80211_APPIE_FRAME_ASSOC_RESP); + if (madwifi_set_wps_ie(priv, beacon ? wpabuf_head(beacon) : NULL, + beacon ? wpabuf_len(beacon) : 0, + IEEE80211_APPIE_FRAME_BEACON)) + return -1; + return madwifi_set_wps_ie(priv, + proberesp ? wpabuf_head(proberesp) : NULL, + proberesp ? wpabuf_len(proberesp): 0, IEEE80211_APPIE_FRAME_PROBE_RESP); } #else /* CONFIG_WPS */ -#define madwifi_set_wps_beacon_ie NULL -#define madwifi_set_wps_probe_resp_ie NULL +#define madwifi_set_ap_wps_ie NULL #endif /* CONFIG_WPS */ -static int +static void madwifi_new_sta(struct madwifi_driver_data *drv, u8 addr[IEEE80211_ADDR_LEN]) { struct hostapd_data *hapd = drv->hapd; struct ieee80211req_wpaie ie; - int ielen = 0, res; + int ielen = 0; u8 *iebuf = NULL; /* @@ -784,15 +819,13 @@ madwifi_new_sta(struct madwifi_driver_data *drv, u8 addr[IEEE80211_ADDR_LEN]) ielen += 2; no_ie: - res = hostapd_notif_assoc(hapd, addr, iebuf, ielen); + drv_event_assoc(hapd, addr, iebuf, ielen); if (memcmp(addr, drv->acct_mac, ETH_ALEN) == 0) { /* Cached accounting data is not valid anymore. */ memset(drv->acct_mac, 0, ETH_ALEN); memset(&drv->acct_data, 0, sizeof(drv->acct_data)); } - - return res; } static void @@ -813,7 +846,12 @@ madwifi_wireless_event_wireless_custom(struct madwifi_driver_data *drv, } pos += 5; if (hwaddr_aton(pos, addr) == 0) { - hostapd_michael_mic_failure(drv->hapd, addr); + union wpa_event_data data; + os_memset(&data, 0, sizeof(data)); + data.michael_mic_failure.unicast = 1; + data.michael_mic_failure.src = addr; + wpa_supplicant_event(drv->hapd, + EVENT_MICHAEL_MIC_FAILURE, &data); } else { wpa_printf(MSG_DEBUG, "MLME-MICHAELMICFAILURE.indication " @@ -848,7 +886,7 @@ madwifi_wireless_event_wireless_custom(struct madwifi_driver_data *drv, /* PROBLEM! this event is received for ALL BSSs ... * so all are enabled for WPS... ugh. */ - hostapd_button_pushed(drv->hapd); + wpa_supplicant_event(drv->hapd, EVENT_WPS_BUTTON_PUSHED, NULL); } else if (strncmp(custom, "Manage.prob_req ", 16) == 0) { /* * Atheros driver uses a hack to pass Probe Request frames as a @@ -905,8 +943,8 @@ madwifi_wireless_event_wireless(struct madwifi_driver_data *drv, switch (iwe->cmd) { case IWEVEXPIRED: - hostapd_notif_disassoc(drv->hapd, - (u8 *) iwe->u.addr.sa_data); + drv_event_disassoc(drv->hapd, + (u8 *) iwe->u.addr.sa_data); break; case IWEVREGISTERED: madwifi_new_sta(drv, (u8 *) iwe->u.addr.sa_data); @@ -936,28 +974,18 @@ madwifi_wireless_event_wireless(struct madwifi_driver_data *drv, static void -madwifi_wireless_event_rtm_newlink(struct madwifi_driver_data *drv, - struct nlmsghdr *h, int len) +madwifi_wireless_event_rtm_newlink(void *ctx, + struct ifinfomsg *ifi, u8 *buf, size_t len) { - struct ifinfomsg *ifi; - int attrlen, nlmsg_len, rta_len; - struct rtattr * attr; - - if (len < (int) sizeof(*ifi)) - return; - - ifi = NLMSG_DATA(h); + struct madwifi_driver_data *drv = ctx; + int attrlen, rta_len; + struct rtattr *attr; if (ifi->ifi_index != drv->ifindex) return; - nlmsg_len = NLMSG_ALIGN(sizeof(struct ifinfomsg)); - - attrlen = h->nlmsg_len - nlmsg_len; - if (attrlen < 0) - return; - - attr = (struct rtattr *) (((char *) ifi) + nlmsg_len); + attrlen = len; + attr = (struct rtattr *) buf; rta_len = RTA_ALIGN(sizeof(struct rtattr)); while (RTA_OK(attr, attrlen)) { @@ -971,55 +999,6 @@ madwifi_wireless_event_rtm_newlink(struct madwifi_driver_data *drv, } -static void -madwifi_wireless_event_receive(int sock, void *eloop_ctx, void *sock_ctx) -{ - char buf[256]; - int left; - struct sockaddr_nl from; - socklen_t fromlen; - struct nlmsghdr *h; - struct madwifi_driver_data *drv = eloop_ctx; - - fromlen = sizeof(from); - left = recvfrom(sock, buf, sizeof(buf), MSG_DONTWAIT, - (struct sockaddr *) &from, &fromlen); - if (left < 0) { - if (errno != EINTR && errno != EAGAIN) - perror("recvfrom(netlink)"); - return; - } - - h = (struct nlmsghdr *) buf; - while (left >= (int) sizeof(*h)) { - int len, plen; - - len = h->nlmsg_len; - plen = len - sizeof(*h); - if (len > left || plen < 0) { - printf("Malformed netlink message: " - "len=%d left=%d plen=%d\n", - len, left, plen); - break; - } - - switch (h->nlmsg_type) { - case RTM_NEWLINK: - madwifi_wireless_event_rtm_newlink(drv, h, plen); - break; - } - - len = NLMSG_ALIGN(len); - left -= len; - h = (struct nlmsghdr *) ((char *) h + len); - } - - if (left > 0) { - printf("%d extra bytes in the end of netlink message\n", left); - } -} - - static int madwifi_get_we_version(struct madwifi_driver_data *drv) { @@ -1069,45 +1048,25 @@ madwifi_get_we_version(struct madwifi_driver_data *drv) static int madwifi_wireless_event_init(struct madwifi_driver_data *drv) { - int s; - struct sockaddr_nl local; + struct netlink_config *cfg; madwifi_get_we_version(drv); - drv->wext_sock = -1; - - s = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE); - if (s < 0) { - perror("socket(PF_NETLINK,SOCK_RAW,NETLINK_ROUTE)"); + cfg = os_zalloc(sizeof(*cfg)); + if (cfg == NULL) return -1; - } - - memset(&local, 0, sizeof(local)); - local.nl_family = AF_NETLINK; - local.nl_groups = RTMGRP_LINK; - if (bind(s, (struct sockaddr *) &local, sizeof(local)) < 0) { - perror("bind(netlink)"); - close(s); + cfg->ctx = drv; + cfg->newlink_cb = madwifi_wireless_event_rtm_newlink; + drv->netlink = netlink_init(cfg); + if (drv->netlink == NULL) { + os_free(cfg); return -1; } - eloop_register_read_sock(s, madwifi_wireless_event_receive, drv, NULL); - drv->wext_sock = s; - return 0; } -static void -madwifi_wireless_event_deinit(struct madwifi_driver_data *drv) -{ - if (drv->wext_sock < 0) - return; - eloop_unregister_read_sock(drv->wext_sock); - close(drv->wext_sock); -} - - static int madwifi_send_eapol(void *priv, const u8 *addr, const u8 *data, size_t data_len, int encrypt, const u8 *own_addr) @@ -1153,9 +1112,8 @@ static void handle_read(void *ctx, const u8 *src_addr, const u8 *buf, size_t len) { struct madwifi_driver_data *drv = ctx; - hostapd_eapol_receive(drv->hapd, src_addr, - buf + sizeof(struct l2_ethhdr), - len - sizeof(struct l2_ethhdr)); + drv_event_eapol_rx(drv->hapd, src_addr, buf + sizeof(struct l2_ethhdr), + len - sizeof(struct l2_ethhdr)); } static void * @@ -1164,6 +1122,7 @@ madwifi_init(struct hostapd_data *hapd, struct wpa_init_params *params) struct madwifi_driver_data *drv; struct ifreq ifr; struct iwreq iwr; + char brname[IFNAMSIZ]; drv = os_zalloc(sizeof(struct madwifi_driver_data)); if (drv == NULL) { @@ -1201,6 +1160,13 @@ madwifi_init(struct hostapd_data *hapd, struct wpa_init_params *params) 1); if (drv->sock_recv == NULL) goto bad; + } else if (linux_br_get(brname, drv->iface) == 0) { + wpa_printf(MSG_DEBUG, "Interface in bridge %s; configure for " + "EAPOL receive", brname); + drv->sock_recv = l2_packet_init(brname, NULL, ETH_P_EAPOL, + handle_read, drv, 1); + if (drv->sock_recv == NULL) + goto bad; } else drv->sock_recv = drv->sock_xmit; @@ -1215,8 +1181,9 @@ madwifi_init(struct hostapd_data *hapd, struct wpa_init_params *params) goto bad; } - madwifi_set_iface_flags(drv, 0); /* mark down during setup */ - madwifi_set_privacy(drv->iface, drv, 0); /* default to no privacy */ + /* mark down during setup */ + linux_set_iface_flags(drv->ioctl_sock, drv->iface, 0); + madwifi_set_privacy(drv, 0); /* default to no privacy */ madwifi_receive_probe_req(drv); @@ -1225,6 +1192,8 @@ madwifi_init(struct hostapd_data *hapd, struct wpa_init_params *params) return drv; bad: + if (drv->sock_recv != NULL && drv->sock_recv != drv->sock_xmit) + l2_packet_deinit(drv->sock_recv); if (drv->sock_xmit != NULL) l2_packet_deinit(drv->sock_xmit); if (drv->ioctl_sock >= 0) @@ -1240,8 +1209,8 @@ madwifi_deinit(void *priv) { struct madwifi_driver_data *drv = priv; - madwifi_wireless_event_deinit(drv); - (void) madwifi_set_iface_flags(drv, 0); + netlink_deinit(drv->netlink); + (void) linux_set_iface_flags(drv->ioctl_sock, drv->iface, 0); if (drv->ioctl_sock >= 0) close(drv->ioctl_sock); if (drv->sock_recv != NULL && drv->sock_recv != drv->sock_xmit) @@ -1254,7 +1223,7 @@ madwifi_deinit(void *priv) } static int -madwifi_set_ssid(const char *ifname, void *priv, const u8 *buf, int len) +madwifi_set_ssid(void *priv, const u8 *buf, int len) { struct madwifi_driver_data *drv = priv; struct iwreq iwr; @@ -1274,7 +1243,7 @@ madwifi_set_ssid(const char *ifname, void *priv, const u8 *buf, int len) } static int -madwifi_get_ssid(const char *ifname, void *priv, u8 *buf, int len) +madwifi_get_ssid(void *priv, u8 *buf, int len) { struct madwifi_driver_data *drv = priv; struct iwreq iwr; @@ -1305,13 +1274,14 @@ madwifi_set_countermeasures(void *priv, int enabled) static int madwifi_commit(void *priv) { - return madwifi_set_iface_flags(priv, 1); + struct madwifi_driver_data *drv = priv; + return linux_set_iface_flags(drv->ioctl_sock, drv->iface, 1); } const struct wpa_driver_ops wpa_driver_atheros_ops = { .name = "atheros", .hapd_init = madwifi_init, - .deinit = madwifi_deinit, + .hapd_deinit = madwifi_deinit, .set_ieee8021x = madwifi_set_ieee8021x, .set_privacy = madwifi_set_privacy, .set_key = madwifi_set_key, @@ -1328,6 +1298,5 @@ const struct wpa_driver_ops wpa_driver_atheros_ops = { .set_countermeasures = madwifi_set_countermeasures, .sta_clear_stats = madwifi_sta_clear_stats, .commit = madwifi_commit, - .set_wps_beacon_ie = madwifi_set_wps_beacon_ie, - .set_wps_probe_resp_ie = madwifi_set_wps_probe_resp_ie, + .set_ap_wps_ie = madwifi_set_ap_wps_ie, };