From 088dee0df758e77f936db4aa822e97878f6a79fd Mon Sep 17 00:00:00 2001 From: nico Date: Sun, 14 Aug 2005 07:01:13 +0000 Subject: add hostapd package with initial support for madwifi git-svn-id: svn://svn.openwrt.org/openwrt/trunk/openwrt@1659 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- .../hostapd/patches/001-cross_compile_fix.patch | 32 ++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 package/hostapd/patches/001-cross_compile_fix.patch (limited to 'package/hostapd/patches') diff --git a/package/hostapd/patches/001-cross_compile_fix.patch b/package/hostapd/patches/001-cross_compile_fix.patch new file mode 100644 index 000000000..d4323a7d9 --- /dev/null +++ b/package/hostapd/patches/001-cross_compile_fix.patch @@ -0,0 +1,32 @@ +diff -ruN hostapd-0.3.9-old/Makefile hostapd-0.3.9-new/Makefile +--- hostapd-0.3.9-old/Makefile 2005-06-11 05:03:36.000000000 +0200 ++++ hostapd-0.3.9-new/Makefile 2005-08-14 08:09:52.000000000 +0200 +@@ -3,7 +3,7 @@ + DIR_HOSTAP=. + + ifndef CFLAGS +-CFLAGS = -MMD -O2 -Wall -g ++CFLAGS = -MMD $(OPTFLAGS) $(CPPFLAGS) + endif + + # define HOSTAPD_DUMP_STATE to include SIGUSR1 handler for dumping state to +@@ -173,7 +173,7 @@ + for i in $(ALL); do cp $$i /usr/local/bin/$$i; done + + hostapd: $(OBJS) +- $(CC) -o hostapd $(OBJS) $(LIBS) ++ $(CC) -o hostapd $(OBJS) $(LDFLAGS) $(LIBS) + + driver_conf.c: Makefile .config + rm -f driver_conf.c +diff -ruN hostapd-0.3.9-old/driver_madwifi.c hostapd-0.3.9-new/driver_madwifi.c +--- hostapd-0.3.9-old/driver_madwifi.c 2005-05-18 05:38:57.000000000 +0200 ++++ hostapd-0.3.9-new/driver_madwifi.c 2005-08-14 08:23:21.000000000 +0200 +@@ -24,6 +24,7 @@ + #include + #include + #include ++#include + #include + + #include -- cgit v1.2.3 From 7af4d79491b826de778160c5f683521bf78195db Mon Sep 17 00:00:00 2001 From: nico Date: Sun, 23 Oct 2005 13:16:37 +0000 Subject: update hostapd to latest development release (v0.4.5), add driver for hostap, enable wpa-psk. git-svn-id: svn://svn.openwrt.org/openwrt/trunk/openwrt@2276 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- .../hostapd/patches/001-cross_compile_fix.patch | 11 - package/hostapd/patches/002-madwifi.patch | 1278 ++++++++++++++++++++ 2 files changed, 1278 insertions(+), 11 deletions(-) create mode 100644 package/hostapd/patches/002-madwifi.patch (limited to 'package/hostapd/patches') diff --git a/package/hostapd/patches/001-cross_compile_fix.patch b/package/hostapd/patches/001-cross_compile_fix.patch index d4323a7d9..ca2bb23c7 100644 --- a/package/hostapd/patches/001-cross_compile_fix.patch +++ b/package/hostapd/patches/001-cross_compile_fix.patch @@ -19,14 +19,3 @@ diff -ruN hostapd-0.3.9-old/Makefile hostapd-0.3.9-new/Makefile driver_conf.c: Makefile .config rm -f driver_conf.c -diff -ruN hostapd-0.3.9-old/driver_madwifi.c hostapd-0.3.9-new/driver_madwifi.c ---- hostapd-0.3.9-old/driver_madwifi.c 2005-05-18 05:38:57.000000000 +0200 -+++ hostapd-0.3.9-new/driver_madwifi.c 2005-08-14 08:23:21.000000000 +0200 -@@ -24,6 +24,7 @@ - #include - #include - #include -+#include - #include - - #include diff --git a/package/hostapd/patches/002-madwifi.patch b/package/hostapd/patches/002-madwifi.patch new file mode 100644 index 000000000..f53ad7d89 --- /dev/null +++ b/package/hostapd/patches/002-madwifi.patch @@ -0,0 +1,1278 @@ +diff -ruN hostapd-0.4.5-old/driver_madwifi.c hostapd-0.4.5-new/driver_madwifi.c +--- hostapd-0.4.5-old/driver_madwifi.c 2005-10-23 14:52:39.000000000 +0200 ++++ hostapd-0.4.5-new/driver_madwifi.c 2005-10-23 15:09:45.000000000 +0200 +@@ -20,19 +20,20 @@ + #include + #include + #include ++#include ++#include + + #include + #include + #ifdef WME_NUM_AC + /* Assume this is built against BSD branch of madwifi driver. */ +-#define MADWIFI_BSD + #include + #endif /* WME_NUM_AC */ + #include + #include + + #include +-#include "wireless_copy.h" ++#include + + #include + #include +diff -ruN hostapd-0.4.5-old/driver_madwifi.~c hostapd-0.4.5-new/driver_madwifi.~c +--- hostapd-0.4.5-old/driver_madwifi.~c 1970-01-01 01:00:00.000000000 +0100 ++++ hostapd-0.4.5-new/driver_madwifi.~c 2005-10-23 15:06:20.000000000 +0200 +@@ -0,0 +1,1248 @@ ++/* ++ * Host AP - driver interaction with MADWIFI 802.11 driver ++ * Copyright (c) 2004, Sam Leffler ++ * Copyright (c) 2004, Video54 Technologies ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * Alternatively, this software may be distributed under the terms of BSD ++ * license. ++ * ++ * See README and COPYING for more details. ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#ifdef WME_NUM_AC ++/* Assume this is built against BSD branch of madwifi driver. */ ++#include ++#endif /* WME_NUM_AC */ ++#include ++#include ++ ++#include ++#include ++ ++#include ++#include ++ ++#include "hostapd.h" ++#include "driver.h" ++#include "ieee802_1x.h" ++#include "eloop.h" ++#include "priv_netlink.h" ++#include "sta_info.h" ++#include "l2_packet.h" ++#include "hostap_common.h" ++ ++#include "eapol_sm.h" ++#include "wpa.h" ++#include "radius.h" ++#include "ieee802_11.h" ++#include "accounting.h" ++#include "common.h" ++ ++ ++struct madwifi_driver_data { ++ struct driver_ops ops; /* base class */ ++ struct hostapd_data *hapd; /* back pointer */ ++ ++ char iface[IFNAMSIZ + 1]; ++ int ifindex; ++ 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 */ ++ int we_version; ++ u8 acct_mac[ETH_ALEN]; ++ struct hostap_sta_driver_data acct_data; ++}; ++ ++static const struct driver_ops madwifi_driver_ops; ++ ++static int madwifi_sta_deauth(void *priv, u8 *addr, int reason_code); ++ ++static int ++set80211priv(struct madwifi_driver_data *drv, int op, void *data, int len) ++{ ++#define N(a) (sizeof(a)/sizeof(a[0])) ++ struct iwreq iwr; ++ ++ memset(&iwr, 0, sizeof(iwr)); ++ strncpy(iwr.ifr_name, drv->iface, IFNAMSIZ); ++ if (len < IFNAMSIZ) { ++ /* ++ * Argument data fits inline; put it there. ++ */ ++ memcpy(iwr.u.name, data, len); ++ } else { ++ /* ++ * Argument data too big for inline transfer; setup a ++ * parameter block instead; the kernel will transfer ++ * the data for the driver. ++ */ ++ iwr.u.data.pointer = data; ++ iwr.u.data.length = len; ++ } ++ ++ if (ioctl(drv->ioctl_sock, op, &iwr) < 0) { ++ static const char *opnames[] = { ++ "ioctl[IEEE80211_IOCTL_SETPARAM]", ++ "ioctl[IEEE80211_IOCTL_GETPARAM]", ++ "ioctl[IEEE80211_IOCTL_SETKEY]", ++ "ioctl[SIOCIWFIRSTPRIV+3]", ++ "ioctl[IEEE80211_IOCTL_DELKEY]", ++ "ioctl[SIOCIWFIRSTPRIV+5]", ++ "ioctl[IEEE80211_IOCTL_SETMLME]", ++ "ioctl[SIOCIWFIRSTPRIV+7]", ++ "ioctl[IEEE80211_IOCTL_SETOPTIE]", ++ "ioctl[IEEE80211_IOCTL_GETOPTIE]", ++ "ioctl[IEEE80211_IOCTL_ADDMAC]", ++ "ioctl[SIOCIWFIRSTPRIV+11]", ++ "ioctl[IEEE80211_IOCTL_DELMAC]", ++ "ioctl[SIOCIWFIRSTPRIV+13]", ++ "ioctl[IEEE80211_IOCTL_CHANLIST]", ++ "ioctl[SIOCIWFIRSTPRIV+15]", ++ "ioctl[IEEE80211_IOCTL_GETRSN]", ++ "ioctl[SIOCIWFIRSTPRIV+17]", ++ "ioctl[IEEE80211_IOCTL_GETKEY]", ++ }; ++ op -= SIOCIWFIRSTPRIV; ++ if (0 <= op && op < N(opnames)) ++ perror(opnames[op]); ++ else ++ perror("ioctl[unknown???]"); ++ return -1; ++ } ++ return 0; ++#undef N ++} ++ ++static int ++set80211param(struct madwifi_driver_data *drv, int op, int arg) ++{ ++ struct iwreq iwr; ++ ++ memset(&iwr, 0, sizeof(iwr)); ++ strncpy(iwr.ifr_name, drv->iface, IFNAMSIZ); ++ iwr.u.mode = op; ++ memcpy(iwr.u.name+sizeof(__u32), &arg, sizeof(arg)); ++ ++ if (ioctl(drv->ioctl_sock, IEEE80211_IOCTL_SETPARAM, &iwr) < 0) { ++ perror("ioctl[IEEE80211_IOCTL_SETPARAM]"); ++ return -1; ++ } ++ return 0; ++} ++ ++static const char * ++ether_sprintf(const u8 *addr) ++{ ++ static char buf[sizeof(MACSTR)]; ++ ++ if (addr != NULL) ++ snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr)); ++ else ++ snprintf(buf, sizeof(buf), MACSTR, 0,0,0,0,0,0); ++ return buf; ++} ++ ++/* ++ * Configure WPA parameters. ++ */ ++static int ++madwifi_configure_wpa(struct madwifi_driver_data *drv) ++{ ++ hostapd *hapd = drv->hapd; ++ struct hostapd_config *conf = hapd->conf; ++ int v; ++ ++ switch (conf->wpa_group) { ++ case WPA_CIPHER_CCMP: ++ v = IEEE80211_CIPHER_AES_CCM; ++ break; ++ case WPA_CIPHER_TKIP: ++ v = IEEE80211_CIPHER_TKIP; ++ break; ++ case WPA_CIPHER_WEP104: ++ v = IEEE80211_CIPHER_WEP; ++ break; ++ case WPA_CIPHER_WEP40: ++ v = IEEE80211_CIPHER_WEP; ++ break; ++ case WPA_CIPHER_NONE: ++ v = IEEE80211_CIPHER_NONE; ++ break; ++ default: ++ printf("Unknown group key cipher %u\n", ++ conf->wpa_group); ++ return -1; ++ } ++ HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, ++ "%s: group key cipher=%d\n", __func__, v); ++ if (set80211param(drv, IEEE80211_PARAM_MCASTCIPHER, v)) { ++ printf("Unable to set group key cipher to %u\n", v); ++ return -1; ++ } ++ if (v == IEEE80211_CIPHER_WEP) { ++ /* key length is done only for specific ciphers */ ++ v = (conf->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; ++ } ++ } ++ ++ v = 0; ++ if (conf->wpa_pairwise & WPA_CIPHER_CCMP) ++ v |= 1<wpa_pairwise & WPA_CIPHER_TKIP) ++ v |= 1<wpa_pairwise & WPA_CIPHER_NONE) ++ v |= 1<wpa_key_mgmt); ++ if (set80211param(drv, IEEE80211_PARAM_KEYMGTALGS, conf->wpa_key_mgmt)) { ++ printf("Unable to set key management algorithms to 0x%x\n", ++ conf->wpa_key_mgmt); ++ return -1; ++ } ++ ++ v = 0; ++ if (conf->rsn_preauth) ++ v |= BIT(0); ++ HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, ++ "%s: rsn capabilities=0x%x\n", __func__, conf->rsn_preauth); ++ if (set80211param(drv, IEEE80211_PARAM_RSNCAPS, v)) { ++ printf("Unable to set RSN capabilities to 0x%x\n", v); ++ return -1; ++ } ++ ++ HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, ++ "%s: enable WPA= 0x%x\n", __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; ++ hostapd *hapd = drv->hapd; ++ struct ifreq ifr; ++ ++ HOSTAPD_DEBUG(HOSTAPD_DEBUG_VERBOSE, ++ "%s: dev_up=%d\n", __func__, dev_up); ++ ++ if (drv->ioctl_sock < 0) ++ return -1; ++ ++ memset(&ifr, 0, sizeof(ifr)); ++ snprintf(ifr.ifr_name, IFNAMSIZ, "%s", drv->iface); ++ ++ 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]"); ++ return -1; ++ } ++ ++ if (dev_up) { ++ memset(&ifr, 0, sizeof(ifr)); ++ snprintf(ifr.ifr_name, IFNAMSIZ, "%s", drv->iface); ++ ifr.ifr_mtu = HOSTAPD_MTU; ++ if (ioctl(drv->ioctl_sock, SIOCSIFMTU, &ifr) != 0) { ++ perror("ioctl[SIOCSIFMTU]"); ++ printf("Setting MTU failed - trying to survive with " ++ "current value\n"); ++ } ++ } ++ ++ return 0; ++} ++ ++static int ++madwifi_set_ieee8021x(void *priv, int enabled) ++{ ++ struct madwifi_driver_data *drv = priv; ++ hostapd *hapd = drv->hapd; ++ struct hostapd_config *conf = hapd->conf; ++ ++ HOSTAPD_DEBUG(HOSTAPD_DEBUG_VERBOSE, ++ "%s: enabled=%d\n", __func__, enabled); ++ ++ if (!enabled) { ++ /* XXX restore state */ ++ return set80211param(priv, IEEE80211_PARAM_AUTHMODE, ++ IEEE80211_AUTH_AUTO); ++ } ++ if (!conf->wpa && !conf->ieee802_1x) { ++ hostapd_logger(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, ++ 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, ++ HOSTAPD_LEVEL_WARNING, "Error enabling WPA/802.1X!"); ++ return -1; ++ } ++ return madwifi_set_iface_flags(priv, 1); ++} ++ ++static int ++madwifi_set_privacy(void *priv, int enabled) ++{ ++ struct madwifi_driver_data *drv = priv; ++ hostapd *hapd = drv->hapd; ++ ++ HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, ++ "%s: enabled=%d\n", __func__, enabled); ++ ++ return set80211param(priv, IEEE80211_PARAM_PRIVACY, enabled); ++} ++ ++static int ++madwifi_set_sta_authorized(void *priv, u8 *addr, int authorized) ++{ ++ struct madwifi_driver_data *drv = priv; ++ hostapd *hapd = drv->hapd; ++ struct ieee80211req_mlme mlme; ++ ++ HOSTAPD_DEBUG(HOSTAPD_DEBUG_VERBOSE, ++ "%s: addr=%s authorized=%d\n", ++ __func__, ether_sprintf(addr), authorized); ++ ++ if (authorized) ++ mlme.im_op = IEEE80211_MLME_AUTHORIZE; ++ else ++ mlme.im_op = IEEE80211_MLME_UNAUTHORIZE; ++ mlme.im_reason = 0; ++ memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); ++ return set80211priv(priv, IEEE80211_IOCTL_SETMLME, &mlme, ++ sizeof(mlme)); ++} ++ ++static int ++madwifi_del_key(void *priv, unsigned char *addr, int key_idx) ++{ ++ struct madwifi_driver_data *drv = priv; ++ hostapd *hapd = drv->hapd; ++ struct ieee80211req_del_key wk; ++ ++ HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, ++ "%s: addr=%s key_idx=%d\n", ++ __func__, ether_sprintf(addr), key_idx); ++ ++ memset(&wk, 0, sizeof(wk)); ++ if (addr != NULL) { ++ memcpy(wk.idk_macaddr, addr, IEEE80211_ADDR_LEN); ++ wk.idk_keyix = (u8) IEEE80211_KEYIX_NONE; ++ } else { ++ wk.idk_keyix = key_idx; ++ } ++ ++ return set80211priv(priv, IEEE80211_IOCTL_DELKEY, &wk, sizeof(wk)); ++} ++ ++static int ++madwifi_set_key(void *priv, const char *alg, ++ unsigned char *addr, int key_idx, ++ u8 *key, size_t key_len) ++{ ++ struct madwifi_driver_data *drv = priv; ++ hostapd *hapd = drv->hapd; ++ struct ieee80211req_key wk; ++ u_int8_t cipher; ++ ++ if (strcmp(alg, "none") == 0) ++ return madwifi_del_key(priv, addr, key_idx); ++ ++ HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, ++ "%s: alg=%s addr=%s key_idx=%d\n", ++ __func__, alg, ether_sprintf(addr), key_idx); ++ ++ if (strcmp(alg, "WEP") == 0) ++ cipher = IEEE80211_CIPHER_WEP; ++ else if (strcmp(alg, "TKIP") == 0) ++ cipher = IEEE80211_CIPHER_TKIP; ++ else if (strcmp(alg, "CCMP") == 0) ++ cipher = IEEE80211_CIPHER_AES_CCM; ++ else { ++ printf("%s: unknown/unsupported algorithm %s\n", ++ __func__, alg); ++ return -1; ++ } ++ ++ if (key_len > sizeof(wk.ik_keydata)) { ++ printf("%s: key length %lu too big\n", __func__, ++ (unsigned long) key_len); ++ return -3; ++ } ++ ++ memset(&wk, 0, sizeof(wk)); ++ wk.ik_type = cipher; ++ wk.ik_flags = IEEE80211_KEY_RECV | IEEE80211_KEY_XMIT; ++ if (addr == NULL) { ++ memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN); ++ wk.ik_keyix = key_idx; ++ wk.ik_flags |= IEEE80211_KEY_DEFAULT; ++ } else { ++ memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN); ++ wk.ik_keyix = IEEE80211_KEYIX_NONE; ++ } ++ wk.ik_keylen = key_len; ++ memcpy(wk.ik_keydata, key, key_len); ++ ++ return set80211priv(priv, IEEE80211_IOCTL_SETKEY, &wk, sizeof(wk)); ++} ++ ++ ++static int ++madwifi_get_seqnum(void *priv, u8 *addr, int idx, u8 *seq) ++{ ++ struct madwifi_driver_data *drv = priv; ++ hostapd *hapd = drv->hapd; ++ struct ieee80211req_key wk; ++ ++ HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, ++ "%s: addr=%s idx=%d\n", __func__, ether_sprintf(addr), idx); ++ ++ memset(&wk, 0, sizeof(wk)); ++ if (addr == NULL) ++ memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN); ++ else ++ memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN); ++ wk.ik_keyix = idx; ++ ++ if (set80211priv(priv, IEEE80211_IOCTL_GETKEY, &wk, sizeof(wk))) { ++ printf("Failed to get encryption.\n"); ++ return -1; ++ } ++ ++#ifdef WORDS_BIGENDIAN ++ { ++ /* ++ * wk.ik_keytsc is in host byte order (big endian), need to ++ * swap it to match with the byte order used in WPA. ++ */ ++ int i; ++ u8 tmp[WPA_KEY_RSC_LEN]; ++ memcpy(tmp, &wk.ik_keytsc, sizeof(wk.ik_keytsc)); ++ for (i = 0; i < WPA_KEY_RSC_LEN; i++) { ++ seq[i] = tmp[WPA_KEY_RSC_LEN - i - 1]; ++ } ++ } ++#else /* WORDS_BIGENDIAN */ ++ memcpy(seq, &wk.ik_keytsc, sizeof(wk.ik_keytsc)); ++#endif /* WORDS_BIGENDIAN */ ++ return 0; ++} ++ ++ ++static int ++madwifi_flush(void *priv) ++{ ++#ifdef MADWIFI_BSD ++ u8 allsta[IEEE80211_ADDR_LEN]; ++ memset(allsta, 0xff, IEEE80211_ADDR_LEN); ++ return madwifi_sta_deauth(priv, allsta, IEEE80211_REASON_AUTH_LEAVE); ++#else /* MADWIFI_BSD */ ++ return 0; /* XXX */ ++#endif /* MADWIFI_BSD */ ++} ++ ++ ++static int ++madwifi_read_sta_driver_data(void *priv, struct hostap_sta_driver_data *data, ++ u8 *addr) ++{ ++ struct madwifi_driver_data *drv = priv; ++ ++#ifdef MADWIFI_BSD ++ struct ieee80211req_sta_stats stats; ++ ++ memset(data, 0, sizeof(*data)); ++ ++ /* ++ * Fetch statistics for station from the system. ++ */ ++ memset(&stats, 0, sizeof(stats)); ++ memcpy(stats.is_u.macaddr, addr, IEEE80211_ADDR_LEN); ++ if (set80211priv(drv, IEEE80211_IOCTL_GETSTASTATS, &stats, ++ sizeof(stats))) { ++ if (memcmp(addr, drv->acct_mac, ETH_ALEN) == 0) { ++ memcpy(data, &drv->acct_data, sizeof(*data)); ++ return 0; ++ } ++ ++ printf("Failed to get station stats information element.\n"); ++ return -1; ++ } ++ ++ data->rx_packets = stats.is_stats.ns_rx_data; ++ data->rx_bytes = stats.is_stats.ns_rx_bytes; ++ data->tx_packets = stats.is_stats.ns_tx_data; ++ data->tx_bytes = stats.is_stats.ns_tx_bytes; ++ return 0; ++ ++#else /* MADWIFI_BSD */ ++ ++ char buf[1024], line[128], *pos; ++ FILE *f; ++ unsigned long val; ++ ++ memset(data, 0, sizeof(*data)); ++ snprintf(buf, sizeof(buf), "/proc/net/madwifi/%s/" MACSTR, ++ drv->iface, MAC2STR(addr)); ++ ++ f = fopen(buf, "r"); ++ if (!f) { ++ if (memcmp(addr, drv->acct_mac, ETH_ALEN) != 0) ++ return -1; ++ memcpy(data, &drv->acct_data, sizeof(*data)); ++ return 0; ++ } ++ /* Need to read proc file with in one piece, so use large enough ++ * buffer. */ ++ setbuffer(f, buf, sizeof(buf)); ++ ++ while (fgets(line, sizeof(line), f)) { ++ pos = strchr(line, '='); ++ if (!pos) ++ continue; ++ *pos++ = '\0'; ++ val = strtoul(pos, NULL, 10); ++ if (strcmp(line, "rx_packets") == 0) ++ data->rx_packets = val; ++ else if (strcmp(line, "tx_packets") == 0) ++ data->tx_packets = val; ++ else if (strcmp(line, "rx_bytes") == 0) ++ data->rx_bytes = val; ++ else if (strcmp(line, "tx_bytes") == 0) ++ data->tx_bytes = val; ++ } ++ ++ fclose(f); ++ ++ return 0; ++#endif /* MADWIFI_BSD */ ++} ++ ++ ++static int ++madwifi_sta_clear_stats(void *priv, u8 *addr) ++{ ++#ifdef MADWIFI_BSD ++ struct madwifi_driver_data *drv = priv; ++ struct hostapd_data *hapd = drv->hapd; ++ struct ieee80211req_mlme mlme; ++ ++ HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "%s: addr=%s\n", ++ __func__, ether_sprintf(addr)); ++ ++ mlme.im_op = IEEE80211_MLME_CLEAR_STATS; ++ memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); ++ return set80211priv(priv, IEEE80211_IOCTL_SETMLME, &mlme, ++ sizeof(mlme)); ++#else /* MADWIFI_BSD */ ++ return 0; /* FIX */ ++#endif /* MADWIFI_BSD */ ++} ++ ++ ++static int ++madwifi_set_opt_ie(void *priv, const u8 *ie, size_t ie_len) ++{ ++ /* ++ * Do nothing; we setup parameters at startup that define the ++ * contents of the beacon information element. ++ */ ++ return 0; ++} ++ ++static int ++madwifi_sta_deauth(void *priv, u8 *addr, int reason_code) ++{ ++ struct madwifi_driver_data *drv = priv; ++ hostapd *hapd = drv->hapd; ++ struct ieee80211req_mlme mlme; ++ ++ HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, ++ "%s: addr=%s reason_code=%d\n", ++ __func__, ether_sprintf(addr), reason_code); ++ ++ mlme.im_op = IEEE80211_MLME_DEAUTH; ++ mlme.im_reason = reason_code; ++ memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); ++ return set80211priv(priv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme)); ++} ++ ++static int ++madwifi_sta_disassoc(void *priv, u8 *addr, int reason_code) ++{ ++ struct madwifi_driver_data *drv = priv; ++ hostapd *hapd = drv->hapd; ++ struct ieee80211req_mlme mlme; ++ ++ HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, ++ "%s: addr=%s reason_code=%d\n", ++ __func__, ether_sprintf(addr), reason_code); ++ ++ mlme.im_reason = reason_code; ++ memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); ++ return set80211priv(priv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme)); ++} ++ ++static int ++madwifi_del_sta(struct madwifi_driver_data *drv, u8 addr[IEEE80211_ADDR_LEN]) ++{ ++ struct hostapd_data *hapd = drv->hapd; ++ struct sta_info *sta; ++ ++ hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211, ++ HOSTAPD_LEVEL_INFO, "deassociated"); ++ ++ sta = ap_get_sta(hapd, addr); ++ if (sta != NULL) { ++ sta->flags &= ~WLAN_STA_ASSOC; ++ wpa_sm_event(hapd, sta, WPA_DISASSOC); ++ sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST; ++ ieee802_1x_set_port_enabled(hapd, sta, 0); ++ ap_free_sta(hapd, sta); ++ } ++ return 0; ++} ++ ++static int ++madwifi_process_wpa_ie(struct madwifi_driver_data *drv, struct sta_info *sta) ++{ ++ struct hostapd_data *hapd = drv->hapd; ++ struct ieee80211req_wpaie ie; ++ int ielen, res; ++ ++ /* ++ * Fetch negotiated WPA/RSN parameters from the system. ++ */ ++ memset(&ie, 0, sizeof(ie)); ++ memcpy(ie.wpa_macaddr, sta->addr, IEEE80211_ADDR_LEN); ++ if (set80211priv(drv, IEEE80211_IOCTL_GETWPAIE, &ie, sizeof(ie))) { ++ printf("Failed to get WPA/RSN information element.\n"); ++ return -1; /* XXX not right */ ++ } ++ ielen = ie.wpa_ie[1]; ++ if (ielen == 0) { ++ printf("No WPA/RSN information element for station!?\n"); ++ return -1; /* XXX not right */ ++ } ++ ielen += 2; ++ res = wpa_validate_wpa_ie(hapd, sta, ie.wpa_ie, ielen, ++ ie.wpa_ie[0] == WLAN_EID_RSN ? ++ HOSTAPD_WPA_VERSION_WPA2 : HOSTAPD_WPA_VERSION_WPA); ++ if (res != WPA_IE_OK) { ++ printf("WPA/RSN information element rejected? (res %u)\n", res); ++ return -1; ++ } ++ free(sta->wpa_ie); ++ sta->wpa_ie = malloc(ielen); ++ if (sta->wpa_ie == NULL) { ++ printf("No memory to save WPA/RSN information element!\n"); ++ return -1; ++ } ++ memcpy(sta->wpa_ie, ie.wpa_ie, ielen); ++ sta->wpa_ie_len = ielen; ++ return 0; ++} ++ ++static int ++madwifi_new_sta(struct madwifi_driver_data *drv, u8 addr[IEEE80211_ADDR_LEN]) ++{ ++ struct hostapd_data *hapd = drv->hapd; ++ struct sta_info *sta; ++ int new_assoc; ++ ++ hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211, ++ HOSTAPD_LEVEL_INFO, "associated"); ++ ++ sta = ap_get_sta(hapd, addr); ++ if (sta) { ++ accounting_sta_stop(hapd, sta); ++ } else { ++ sta = ap_sta_add(hapd, addr); ++ if (sta == NULL) ++ return -1; ++ } ++ ++ 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)); ++ } ++ accounting_sta_get_id(hapd, sta); ++ ++ if (hapd->conf->wpa) { ++ if (madwifi_process_wpa_ie(drv, sta)) ++ return -1; ++ } else { ++ free(sta->wpa_ie); ++ sta->wpa_ie = NULL; ++ sta->wpa_ie_len = 0; ++ } ++ ++ /* ++ * Now that the internal station state is setup ++ * kick the authenticator into action. ++ */ ++ new_assoc = (sta->flags & WLAN_STA_ASSOC) == 0; ++ sta->flags |= WLAN_STA_ASSOC; ++ wpa_sm_event(hapd, sta, WPA_ASSOC); ++ hostapd_new_assoc_sta(hapd, sta, !new_assoc); ++ ieee802_1x_notify_port_enabled(sta->eapol_sm, 1); ++ return 0; ++} ++ ++static void ++madwifi_wireless_event_wireless_custom(struct madwifi_driver_data *drv, ++ char *custom) ++{ ++ struct hostapd_data *hapd = drv->hapd; ++ ++ HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "Custom wireless event: '%s'\n", ++ custom); ++ ++ if (strncmp(custom, "MLME-MICHAELMICFAILURE.indication", 33) == 0) { ++ char *pos; ++ u8 addr[ETH_ALEN]; ++ pos = strstr(custom, "addr="); ++ if (pos == NULL) { ++ HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, ++ "MLME-MICHAELMICFAILURE.indication " ++ "without sender address ignored\n"); ++ return; ++ } ++ pos += 5; ++ if (hwaddr_aton(pos, addr) == 0) { ++ ieee80211_michael_mic_failure(drv->hapd, addr, 1); ++ } else { ++ HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, ++ "MLME-MICHAELMICFAILURE.indication " ++ "with invalid MAC address"); ++ } ++ } else if (strncmp(custom, "STA-TRAFFIC-STAT", 16) == 0) { ++ char *key, *value; ++ u32 val; ++ key = custom; ++ while ((key = strchr(key, '\n')) != NULL) { ++ key++; ++ value = strchr(key, '='); ++ if (value == NULL) ++ continue; ++ *value++ = '\0'; ++ val = strtoul(value, NULL, 10); ++ if (strcmp(key, "mac") == 0) ++ hwaddr_aton(value, drv->acct_mac); ++ else if (strcmp(key, "rx_packets") == 0) ++ drv->acct_data.rx_packets = val; ++ else if (strcmp(key, "tx_packets") == 0) ++ drv->acct_data.tx_packets = val; ++ else if (strcmp(key, "rx_bytes") == 0) ++ drv->acct_data.rx_bytes = val; ++ else if (strcmp(key, "tx_bytes") == 0) ++ drv->acct_data.tx_bytes = val; ++ key = value; ++ } ++ } ++} ++ ++static void ++madwifi_wireless_event_wireless(struct madwifi_driver_data *drv, ++ char *data, int len) ++{ ++ struct hostapd_data *hapd = drv->hapd; ++ struct iw_event iwe_buf, *iwe = &iwe_buf; ++ char *pos, *end, *custom, *buf; ++ ++ pos = data; ++ end = data + len; ++ ++ while (pos + IW_EV_LCP_LEN <= end) { ++ /* Event data may be unaligned, so make a local, aligned copy ++ * before processing. */ ++ memcpy(&iwe_buf, pos, IW_EV_LCP_LEN); ++ HOSTAPD_DEBUG(HOSTAPD_DEBUG_VERBOSE, "Wireless event: " ++ "cmd=0x%x len=%d\n", iwe->cmd, iwe->len); ++ if (iwe->len <= IW_EV_LCP_LEN) ++ return; ++ ++ custom = pos + IW_EV_POINT_LEN; ++ if (drv->we_version > 18 && ++ (iwe->cmd == IWEVMICHAELMICFAILURE || ++ iwe->cmd == IWEVCUSTOM)) { ++ /* WE-19 removed the pointer from struct iw_point */ ++ char *dpos = (char *) &iwe_buf.u.data.length; ++ int dlen = dpos - (char *) &iwe_buf; ++ memcpy(dpos, pos + IW_EV_LCP_LEN, ++ sizeof(struct iw_event) - dlen); ++ } else { ++ memcpy(&iwe_buf, pos, sizeof(struct iw_event)); ++ custom += IW_EV_POINT_OFF; ++ } ++ ++ switch (iwe->cmd) { ++ case IWEVEXPIRED: ++ madwifi_del_sta(drv, iwe->u.addr.sa_data); ++ break; ++ case IWEVREGISTERED: ++ madwifi_new_sta(drv, iwe->u.addr.sa_data); ++ break; ++ case IWEVCUSTOM: ++ if (custom + iwe->u.data.length > end) ++ return; ++ buf = malloc(iwe->u.data.length + 1); ++ if (buf == NULL) ++ return; /* XXX */ ++ memcpy(buf, custom, iwe->u.data.length); ++ buf[iwe->u.data.length] = '\0'; ++ madwifi_wireless_event_wireless_custom(drv, buf); ++ free(buf); ++ break; ++ } ++ ++ pos += iwe->len; ++ } ++} ++ ++ ++static void ++madwifi_wireless_event_rtm_newlink(struct madwifi_driver_data *drv, ++ struct nlmsghdr *h, int len) ++{ ++ struct ifinfomsg *ifi; ++ int attrlen, nlmsg_len, rta_len; ++ struct rtattr * attr; ++ ++ if (len < sizeof(*ifi)) ++ return; ++ ++ ifi = NLMSG_DATA(h); ++ ++ 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); ++ ++ rta_len = RTA_ALIGN(sizeof(struct rtattr)); ++ while (RTA_OK(attr, attrlen)) { ++ if (attr->rta_type == IFLA_WIRELESS) { ++ madwifi_wireless_event_wireless( ++ drv, ((char *) attr) + rta_len, ++ attr->rta_len - rta_len); ++ } ++ attr = RTA_NEXT(attr, attrlen); ++ } ++} ++ ++ ++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 >= 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) ++{ ++ struct iw_range *range; ++ struct iwreq iwr; ++ int minlen; ++ size_t buflen; ++ ++ drv->we_version = 0; ++ ++ /* ++ * Use larger buffer than struct iw_range in order to allow the ++ * structure to grow in the future. ++ */ ++ buflen = sizeof(struct iw_range) + 500; ++ range = malloc(buflen); ++ if (range == NULL) ++ return -1; ++ memset(range, 0, buflen); ++ ++ memset(&iwr, 0, sizeof(iwr)); ++ strncpy(iwr.ifr_name, drv->iface, IFNAMSIZ); ++ iwr.u.data.pointer = (caddr_t) range; ++ iwr.u.data.length = buflen; ++ ++ minlen = ((char *) &range->enc_capa) - (char *) range + ++ sizeof(range->enc_capa); ++ ++ if (ioctl(drv->ioctl_sock, SIOCGIWRANGE, &iwr) < 0) { ++ perror("ioctl[SIOCGIWRANGE]"); ++ free(range); ++ return -1; ++ } else if (iwr.u.data.length >= minlen && ++ range->we_version_compiled >= 18) { ++ wpa_printf(MSG_DEBUG, "SIOCGIWRANGE: WE(compiled)=%d " ++ "WE(source)=%d enc_capa=0x%x", ++ range->we_version_compiled, ++ range->we_version_source, ++ range->enc_capa); ++ drv->we_version = range->we_version_compiled; ++ } ++ ++ free(range); ++ return 0; ++} ++ ++ ++static int ++madwifi_wireless_event_init(void *priv) ++{ ++ struct madwifi_driver_data *drv = priv; ++ int s; ++ struct sockaddr_nl local; ++ ++ 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)"); ++ 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); ++ 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(void *priv) ++{ ++ struct madwifi_driver_data *drv = priv; ++ ++ if (drv != NULL) { ++ if (drv->wext_sock < 0) ++ return; ++ eloop_unregister_read_sock(drv->wext_sock); ++ close(drv->wext_sock); ++ } ++} ++ ++ ++static int ++madwifi_send_eapol(void *priv, u8 *addr, u8 *data, size_t data_len, int encrypt) ++{ ++ struct madwifi_driver_data *drv = priv; ++ hostapd *hapd = drv->hapd; ++ unsigned char buf[3000]; ++ unsigned char *bp = buf; ++ struct l2_ethhdr *eth; ++ size_t len; ++ int status; ++ ++ /* ++ * Prepend the Etherent header. If the caller left us ++ * space at the front we could just insert it but since ++ * we don't know we copy to a local buffer. Given the frequency ++ * and size of frames this probably doesn't matter. ++ */ ++ len = data_len + sizeof(struct l2_ethhdr); ++ if (len > sizeof(buf)) { ++ bp = malloc(len); ++ if (bp == NULL) { ++ printf("EAPOL frame discarded, cannot malloc temp " ++ "buffer of size %lu!\n", (unsigned long) len); ++ return -1; ++ } ++ } ++ eth = (struct l2_ethhdr *) bp; ++ memcpy(eth->h_dest, addr, ETH_ALEN); ++ memcpy(eth->h_source, drv->hapd->own_addr, ETH_ALEN); ++ eth->h_proto = htons(ETH_P_EAPOL); ++ memcpy(eth+1, data, data_len); ++ ++ if (HOSTAPD_DEBUG_COND(HOSTAPD_DEBUG_MSGDUMPS)) ++ hostapd_hexdump("TX EAPOL", bp, len); ++ ++ status = l2_packet_send(drv->sock_xmit, addr, ETH_P_EAPOL, bp, len); ++ ++ if (bp != buf) ++ free(bp); ++ return status; ++} ++ ++static void ++handle_read(void *ctx, const u8 *src_addr, const u8 *buf, size_t len) ++{ ++ struct madwifi_driver_data *drv = ctx; ++ hostapd *hapd = drv->hapd; ++ struct sta_info *sta; ++ ++ sta = ap_get_sta(hapd, src_addr); ++ if (!sta || !(sta->flags & WLAN_STA_ASSOC)) { ++ printf("Data frame from not associated STA %s\n", ++ ether_sprintf(src_addr)); ++ /* XXX cannot happen */ ++ return; ++ } ++ ieee802_1x_receive(hapd, src_addr, buf + sizeof(struct l2_ethhdr), ++ len - sizeof(struct l2_ethhdr)); ++} ++ ++static int ++madwifi_init(struct hostapd_data *hapd) ++{ ++ struct madwifi_driver_data *drv; ++ struct ifreq ifr; ++ struct iwreq iwr; ++ ++ drv = malloc(sizeof(struct madwifi_driver_data)); ++ if (drv == NULL) { ++ printf("Could not allocate memory for madwifi driver data\n"); ++ goto bad; ++ } ++ ++ memset(drv, 0, sizeof(*drv)); ++ drv->ops = madwifi_driver_ops; ++ drv->hapd = hapd; ++ drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0); ++ if (drv->ioctl_sock < 0) { ++ perror("socket[PF_INET,SOCK_DGRAM]"); ++ goto bad; ++ } ++ memcpy(drv->iface, hapd->conf->iface, sizeof(drv->iface)); ++ ++ memset(&ifr, 0, sizeof(ifr)); ++ snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", drv->iface); ++ if (ioctl(drv->ioctl_sock, SIOCGIFINDEX, &ifr) != 0) { ++ perror("ioctl(SIOCGIFINDEX)"); ++ goto bad; ++ } ++ drv->ifindex = ifr.ifr_ifindex; ++ ++ drv->sock_xmit = l2_packet_init(drv->iface, NULL, ETH_P_EAPOL, ++ handle_read, drv, 1); ++ if (drv->sock_xmit == NULL) ++ goto bad; ++ if (l2_packet_get_own_addr(drv->sock_xmit, hapd->own_addr)) ++ goto bad; ++ if (hapd->conf->bridge[0] != '\0') { ++ HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, ++ "Configure bridge %s for EAPOL traffic.\n", ++ hapd->conf->bridge); ++ drv->sock_recv = l2_packet_init(hapd->conf->bridge, NULL, ++ ETH_P_EAPOL, handle_read, drv, ++ 0); ++ if (drv->sock_recv == NULL) ++ goto bad; ++ } else ++ drv->sock_recv = drv->sock_xmit; ++ ++ memset(&iwr, 0, sizeof(iwr)); ++ strncpy(iwr.ifr_name, drv->iface, IFNAMSIZ); ++ ++ iwr.u.mode = IW_MODE_MASTER; ++ ++ if (ioctl(drv->ioctl_sock, SIOCSIWMODE, &iwr) < 0) { ++ perror("ioctl[SIOCSIWMODE]"); ++ printf("Could not set interface to master mode!\n"); ++ goto bad; ++ } ++ ++ madwifi_set_iface_flags(drv, 0); /* mark down during setup */ ++ ++ hapd->driver = &drv->ops; ++ return 0; ++bad: ++ if (drv->sock_xmit != NULL) ++ l2_packet_deinit(drv->sock_xmit); ++ if (drv->ioctl_sock >= 0) ++ close(drv->ioctl_sock); ++ if (drv != NULL) ++ free(drv); ++ return -1; ++} ++ ++ ++static void ++madwifi_deinit(void *priv) ++{ ++ struct madwifi_driver_data *drv = priv; ++ ++ drv->hapd->driver = NULL; ++ ++ (void) madwifi_set_iface_flags(drv, 0); ++ if (drv->ioctl_sock >= 0) ++ close(drv->ioctl_sock); ++ 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); ++ free(drv); ++} ++ ++static int ++madwifi_set_ssid(void *priv, u8 *buf, int len) ++{ ++ struct madwifi_driver_data *drv = priv; ++ struct iwreq iwr; ++ ++ memset(&iwr, 0, sizeof(iwr)); ++ strncpy(iwr.ifr_name, drv->iface, IFNAMSIZ); ++ iwr.u.essid.flags = 1; /* SSID active */ ++ iwr.u.essid.pointer = (caddr_t) buf; ++ iwr.u.essid.length = len + 1; ++ ++ if (ioctl(drv->ioctl_sock, SIOCSIWESSID, &iwr) < 0) { ++ perror("ioctl[SIOCSIWESSID]"); ++ printf("len=%d\n", len); ++ return -1; ++ } ++ return 0; ++} ++ ++static int ++madwifi_get_ssid(void *priv, u8 *buf, int len) ++{ ++ struct madwifi_driver_data *drv = priv; ++ struct iwreq iwr; ++ int ret = 0; ++ ++ memset(&iwr, 0, sizeof(iwr)); ++ strncpy(iwr.ifr_name, drv->iface, IFNAMSIZ); ++ iwr.u.essid.pointer = (caddr_t) buf; ++ iwr.u.essid.length = len; ++ ++ if (ioctl(drv->ioctl_sock, SIOCGIWESSID, &iwr) < 0) { ++ perror("ioctl[SIOCGIWESSID]"); ++ ret = -1; ++ } else ++ ret = iwr.u.essid.length; ++ ++ return ret; ++} ++ ++static const struct driver_ops madwifi_driver_ops = { ++ .name = "madwifi", ++ .init = madwifi_init, ++ .deinit = madwifi_deinit, ++ .set_ieee8021x = madwifi_set_ieee8021x, ++ .set_privacy = madwifi_set_privacy, ++ .set_encryption = madwifi_set_key, ++ .get_seqnum = madwifi_get_seqnum, ++ .flush = madwifi_flush, ++ .set_generic_elem = madwifi_set_opt_ie, ++ .wireless_event_init = madwifi_wireless_event_init, ++ .wireless_event_deinit = madwifi_wireless_event_deinit, ++ .set_sta_authorized = madwifi_set_sta_authorized, ++ .read_sta_data = madwifi_read_sta_driver_data, ++ .send_eapol = madwifi_send_eapol, ++ .sta_disassoc = madwifi_sta_disassoc, ++ .sta_deauth = madwifi_sta_deauth, ++ .set_ssid = madwifi_set_ssid, ++ .get_ssid = madwifi_get_ssid, ++ .sta_clear_stats = madwifi_sta_clear_stats, ++}; ++ ++void madwifi_driver_register(void) ++{ ++ driver_register(madwifi_driver_ops.name, &madwifi_driver_ops); ++} -- cgit v1.2.3 From c6df1caef5c56750808f4dd8f228f8ac2eafabf6 Mon Sep 17 00:00:00 2001 From: nico Date: Tue, 22 Nov 2005 03:10:56 +0000 Subject: update hostapd to new upstream stable release (v0.4.7) git-svn-id: svn://svn.openwrt.org/openwrt/trunk/openwrt@2542 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- package/hostapd/patches/002-madwifi.patch | 1278 ----------------------------- 1 file changed, 1278 deletions(-) delete mode 100644 package/hostapd/patches/002-madwifi.patch (limited to 'package/hostapd/patches') diff --git a/package/hostapd/patches/002-madwifi.patch b/package/hostapd/patches/002-madwifi.patch deleted file mode 100644 index f53ad7d89..000000000 --- a/package/hostapd/patches/002-madwifi.patch +++ /dev/null @@ -1,1278 +0,0 @@ -diff -ruN hostapd-0.4.5-old/driver_madwifi.c hostapd-0.4.5-new/driver_madwifi.c ---- hostapd-0.4.5-old/driver_madwifi.c 2005-10-23 14:52:39.000000000 +0200 -+++ hostapd-0.4.5-new/driver_madwifi.c 2005-10-23 15:09:45.000000000 +0200 -@@ -20,19 +20,20 @@ - #include - #include - #include -+#include -+#include - - #include - #include - #ifdef WME_NUM_AC - /* Assume this is built against BSD branch of madwifi driver. */ --#define MADWIFI_BSD - #include - #endif /* WME_NUM_AC */ - #include - #include - - #include --#include "wireless_copy.h" -+#include - - #include - #include -diff -ruN hostapd-0.4.5-old/driver_madwifi.~c hostapd-0.4.5-new/driver_madwifi.~c ---- hostapd-0.4.5-old/driver_madwifi.~c 1970-01-01 01:00:00.000000000 +0100 -+++ hostapd-0.4.5-new/driver_madwifi.~c 2005-10-23 15:06:20.000000000 +0200 -@@ -0,0 +1,1248 @@ -+/* -+ * Host AP - driver interaction with MADWIFI 802.11 driver -+ * Copyright (c) 2004, Sam Leffler -+ * Copyright (c) 2004, Video54 Technologies -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * Alternatively, this software may be distributed under the terms of BSD -+ * license. -+ * -+ * See README and COPYING for more details. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#ifdef WME_NUM_AC -+/* Assume this is built against BSD branch of madwifi driver. */ -+#include -+#endif /* WME_NUM_AC */ -+#include -+#include -+ -+#include -+#include -+ -+#include -+#include -+ -+#include "hostapd.h" -+#include "driver.h" -+#include "ieee802_1x.h" -+#include "eloop.h" -+#include "priv_netlink.h" -+#include "sta_info.h" -+#include "l2_packet.h" -+#include "hostap_common.h" -+ -+#include "eapol_sm.h" -+#include "wpa.h" -+#include "radius.h" -+#include "ieee802_11.h" -+#include "accounting.h" -+#include "common.h" -+ -+ -+struct madwifi_driver_data { -+ struct driver_ops ops; /* base class */ -+ struct hostapd_data *hapd; /* back pointer */ -+ -+ char iface[IFNAMSIZ + 1]; -+ int ifindex; -+ 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 */ -+ int we_version; -+ u8 acct_mac[ETH_ALEN]; -+ struct hostap_sta_driver_data acct_data; -+}; -+ -+static const struct driver_ops madwifi_driver_ops; -+ -+static int madwifi_sta_deauth(void *priv, u8 *addr, int reason_code); -+ -+static int -+set80211priv(struct madwifi_driver_data *drv, int op, void *data, int len) -+{ -+#define N(a) (sizeof(a)/sizeof(a[0])) -+ struct iwreq iwr; -+ -+ memset(&iwr, 0, sizeof(iwr)); -+ strncpy(iwr.ifr_name, drv->iface, IFNAMSIZ); -+ if (len < IFNAMSIZ) { -+ /* -+ * Argument data fits inline; put it there. -+ */ -+ memcpy(iwr.u.name, data, len); -+ } else { -+ /* -+ * Argument data too big for inline transfer; setup a -+ * parameter block instead; the kernel will transfer -+ * the data for the driver. -+ */ -+ iwr.u.data.pointer = data; -+ iwr.u.data.length = len; -+ } -+ -+ if (ioctl(drv->ioctl_sock, op, &iwr) < 0) { -+ static const char *opnames[] = { -+ "ioctl[IEEE80211_IOCTL_SETPARAM]", -+ "ioctl[IEEE80211_IOCTL_GETPARAM]", -+ "ioctl[IEEE80211_IOCTL_SETKEY]", -+ "ioctl[SIOCIWFIRSTPRIV+3]", -+ "ioctl[IEEE80211_IOCTL_DELKEY]", -+ "ioctl[SIOCIWFIRSTPRIV+5]", -+ "ioctl[IEEE80211_IOCTL_SETMLME]", -+ "ioctl[SIOCIWFIRSTPRIV+7]", -+ "ioctl[IEEE80211_IOCTL_SETOPTIE]", -+ "ioctl[IEEE80211_IOCTL_GETOPTIE]", -+ "ioctl[IEEE80211_IOCTL_ADDMAC]", -+ "ioctl[SIOCIWFIRSTPRIV+11]", -+ "ioctl[IEEE80211_IOCTL_DELMAC]", -+ "ioctl[SIOCIWFIRSTPRIV+13]", -+ "ioctl[IEEE80211_IOCTL_CHANLIST]", -+ "ioctl[SIOCIWFIRSTPRIV+15]", -+ "ioctl[IEEE80211_IOCTL_GETRSN]", -+ "ioctl[SIOCIWFIRSTPRIV+17]", -+ "ioctl[IEEE80211_IOCTL_GETKEY]", -+ }; -+ op -= SIOCIWFIRSTPRIV; -+ if (0 <= op && op < N(opnames)) -+ perror(opnames[op]); -+ else -+ perror("ioctl[unknown???]"); -+ return -1; -+ } -+ return 0; -+#undef N -+} -+ -+static int -+set80211param(struct madwifi_driver_data *drv, int op, int arg) -+{ -+ struct iwreq iwr; -+ -+ memset(&iwr, 0, sizeof(iwr)); -+ strncpy(iwr.ifr_name, drv->iface, IFNAMSIZ); -+ iwr.u.mode = op; -+ memcpy(iwr.u.name+sizeof(__u32), &arg, sizeof(arg)); -+ -+ if (ioctl(drv->ioctl_sock, IEEE80211_IOCTL_SETPARAM, &iwr) < 0) { -+ perror("ioctl[IEEE80211_IOCTL_SETPARAM]"); -+ return -1; -+ } -+ return 0; -+} -+ -+static const char * -+ether_sprintf(const u8 *addr) -+{ -+ static char buf[sizeof(MACSTR)]; -+ -+ if (addr != NULL) -+ snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr)); -+ else -+ snprintf(buf, sizeof(buf), MACSTR, 0,0,0,0,0,0); -+ return buf; -+} -+ -+/* -+ * Configure WPA parameters. -+ */ -+static int -+madwifi_configure_wpa(struct madwifi_driver_data *drv) -+{ -+ hostapd *hapd = drv->hapd; -+ struct hostapd_config *conf = hapd->conf; -+ int v; -+ -+ switch (conf->wpa_group) { -+ case WPA_CIPHER_CCMP: -+ v = IEEE80211_CIPHER_AES_CCM; -+ break; -+ case WPA_CIPHER_TKIP: -+ v = IEEE80211_CIPHER_TKIP; -+ break; -+ case WPA_CIPHER_WEP104: -+ v = IEEE80211_CIPHER_WEP; -+ break; -+ case WPA_CIPHER_WEP40: -+ v = IEEE80211_CIPHER_WEP; -+ break; -+ case WPA_CIPHER_NONE: -+ v = IEEE80211_CIPHER_NONE; -+ break; -+ default: -+ printf("Unknown group key cipher %u\n", -+ conf->wpa_group); -+ return -1; -+ } -+ HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, -+ "%s: group key cipher=%d\n", __func__, v); -+ if (set80211param(drv, IEEE80211_PARAM_MCASTCIPHER, v)) { -+ printf("Unable to set group key cipher to %u\n", v); -+ return -1; -+ } -+ if (v == IEEE80211_CIPHER_WEP) { -+ /* key length is done only for specific ciphers */ -+ v = (conf->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; -+ } -+ } -+ -+ v = 0; -+ if (conf->wpa_pairwise & WPA_CIPHER_CCMP) -+ v |= 1<wpa_pairwise & WPA_CIPHER_TKIP) -+ v |= 1<wpa_pairwise & WPA_CIPHER_NONE) -+ v |= 1<wpa_key_mgmt); -+ if (set80211param(drv, IEEE80211_PARAM_KEYMGTALGS, conf->wpa_key_mgmt)) { -+ printf("Unable to set key management algorithms to 0x%x\n", -+ conf->wpa_key_mgmt); -+ return -1; -+ } -+ -+ v = 0; -+ if (conf->rsn_preauth) -+ v |= BIT(0); -+ HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, -+ "%s: rsn capabilities=0x%x\n", __func__, conf->rsn_preauth); -+ if (set80211param(drv, IEEE80211_PARAM_RSNCAPS, v)) { -+ printf("Unable to set RSN capabilities to 0x%x\n", v); -+ return -1; -+ } -+ -+ HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, -+ "%s: enable WPA= 0x%x\n", __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; -+ hostapd *hapd = drv->hapd; -+ struct ifreq ifr; -+ -+ HOSTAPD_DEBUG(HOSTAPD_DEBUG_VERBOSE, -+ "%s: dev_up=%d\n", __func__, dev_up); -+ -+ if (drv->ioctl_sock < 0) -+ return -1; -+ -+ memset(&ifr, 0, sizeof(ifr)); -+ snprintf(ifr.ifr_name, IFNAMSIZ, "%s", drv->iface); -+ -+ 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]"); -+ return -1; -+ } -+ -+ if (dev_up) { -+ memset(&ifr, 0, sizeof(ifr)); -+ snprintf(ifr.ifr_name, IFNAMSIZ, "%s", drv->iface); -+ ifr.ifr_mtu = HOSTAPD_MTU; -+ if (ioctl(drv->ioctl_sock, SIOCSIFMTU, &ifr) != 0) { -+ perror("ioctl[SIOCSIFMTU]"); -+ printf("Setting MTU failed - trying to survive with " -+ "current value\n"); -+ } -+ } -+ -+ return 0; -+} -+ -+static int -+madwifi_set_ieee8021x(void *priv, int enabled) -+{ -+ struct madwifi_driver_data *drv = priv; -+ hostapd *hapd = drv->hapd; -+ struct hostapd_config *conf = hapd->conf; -+ -+ HOSTAPD_DEBUG(HOSTAPD_DEBUG_VERBOSE, -+ "%s: enabled=%d\n", __func__, enabled); -+ -+ if (!enabled) { -+ /* XXX restore state */ -+ return set80211param(priv, IEEE80211_PARAM_AUTHMODE, -+ IEEE80211_AUTH_AUTO); -+ } -+ if (!conf->wpa && !conf->ieee802_1x) { -+ hostapd_logger(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, -+ 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, -+ HOSTAPD_LEVEL_WARNING, "Error enabling WPA/802.1X!"); -+ return -1; -+ } -+ return madwifi_set_iface_flags(priv, 1); -+} -+ -+static int -+madwifi_set_privacy(void *priv, int enabled) -+{ -+ struct madwifi_driver_data *drv = priv; -+ hostapd *hapd = drv->hapd; -+ -+ HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, -+ "%s: enabled=%d\n", __func__, enabled); -+ -+ return set80211param(priv, IEEE80211_PARAM_PRIVACY, enabled); -+} -+ -+static int -+madwifi_set_sta_authorized(void *priv, u8 *addr, int authorized) -+{ -+ struct madwifi_driver_data *drv = priv; -+ hostapd *hapd = drv->hapd; -+ struct ieee80211req_mlme mlme; -+ -+ HOSTAPD_DEBUG(HOSTAPD_DEBUG_VERBOSE, -+ "%s: addr=%s authorized=%d\n", -+ __func__, ether_sprintf(addr), authorized); -+ -+ if (authorized) -+ mlme.im_op = IEEE80211_MLME_AUTHORIZE; -+ else -+ mlme.im_op = IEEE80211_MLME_UNAUTHORIZE; -+ mlme.im_reason = 0; -+ memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); -+ return set80211priv(priv, IEEE80211_IOCTL_SETMLME, &mlme, -+ sizeof(mlme)); -+} -+ -+static int -+madwifi_del_key(void *priv, unsigned char *addr, int key_idx) -+{ -+ struct madwifi_driver_data *drv = priv; -+ hostapd *hapd = drv->hapd; -+ struct ieee80211req_del_key wk; -+ -+ HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, -+ "%s: addr=%s key_idx=%d\n", -+ __func__, ether_sprintf(addr), key_idx); -+ -+ memset(&wk, 0, sizeof(wk)); -+ if (addr != NULL) { -+ memcpy(wk.idk_macaddr, addr, IEEE80211_ADDR_LEN); -+ wk.idk_keyix = (u8) IEEE80211_KEYIX_NONE; -+ } else { -+ wk.idk_keyix = key_idx; -+ } -+ -+ return set80211priv(priv, IEEE80211_IOCTL_DELKEY, &wk, sizeof(wk)); -+} -+ -+static int -+madwifi_set_key(void *priv, const char *alg, -+ unsigned char *addr, int key_idx, -+ u8 *key, size_t key_len) -+{ -+ struct madwifi_driver_data *drv = priv; -+ hostapd *hapd = drv->hapd; -+ struct ieee80211req_key wk; -+ u_int8_t cipher; -+ -+ if (strcmp(alg, "none") == 0) -+ return madwifi_del_key(priv, addr, key_idx); -+ -+ HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, -+ "%s: alg=%s addr=%s key_idx=%d\n", -+ __func__, alg, ether_sprintf(addr), key_idx); -+ -+ if (strcmp(alg, "WEP") == 0) -+ cipher = IEEE80211_CIPHER_WEP; -+ else if (strcmp(alg, "TKIP") == 0) -+ cipher = IEEE80211_CIPHER_TKIP; -+ else if (strcmp(alg, "CCMP") == 0) -+ cipher = IEEE80211_CIPHER_AES_CCM; -+ else { -+ printf("%s: unknown/unsupported algorithm %s\n", -+ __func__, alg); -+ return -1; -+ } -+ -+ if (key_len > sizeof(wk.ik_keydata)) { -+ printf("%s: key length %lu too big\n", __func__, -+ (unsigned long) key_len); -+ return -3; -+ } -+ -+ memset(&wk, 0, sizeof(wk)); -+ wk.ik_type = cipher; -+ wk.ik_flags = IEEE80211_KEY_RECV | IEEE80211_KEY_XMIT; -+ if (addr == NULL) { -+ memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN); -+ wk.ik_keyix = key_idx; -+ wk.ik_flags |= IEEE80211_KEY_DEFAULT; -+ } else { -+ memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN); -+ wk.ik_keyix = IEEE80211_KEYIX_NONE; -+ } -+ wk.ik_keylen = key_len; -+ memcpy(wk.ik_keydata, key, key_len); -+ -+ return set80211priv(priv, IEEE80211_IOCTL_SETKEY, &wk, sizeof(wk)); -+} -+ -+ -+static int -+madwifi_get_seqnum(void *priv, u8 *addr, int idx, u8 *seq) -+{ -+ struct madwifi_driver_data *drv = priv; -+ hostapd *hapd = drv->hapd; -+ struct ieee80211req_key wk; -+ -+ HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, -+ "%s: addr=%s idx=%d\n", __func__, ether_sprintf(addr), idx); -+ -+ memset(&wk, 0, sizeof(wk)); -+ if (addr == NULL) -+ memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN); -+ else -+ memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN); -+ wk.ik_keyix = idx; -+ -+ if (set80211priv(priv, IEEE80211_IOCTL_GETKEY, &wk, sizeof(wk))) { -+ printf("Failed to get encryption.\n"); -+ return -1; -+ } -+ -+#ifdef WORDS_BIGENDIAN -+ { -+ /* -+ * wk.ik_keytsc is in host byte order (big endian), need to -+ * swap it to match with the byte order used in WPA. -+ */ -+ int i; -+ u8 tmp[WPA_KEY_RSC_LEN]; -+ memcpy(tmp, &wk.ik_keytsc, sizeof(wk.ik_keytsc)); -+ for (i = 0; i < WPA_KEY_RSC_LEN; i++) { -+ seq[i] = tmp[WPA_KEY_RSC_LEN - i - 1]; -+ } -+ } -+#else /* WORDS_BIGENDIAN */ -+ memcpy(seq, &wk.ik_keytsc, sizeof(wk.ik_keytsc)); -+#endif /* WORDS_BIGENDIAN */ -+ return 0; -+} -+ -+ -+static int -+madwifi_flush(void *priv) -+{ -+#ifdef MADWIFI_BSD -+ u8 allsta[IEEE80211_ADDR_LEN]; -+ memset(allsta, 0xff, IEEE80211_ADDR_LEN); -+ return madwifi_sta_deauth(priv, allsta, IEEE80211_REASON_AUTH_LEAVE); -+#else /* MADWIFI_BSD */ -+ return 0; /* XXX */ -+#endif /* MADWIFI_BSD */ -+} -+ -+ -+static int -+madwifi_read_sta_driver_data(void *priv, struct hostap_sta_driver_data *data, -+ u8 *addr) -+{ -+ struct madwifi_driver_data *drv = priv; -+ -+#ifdef MADWIFI_BSD -+ struct ieee80211req_sta_stats stats; -+ -+ memset(data, 0, sizeof(*data)); -+ -+ /* -+ * Fetch statistics for station from the system. -+ */ -+ memset(&stats, 0, sizeof(stats)); -+ memcpy(stats.is_u.macaddr, addr, IEEE80211_ADDR_LEN); -+ if (set80211priv(drv, IEEE80211_IOCTL_GETSTASTATS, &stats, -+ sizeof(stats))) { -+ if (memcmp(addr, drv->acct_mac, ETH_ALEN) == 0) { -+ memcpy(data, &drv->acct_data, sizeof(*data)); -+ return 0; -+ } -+ -+ printf("Failed to get station stats information element.\n"); -+ return -1; -+ } -+ -+ data->rx_packets = stats.is_stats.ns_rx_data; -+ data->rx_bytes = stats.is_stats.ns_rx_bytes; -+ data->tx_packets = stats.is_stats.ns_tx_data; -+ data->tx_bytes = stats.is_stats.ns_tx_bytes; -+ return 0; -+ -+#else /* MADWIFI_BSD */ -+ -+ char buf[1024], line[128], *pos; -+ FILE *f; -+ unsigned long val; -+ -+ memset(data, 0, sizeof(*data)); -+ snprintf(buf, sizeof(buf), "/proc/net/madwifi/%s/" MACSTR, -+ drv->iface, MAC2STR(addr)); -+ -+ f = fopen(buf, "r"); -+ if (!f) { -+ if (memcmp(addr, drv->acct_mac, ETH_ALEN) != 0) -+ return -1; -+ memcpy(data, &drv->acct_data, sizeof(*data)); -+ return 0; -+ } -+ /* Need to read proc file with in one piece, so use large enough -+ * buffer. */ -+ setbuffer(f, buf, sizeof(buf)); -+ -+ while (fgets(line, sizeof(line), f)) { -+ pos = strchr(line, '='); -+ if (!pos) -+ continue; -+ *pos++ = '\0'; -+ val = strtoul(pos, NULL, 10); -+ if (strcmp(line, "rx_packets") == 0) -+ data->rx_packets = val; -+ else if (strcmp(line, "tx_packets") == 0) -+ data->tx_packets = val; -+ else if (strcmp(line, "rx_bytes") == 0) -+ data->rx_bytes = val; -+ else if (strcmp(line, "tx_bytes") == 0) -+ data->tx_bytes = val; -+ } -+ -+ fclose(f); -+ -+ return 0; -+#endif /* MADWIFI_BSD */ -+} -+ -+ -+static int -+madwifi_sta_clear_stats(void *priv, u8 *addr) -+{ -+#ifdef MADWIFI_BSD -+ struct madwifi_driver_data *drv = priv; -+ struct hostapd_data *hapd = drv->hapd; -+ struct ieee80211req_mlme mlme; -+ -+ HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "%s: addr=%s\n", -+ __func__, ether_sprintf(addr)); -+ -+ mlme.im_op = IEEE80211_MLME_CLEAR_STATS; -+ memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); -+ return set80211priv(priv, IEEE80211_IOCTL_SETMLME, &mlme, -+ sizeof(mlme)); -+#else /* MADWIFI_BSD */ -+ return 0; /* FIX */ -+#endif /* MADWIFI_BSD */ -+} -+ -+ -+static int -+madwifi_set_opt_ie(void *priv, const u8 *ie, size_t ie_len) -+{ -+ /* -+ * Do nothing; we setup parameters at startup that define the -+ * contents of the beacon information element. -+ */ -+ return 0; -+} -+ -+static int -+madwifi_sta_deauth(void *priv, u8 *addr, int reason_code) -+{ -+ struct madwifi_driver_data *drv = priv; -+ hostapd *hapd = drv->hapd; -+ struct ieee80211req_mlme mlme; -+ -+ HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, -+ "%s: addr=%s reason_code=%d\n", -+ __func__, ether_sprintf(addr), reason_code); -+ -+ mlme.im_op = IEEE80211_MLME_DEAUTH; -+ mlme.im_reason = reason_code; -+ memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); -+ return set80211priv(priv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme)); -+} -+ -+static int -+madwifi_sta_disassoc(void *priv, u8 *addr, int reason_code) -+{ -+ struct madwifi_driver_data *drv = priv; -+ hostapd *hapd = drv->hapd; -+ struct ieee80211req_mlme mlme; -+ -+ HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, -+ "%s: addr=%s reason_code=%d\n", -+ __func__, ether_sprintf(addr), reason_code); -+ -+ mlme.im_reason = reason_code; -+ memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); -+ return set80211priv(priv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme)); -+} -+ -+static int -+madwifi_del_sta(struct madwifi_driver_data *drv, u8 addr[IEEE80211_ADDR_LEN]) -+{ -+ struct hostapd_data *hapd = drv->hapd; -+ struct sta_info *sta; -+ -+ hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211, -+ HOSTAPD_LEVEL_INFO, "deassociated"); -+ -+ sta = ap_get_sta(hapd, addr); -+ if (sta != NULL) { -+ sta->flags &= ~WLAN_STA_ASSOC; -+ wpa_sm_event(hapd, sta, WPA_DISASSOC); -+ sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST; -+ ieee802_1x_set_port_enabled(hapd, sta, 0); -+ ap_free_sta(hapd, sta); -+ } -+ return 0; -+} -+ -+static int -+madwifi_process_wpa_ie(struct madwifi_driver_data *drv, struct sta_info *sta) -+{ -+ struct hostapd_data *hapd = drv->hapd; -+ struct ieee80211req_wpaie ie; -+ int ielen, res; -+ -+ /* -+ * Fetch negotiated WPA/RSN parameters from the system. -+ */ -+ memset(&ie, 0, sizeof(ie)); -+ memcpy(ie.wpa_macaddr, sta->addr, IEEE80211_ADDR_LEN); -+ if (set80211priv(drv, IEEE80211_IOCTL_GETWPAIE, &ie, sizeof(ie))) { -+ printf("Failed to get WPA/RSN information element.\n"); -+ return -1; /* XXX not right */ -+ } -+ ielen = ie.wpa_ie[1]; -+ if (ielen == 0) { -+ printf("No WPA/RSN information element for station!?\n"); -+ return -1; /* XXX not right */ -+ } -+ ielen += 2; -+ res = wpa_validate_wpa_ie(hapd, sta, ie.wpa_ie, ielen, -+ ie.wpa_ie[0] == WLAN_EID_RSN ? -+ HOSTAPD_WPA_VERSION_WPA2 : HOSTAPD_WPA_VERSION_WPA); -+ if (res != WPA_IE_OK) { -+ printf("WPA/RSN information element rejected? (res %u)\n", res); -+ return -1; -+ } -+ free(sta->wpa_ie); -+ sta->wpa_ie = malloc(ielen); -+ if (sta->wpa_ie == NULL) { -+ printf("No memory to save WPA/RSN information element!\n"); -+ return -1; -+ } -+ memcpy(sta->wpa_ie, ie.wpa_ie, ielen); -+ sta->wpa_ie_len = ielen; -+ return 0; -+} -+ -+static int -+madwifi_new_sta(struct madwifi_driver_data *drv, u8 addr[IEEE80211_ADDR_LEN]) -+{ -+ struct hostapd_data *hapd = drv->hapd; -+ struct sta_info *sta; -+ int new_assoc; -+ -+ hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211, -+ HOSTAPD_LEVEL_INFO, "associated"); -+ -+ sta = ap_get_sta(hapd, addr); -+ if (sta) { -+ accounting_sta_stop(hapd, sta); -+ } else { -+ sta = ap_sta_add(hapd, addr); -+ if (sta == NULL) -+ return -1; -+ } -+ -+ 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)); -+ } -+ accounting_sta_get_id(hapd, sta); -+ -+ if (hapd->conf->wpa) { -+ if (madwifi_process_wpa_ie(drv, sta)) -+ return -1; -+ } else { -+ free(sta->wpa_ie); -+ sta->wpa_ie = NULL; -+ sta->wpa_ie_len = 0; -+ } -+ -+ /* -+ * Now that the internal station state is setup -+ * kick the authenticator into action. -+ */ -+ new_assoc = (sta->flags & WLAN_STA_ASSOC) == 0; -+ sta->flags |= WLAN_STA_ASSOC; -+ wpa_sm_event(hapd, sta, WPA_ASSOC); -+ hostapd_new_assoc_sta(hapd, sta, !new_assoc); -+ ieee802_1x_notify_port_enabled(sta->eapol_sm, 1); -+ return 0; -+} -+ -+static void -+madwifi_wireless_event_wireless_custom(struct madwifi_driver_data *drv, -+ char *custom) -+{ -+ struct hostapd_data *hapd = drv->hapd; -+ -+ HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "Custom wireless event: '%s'\n", -+ custom); -+ -+ if (strncmp(custom, "MLME-MICHAELMICFAILURE.indication", 33) == 0) { -+ char *pos; -+ u8 addr[ETH_ALEN]; -+ pos = strstr(custom, "addr="); -+ if (pos == NULL) { -+ HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, -+ "MLME-MICHAELMICFAILURE.indication " -+ "without sender address ignored\n"); -+ return; -+ } -+ pos += 5; -+ if (hwaddr_aton(pos, addr) == 0) { -+ ieee80211_michael_mic_failure(drv->hapd, addr, 1); -+ } else { -+ HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, -+ "MLME-MICHAELMICFAILURE.indication " -+ "with invalid MAC address"); -+ } -+ } else if (strncmp(custom, "STA-TRAFFIC-STAT", 16) == 0) { -+ char *key, *value; -+ u32 val; -+ key = custom; -+ while ((key = strchr(key, '\n')) != NULL) { -+ key++; -+ value = strchr(key, '='); -+ if (value == NULL) -+ continue; -+ *value++ = '\0'; -+ val = strtoul(value, NULL, 10); -+ if (strcmp(key, "mac") == 0) -+ hwaddr_aton(value, drv->acct_mac); -+ else if (strcmp(key, "rx_packets") == 0) -+ drv->acct_data.rx_packets = val; -+ else if (strcmp(key, "tx_packets") == 0) -+ drv->acct_data.tx_packets = val; -+ else if (strcmp(key, "rx_bytes") == 0) -+ drv->acct_data.rx_bytes = val; -+ else if (strcmp(key, "tx_bytes") == 0) -+ drv->acct_data.tx_bytes = val; -+ key = value; -+ } -+ } -+} -+ -+static void -+madwifi_wireless_event_wireless(struct madwifi_driver_data *drv, -+ char *data, int len) -+{ -+ struct hostapd_data *hapd = drv->hapd; -+ struct iw_event iwe_buf, *iwe = &iwe_buf; -+ char *pos, *end, *custom, *buf; -+ -+ pos = data; -+ end = data + len; -+ -+ while (pos + IW_EV_LCP_LEN <= end) { -+ /* Event data may be unaligned, so make a local, aligned copy -+ * before processing. */ -+ memcpy(&iwe_buf, pos, IW_EV_LCP_LEN); -+ HOSTAPD_DEBUG(HOSTAPD_DEBUG_VERBOSE, "Wireless event: " -+ "cmd=0x%x len=%d\n", iwe->cmd, iwe->len); -+ if (iwe->len <= IW_EV_LCP_LEN) -+ return; -+ -+ custom = pos + IW_EV_POINT_LEN; -+ if (drv->we_version > 18 && -+ (iwe->cmd == IWEVMICHAELMICFAILURE || -+ iwe->cmd == IWEVCUSTOM)) { -+ /* WE-19 removed the pointer from struct iw_point */ -+ char *dpos = (char *) &iwe_buf.u.data.length; -+ int dlen = dpos - (char *) &iwe_buf; -+ memcpy(dpos, pos + IW_EV_LCP_LEN, -+ sizeof(struct iw_event) - dlen); -+ } else { -+ memcpy(&iwe_buf, pos, sizeof(struct iw_event)); -+ custom += IW_EV_POINT_OFF; -+ } -+ -+ switch (iwe->cmd) { -+ case IWEVEXPIRED: -+ madwifi_del_sta(drv, iwe->u.addr.sa_data); -+ break; -+ case IWEVREGISTERED: -+ madwifi_new_sta(drv, iwe->u.addr.sa_data); -+ break; -+ case IWEVCUSTOM: -+ if (custom + iwe->u.data.length > end) -+ return; -+ buf = malloc(iwe->u.data.length + 1); -+ if (buf == NULL) -+ return; /* XXX */ -+ memcpy(buf, custom, iwe->u.data.length); -+ buf[iwe->u.data.length] = '\0'; -+ madwifi_wireless_event_wireless_custom(drv, buf); -+ free(buf); -+ break; -+ } -+ -+ pos += iwe->len; -+ } -+} -+ -+ -+static void -+madwifi_wireless_event_rtm_newlink(struct madwifi_driver_data *drv, -+ struct nlmsghdr *h, int len) -+{ -+ struct ifinfomsg *ifi; -+ int attrlen, nlmsg_len, rta_len; -+ struct rtattr * attr; -+ -+ if (len < sizeof(*ifi)) -+ return; -+ -+ ifi = NLMSG_DATA(h); -+ -+ 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); -+ -+ rta_len = RTA_ALIGN(sizeof(struct rtattr)); -+ while (RTA_OK(attr, attrlen)) { -+ if (attr->rta_type == IFLA_WIRELESS) { -+ madwifi_wireless_event_wireless( -+ drv, ((char *) attr) + rta_len, -+ attr->rta_len - rta_len); -+ } -+ attr = RTA_NEXT(attr, attrlen); -+ } -+} -+ -+ -+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 >= 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) -+{ -+ struct iw_range *range; -+ struct iwreq iwr; -+ int minlen; -+ size_t buflen; -+ -+ drv->we_version = 0; -+ -+ /* -+ * Use larger buffer than struct iw_range in order to allow the -+ * structure to grow in the future. -+ */ -+ buflen = sizeof(struct iw_range) + 500; -+ range = malloc(buflen); -+ if (range == NULL) -+ return -1; -+ memset(range, 0, buflen); -+ -+ memset(&iwr, 0, sizeof(iwr)); -+ strncpy(iwr.ifr_name, drv->iface, IFNAMSIZ); -+ iwr.u.data.pointer = (caddr_t) range; -+ iwr.u.data.length = buflen; -+ -+ minlen = ((char *) &range->enc_capa) - (char *) range + -+ sizeof(range->enc_capa); -+ -+ if (ioctl(drv->ioctl_sock, SIOCGIWRANGE, &iwr) < 0) { -+ perror("ioctl[SIOCGIWRANGE]"); -+ free(range); -+ return -1; -+ } else if (iwr.u.data.length >= minlen && -+ range->we_version_compiled >= 18) { -+ wpa_printf(MSG_DEBUG, "SIOCGIWRANGE: WE(compiled)=%d " -+ "WE(source)=%d enc_capa=0x%x", -+ range->we_version_compiled, -+ range->we_version_source, -+ range->enc_capa); -+ drv->we_version = range->we_version_compiled; -+ } -+ -+ free(range); -+ return 0; -+} -+ -+ -+static int -+madwifi_wireless_event_init(void *priv) -+{ -+ struct madwifi_driver_data *drv = priv; -+ int s; -+ struct sockaddr_nl local; -+ -+ 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)"); -+ 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); -+ 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(void *priv) -+{ -+ struct madwifi_driver_data *drv = priv; -+ -+ if (drv != NULL) { -+ if (drv->wext_sock < 0) -+ return; -+ eloop_unregister_read_sock(drv->wext_sock); -+ close(drv->wext_sock); -+ } -+} -+ -+ -+static int -+madwifi_send_eapol(void *priv, u8 *addr, u8 *data, size_t data_len, int encrypt) -+{ -+ struct madwifi_driver_data *drv = priv; -+ hostapd *hapd = drv->hapd; -+ unsigned char buf[3000]; -+ unsigned char *bp = buf; -+ struct l2_ethhdr *eth; -+ size_t len; -+ int status; -+ -+ /* -+ * Prepend the Etherent header. If the caller left us -+ * space at the front we could just insert it but since -+ * we don't know we copy to a local buffer. Given the frequency -+ * and size of frames this probably doesn't matter. -+ */ -+ len = data_len + sizeof(struct l2_ethhdr); -+ if (len > sizeof(buf)) { -+ bp = malloc(len); -+ if (bp == NULL) { -+ printf("EAPOL frame discarded, cannot malloc temp " -+ "buffer of size %lu!\n", (unsigned long) len); -+ return -1; -+ } -+ } -+ eth = (struct l2_ethhdr *) bp; -+ memcpy(eth->h_dest, addr, ETH_ALEN); -+ memcpy(eth->h_source, drv->hapd->own_addr, ETH_ALEN); -+ eth->h_proto = htons(ETH_P_EAPOL); -+ memcpy(eth+1, data, data_len); -+ -+ if (HOSTAPD_DEBUG_COND(HOSTAPD_DEBUG_MSGDUMPS)) -+ hostapd_hexdump("TX EAPOL", bp, len); -+ -+ status = l2_packet_send(drv->sock_xmit, addr, ETH_P_EAPOL, bp, len); -+ -+ if (bp != buf) -+ free(bp); -+ return status; -+} -+ -+static void -+handle_read(void *ctx, const u8 *src_addr, const u8 *buf, size_t len) -+{ -+ struct madwifi_driver_data *drv = ctx; -+ hostapd *hapd = drv->hapd; -+ struct sta_info *sta; -+ -+ sta = ap_get_sta(hapd, src_addr); -+ if (!sta || !(sta->flags & WLAN_STA_ASSOC)) { -+ printf("Data frame from not associated STA %s\n", -+ ether_sprintf(src_addr)); -+ /* XXX cannot happen */ -+ return; -+ } -+ ieee802_1x_receive(hapd, src_addr, buf + sizeof(struct l2_ethhdr), -+ len - sizeof(struct l2_ethhdr)); -+} -+ -+static int -+madwifi_init(struct hostapd_data *hapd) -+{ -+ struct madwifi_driver_data *drv; -+ struct ifreq ifr; -+ struct iwreq iwr; -+ -+ drv = malloc(sizeof(struct madwifi_driver_data)); -+ if (drv == NULL) { -+ printf("Could not allocate memory for madwifi driver data\n"); -+ goto bad; -+ } -+ -+ memset(drv, 0, sizeof(*drv)); -+ drv->ops = madwifi_driver_ops; -+ drv->hapd = hapd; -+ drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0); -+ if (drv->ioctl_sock < 0) { -+ perror("socket[PF_INET,SOCK_DGRAM]"); -+ goto bad; -+ } -+ memcpy(drv->iface, hapd->conf->iface, sizeof(drv->iface)); -+ -+ memset(&ifr, 0, sizeof(ifr)); -+ snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", drv->iface); -+ if (ioctl(drv->ioctl_sock, SIOCGIFINDEX, &ifr) != 0) { -+ perror("ioctl(SIOCGIFINDEX)"); -+ goto bad; -+ } -+ drv->ifindex = ifr.ifr_ifindex; -+ -+ drv->sock_xmit = l2_packet_init(drv->iface, NULL, ETH_P_EAPOL, -+ handle_read, drv, 1); -+ if (drv->sock_xmit == NULL) -+ goto bad; -+ if (l2_packet_get_own_addr(drv->sock_xmit, hapd->own_addr)) -+ goto bad; -+ if (hapd->conf->bridge[0] != '\0') { -+ HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, -+ "Configure bridge %s for EAPOL traffic.\n", -+ hapd->conf->bridge); -+ drv->sock_recv = l2_packet_init(hapd->conf->bridge, NULL, -+ ETH_P_EAPOL, handle_read, drv, -+ 0); -+ if (drv->sock_recv == NULL) -+ goto bad; -+ } else -+ drv->sock_recv = drv->sock_xmit; -+ -+ memset(&iwr, 0, sizeof(iwr)); -+ strncpy(iwr.ifr_name, drv->iface, IFNAMSIZ); -+ -+ iwr.u.mode = IW_MODE_MASTER; -+ -+ if (ioctl(drv->ioctl_sock, SIOCSIWMODE, &iwr) < 0) { -+ perror("ioctl[SIOCSIWMODE]"); -+ printf("Could not set interface to master mode!\n"); -+ goto bad; -+ } -+ -+ madwifi_set_iface_flags(drv, 0); /* mark down during setup */ -+ -+ hapd->driver = &drv->ops; -+ return 0; -+bad: -+ if (drv->sock_xmit != NULL) -+ l2_packet_deinit(drv->sock_xmit); -+ if (drv->ioctl_sock >= 0) -+ close(drv->ioctl_sock); -+ if (drv != NULL) -+ free(drv); -+ return -1; -+} -+ -+ -+static void -+madwifi_deinit(void *priv) -+{ -+ struct madwifi_driver_data *drv = priv; -+ -+ drv->hapd->driver = NULL; -+ -+ (void) madwifi_set_iface_flags(drv, 0); -+ if (drv->ioctl_sock >= 0) -+ close(drv->ioctl_sock); -+ 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); -+ free(drv); -+} -+ -+static int -+madwifi_set_ssid(void *priv, u8 *buf, int len) -+{ -+ struct madwifi_driver_data *drv = priv; -+ struct iwreq iwr; -+ -+ memset(&iwr, 0, sizeof(iwr)); -+ strncpy(iwr.ifr_name, drv->iface, IFNAMSIZ); -+ iwr.u.essid.flags = 1; /* SSID active */ -+ iwr.u.essid.pointer = (caddr_t) buf; -+ iwr.u.essid.length = len + 1; -+ -+ if (ioctl(drv->ioctl_sock, SIOCSIWESSID, &iwr) < 0) { -+ perror("ioctl[SIOCSIWESSID]"); -+ printf("len=%d\n", len); -+ return -1; -+ } -+ return 0; -+} -+ -+static int -+madwifi_get_ssid(void *priv, u8 *buf, int len) -+{ -+ struct madwifi_driver_data *drv = priv; -+ struct iwreq iwr; -+ int ret = 0; -+ -+ memset(&iwr, 0, sizeof(iwr)); -+ strncpy(iwr.ifr_name, drv->iface, IFNAMSIZ); -+ iwr.u.essid.pointer = (caddr_t) buf; -+ iwr.u.essid.length = len; -+ -+ if (ioctl(drv->ioctl_sock, SIOCGIWESSID, &iwr) < 0) { -+ perror("ioctl[SIOCGIWESSID]"); -+ ret = -1; -+ } else -+ ret = iwr.u.essid.length; -+ -+ return ret; -+} -+ -+static const struct driver_ops madwifi_driver_ops = { -+ .name = "madwifi", -+ .init = madwifi_init, -+ .deinit = madwifi_deinit, -+ .set_ieee8021x = madwifi_set_ieee8021x, -+ .set_privacy = madwifi_set_privacy, -+ .set_encryption = madwifi_set_key, -+ .get_seqnum = madwifi_get_seqnum, -+ .flush = madwifi_flush, -+ .set_generic_elem = madwifi_set_opt_ie, -+ .wireless_event_init = madwifi_wireless_event_init, -+ .wireless_event_deinit = madwifi_wireless_event_deinit, -+ .set_sta_authorized = madwifi_set_sta_authorized, -+ .read_sta_data = madwifi_read_sta_driver_data, -+ .send_eapol = madwifi_send_eapol, -+ .sta_disassoc = madwifi_sta_disassoc, -+ .sta_deauth = madwifi_sta_deauth, -+ .set_ssid = madwifi_set_ssid, -+ .get_ssid = madwifi_get_ssid, -+ .sta_clear_stats = madwifi_sta_clear_stats, -+}; -+ -+void madwifi_driver_register(void) -+{ -+ driver_register(madwifi_driver_ops.name, &madwifi_driver_ops); -+} -- cgit v1.2.3 From 044fe334088e0a940173cf6e602ca08ac41ed80b Mon Sep 17 00:00:00 2001 From: nbd Date: Tue, 31 Jan 2006 21:45:23 +0000 Subject: fix hostapd/madwifi crash (#247) git-svn-id: svn://svn.openwrt.org/openwrt/trunk/openwrt@3102 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- package/hostapd/patches/100-wpa_fix.patch | 58 +++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 package/hostapd/patches/100-wpa_fix.patch (limited to 'package/hostapd/patches') diff --git a/package/hostapd/patches/100-wpa_fix.patch b/package/hostapd/patches/100-wpa_fix.patch new file mode 100644 index 000000000..502167cbd --- /dev/null +++ b/package/hostapd/patches/100-wpa_fix.patch @@ -0,0 +1,58 @@ +--- hostapd-0.4.7/driver_madwifi.c 2006-01-30 10:00:44.199096000 -0800 ++++ hostapd-0.4.7-new/driver_madwifi.c 2006-01-30 10:05:55.925511000 -0800 +@@ -692,6 +692,7 @@ + struct hostapd_data *hapd = drv->hapd; + struct ieee80211req_wpaie ie; + int ielen, res; ++ int rsn = 0; + + /* + * Fetch negotiated WPA/RSN parameters from the system. +@@ -702,26 +703,37 @@ + printf("Failed to get WPA/RSN information element.\n"); + return -1; /* XXX not right */ + } +- ielen = ie.wpa_ie[1]; +- if (ielen == 0) { ++ if ((ie.wpa_ie[1] == 0) && (ie.rsn_ie[1] == 0)){ + printf("No WPA/RSN information element for station!?\n"); + return -1; /* XXX not right */ + } ++ ielen = ie.rsn_ie[1]; + ielen += 2; +- res = wpa_validate_wpa_ie(hapd, sta, ie.wpa_ie, ielen, +- ie.wpa_ie[0] == WLAN_EID_RSN ? +- HOSTAPD_WPA_VERSION_WPA2 : HOSTAPD_WPA_VERSION_WPA); +- if (res != WPA_IE_OK) { +- printf("WPA/RSN information element rejected? (res %u)\n", res); +- return -1; +- } ++ res = wpa_validate_wpa_ie(hapd, sta, ie.rsn_ie, ielen, ++ HOSTAPD_WPA_VERSION_WPA2); ++ if (res != WPA_IE_OK){ ++ // now look for WPA IE ++ ielen = ie.wpa_ie[1]; ++ ielen += 2; ++ res = wpa_validate_wpa_ie(hapd, sta, ie.wpa_ie, ielen, ++ HOSTAPD_WPA_VERSION_WPA); ++ if (res != WPA_IE_OK) { ++ printf("WPA/RSN information element rejected? (res %u)\n", res); ++ return -1; ++ } ++ } else { ++ rsn = 1; ++ } + free(sta->wpa_ie); + sta->wpa_ie = malloc(ielen); + if (sta->wpa_ie == NULL) { + printf("No memory to save WPA/RSN information element!\n"); + return -1; + } +- memcpy(sta->wpa_ie, ie.wpa_ie, ielen); ++ if (rsn) ++ memcpy(sta->wpa_ie, ie.rsn_ie, ielen); ++ else ++ memcpy(sta->wpa_ie, ie.wpa_ie, ielen); + sta->wpa_ie_len = ielen; + return 0; + } -- cgit v1.2.3 From 428f4a4fb597d08c8382ee90ac5f291dfa8b15dc Mon Sep 17 00:00:00 2001 From: wbx Date: Sun, 12 Mar 2006 13:51:39 +0000 Subject: update to newer version, fix compile issues, 100-wpa_fix.patch removed, is it needed? git-svn-id: svn://svn.openwrt.org/openwrt/trunk/openwrt@3352 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- package/hostapd/patches/100-wpa_fix.patch | 58 ------------------------------- 1 file changed, 58 deletions(-) delete mode 100644 package/hostapd/patches/100-wpa_fix.patch (limited to 'package/hostapd/patches') diff --git a/package/hostapd/patches/100-wpa_fix.patch b/package/hostapd/patches/100-wpa_fix.patch deleted file mode 100644 index 502167cbd..000000000 --- a/package/hostapd/patches/100-wpa_fix.patch +++ /dev/null @@ -1,58 +0,0 @@ ---- hostapd-0.4.7/driver_madwifi.c 2006-01-30 10:00:44.199096000 -0800 -+++ hostapd-0.4.7-new/driver_madwifi.c 2006-01-30 10:05:55.925511000 -0800 -@@ -692,6 +692,7 @@ - struct hostapd_data *hapd = drv->hapd; - struct ieee80211req_wpaie ie; - int ielen, res; -+ int rsn = 0; - - /* - * Fetch negotiated WPA/RSN parameters from the system. -@@ -702,26 +703,37 @@ - printf("Failed to get WPA/RSN information element.\n"); - return -1; /* XXX not right */ - } -- ielen = ie.wpa_ie[1]; -- if (ielen == 0) { -+ if ((ie.wpa_ie[1] == 0) && (ie.rsn_ie[1] == 0)){ - printf("No WPA/RSN information element for station!?\n"); - return -1; /* XXX not right */ - } -+ ielen = ie.rsn_ie[1]; - ielen += 2; -- res = wpa_validate_wpa_ie(hapd, sta, ie.wpa_ie, ielen, -- ie.wpa_ie[0] == WLAN_EID_RSN ? -- HOSTAPD_WPA_VERSION_WPA2 : HOSTAPD_WPA_VERSION_WPA); -- if (res != WPA_IE_OK) { -- printf("WPA/RSN information element rejected? (res %u)\n", res); -- return -1; -- } -+ res = wpa_validate_wpa_ie(hapd, sta, ie.rsn_ie, ielen, -+ HOSTAPD_WPA_VERSION_WPA2); -+ if (res != WPA_IE_OK){ -+ // now look for WPA IE -+ ielen = ie.wpa_ie[1]; -+ ielen += 2; -+ res = wpa_validate_wpa_ie(hapd, sta, ie.wpa_ie, ielen, -+ HOSTAPD_WPA_VERSION_WPA); -+ if (res != WPA_IE_OK) { -+ printf("WPA/RSN information element rejected? (res %u)\n", res); -+ return -1; -+ } -+ } else { -+ rsn = 1; -+ } - free(sta->wpa_ie); - sta->wpa_ie = malloc(ielen); - if (sta->wpa_ie == NULL) { - printf("No memory to save WPA/RSN information element!\n"); - return -1; - } -- memcpy(sta->wpa_ie, ie.wpa_ie, ielen); -+ if (rsn) -+ memcpy(sta->wpa_ie, ie.rsn_ie, ielen); -+ else -+ memcpy(sta->wpa_ie, ie.wpa_ie, ielen); - sta->wpa_ie_len = ielen; - return 0; - } -- cgit v1.2.3 From 21cd1a1ee305e3729d880b0f2aa5f8c7f8d9856f Mon Sep 17 00:00:00 2001 From: wbx Date: Tue, 28 Mar 2006 22:30:12 +0000 Subject: fix problems from ticket #385, thx mikea git-svn-id: svn://svn.openwrt.org/openwrt/trunk/openwrt@3532 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- .../hostapd/patches/001-cross_compile_fix.patch | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) (limited to 'package/hostapd/patches') diff --git a/package/hostapd/patches/001-cross_compile_fix.patch b/package/hostapd/patches/001-cross_compile_fix.patch index ca2bb23c7..8b5ca681d 100644 --- a/package/hostapd/patches/001-cross_compile_fix.patch +++ b/package/hostapd/patches/001-cross_compile_fix.patch @@ -1,6 +1,7 @@ -diff -ruN hostapd-0.3.9-old/Makefile hostapd-0.3.9-new/Makefile ---- hostapd-0.3.9-old/Makefile 2005-06-11 05:03:36.000000000 +0200 -+++ hostapd-0.3.9-new/Makefile 2005-08-14 08:09:52.000000000 +0200 +Common subdirectories: hostapd-0.5.2/logwatch and hostapd-0.5.2.new/logwatch +diff -u hostapd-0.5.2/Makefile hostapd-0.5.2.new/Makefile +--- hostapd-0.5.2/Makefile 2006-03-20 03:20:09.000000000 +0000 ++++ hostapd-0.5.2.new/Makefile 2006-03-21 22:25:23.803473592 +0000 @@ -3,7 +3,7 @@ DIR_HOSTAP=. @@ -10,7 +11,7 @@ diff -ruN hostapd-0.3.9-old/Makefile hostapd-0.3.9-new/Makefile endif # define HOSTAPD_DUMP_STATE to include SIGUSR1 handler for dumping state to -@@ -173,7 +173,7 @@ +@@ -266,7 +266,7 @@ for i in $(ALL); do cp $$i /usr/local/bin/$$i; done hostapd: $(OBJS) @@ -19,3 +20,16 @@ diff -ruN hostapd-0.3.9-old/Makefile hostapd-0.3.9-new/Makefile driver_conf.c: Makefile .config rm -f driver_conf.c +@@ -330,10 +330,10 @@ + endif + + nt_password_hash: $(NOBJS) +- $(CC) -o nt_password_hash $(NOBJS) $(LIBS_n) ++ $(CC) -o nt_password_hash $(NOBJS) $(LDFLAGS) $(LIBS_n) + + hlr_auc_gw: $(HOBJS) +- $(CC) -o hlr_auc_gw $(HOBJS) $(LIBS_h) ++ $(CC) -o hlr_auc_gw $(HOBJS) $(LDFLAGS) $(LIBS_h) + + clean: + rm -f core *~ *.o hostapd hostapd_cli nt_password_hash hlr_auc_gw -- cgit v1.2.3 From 737022a15e9e7b872ffd8220604f29c6e4bc399d Mon Sep 17 00:00:00 2001 From: nbd Date: Thu, 13 Apr 2006 22:20:15 +0000 Subject: remove lots of non-essential packages git-svn-id: svn://svn.openwrt.org/openwrt/branches/buildroot-ng/openwrt@3641 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- .../hostapd/patches/001-cross_compile_fix.patch | 35 ---------------------- 1 file changed, 35 deletions(-) delete mode 100644 package/hostapd/patches/001-cross_compile_fix.patch (limited to 'package/hostapd/patches') diff --git a/package/hostapd/patches/001-cross_compile_fix.patch b/package/hostapd/patches/001-cross_compile_fix.patch deleted file mode 100644 index 8b5ca681d..000000000 --- a/package/hostapd/patches/001-cross_compile_fix.patch +++ /dev/null @@ -1,35 +0,0 @@ -Common subdirectories: hostapd-0.5.2/logwatch and hostapd-0.5.2.new/logwatch -diff -u hostapd-0.5.2/Makefile hostapd-0.5.2.new/Makefile ---- hostapd-0.5.2/Makefile 2006-03-20 03:20:09.000000000 +0000 -+++ hostapd-0.5.2.new/Makefile 2006-03-21 22:25:23.803473592 +0000 -@@ -3,7 +3,7 @@ - DIR_HOSTAP=. - - ifndef CFLAGS --CFLAGS = -MMD -O2 -Wall -g -+CFLAGS = -MMD $(OPTFLAGS) $(CPPFLAGS) - endif - - # define HOSTAPD_DUMP_STATE to include SIGUSR1 handler for dumping state to -@@ -266,7 +266,7 @@ - for i in $(ALL); do cp $$i /usr/local/bin/$$i; done - - hostapd: $(OBJS) -- $(CC) -o hostapd $(OBJS) $(LIBS) -+ $(CC) -o hostapd $(OBJS) $(LDFLAGS) $(LIBS) - - driver_conf.c: Makefile .config - rm -f driver_conf.c -@@ -330,10 +330,10 @@ - endif - - nt_password_hash: $(NOBJS) -- $(CC) -o nt_password_hash $(NOBJS) $(LIBS_n) -+ $(CC) -o nt_password_hash $(NOBJS) $(LDFLAGS) $(LIBS_n) - - hlr_auc_gw: $(HOBJS) -- $(CC) -o hlr_auc_gw $(HOBJS) $(LIBS_h) -+ $(CC) -o hlr_auc_gw $(HOBJS) $(LDFLAGS) $(LIBS_h) - - clean: - rm -f core *~ *.o hostapd hostapd_cli nt_password_hash hlr_auc_gw -- cgit v1.2.3 From 27828bb0a4d584e1869ce8aadbe62131479f7f97 Mon Sep 17 00:00:00 2001 From: nbd Date: Sun, 11 Jun 2006 00:41:16 +0000 Subject: add hostapd git-svn-id: svn://svn.openwrt.org/openwrt/branches/buildroot-ng/openwrt@3932 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- .../hostapd/patches/001-cross_compile_fix.patch | 35 ++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 package/hostapd/patches/001-cross_compile_fix.patch (limited to 'package/hostapd/patches') diff --git a/package/hostapd/patches/001-cross_compile_fix.patch b/package/hostapd/patches/001-cross_compile_fix.patch new file mode 100644 index 000000000..8b5ca681d --- /dev/null +++ b/package/hostapd/patches/001-cross_compile_fix.patch @@ -0,0 +1,35 @@ +Common subdirectories: hostapd-0.5.2/logwatch and hostapd-0.5.2.new/logwatch +diff -u hostapd-0.5.2/Makefile hostapd-0.5.2.new/Makefile +--- hostapd-0.5.2/Makefile 2006-03-20 03:20:09.000000000 +0000 ++++ hostapd-0.5.2.new/Makefile 2006-03-21 22:25:23.803473592 +0000 +@@ -3,7 +3,7 @@ + DIR_HOSTAP=. + + ifndef CFLAGS +-CFLAGS = -MMD -O2 -Wall -g ++CFLAGS = -MMD $(OPTFLAGS) $(CPPFLAGS) + endif + + # define HOSTAPD_DUMP_STATE to include SIGUSR1 handler for dumping state to +@@ -266,7 +266,7 @@ + for i in $(ALL); do cp $$i /usr/local/bin/$$i; done + + hostapd: $(OBJS) +- $(CC) -o hostapd $(OBJS) $(LIBS) ++ $(CC) -o hostapd $(OBJS) $(LDFLAGS) $(LIBS) + + driver_conf.c: Makefile .config + rm -f driver_conf.c +@@ -330,10 +330,10 @@ + endif + + nt_password_hash: $(NOBJS) +- $(CC) -o nt_password_hash $(NOBJS) $(LIBS_n) ++ $(CC) -o nt_password_hash $(NOBJS) $(LDFLAGS) $(LIBS_n) + + hlr_auc_gw: $(HOBJS) +- $(CC) -o hlr_auc_gw $(HOBJS) $(LIBS_h) ++ $(CC) -o hlr_auc_gw $(HOBJS) $(LDFLAGS) $(LIBS_h) + + clean: + rm -f core *~ *.o hostapd hostapd_cli nt_password_hash hlr_auc_gw -- cgit v1.2.3 From 6a15fdaff156a48651c710d80d3027364f9732ab Mon Sep 17 00:00:00 2001 From: nbd Date: Mon, 12 Jun 2006 20:51:14 +0000 Subject: fix wpa/wpa2 with madwifi git-svn-id: svn://svn.openwrt.org/openwrt/branches/buildroot-ng/openwrt@3935 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- package/hostapd/patches/100-madwifi_fixes.patch | 52 +++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 package/hostapd/patches/100-madwifi_fixes.patch (limited to 'package/hostapd/patches') diff --git a/package/hostapd/patches/100-madwifi_fixes.patch b/package/hostapd/patches/100-madwifi_fixes.patch new file mode 100644 index 000000000..eb7299b41 --- /dev/null +++ b/package/hostapd/patches/100-madwifi_fixes.patch @@ -0,0 +1,52 @@ +diff -ur hostapd.old/driver_madwifi.c hostapd.dev/driver_madwifi.c +--- hostapd.old/driver_madwifi.c 2006-03-25 20:55:18.000000000 +0100 ++++ hostapd.dev/driver_madwifi.c 2006-06-12 21:54:22.000000000 +0200 +@@ -20,11 +20,6 @@ + + #include + #include +-#ifdef WME_NUM_AC +-/* Assume this is built against BSD branch of madwifi driver. */ +-#define MADWIFI_BSD +-#include +-#endif /* WME_NUM_AC */ + #include + #include + +@@ -168,7 +164,10 @@ + } + return 0; + } +- ++static int madwifi_get_inact_sec(void *priv, const u8 *addr) ++{ ++return 0; ++} + static int + set80211param(struct madwifi_driver_data *drv, int op, int arg) + { +@@ -1204,8 +1203,6 @@ + goto bad; + } + +- madwifi_set_iface_flags(drv, 0); /* mark down during setup */ +- + hapd->driver = &drv->ops; + return 0; + bad: +@@ -1226,7 +1223,6 @@ + + drv->hapd->driver = NULL; + +- (void) madwifi_set_iface_flags(drv, 0); + if (drv->ioctl_sock >= 0) + close(drv->ioctl_sock); + if (drv->sock_recv != NULL && drv->sock_recv != drv->sock_xmit) +@@ -1306,6 +1452,7 @@ + .get_ssid = madwifi_get_ssid, + .set_countermeasures = madwifi_set_countermeasures, + .sta_clear_stats = madwifi_sta_clear_stats, ++ .get_inact_sec = madwifi_get_inact_sec, + }; + + void madwifi_driver_register(void) -- cgit v1.2.3