diff options
author | Roman Yeryomin <roman@advem.lv> | 2012-09-22 19:44:27 +0300 |
---|---|---|
committer | Roman Yeryomin <roman@advem.lv> | 2012-09-22 19:44:27 +0300 |
commit | 1784b1575a27ac1bfc5cf9d9e5fd3b2d869d991d (patch) | |
tree | f8cad2717e99cad8b0f3e027430b03c38ec02aec /package/hostapd-rtk/patches/004-hostapd-files.patch | |
parent | 6fc13c5885603ee5257c79b0f922f6b220ddfcf2 (diff) |
Add hostapd-rtk and librtk-inband packages
Signed-off-by: Roman Yeryomin <roman@advem.lv>
Diffstat (limited to 'package/hostapd-rtk/patches/004-hostapd-files.patch')
-rw-r--r-- | package/hostapd-rtk/patches/004-hostapd-files.patch | 3529 |
1 files changed, 3529 insertions, 0 deletions
diff --git a/package/hostapd-rtk/patches/004-hostapd-files.patch b/package/hostapd-rtk/patches/004-hostapd-files.patch new file mode 100644 index 000000000..a25374ef4 --- /dev/null +++ b/package/hostapd-rtk/patches/004-hostapd-files.patch @@ -0,0 +1,3529 @@ +Index: hostapd-rtk-0.6.10/hostapd/driver_realtek.c +=================================================================== +--- /dev/null ++++ hostapd-rtk-0.6.10/hostapd/driver_realtek.c +@@ -0,0 +1,3251 @@ ++/* ++ * hostapd / Driver interaction with Realtek 802.11 driver ++ * Copyright (c) ++ * ++ * 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 "includes.h" ++#include "common.h" ++#include <net/if.h> ++#include <sys/ioctl.h> ++ ++#include <net80211/ieee80211.h> ++#ifdef WME_NUM_AC ++/* Assume this is built against BSD branch of realtek driver. */ ++#define REALTEK_BSD ++#include <net80211/_ieee80211.h> ++#endif /* WME_NUM_AC */ ++#include <net80211/ieee80211_crypto.h> ++#include <net80211/ieee80211_ioctl.h> ++ ++#ifdef IEEE80211_IOCTL_SETWMMPARAMS ++/* Assume this is built against realtek-ng */ ++#define REALTEK_NG ++#endif /* IEEE80211_IOCTL_SETWMMPARAMS */ ++ ++#include <net/if_arp.h> ++#include "wireless_copy.h" ++//#include <linux/wireless.h> ++ ++//#include <netpacket/packet.h> ++ ++#include "hostapd.h" ++#include "driver.h" ++#include "ieee802_1x.h" ++#include "eloop.h" ++#include "priv_netlink.h" ++#include "sta_info.h" ++#include "l2_packet/l2_packet.h" ++ ++#include "eapol_sm.h" ++#include "wpa.h" ++#include "radius/radius.h" ++#include "ieee802_11.h" ++#include "accounting.h" ++#include "common.h" ++#include "wps_hostapd.h" ++ ++#ifndef EAP_WPS ++#define EAP_WPS ++#endif ++ ++#include "./driver_realtek.h" ++ ++#ifdef CONFIG_WPS ++#ifdef IEEE80211_IOCTL_FILTERFRAME ++//#include <netpacket/packet.h> ++#ifndef __LINUX_IF_PACKET_H ++//#ifndef __NETPACKET_PACKET_H ++#include <linux/if_packet.h> ++//#include <netpacket/packet.h> ++#endif ++ ++#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 RSN_VERSION ++#undef WPA_VERSION ++#undef WPA_OUI_TYPE ++#undef WME_OUI_TYPE ++ ++#if defined(INBAND_CTRL) ++#ifndef __IOH_H ++#include <librtk-inband/ioh.h> ++#endif ++#define INBAND_INTF "br0" ++#define INBAND_SLAVE ("001234567899") ++#define INBAND_IOCTL_TYPE 0x8899 ++#define INBAND_NETLINK_TYPE 0x9000 ++#define INBAND_DEBUG 0 ++#define INBAND_IOCTLPKT_DUMP //hex_dump ++#undef STAND_ALONE ++#define IWREQ_LEN 32 ++#define INBAND_IOCTLTYPE_LEN 4 ++#define INBAND_IOCTLHDR_LEN 6 ++#define INBAND_PENDING_START(data) data+INBAND_IOCTLHDR_LEN+IWREQ_LEN ++#define INBAND_IOCTLRET_PTR(data) data+INBAND_IOCTLTYPE_LEN ++#define IOH_HDR_LEN sizeof(struct ioh_header) ++#else ++#define STAND_ALONE ++#endif ++ ++//#define HOST_LITTLE_ENDIAN 1 //mark_endian ++ ++#ifdef RTK_MBSSID ++ ++struct i802_bss { ++ //void *ctx; //back pointer to hapd per bss data ++ struct realtek_driver_data *drv; ++ struct i802_bss *next; ++ int ifindex; ++ char ifname[IFNAMSIZ + 1]; ++ struct l2_packet_data *sock_xmit; /* raw packet xmit socket */ ++ //unsigned int beacon_set:1; ++}; ++ ++#endif ++ ++ ++struct realtek_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 */ ++#ifdef RTK_MBSSID ++ int sock_recv; ++#else ++ struct l2_packet_data *sock_recv; /* raw packet recv socket */ ++#endif ++ 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; ++#if defined(INBAND_CTRL) ++ struct ioh_class netlink_ioh_obj; ++#endif ++ ++#ifdef RTK_MBSSID ++ struct i802_bss first_bss; ++ int if_indices[RTK_MAX_IF_INDEX]; ++ int num_if_indices; ++#endif ++}; ++ ++struct rtk_hapd_config rtk_config; ++ ++const struct wpa_driver_ops wpa_driver_realtek_ops; ++ ++static void realtek_deinit(void *priv); ++static int realtek_sta_deauth(void *priv, const u8 *addr, int reason_code); ++ ++#ifdef EAP_WPS ++static int realtek_set_wps_beacon_ie(const char *ifname, void *priv, const u8 *iebuf, size_t iebuflen); ++static int realtek_set_wps_probe_resp_ie(const char *ifname, void *priv, const u8 *iebuf, size_t iebuflen); ++static int realtek_set_wps_assoc_resp_ie(const char *ifname, void *priv, const u8 *iebuf, size_t iebuflen); ++static int realtek_start_receive_prob_req(void *priv); ++#endif /* EAP_WPS */ ++ ++#ifdef RTK_HAPD ++static int realtek_driver_on(void *priv, int on); ++static int realtek_hapd_config(void *priv); ++#endif ++ ++static int realtek_read_priv_vap_cfg(const char *ifname,void *priv, struct rtk_hapd_config* config); ++static int realtek_config_rate(int *rate_list, unsigned int *rate_config); ++static int realtek_read_hapd_cfg(struct hostapd_data *hapd,void *priv, struct rtk_hapd_config* config); ++ ++ ++#ifdef MODIFIED_BY_SONY ++static int wext_set_key(void *priv, int alg, ++ const u8 *addr, int key_idx, ++ int set_tx, const u8 *seq, size_t seq_len, ++ const u8 *key, size_t key_len); ++#endif /* MODIFIED_BY_SONY */ ++ ++#ifdef RTK_MBSSID ++static int add_ifidx(struct realtek_driver_data *drv, int ifidx) ++{ ++ int i; ++ wpa_printf(MSG_DEBUG, "nl80211: Add own interface ifindex %d", ++ ifidx); ++ for (i = 0; i < drv->num_if_indices; i++) { ++ if (drv->if_indices[i] == 0) { ++ drv->if_indices[i] = ifidx; ++ return; ++ } ++ } ++ ++ return -1; ++} ++ ++static int have_ifidx(struct realtek_driver_data *drv, int ifidx) ++{ ++ int i; ++ ++ for (i = 0; i < drv->num_if_indices; i++) ++ if (drv->if_indices[i] == ifidx) ++ return 1; ++ return 0; ++} ++ ++ ++static struct hostapd_data *find_hapd_by_ifname(void *priv,const char *ifname) ++{ ++ struct realtek_driver_data *drv = priv; ++ struct hostapd_data *hapd = drv->hapd,*bss_hapd=hapd; ++ struct hostapd_iface *iface = hapd->iface; ++ struct hostapd_bss_config *conf; ++ int j; ++ ++ ++ for (j = 0; j < iface->num_bss; j++) ++ { ++ bss_hapd = iface->bss[j] ; ++ conf = bss_hapd->conf; ++ if(os_strcmp(conf->iface, ifname) == 0) //find the entry ++ break; ++ ++ } ++ ++ return bss_hapd; ++} ++ ++static struct hostapd_data *find_hapd_by_ifindex(void *priv,int ifindex) ++{ ++ struct realtek_driver_data *drv = priv; ++ struct hostapd_data *hapd = drv->hapd; ++ struct i802_bss *tbss = &drv->first_bss,*bss; ++ ++ ++ if( drv->ifindex == ifindex) //if it's for Root AP ++ goto end; ++ ++ while (tbss) { //find the VAP ++ ++ bss = tbss->next; ++ ++ if(bss == NULL) ++ break; ++ ++ if( bss->ifindex == ifindex ) //find the entry ++ { ++ hapd = (struct hostapd_data *)find_hapd_by_ifname(drv,bss->ifname); ++ break; ++ } ++ tbss = tbss->next; ++ } ++end: ++ return hapd; ++} ++ ++static struct hostapd_data *find_hapd_by_sta(void *priv,u8 *sta_addr) ++{ ++ struct realtek_driver_data *drv = priv; ++ struct hostapd_data *hapd = drv->hapd; ++ struct hostapd_iface *iface = hapd->iface; ++ int j; ++ ++ for (j = 0; j < iface->num_bss; j++) { ++ if (ap_get_sta(iface->bss[j], sta_addr)) { ++ hapd = iface->bss[j]; ++ break; ++ } ++ } ++ ++ return hapd; ++} ++ ++static int rtk_free_bss_by_ifname(void *priv, const char *ifname) ++{ ++ struct realtek_driver_data *drv = priv; ++ struct i802_bss *tbss = &drv->first_bss,*bss; ++ ++ while (tbss) { ++ ++ bss = tbss->next; ++ if(bss == NULL) ++ break; ++ if(os_strcmp(bss->ifname, ifname) == 0) //find the entry ++ { ++ if (bss->sock_xmit != NULL) //deinit socket ++ l2_packet_deinit(bss->sock_xmit); ++ ++ tbss->next = bss->next; ++ os_free(bss); ++ break; ++ } ++ tbss = tbss->next ; ++ } ++ return 0; ++} ++ ++static struct l2_packet_data *rtk_find_l2sock_by_ifname(void *priv, const char *ifname) ++{ ++ struct realtek_driver_data *drv = priv; ++ struct i802_bss *tbss = &drv->first_bss,*bss; ++ struct l2_packet_data *eapol_sock=drv->sock_xmit; ++ ++ if(os_strcmp(drv->iface,ifname)==0) //if it's for Root AP ++ goto end; ++ ++ ++ while (tbss) { //find the VAP ++ ++ bss = tbss->next; ++ ++ if(bss == NULL) ++ break; ++ ++ if(os_strcmp(bss->ifname, ifname) == 0) //find the entry ++ { ++ eapol_sock = bss->sock_xmit; ++ break; ++ } ++ tbss = tbss->next; ++ } ++ ++end: ++ return eapol_sock; ++} ++ ++static void handle_eapol(int sock, void *eloop_ctx, void *sock_ctx) ++{ ++ struct realtek_driver_data *drv = eloop_ctx; ++ struct hostapd_data *hapd = drv->hapd; ++ struct sockaddr_ll lladdr; ++ unsigned char buf[3000]; ++ int len,j; ++ socklen_t fromlen = sizeof(lladdr); ++ struct hostapd_iface *iface = hapd->iface; ++ unsigned char *sa; ++ len = recvfrom(sock, buf, sizeof(buf), 0, ++ (struct sockaddr *)&lladdr, &fromlen); ++ ++ if (len < 0) { ++ perror("recv"); ++ return; ++ } ++ sa = (unsigned char *)lladdr.sll_addr; ++ //if (have_ifidx(drv, lladdr.sll_ifindex)) //mark_mbssid , if br0 rcv?? ++ //{ ++ for (j = 0; j < iface->num_bss; j++) { ++ if (ap_get_sta(iface->bss[j], sa)) { ++ hapd = iface->bss[j]; ++ break; ++ } ++ } ++ ++ /*printf("handle_eapol if=%s src_mac=%x:%x:%x:%x:%x:%x\n",hapd->conf->iface, ++ sa[0],sa[1],sa[2],sa[3],sa[4],sa[5]);*/ ++ ieee802_1x_receive(hapd, sa, buf, len); ++ //} ++} ++#endif ++ ++#ifdef INBAND_CTRL // HOST_LITTLE_ENDIAN ++static void rtk_cfg_to_bigEndian(struct rtk_hapd_config *config_ptr) ++{ ++ config_ptr->band = htonl(config_ptr->band); ++ config_ptr->channel = htonl(config_ptr->channel); ++ config_ptr->bcnint = htonl(config_ptr->bcnint); ++ config_ptr->dtimperiod = htonl(config_ptr->dtimperiod); ++ config_ptr->stanum = htonl(config_ptr->stanum); ++ config_ptr->rtsthres = htonl(config_ptr->rtsthres); ++ config_ptr->fragthres = htonl(config_ptr->fragthres); ++ config_ptr->oprates = htonl(config_ptr->oprates); ++ config_ptr->basicrates = htonl(config_ptr->basicrates); ++ config_ptr->preamble = htonl(config_ptr->preamble); ++ config_ptr->aclmode = htonl(config_ptr->aclmode); ++ config_ptr->aclnum = htonl(config_ptr->aclnum); ++ config_ptr->hiddenAP = htonl(config_ptr->hiddenAP); ++ config_ptr->qos_enable = htonl(config_ptr->qos_enable); ++ config_ptr->expired_time = htonl(config_ptr->expired_time); ++ config_ptr->block_relay = htonl(config_ptr->block_relay); ++ config_ptr->shortGI20M = htonl(config_ptr->shortGI20M); ++ config_ptr->shortGI40M = htonl(config_ptr->shortGI40M); ++ //Above are for Hostapd owned configurations //==================================================== ++ config_ptr->phyBandSelect = htonl(config_ptr->phyBandSelect); ++ config_ptr->ther = htonl(config_ptr->ther); ++ config_ptr->swcrypto = htonl(config_ptr->swcrypto); ++ config_ptr->regdomain = htonl(config_ptr->regdomain); ++ config_ptr->autorate = htonl(config_ptr->autorate); ++ config_ptr->fixrate = htonl(config_ptr->fixrate); ++ config_ptr->disable_protection = htonl(config_ptr->disable_protection); ++ config_ptr->disable_olbc = htonl(config_ptr->disable_olbc); ++ config_ptr->deny_legacy = htonl(config_ptr->deny_legacy); ++ config_ptr->opmode = htonl(config_ptr->opmode); ++ config_ptr->vap_enable = htonl(config_ptr->vap_enable); ++ config_ptr->use40M = htonl(config_ptr->use40M); ++ config_ptr->_2ndchoffset = htonl(config_ptr->_2ndchoffset); ++ config_ptr->ampdu = htonl(config_ptr->ampdu); ++ config_ptr->coexist = htonl(config_ptr->coexist); ++ config_ptr->rssi_dump = htonl(config_ptr->rssi_dump); ++ config_ptr->mp_specific = htonl(config_ptr->mp_specific); ++ config_ptr->use_ext_pa = htonl(config_ptr->use_ext_pa); ++ config_ptr->macPhyMode = htonl(config_ptr->macPhyMode); ++ //Below are for RTK private configurations ++ } ++#endif ++ ++ ++static int ++set80211priv(const char *ifname,struct realtek_driver_data *drv, int op, void *data, int len) ++{ ++ struct iwreq iwr; ++ int do_inline = (len < IFNAMSIZ); ++ ++ /* Poorly thought out inteface -- certain ioctls MUST use ++ * the non-inline method: ++ */ ++ if ( ++ #ifdef IEEE80211_IOCTL_SET_APPIEBUF ++ op == IEEE80211_IOCTL_SET_APPIEBUF || ++ #endif ++ #ifdef IEEE80211_IOCTL_FILTERFRAME ++ op == IEEE80211_IOCTL_FILTERFRAME || ++ #endif ++ 0 ++ ) { ++ do_inline = 0; ++ } ++ ++ memset(&iwr, 0, sizeof(iwr)); ++ strncpy(iwr.ifr_name, ifname, IFNAMSIZ); ++ ++ if (do_inline) { ++ memcpy(iwr.u.name, data, len); ++ } else { ++ /* ++ * Argument data MAY BE 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; ++ } ++ ++#ifdef STAND_ALONE ++ if (ioctl(drv->ioctl_sock, op, &iwr) < 0) { ++ { ++ int err = errno; ++ perror("set80211priv ioctl failed"); ++ wpa_printf(MSG_ERROR, "ioctl 0x%x failed errno=%d", ++ op, err); ++ } ++ return -1; ++ } ++#endif ++#if defined(INBAND_CTRL) ++ INBAND_IOCTLPKT_DUMP(&iwr,sizeof(iwr)); ++ ++ if ( inband_ioctl(op, &iwr) < 0) { ++ perror("set80211priv ioctl failed"); ++ wpa_printf(MSG_ERROR, "ioctl 0x%x failed", op); ++ return -1; ++ } ++#endif ++ ++ ++ return 0; ++} ++ ++static int ++set80211param(const char *ifname,struct realtek_driver_data *drv, int op, int arg) ++{ ++ struct iwreq iwr; ++ ++ memset(&iwr, 0, sizeof(iwr)); ++ strncpy(iwr.ifr_name, ifname, IFNAMSIZ); ++#ifdef INBAND_CTRL //HOST_LITTLE_ENDIAN ++// int need endian swap ++ op = htonl(op); ++ arg = htonl(arg); ++#endif ++ iwr.u.mode = op; ++ memcpy(iwr.u.name+sizeof(__u32), &arg, sizeof(arg)); ++ ++#ifdef STAND_ALONE ++ 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); ++ return -1; ++ } ++#endif ++#if defined(INBAND_CTRL) ++ INBAND_IOCTLPKT_DUMP(&iwr,sizeof(iwr)); ++ if (inband_ioctl(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); ++ return -1; ++ } ++#endif ++ ++ 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; ++} ++ ++ ++static int ++realtek_set_wpa(char *ifname,struct realtek_driver_data *drv, int wpa, int psk, int cipher) ++{ ++ ++ if(psk & WPA_KEY_MGMT_PSK) ++ {//PSK mode, set PSK & cipher ++ if (set80211param(ifname,drv, IEEE80211_PARAM_KEYMGTALGS, wpa)) ++ { ++ wpa_printf(MSG_ERROR, "Unable to set key management algorithms"); ++ return -1; ++ } ++ if (set80211param(ifname,drv, IEEE80211_PARAM_UCASTCIPHERS, cipher)) ++ { ++ wpa_printf(MSG_ERROR, "Unable to set pairwise key ciphers"); ++ return -1; ++ } ++ ++ } ++ else ++ {//Enterprise mode, Disable PSK & set cipher. ++ if (set80211param(ifname,drv, IEEE80211_PARAM_KEYMGTALGS, 0)) ++ { ++ wpa_printf(MSG_ERROR, "Unable to set key management algorithms"); ++ return -1; ++ } ++ if (set80211param(ifname,drv, IEEE80211_PARAM_UCASTCIPHERS, cipher)) ++ { ++ wpa_printf(MSG_ERROR, "Unable to set pairwise key ciphers"); ++ return -1; ++ } ++ ++ } ++ ++ if (set80211param(ifname,drv, IEEE80211_PARAM_WPA, wpa)) ++ { ++ wpa_printf(MSG_ERROR, "Unable to set WPA"); ++ return -1; ++ } ++ ++ return set80211param(ifname,drv, IEEE80211_PARAM_AUTHMODE, IEEE80211_AUTH_WPA); ++ ++} ++ ++/* ++ * Configure WPA parameters. ++ */ ++static int ++realtek_configure_wpa(struct hostapd_data *hapd,struct realtek_driver_data *drv) ++{ ++ struct hostapd_bss_config *conf = hapd->conf; ++ int v; ++ ++ //delete conf->wpa_group & conf->rsn_preauth related parts (like ralink) ++ ++ wpa_printf(MSG_DEBUG, "realtek_configure_wpa +++ wpa=0x%x, psk=0x%x, cipher=0x%x", ++ conf->wpa, conf->wpa_key_mgmt, conf->wpa_pairwise); ++ ++ v = 0; ++ if (conf->wpa_pairwise & WPA_CIPHER_CCMP) ++ v |= 1<<IEEE80211_CIPHER_AES_CCM; ++ if (conf->wpa_pairwise & WPA_CIPHER_TKIP) ++ v |= 1<<IEEE80211_CIPHER_TKIP; ++ if (conf->wpa_pairwise & WPA_CIPHER_NONE) ++ v |= 1<<IEEE80211_CIPHER_NONE; ++ ++ if((conf->wpa == 0) || (conf->wpa > (HOSTAPD_WPA_VERSION_WPA|HOSTAPD_WPA_VERSION_WPA2))) ++ return -1; ++ else ++ return realtek_set_wpa(conf->iface,drv, conf->wpa , conf->wpa_key_mgmt, v); ++ ++} ++ ++static int ++realtek_set_iface_hwMac(const char *ifname,void *priv, char *addr) ++{ ++ struct realtek_driver_data *drv = priv; ++ struct ifreq ifreq; ++ ++ if (drv->ioctl_sock < 0) ++ return -1; ++ ++ os_memset(&ifreq, 0, sizeof(ifreq)); ++ os_strlcpy(ifreq.ifr_name, ifname, IFNAMSIZ); ++ ++ memcpy(ifreq.ifr_hwaddr.sa_data, addr, ETH_ALEN); ++ ifreq.ifr_hwaddr.sa_family = ARPHRD_ETHER; ++ ++#if defined(INBAND_CTRL) ++ INBAND_IOCTLPKT_DUMP(&ifreq,sizeof(ifreq)); ++ if (inband_ioctl(SIOCSIFHWADDR, &ifreq) < 0) { ++ perror("inband_ioctl[SIOCSIFHWADDR]"); ++ return -1; ++ } ++#else ++ if (ioctl(drv->ioctl_sock, SIOCSIFHWADDR, &ifreq) != 0) { ++ perror("ioctl[SIOCSIFHWADDR]"); ++ return -1; ++ } ++#endif ++ ++ ++ return 0; ++} ++ ++static int ++realtek_set_iface_flags(const char *ifname,void *priv, int dev_up) ++{ ++ struct realtek_driver_data *drv = priv; ++ struct ifreq ifr; ++ ++ wpa_printf(MSG_DEBUG, "realtek_set_iface_flags +++ dev_up = %d", dev_up); ++ ++ if (drv->ioctl_sock < 0) ++ return -1; ++ ++ if (dev_up) { ++ memset(&ifr, 0, sizeof(ifr)); ++ snprintf(ifr.ifr_name, IFNAMSIZ, "%s", ifname); ++ ifr.ifr_mtu = HOSTAPD_MTU; ++#ifdef STAND_ALONE ++ if (ioctl(drv->ioctl_sock, SIOCSIFMTU, &ifr) != 0) { ++ perror("ioctl[SIOCSIFMTU]"); ++ printf("Setting MTU failed - trying to survive with " ++ "current value\n"); ++ } ++#endif ++#if defined(INBAND_CTRL) ++ INBAND_IOCTLPKT_DUMP(&ifr,sizeof(ifr)); ++ if (inband_ioctl(SIOCSIFMTU, &ifr) < 0) { ++ perror("inband_ioctl[SIOCSIFMTU]"); ++ printf("Setting MTU failed - trying to survive with " ++ "current value\n"); ++ } ++#endif ++ } ++ ++ memset(&ifr, 0, sizeof(ifr)); ++ snprintf(ifr.ifr_name, IFNAMSIZ, "%s", ifname); ++#ifdef STAND_ALONE ++ if (ioctl(drv->ioctl_sock, SIOCGIFFLAGS, &ifr) != 0) { ++ perror("ioctl[SIOCGIFFLAGS]"); ++ return -1; ++ } ++#endif ++#if defined(INBAND_CTRL) ++ INBAND_IOCTLPKT_DUMP(&ifr,sizeof(ifr)); ++ if (inband_ioctl(SIOCGIFFLAGS, &ifr) < 0) { ++ perror("inband_ioctl[SIOCGIFFLAGS]"); ++ printf("inband_ioctl[SIOCGIFFLAGS] fail"); ++ return -1; ++ } ++#endif ++ ++ if (dev_up) ++ ifr.ifr_flags |= IFF_UP; ++ else ++ ifr.ifr_flags &= ~IFF_UP; ++#ifdef STAND_ALONE ++ if (ioctl(drv->ioctl_sock, SIOCSIFFLAGS, &ifr) != 0) { ++ perror("ioctl[SIOCSIFFLAGS]"); ++ return -1; ++ } ++#endif ++#if defined(INBAND_CTRL) ++ INBAND_IOCTLPKT_DUMP(&ifr,sizeof(ifr)); ++ if (inband_ioctl(SIOCSIFFLAGS, &ifr) < 0) { ++ perror("inband_ioctl[SIOCSIFFLAGS]"); ++ printf("inband_ioctl[SIOCGIFFLAGS] fail"); ++ return -1; ++ } ++#endif ++ ++ wpa_printf(MSG_DEBUG, "realtek_set_iface_flags ---"); ++ return 0; ++} ++ ++static int realtek_set_ieee8021x(const char *ifname, void *priv, int enabled) ++{ ++ struct realtek_driver_data *drv = priv; ++ struct hostapd_data *hapd = drv->hapd; ++ struct hostapd_bss_config *conf = hapd->conf; ++ struct hostapd_wep_keys wep = conf->ssid.wep; ++ ++#ifdef RTK_MBSSID //find the real VAP ++ hapd =(struct hostapd_data *) find_hapd_by_ifname(priv,ifname); ++ conf = hapd->conf; ++ wep = conf->ssid.wep; ++#endif ++ ++ wpa_printf(MSG_DEBUG, "realtek_set_ieee8021x+++ \n" ++ "enabled=%d, conf->auth_algs=%d, wep.keys_set=%d, conf->ieee802_1x=%d" ++ ,enabled, conf->auth_algs, wep.keys_set, conf->ieee802_1x); ++ ++ if(set80211param(ifname,priv, IEEE80211_PARAM_UCASTKEYLEN, conf->individual_wep_key_len)) ++ return -1; ++ ++ if (!enabled) { ++ wpa_printf(MSG_DEBUG, "set WEP"); ++ /* Set interface up flags after setting authentication modes, ++ done atlast in realtek_commit() */ ++ if(conf->auth_algs==1 && wep.keys_set==0) ++ return set80211param(ifname,priv, IEEE80211_PARAM_AUTHMODE, IEEE80211_AUTH_OPEN); ++ else if(conf->auth_algs==1 && wep.keys_set==1){ ++ return set80211param(ifname,priv, IEEE80211_PARAM_AUTHMODE, IEEE80211_AUTH_OPEN); ++ /*Fix for open wep when run using hostapd*/ ++ //return set80211param(priv, IEEE80211_PARAM_PRIVACY, 1); ++ } ++ else if(conf->auth_algs==2) ++ return set80211param(ifname,priv, IEEE80211_PARAM_AUTHMODE, IEEE80211_AUTH_SHARED); ++ else if(conf->auth_algs==3) ++ return set80211param(ifname,priv, IEEE80211_PARAM_AUTHMODE, IEEE80211_AUTH_AUTO); ++ else if(conf->auth_algs==8) //RTK_HAPD, add auth_algs=BIT(3) as value of none authentication. ++ return set80211param(ifname,priv, IEEE80211_PARAM_AUTHMODE, IEEE80211_AUTH_NONE); ++ } ++ ++ 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 == 0) && (conf->ieee802_1x)) ++ { ++ if(set80211param(ifname,priv, IEEE80211_PARAM_AUTHMODE, IEEE80211_AUTH_8021X)) ++ return -1; ++ } ++ ++ if (conf->wpa) ++ { ++ return realtek_configure_wpa(hapd,drv); ++ } ++ ++ return 0; ++} ++ ++static int ++realtek_set_privacy(const char *ifname, void *priv, int enabled) ++{ ++ struct realtek_driver_data *drv = priv; ++ struct hostapd_data *hapd = drv->hapd; ++ ++ wpa_printf(MSG_DEBUG, "realtek_set_privacy +++"); ++ ++ return set80211param(ifname,priv, IEEE80211_PARAM_PRIVACY, enabled); ++} ++ ++static int ++realtek_set_sta_authorized(void *priv, const u8 *addr, int authorized) ++{ ++ struct realtek_driver_data *drv = priv; ++ struct hostapd_data *hapd = drv->hapd; ++ struct hostapd_bss_config *conf = hapd->conf; ++ struct ieee80211req_mlme mlme; ++ int ret; ++ ++#ifdef RTK_MBSSID ++ hapd = (struct hostapd_data *)find_hapd_by_sta(priv,addr); ++ conf = hapd->conf; ++#endif ++ ++ 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); ++ ret = set80211priv(conf->iface,priv, IEEE80211_IOCTL_SETMLME, &mlme, ++ sizeof(mlme)); ++ if (ret < 0) { ++ wpa_printf(MSG_DEBUG, "%s: Failed to %sauthorize STA " MACSTR, ++ __func__, authorized ? "" : "un", MAC2STR(addr)); ++ } ++ ++ return ret; ++} ++ ++static int ++realtek_sta_set_flags(void *priv, const u8 *addr, int flags_or, int flags_and) ++{ ++ ++ wpa_printf(MSG_DEBUG, "realtek_sta_set_flags +++"); ++ ++ /* For now, only support setting Authorized flag */ ++ if (flags_or & WLAN_STA_AUTHORIZED) ++ return realtek_set_sta_authorized(priv, addr, 1); ++ if (!(flags_and & WLAN_STA_AUTHORIZED)) ++ return realtek_set_sta_authorized(priv, addr, 0); ++ return 0; ++} ++ ++static int ++realtek_del_key(const char *ifname,void *priv, const u8 *addr, int key_idx) ++{ ++ struct realtek_driver_data *drv = priv; ++ struct hostapd_data *hapd = drv->hapd; ++ struct ieee80211req_del_key wk; ++ int ret; ++ ++ wpa_printf(MSG_DEBUG, "realtek_del_key +++"); ++ ++ 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; ++ } ++ ++ ret = set80211priv(ifname ,priv, IEEE80211_IOCTL_DELKEY, &wk, sizeof(wk)); ++ if (ret < 0) { ++ wpa_printf(MSG_DEBUG, "%s: Failed to delete key (addr %s" ++ " key_idx %d)", __func__, ether_sprintf(addr), ++ key_idx); ++ } ++ ++ wpa_printf(MSG_DEBUG, "realtek_del_key ---"); ++ return ret; ++} ++ ++static int ++realtek_set_key(const char *ifname, void *priv, const char *alg, ++ const u8 *addr, int key_idx, ++ const u8 *key, size_t key_len, int txkey) ++{ ++ struct realtek_driver_data *drv = priv; ++ struct hostapd_data *hapd = drv->hapd; ++ struct hostapd_bss_config *conf = hapd->conf; ++ struct hostapd_wep_keys wep = conf->ssid.wep; ++ struct ieee80211req_key wk; ++ u_int8_t cipher; ++ int ret; ++ ++#ifdef RTK_MBSSID //find the real VAP ++ hapd = (struct hostapd_data *)find_hapd_by_ifname(priv,ifname); ++ conf = hapd->conf; ++ wep = conf->ssid.wep; ++#endif ++ ++ wpa_printf(MSG_DEBUG, "realtek_set_key +++"); ++ wpa_printf(MSG_DEBUG, "alg = %s\n, addr = %s\n, key_index = %d", alg, ether_sprintf(addr), key_idx); ++ ++ if (strcmp(alg, "none") == 0) ++ return realtek_del_key(ifname,priv, addr, key_idx); ++ ++ if ((strcmp(alg, "WEP") == 0) && ((wep.keys_set >= 1) && (wep.keys_set <= 4))) ++ 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 = key_idx; ++ //wk.ik_keyix = IEEE80211_KEYIX_NONE; ++ } ++ wk.ik_keylen = key_len; ++ memcpy(wk.ik_keydata, key, key_len); ++ ++#ifdef INBAND_CTRL //HOST_LITTLE_ENDIAN ++ // ik_keyix int16 need endian-swap ++ wk.ik_keyix = htons(wk.ik_keyix); ++ wk.ik_keylen = htonl(key_len); ++#endif ++ ret = set80211priv(ifname,priv, IEEE80211_IOCTL_SETKEY, &wk, sizeof(wk)); ++ if (ret < 0) { ++ wpa_printf(MSG_DEBUG, "%s: Failed to set key (addr %s" ++ " key_idx %d alg '%s' key_len %lu txkey %d)", ++ __func__, ether_sprintf(wk.ik_macaddr), key_idx, ++ alg, (unsigned long) key_len, txkey); ++ } ++ ++ wpa_printf(MSG_DEBUG, "realtek_set_key ---"); ++ return ret; ++} ++ ++ ++static int ++realtek_get_seqnum(const char *ifname, void *priv, const u8 *addr, int idx, ++ u8 *seq) ++{ ++//do nothing like broadcom & ralink, even madwifi did not call back for hosapd. ++ ++ wpa_printf(MSG_DEBUG, "realtek_get_seqnum +++"); ++ wpa_printf(MSG_DEBUG, "realtek_get_seqnum ---"); ++ ++ return 0; ++} ++ ++ ++static int ++realtek_flush(void *priv) ++{ ++//do nothing like broadcom & ralink ++ wpa_printf(MSG_DEBUG, "realtek_flush +++"); ++ wpa_printf(MSG_DEBUG, "realtek_flush ---"); ++ return 0; ++} ++ ++ ++static int ++realtek_read_sta_driver_data(void *priv, struct hostap_sta_driver_data *data, ++ const u8 *addr) ++{ ++#if 0 //not use now ++ struct realtek_driver_data *drv = priv; ++ wpa_printf(MSG_DEBUG, "realtek_read_sta_driver_data +++"); ++ ++#ifdef REALTEK_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, ++#ifdef REALTEK_NG ++ IEEE80211_IOCTL_STA_STATS, ++#else /* REALTEK_NG */ ++ IEEE80211_IOCTL_GETSTASTATS, ++#endif /* REALTEK_NG */ ++ &stats, sizeof(stats))) { ++ wpa_printf(MSG_DEBUG, "%s: Failed to fetch STA stats (addr " ++ MACSTR ")", __func__, MAC2STR(addr)); ++ 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; ++ } ++#ifdef INBAND_CTRL //HOST_LITTLE_ENDIAN ++ stats.is_stats.ns_rx_data = ntohl(stats.is_stats.ns_rx_data); ++ stats.is_stats.ns_rx_bytes = ntohl(stats.is_stats.ns_rx_bytes); ++ stats.is_stats.ns_tx_data = ntohl(stats.is_stats.ns_tx_data); ++ stats.is_stats.ns_tx_bytes = ntohl(stats.is_stats.ns_tx_bytes); ++#endif ++ 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 /* REALTEK_BSD */ ++ ++ char buf[1024], line[128], *pos; ++ FILE *f; ++ unsigned long val; ++ ++ memset(data, 0, sizeof(*data)); ++ snprintf(buf, sizeof(buf), "/proc/net/realtek/%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 /* REALTEK_BSD */ ++#endif ++return 0; ++} ++ ++ ++static int ++realtek_sta_clear_stats(void *priv, const u8 *addr) ++{ ++#if 0 //not support now ++#if defined(REALTEK_BSD) && defined(IEEE80211_MLME_CLEAR_STATS) ++ struct realtek_driver_data *drv = priv; ++ struct hostapd_data *hapd = drv->hapd; ++ struct ieee80211req_mlme mlme; ++ int ret; ++ ++ wpa_printf(MSG_DEBUG, "realtek_sta_clear_stats (BSD) +++"); ++ ++ mlme.im_op = IEEE80211_MLME_CLEAR_STATS; ++ memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); ++ ret = set80211priv(priv, IEEE80211_IOCTL_SETMLME, &mlme, ++ sizeof(mlme)); ++ if (ret < 0) { ++ wpa_printf(MSG_DEBUG, "%s: Failed to clear STA stats (addr " ++ MACSTR ")", __func__, MAC2STR(addr)); ++ } ++ ++ return ret; ++#else /* REALTEK_BSD && IEEE80211_MLME_CLEAR_STATS */ ++ wpa_printf(MSG_DEBUG, "realtek_sta_clear_stats +++"); ++ return 0; /* FIX */ ++#endif /* REALTEK_BSD && IEEE80211_MLME_CLEAR_STATS */ ++#endif ++return 0; ++} ++ ++ ++static int ++realtek_set_opt_ie(const char *ifname, void *priv, const u8 *ie, size_t ie_len) ++{ ++//do nothing like broadcom & ralink & madwifi ++ ++ wpa_printf(MSG_DEBUG, "realtek_set_opt_ie +++"); ++ wpa_printf(MSG_DEBUG, "realtek_set_opt_ie ---"); ++ return 0; ++} ++ ++static int ++realtek_is_ifup(const char *ifname,struct realtek_driver_data *drv) ++{ ++ struct ifreq ifr; ++ ++ if (drv->ioctl_sock < 0) ++ return 0; ++ ++ memset(&ifr, 0, sizeof(ifr)); ++ snprintf(ifr.ifr_name, IFNAMSIZ, "%s", ifname); ++#ifdef STAND_ALONE ++ if (ioctl(drv->ioctl_sock, SIOCGIFFLAGS, &ifr) != 0) { ++ perror("ioctl[SIOCGIFFLAGS]"); ++ return 0; ++ } ++#endif ++#if defined(INBAND_CTRL) ++ INBAND_IOCTLPKT_DUMP(&ifr,sizeof(ifr)); ++ if (inband_ioctl(SIOCGIFFLAGS, &ifr) < 0) { ++ perror("ioctl[SIOCGIFFLAGS]"); ++ return 0; ++ } ++#endif ++ ++ return ((ifr.ifr_flags & IFF_UP) == IFF_UP); ++} ++ ++static int ++realtek_sta_deauth(void *priv, const u8 *addr, int reason_code) ++{ ++ struct realtek_driver_data *drv = priv; ++ struct hostapd_data *hapd = drv->hapd; ++ struct hostapd_bss_config *conf = hapd->conf; ++ struct ieee80211req_mlme mlme; ++ int ret; ++ ++#ifdef RTK_MBSSID //find the sta belong to which MBSSID ++ hapd = (struct hostapd_data *)find_hapd_by_sta(priv,addr); ++ conf = hapd->conf; ++#endif ++ ++ wpa_printf(MSG_DEBUG, "realtek_sta_deauth +++"); ++ ++ mlme.im_op = IEEE80211_MLME_DEAUTH; ++ mlme.im_reason = reason_code; ++ memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); ++ if (!realtek_is_ifup(conf->iface,drv)) { ++ return EINVAL; ++ } ++#ifdef INBAND_CTRL //HOST_LITTLE_ENDIAN ++ //im_reason need swap ++ mlme.im_reason = htons(mlme.im_reason); ++#endif ++ ret = set80211priv(conf->iface,priv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme)); ++ if (ret < 0) { ++ wpa_printf(MSG_DEBUG, "%s: Failed to deauth STA (addr " MACSTR ++ " reason %d)", ++ __func__, MAC2STR(addr), reason_code); ++ } ++ ++ return ret; ++} ++ ++static int ++realtek_sta_disassoc(void *priv, const u8 *addr, int reason_code) ++{ ++ struct realtek_driver_data *drv = priv; ++ struct hostapd_data *hapd = drv->hapd; ++ struct hostapd_bss_config *conf = hapd->conf; ++ struct ieee80211req_mlme mlme; ++ int ret; ++ ++#ifdef RTK_MBSSID //find the sta belong to which MBSSID ++ hapd = (struct hostapd_data *)find_hapd_by_sta(priv,addr); ++ conf = hapd->conf; ++#endif ++ ++ wpa_printf(MSG_DEBUG, "realtek_sta_disassoc +++"); ++ ++ mlme.im_op = IEEE80211_MLME_DISASSOC; ++ mlme.im_reason = reason_code; ++ memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); ++#ifdef INBAND_CTRL //HOST_LITTLE_ENDIAN ++ //im_reason need swap ++ mlme.im_reason = htons(mlme.im_reason); ++#endif ++ ret = set80211priv(conf->iface,priv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme)); ++ if (ret < 0) { ++ wpa_printf(MSG_DEBUG, "%s: Failed to disassoc STA (addr " ++ MACSTR " reason %d)", ++ __func__, MAC2STR(addr), reason_code); ++ } ++ ++ return ret; ++} ++ ++#ifdef RTK_HAPD ++//Announce driver to remove sta list for IAPP function ++static int ++realtek_sta_remove(void *priv, const u8 *addr) ++{ ++ struct realtek_driver_data *drv = priv; ++ struct hostapd_data *hapd = drv->hapd; ++ struct hostapd_bss_config *conf = hapd->conf; ++ unsigned char para[32]; ++ struct iwreq wrq; ++ ++#ifdef RTK_MBSSID //find the sta belong to which MBSSID ++ hapd = (struct hostapd_data *)find_hapd_by_sta(priv,addr); ++ conf = hapd->conf; ++#endif ++ wpa_printf(MSG_DEBUG, "realtek_sta_remove +++"); ++ memset(para, 0, 32); ++ sprintf(para, "%02x%02x%02x%02x%02x%02x", addr[0], addr[1], ++ addr[2], addr[3], addr[4], addr[5]); ++ wrq.u.data.pointer = para; ++ wrq.u.data.length = strlen(para); ++ strncpy(wrq.ifr_name, conf->iface, IFNAMSIZ); ++#ifdef STAND_ALONE ++ ioctl(drv->ioctl_sock, RTL8192CD_IOCTL_DEL_STA, &wrq); ++#endif ++#ifdef INBAND_CTRL ++ inband_ioctl(RTL8192CD_IOCTL_DEL_STA, &wrq); ++#endif ++ ++ wpa_printf(MSG_DEBUG, "realtek_sta_remove ---"); ++ ++ return 0; ++} ++#endif ++ ++static int ++realtek_del_sta(struct hostapd_data *hapd,struct realtek_driver_data *drv, u8 addr[IEEE80211_ADDR_LEN]) ++{ ++ struct sta_info *sta; ++ ++ hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211, ++ HOSTAPD_LEVEL_INFO, "disassociated"); ++ ++ sta = ap_get_sta(hapd, addr); ++ if (sta != NULL) { ++ sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC); ++ wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC); ++ sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST; ++ ieee802_1x_notify_port_enabled(sta->eapol_sm, 0); ++ ap_free_sta(hapd, sta); ++ } ++ return 0; ++} ++ ++static int ++realtek_process_wpa_ie(struct hostapd_data *hapd,struct realtek_driver_data *drv, struct sta_info *sta) ++{ ++ struct ieee80211req_wpaie ie; ++ int ielen, res; ++ u8 *iebuf = NULL; ++ struct hostapd_bss_config *conf = hapd->conf; ++ ++ wpa_printf(MSG_DEBUG, "realtek_process_wpa_ie +++"); ++ ++ /* ++ * Fetch negotiated WPA/RSN parameters from the system. ++ */ ++ memset(&ie, 0, sizeof(ie)); ++ memcpy(ie.wpa_macaddr, sta->addr, IEEE80211_ADDR_LEN); ++ ++ if (set80211priv(conf->iface,drv, HAPD_IOCTL_GETWPAIE, &ie, sizeof(ie))) ++ { ++ wpa_printf(MSG_ERROR, "%s: Failed to get WPA/RSN IE", __func__); ++ printf("Failed to get WPA/RSN information element.\n"); ++ return -1; ++ } ++ ++ //wpa_printf(MSG_DEBUG, "get wpa_ie = 0x%02x, 0x%02x, 0x%02x", ie.wpa_ie[0], ie.wpa_ie[1], ie.wpa_ie[2]); ++ //wpa_printf(MSG_DEBUG, "get wps_ie = 0x%02x, 0x%02x, 0x%02x", ie.wps_ie[0], ie.wps_ie[1], ie.wps_ie[2]); ++ ++ do { ++ iebuf = 0; ielen = 0; ++ if (conf->wpa & HOSTAPD_WPA_VERSION_WPA) { ++ iebuf = ie.wpa_ie; ielen = 0; ++ if ((iebuf[0] == WLAN_EID_VENDOR_SPECIFIC) && iebuf[1]) { ++ wpa_printf(MSG_DEBUG, "get wpa_ie"); ++ ielen = iebuf[1]; ++ break; ++ } ++ } ++ if (conf->wpa & HOSTAPD_WPA_VERSION_WPA2) { ++ iebuf = ie.rsn_ie; ielen = 0; ++ if ((iebuf[0] == WLAN_EID_RSN) && iebuf[1]) { ++ wpa_printf(MSG_DEBUG, "get rsn_ie"); ++ ielen = iebuf[1]; ++ break; ++ } ++ } ++ } while (0); ++ ++ wpabuf_free(sta->wps_ie); ++ if ((ie.wps_ie[0] == WLAN_EID_VENDOR_SPECIFIC) && ie.wps_ie[1]) ++ { ++ //Test rtl8192su usb-dongle wps_pbc/wps_pin ok via here. ++ wpa_printf(MSG_DEBUG, "get wps_ie"); ++ ielen = ie.wps_ie[1] + 2; ++ ++ sta->wps_ie = wpabuf_alloc(0); ++ sta->wps_ie->size = ielen; ++ sta->wps_ie->used = ielen; ++ sta->wps_ie->ext_data = os_malloc(ielen); ++ memcpy(sta->wps_ie->ext_data, ie.wps_ie, ielen); ++ ++ sta->flags |= WLAN_STA_WPS; ++ return 0; ++ } ++ else ++ { ++ sta->wps_ie = wpabuf_alloc(0); ++ sta->wps_ie->used = 0; ++ sta->wps_ie->ext_data = NULL; ++ ++ sta->flags &= ~WLAN_STA_WPS; ++ ++ ++ if((ielen == 0) && (conf->wps_state)){ ++ wpa_printf(MSG_DEBUG, "STA did not include WPA/RSN/WPS IE in (Re)Association Request " ++ "but WPS enabled at hostapd conf file - possible WPS use"); ++ sta->flags |= WLAN_STA_MAYBE_WPS; // Test dwa140 and wn111 wps_pbc/wps_pin ok because of here!!!! --zj ++ } ++ else{ ++ sta->flags &= ~WLAN_STA_MAYBE_WPS; ++ } ++ } ++ ++ if(ielen != 0) //_For WPS, neglect wpa_ie?? ++ { ++ if (sta->wpa_sm == NULL) ++ sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth, sta->addr); ++ ++ if (sta->wpa_sm == NULL) ++ { ++ wpa_printf(MSG_ERROR, "Failed to initialize WPA state machine"); ++ return -1; ++ } ++ ++ ielen += 2; ++ res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm, iebuf, ielen, NULL, 0); ++ ++ if (res != WPA_IE_OK) ++ { ++ wpa_printf(MSG_ERROR, "WPA/RSN information element rejected? (res %u)", res); ++ return -1; ++ } ++ else ++ wpa_printf(MSG_DEBUG, "WPA_IE_OK"); ++ } ++ ++ ++ return 0; ++} ++ ++static int ++realtek_issue_asocrsp(char *ifname,struct realtek_driver_data *drv, struct sta_info *sta) ++{ ++ int retVal = 0; ++ struct iwreq iwr; ++ DOT11_ASSOCIATION_RSP Association_Rsp; ++ ++ wpa_printf(MSG_DEBUG, "realtek_issue_asocrsp +++"); ++ ++ strncpy(iwr.ifr_name, ifname, IFNAMSIZ); ++ ++ iwr.u.data.pointer = (caddr_t)&Association_Rsp; ++ iwr.u.data.length = sizeof(DOT11_ASSOCIATION_RSP); ++ ++ Association_Rsp.EventId = DOT11_EVENT_ASSOCIATION_RSP; ++ ++ //?? Re-Association case?? ++ //Association_Rsp.EventId = DOT11_EVENT_REASSOCIATION_RSP; ++ ++ Association_Rsp.IsMoreEvent = FALSE; ++ Association_Rsp.Status = _STATS_SUCCESSFUL_; ++ memcpy(&Association_Rsp.MACAddr, sta->addr, IEEE80211_ADDR_LEN); ++ ++#ifdef STAND_ALONE ++ if(ioctl(drv->ioctl_sock, SIOCGIWIND, &iwr) < 0) ++ retVal = -1; ++ else ++ retVal = 0; ++#endif ++#if defined(INBAND_CTRL) ++ INBAND_IOCTLPKT_DUMP(&iwr,sizeof(iwr)); ++ if (inband_ioctl(SIOCGIWIND, &iwr) < 0) ++ retVal = -1; ++ else ++ retVal = 0; ++#endif ++ return retVal; ++ ++} ++ ++ ++static int ++realtek_new_sta(struct hostapd_data *hapd,struct realtek_driver_data *drv, u8 addr[IEEE80211_ADDR_LEN]) ++{ ++ struct hostapd_bss_config *conf = hapd->conf; ++ 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 { ++ //printf("realtek_new_sta hapd=%s \n",conf->iface); ++ sta = ap_sta_add(hapd, addr); ++ if (sta == NULL) ++ return -1; ++ } ++ //mark_mbssid , acct_mac ? per VAP? ++ 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 || hapd->conf->wps_state) { ++ if (realtek_process_wpa_ie(hapd,drv, sta)) ++ return -1; ++ if((sta->wps_ie->used == 0) && ((conf->wpa_key_mgmt & WPA_KEY_MGMT_PSK) == 0) && (conf->ieee802_1x != 0)) ++ {//do issue Association response just for RADIUS authentication. ++ if(realtek_issue_asocrsp(hapd->conf->iface,drv, sta)) ++ return -1; ++ } ++ } ++ else ++ { ++ if(conf->ieee802_1x != 0) ++ if(realtek_issue_asocrsp(hapd->conf->iface,drv, sta)) ++ return -1; ++ } ++ ++ /* ++ * Now that the internal station state is setup ++ * kick the authenticator into action. ++ */ ++ ++ wpa_printf(MSG_DEBUG, "Try to kick the authenticator into action"); ++ ++ new_assoc = (sta->flags & WLAN_STA_ASSOC) == 0; ++ sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC; ++ wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC); ++ hostapd_new_assoc_sta(hapd, sta, !new_assoc); ++ ieee802_1x_notify_port_enabled(sta->eapol_sm, 1); ++ return 0; ++} ++ ++ ++ ++int realtek_set_wds(void *priv, struct rtk_wds_config wds) ++{ ++ struct realtek_driver_data *drv = priv; ++ struct hostapd_data *hapd = drv->hapd; ++ struct hostapd_bss_config *conf = hapd->conf; ++ struct iwreq iwr; ++ int op = 0; ++ ++ wpa_printf(MSG_DEBUG, "realtek_set_wds +++"); ++ ++ memset(&iwr, 0, sizeof(iwr)); ++ strncpy(iwr.ifr_name, drv->iface, IFNAMSIZ); ++ ++ iwr.u.data.pointer = &wds; ++ iwr.u.data.length = sizeof(struct rtk_wds_config); ++ ++ if(wds.wdsEnabled) ++ op = IEEE80211_IOCTL_WDSADDMAC; ++ else ++ op = IEEE80211_IOCTL_WDSDELMAC; ++#ifdef STAND_ALONE ++ if (ioctl(drv->ioctl_sock, op, &iwr) < 0) ++ { ++ { ++ int err = errno; ++ perror("set WDS ioctl failed"); ++ wpa_printf(MSG_ERROR, "ioctl 0x%x failed errno=%d", ++ op, err); ++ } ++ return -1; ++ } ++#endif ++#if defined(INBAND_CTRL) ++ INBAND_IOCTLPKT_DUMP(&iwr,sizeof(iwr)); ++ if (inband_ioctl(op, &iwr) < 0) ++ { ++ { ++ perror("set80211priv ioctl failed"); ++ wpa_printf(MSG_ERROR, "ioctl 0x%x failed", op); ++ } ++ return -1; ++ } ++#endif ++ ++ ++ return 0; ++} ++ ++ ++static void ++realtek_wireless_event_wireless_custom(struct hostapd_data *hapd,struct realtek_driver_data *drv, u16 flags, char * custom, size_t len) ++{ ++ wpa_printf(MSG_DEBUG, "custom event =%d, len=%d", flags, len); ++ ++ switch(flags) ++ { ++ case HAPD_MIC_FAILURE: ++ { ++ unsigned char * mac = (unsigned char *)custom; ++ wpa_printf(MSG_DEBUG, "MIC failed sta: %02x %02x %02x %02x %02x %02x" ++ , mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); ++ ieee80211_michael_mic_failure(hapd, mac, 1); ++ break; ++ } ++ case HAPD_WPS_PROBEREQ: ++ { ++ struct _DOT11_PROBE_REQUEST_IND *wps_ie = (struct _DOT11_PROBE_REQUEST_IND *) custom; ++ wpa_printf(MSG_DEBUG, "IsMoreEvent =%d, ProbeIELen =%d", wps_ie->IsMoreEvent, wps_ie->ProbeIELen); ++ hostapd_wps_probe_req_rx(hapd, wps_ie->MACAddr, wps_ie->ProbeIE, wps_ie->ProbeIELen); ++ break; ++ } ++ } ++ ++} ++ ++ ++static void ++realtek_wireless_event_wireless(struct hostapd_data *hapd,struct realtek_driver_data *drv, ++ u8 *data, int len) ++{ ++ struct iw_event iwe_buf, *iwe = &iwe_buf; ++ u8 *pos, *end, *custom, *buf; ++ u8 macaddr[ETH_ALEN] = {}; ++ ++ pos = data; ++ end = data + len; ++ ++ wpa_printf(MSG_DEBUG, "realtek_wireless_event_wireless +++"); ++ ++ 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); ++ ++#ifdef INBAND_CTRL //HOST_LITTLE_ENDIAN ++ iwe->len = ntohs(iwe->len); ++ iwe->cmd = ntohs(iwe->cmd); ++#endif ++ if (iwe->len <= IW_EV_LCP_LEN) ++ return; ++ ++ custom = pos + IW_EV_POINT_LEN; ++ if (drv->we_version > 18 && ++ (iwe->cmd == IWEVMICHAELMICFAILURE || ++ iwe->cmd == SIOCGIWESSID || ++ iwe->cmd == SIOCGIWENCODE || ++ iwe->cmd == IWEVGENIE || ++ iwe->cmd == IWEVASSOCREQIE || ++ iwe->cmd == IWEVASSOCRESPIE || ++ 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; ++#ifdef INBAND_CTRL //HOST_LITTLE_ENDIAN ++ iwe->len = ntohs(iwe->len); ++ iwe->cmd = ntohs(iwe->cmd); ++#endif ++ } ++ ++ switch (iwe->cmd) { ++ case IWEVEXPIRED: ++ wpa_printf(MSG_DEBUG, "case IWEVEXPIRED"); ++ realtek_del_sta(hapd,drv, (u8 *) iwe->u.addr.sa_data); ++ break; ++ case IWEVREGISTERED: ++ wpa_printf(MSG_DEBUG, "case IWEVREGISTERED"); ++ realtek_new_sta(hapd,drv, (u8 *) iwe->u.addr.sa_data); ++ break; ++ case IWEVCUSTOM: ++ case IWEVGENIE: ++ wpa_printf(MSG_DEBUG, "case IWEVCUSTOM|IWEVGENIE"); ++#ifdef INBAND_CTRL //HOST_LITTLE_ENDIAN ++ iwe->u.data.length = ntohs(iwe->u.data.length); ++ iwe->u.data.flags = ntohs(iwe->u.data.flags); ++#endif ++ 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'; ++ realtek_wireless_event_wireless_custom(hapd,drv, iwe->u.data.flags, buf, iwe->u.data.length); ++ free(buf); ++ break; ++ } ++ pos += iwe->len; ++ } ++} ++ ++ ++static void ++realtek_wireless_event_rtm_newlink(struct realtek_driver_data *drv, ++ struct nlmsghdr *h, int len) ++{ ++ struct ifinfomsg *ifi; ++ int attrlen, nlmsg_len, rta_len; ++ struct rtattr * attr; ++ struct hostapd_data *hapd = drv->hapd; ++ ++ wpa_printf(MSG_DEBUG, "realtek_wireless_event_rtm_newlink +++"); ++ ++ if (len < (int) sizeof(*ifi)) ++ return; ++ ++ ifi = NLMSG_DATA(h); ++#ifdef INBAND_CTRL //HOST_LITTLE_ENDIAN ++ ifi->ifi_index = ntohl(ifi->ifi_index); ++#endif ++#ifdef RTK_MBSSID ++ if(!have_ifidx(drv, ifi->ifi_index)) ++ return; ++ hapd = find_hapd_by_ifindex(drv,ifi->ifi_index); ++#else ++ if (ifi->ifi_index != drv->ifindex) ++ return; ++#endif ++ nlmsg_len = NLMSG_ALIGN(sizeof(struct ifinfomsg)); ++ ++ attrlen = h->nlmsg_len - nlmsg_len; ++ if (attrlen < 0) ++ return; ++ ++ attr = (struct rtattr *) (((char *) ifi) + nlmsg_len); ++ ++#ifdef INBAND_CTRL //HOST_LITTLE_ENDIAN ++ attr->rta_len = ntohs(attr->rta_len); ++ attr->rta_type = ntohs(attr->rta_type); ++#endif ++ rta_len = RTA_ALIGN(sizeof(struct rtattr)); ++ while (RTA_OK(attr, attrlen)) { ++ if (attr->rta_type == IFLA_WIRELESS) { ++ realtek_wireless_event_wireless(hapd, ++ drv, ((u8 *) attr) + rta_len, ++ attr->rta_len - rta_len); ++ } ++ attr = RTA_NEXT(attr, attrlen); ++#ifdef INBAND_CTRL //HOST_LITTLE_ENDIAN ++ attr->rta_len = ntohs(attr->rta_len); ++ attr->rta_type = ntohs(attr->rta_type); ++#endif ++ } ++} ++ ++ ++static void ++realtek_wireless_event_receive(int sock, void *eloop_ctx, void *sock_ctx) ++{ ++ //char buf[256]; ++ char buf[1024], cmd_type=0x01; //increse size for IWEVGENIE event ++ int left; ++ struct sockaddr_nl from; ++ socklen_t fromlen; ++ struct nlmsghdr *h; ++ struct realtek_driver_data *drv = eloop_ctx; ++#ifdef INBAND_CTRL ++ left = ioh_recv(&drv->netlink_ioh_obj, 3000); ++ if (left < 0) { ++ perror("recvfrom(rawsock)"); ++ return; ++ } ++ INBAND_IOCTLPKT_DUMP(drv->netlink_ioh_obj.rx_data,left); ++ left -= IOH_HDR_LEN; ++ ++ h = (struct nlmsghdr *)drv->netlink_ioh_obj.rx_data ; ++#else ++ 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; ++#endif ++ while (left >= (int) sizeof(*h)) { ++ int len, plen; ++#ifdef INBAND_CTRL //HOST_LITTLE_ENDIAN //mark_x86 ++ h->nlmsg_len = ntohl(h->nlmsg_len); ++ h->nlmsg_type = ntohs(h->nlmsg_type); ++ h->nlmsg_flags = ntohs(h->nlmsg_flags); ++ h->nlmsg_seq = ntohl(h->nlmsg_seq); ++ h->nlmsg_pid = ntohl(h->nlmsg_pid); ++#endif ++ 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: ++ realtek_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 ++realtek_get_we_version(struct realtek_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 = os_zalloc(buflen); ++ if (range == NULL) ++ return -1; ++ ++ 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); ++#ifdef STAND_ALONE ++ 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; ++ } ++#endif ++#if defined(INBAND_CTRL) ++ INBAND_IOCTLPKT_DUMP(&iwr,sizeof(iwr)); ++ if (inband_ioctl(SIOCGIWRANGE, &iwr) < 0) { ++ perror("inband_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; ++ } ++#endif ++ ++ ++ free(range); ++ return 0; ++} ++ ++ ++static int ++realtek_wireless_event_init(void *priv) ++{ ++ struct realtek_driver_data *drv = priv; ++ int s; ++ struct sockaddr_nl local; ++ ++ realtek_get_we_version(drv); ++ ++ drv->wext_sock = -1; ++#ifdef INBAND_CTRL ++ s = ioh_open(&drv->netlink_ioh_obj,INBAND_INTF,INBAND_SLAVE,INBAND_NETLINK_TYPE,INBAND_DEBUG); ++ if (s < 0) { ++ perror("socket(PF_PACKET,SOCK_RAW,INBAND_NETLINK_TYPE)"); ++ return -1; ++ } ++#else ++ 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; ++ } ++#endif ++ ++#ifdef INBAND_CTRL ++ eloop_register_read_sock(drv->netlink_ioh_obj.sockfd, realtek_wireless_event_receive, drv, NULL); ++#else ++ eloop_register_read_sock(s, realtek_wireless_event_receive, drv, NULL); ++#endif ++#ifdef INBAND_CTRL ++ drv->wext_sock = drv->netlink_ioh_obj.sockfd; ++#else ++ drv->wext_sock = 0; ++#endif ++ ++ return 0; ++} ++ ++ ++static void ++realtek_wireless_event_deinit(void *priv) ++{ ++ struct realtek_driver_data *drv = priv; ++ ++ wpa_printf(MSG_DEBUG, "realtek_wireless_event_deinit +++"); ++ ++ if (drv != NULL) { ++ if (drv->wext_sock < 0) ++ return; ++ eloop_unregister_read_sock(drv->wext_sock); ++ close(drv->wext_sock); ++ } ++} ++ ++ ++static int ++realtek_send_eapol(void *priv, const u8 *addr, const u8 *data, size_t data_len, ++ int encrypt, const u8 *own_addr) ++{ ++ struct realtek_driver_data *drv = priv; ++ unsigned char buf[3000]; ++ unsigned char *bp = buf; ++ struct l2_ethhdr *eth; ++ size_t len; ++ int status; ++ struct l2_packet_data *eapol_sock=drv->sock_xmit; ++#ifdef RTK_MBSSID ++#ifndef INBAND_CTRL ++ struct hostapd_data *hapd = drv->hapd; ++ ++ hapd = (struct hostapd_data *)find_hapd_by_sta(priv,addr); ++ eapol_sock = (struct l2_packet_data *)rtk_find_l2sock_by_ifname(priv,hapd->conf->iface); ++#endif ++#endif ++ wpa_printf(MSG_DEBUG, "realtek_send_eapol +++"); ++ ++ /* ++ * Prepend the Ethernet 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); ++ ++ //mark wpa_hexdump because both ralink & broadcom NOT call this function ++ //wpa_hexdump(MSG_MSGDUMP, "TX EAPOL", bp, len); ++ ++ status = l2_packet_send(eapol_sock, 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 realtek_driver_data *drv = ctx; ++ struct hostapd_data *hapd = drv->hapd; ++ struct sta_info *sta; ++ ++ //printf("handle_read +++"); ++#ifndef RTK_MBSSID ++ 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)); ++#else ++ return; // do nothing here , all handle in handle_eapol ++#endif ++} ++ ++#ifdef INBAND_CTRL ++static int rtk_l2_packet_get_own_addr(struct realtek_driver_data *drv, u8 *addr) ++{ ++ unsigned char cmd[100]; ++ struct ifreq ifr; ++ ++ os_memset(&ifr, 0, sizeof(ifr)); ++ os_strlcpy(ifr.ifr_name, INBAND_INTF, sizeof(INBAND_INTF)); ++ ++ if(ioctl(drv->ioctl_sock,SIOCGIFHWADDR, &ifr ) < 0){ ++ return -1; ++ } ++ ++ sprintf(cmd,"echo %d:%d:%d:%d:%d:%d > /proc/br_hostmac",ifr.ifr_hwaddr.sa_data[0], ++ ifr.ifr_hwaddr.sa_data[1],ifr.ifr_hwaddr.sa_data[2],ifr.ifr_hwaddr.sa_data[3], ++ ifr.ifr_hwaddr.sa_data[4],ifr.ifr_hwaddr.sa_data[5]); ++ ++ if (inband_remote_cmd(cmd) < 0) ++ return -1; ++ ++ os_strlcpy(ifr.ifr_name, drv->iface, sizeof(ifr.ifr_name)); ++ if (inband_ioctl(SIOCGIFHWADDR,&ifr) < 0) ++ return -1; ++ else ++ os_memcpy(addr, ifr.ifr_hwaddr.sa_data, ETH_ALEN); ++ return 0; ++} ++#endif ++ ++#ifdef RTK_MBSSID ++static int realtek_bss_add(void *priv, const char *ifname, const u8 *bssid) ++{ ++ struct realtek_driver_data *drv = priv; ++ struct i802_bss *new_bss = NULL; ++ struct ifreq ifr; ++ struct rtk_hapd_config config; ++ struct hostapd_data *hapd = drv->hapd; ++ ++ //printf("realtek_bss_add : ifname = %s\n",ifname); ++ ++ new_bss = os_zalloc(sizeof(*new_bss)); ++ if (new_bss == NULL) ++ return -1; ++ ++ ++ memset(&ifr, 0, sizeof(ifr)); ++ snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", ifname); ++#ifdef STAND_ALONE ++ if (ioctl(drv->ioctl_sock, SIOCGIFINDEX, &ifr) != 0) { ++ perror("ioctl(SIOCGIFINDEX)"); ++ goto bad; ++ } ++#endif ++#if defined(INBAND_CTRL) ++ INBAND_IOCTLPKT_DUMP(&ifr,sizeof(ifr)); ++ if (inband_ioctl(SIOCGIFINDEX, &ifr) < 0) { ++ perror("inband_ioctl(SIOCGIFINDEX)"); ++ goto bad; ++ } ++#endif ++ os_strlcpy(new_bss->ifname, ifname, IFNAMSIZ); ++ ++#ifdef INBAND_CTRL ++ new_bss->sock_xmit = drv->sock_xmit; ++#else ++ new_bss->sock_xmit = l2_packet_init(new_bss->ifname, NULL, ETH_P_EAPOL, handle_read, drv, 1); ++#endif ++ if (new_bss->sock_xmit == NULL) ++ goto bad; ++ ++ //do we nee to set HW addr to VAP?? ++ realtek_set_iface_flags(new_bss->ifname,drv, 0); //down the interface ...... , bring up in realtek_commit!! ++ ++ if (bssid[0] | bssid[1] | bssid[2] | bssid[3] | bssid[4] | bssid[5]) ++ realtek_set_iface_hwMac(new_bss->ifname,drv, bssid); ++ else ++ printf("Warning !!! VAP no HW addr setting \n"); ++ ++ //memset(&config, 0, sizeof(struct rtk_hapd_config)); ++ os_memcpy(&config, &rtk_config, sizeof(struct rtk_hapd_config)); //get some val from root ++ hapd =(struct hostapd_data *) find_hapd_by_ifname(priv,ifname); ++ ++ realtek_set_privacy(ifname, drv, 0); /* default to no privacy */ ++ ++ if(realtek_read_hapd_cfg(hapd,priv, &config)) ++ goto bad; ++ ++ //if(realtek_read_priv_cfg(priv, &config)) //already read in init ++ // goto bad; ++ if(realtek_read_priv_vap_cfg(ifname,priv, &config)) //already read in init ++ goto bad; ++ ++ ++#ifdef INBAND_CTRL //HOST_LITTLE_ENDIAN ++ // rtk_hapd_config need to swap , write a function to do it ++ rtk_cfg_to_bigEndian(&config); ++#endif ++ ++ if(set80211priv(ifname,drv, HAPD_IOCTL_SETCONFIG, &config, sizeof(config))) ++ { ++ wpa_printf(MSG_ERROR, "%s: Failed to set Configurations", __func__); ++ goto bad; ++ } ++ ++ /*if(realtek_read_wds_cfg(priv, &wds)) //mark_mbssid , wds for vap ?? ++ return -1;*/ ++ ++ if((hapd->conf->wpa == 0) && (hapd->conf->ieee802_1x == 0 )) ++ realtek_set_ieee8021x(ifname, drv, 0); ++ ++ new_bss->ifindex = ifr.ifr_ifindex; ++ new_bss->drv = drv; ++ new_bss->next = drv->first_bss.next; ++ drv->first_bss.next = new_bss; ++ add_ifidx(drv, new_bss->ifindex); ++ ++ return 0; ++ ++bad : ++ os_free(new_bss); ++ return -1; ++} ++ ++static int realtek_bss_remove(void *priv, const char *ifname) ++{ ++ ++ //printf("realtek_bss_remove : ifname = %s\n",ifname); ++ ++ rtk_free_bss_by_ifname(priv,ifname); ++ ++ realtek_set_iface_flags(ifname,priv, 0); //down VAP ++ ++ return 0; ++} ++ ++static void * ++realtek_driver_init(struct hostapd_data *hapd) ++{ ++ struct realtek_driver_data *drv; ++ struct ifreq ifr; ++ struct iwreq iwr; ++ struct i802_bss *bss; ++ ++ wpa_printf(MSG_DEBUG, "realtek_init +++"); ++ ++ drv = os_zalloc(sizeof(struct realtek_driver_data)); ++ if (drv == NULL) { ++ printf("Could not allocate memory for realtek driver data\n"); ++ goto bad; ++ } ++ ++ drv->hapd = hapd; ++ bss = &drv->first_bss; ++ bss->drv = drv; ++ os_strlcpy(bss->ifname, hapd->conf->iface, sizeof(bss->ifname)); ++ ++ 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); ++#ifdef STAND_ALONE ++ if (ioctl(drv->ioctl_sock, SIOCGIFINDEX, &ifr) != 0) { ++ perror("ioctl(SIOCGIFINDEX)"); ++ goto bad; ++ } ++#endif ++#if defined(INBAND_CTRL) ++ INBAND_IOCTLPKT_DUMP(&ifr,sizeof(ifr)); ++ if (inband_ioctl(SIOCGIFINDEX, &ifr) < 0) { ++ perror("inband_ioctl(SIOCGIFINDEX)"); ++ goto bad; ++ } ++#endif ++ drv->ifindex = ifr.ifr_ifindex; ++ bss->ifindex = drv->ifindex; ++#ifdef INBAND_CTRL ++ drv->sock_xmit = l2_packet_init(INBAND_INTF, NULL, ETH_P_EAPOL, handle_read, drv, 1); ++#else ++ drv->sock_xmit = l2_packet_init(drv->iface, NULL, ETH_P_EAPOL, handle_read, drv, 1); ++#endif ++ if (drv->sock_xmit == NULL) ++ goto bad; ++#ifdef INBAND_CTRL ++ if( rtk_l2_packet_get_own_addr(drv,hapd->own_addr) ) ++#else ++ if (l2_packet_get_own_addr(drv->sock_xmit, hapd->own_addr)) ++#endif ++ goto bad; ++ ++ //mark_mbssid , now recv all EAPOL from one socket ++ drv->sock_recv = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_EAPOL)); ++ if (drv->sock_recv < 0) { ++ perror("socket(PF_PACKET, SOCK_DGRAM, ETH_P_EAPOL)"); ++ goto bad; ++ } ++ if (eloop_register_read_sock(drv->sock_recv, handle_eapol, drv, NULL)) ++ { ++ printf("Could not register read socket for eapol\n"); ++ goto bad; ++ } ++ ++ memset(&iwr, 0, sizeof(iwr)); ++ strncpy(iwr.ifr_name, drv->iface, IFNAMSIZ); ++ ++ realtek_set_iface_flags(drv->iface,drv, 0); /* mark down during setup */ ++ realtek_set_privacy(drv->iface, drv, 0); /* default to no privacy */ ++ ++ if(realtek_hapd_config(drv)) ++ goto bad; ++ ++ if((hapd->conf->wpa == 0) && (hapd->conf->ieee802_1x == 0 )) ++ realtek_set_ieee8021x(drv->iface, drv, 0); ++ ++ wpa_printf(MSG_DEBUG, "realtek_init ---"); ++ return bss; ++bad: ++ wpa_printf(MSG_ERROR, "realtek_init failed!"); ++ ++ if (drv != NULL) ++ realtek_deinit(drv); ++ ++ return NULL; ++} ++ ++static void * ++realtek_init(struct hostapd_data *hapd) ++{ ++ struct realtek_driver_data *drv; ++ struct i802_bss *bss; ++ int i; ++ ++ bss = realtek_driver_init(hapd); ++ ++ if (bss == NULL) ++ return NULL; ++ ++ drv = bss->drv; ++ ++ drv->num_if_indices = RTK_MAX_IF_INDEX; ++ for(i=0;i<drv->num_if_indices;i++) ++ drv->if_indices[i]=0; ++ ++ add_ifidx(drv, drv->ifindex); ++ ++ //below maybe add bridge control in the future ++ //return bss; ++ return drv; ++ ++} ++ ++#else //mark_mbssid , remove below in future ++ ++static void * ++realtek_init(struct hostapd_data *hapd) ++{ ++ struct realtek_driver_data *drv; ++ struct ifreq ifr; ++ struct iwreq iwr; ++ ++ wpa_printf(MSG_DEBUG, "realtek_init +++"); ++ ++ drv = os_zalloc(sizeof(struct realtek_driver_data)); ++ if (drv == NULL) { ++ printf("Could not allocate memory for realtek driver data\n"); ++ goto bad; ++ } ++ ++ 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); ++#ifdef STAND_ALONE ++ if (ioctl(drv->ioctl_sock, SIOCGIFINDEX, &ifr) != 0) { ++ perror("ioctl(SIOCGIFINDEX)"); ++ goto bad; ++ } ++#endif ++#if defined(INBAND_CTRL) ++ INBAND_IOCTLPKT_DUMP(&ifr,sizeof(ifr)); ++ if (inband_ioctl(SIOCGIFINDEX, &ifr) < 0) { ++ perror("inband_ioctl(SIOCGIFINDEX)"); ++ goto bad; ++ } ++#endif ++ drv->ifindex = ifr.ifr_ifindex; ++#ifdef INBAND_CTRL ++ drv->sock_xmit = l2_packet_init(INBAND_INTF, NULL, ETH_P_EAPOL, handle_read, drv, 1); ++#else ++ drv->sock_xmit = l2_packet_init(drv->iface, NULL, ETH_P_EAPOL, handle_read, drv, 1); ++#endif ++ if (drv->sock_xmit == NULL) ++ goto bad; ++#ifdef INBAND_CTRL ++ if( rtk_l2_packet_get_own_addr(drv,hapd->own_addr) ) ++#else ++ if (l2_packet_get_own_addr(drv->sock_xmit, hapd->own_addr)) ++#endif ++ goto bad; ++ if (hapd->conf->bridge[0] != '\0') { ++ drv->sock_recv = l2_packet_init(hapd->conf->bridge, NULL, ++ ETH_P_EAPOL, handle_read, drv, ++ 1); //fix receive sock?? ++ 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); ++ ++ realtek_set_iface_flags(drv->iface,drv, 0); /* mark down during setup */ ++ realtek_set_privacy(drv->iface, drv, 0); /* default to no privacy */ ++ ++ if(realtek_hapd_config(drv)) ++ goto bad; ++ ++ if((hapd->conf->wpa == 0) && (hapd->conf->ieee802_1x == 0 )) ++ realtek_set_ieee8021x(drv->iface, drv, 0); ++ ++ wpa_printf(MSG_DEBUG, "realtek_init ---"); ++ return drv; ++bad: ++ wpa_printf(MSG_ERROR, "realtek_init failed!"); ++ ++ if (drv != NULL) ++ realtek_deinit(drv); ++ ++ return -1; ++} ++#endif ++ ++static void ++realtek_deinit(void *priv) ++{ ++ struct realtek_driver_data *drv = priv; ++ ++ wpa_printf(MSG_DEBUG, "realtek_deinit +++"); ++ ++ drv->hapd->driver = NULL; ++ ++ realtek_set_iface_flags(drv->iface,drv, 0); ++ #if 0 /* OLD */ ++ if (drv->probe_recv != NULL) ++ l2_packet_deinit(drv->probe_recv); ++ #endif ++ if (drv->ioctl_sock >= 0) ++ close(drv->ioctl_sock); ++#ifdef RTK_MBSSID ++ if (drv->sock_recv >= 0) { ++ eloop_unregister_read_sock(drv->sock_recv); ++ close(drv->sock_recv); ++ } ++#else ++ if (drv->sock_recv != NULL && drv->sock_recv != drv->sock_xmit) ++ l2_packet_deinit(drv->sock_recv); ++#endif ++ if (drv->sock_xmit != NULL) ++ l2_packet_deinit(drv->sock_xmit); ++ free(drv); ++ ++ wpa_printf(MSG_DEBUG, "realtek_deinit ---"); ++} ++ ++static int ++realtek_set_ssid(const char *ifname, void *priv, const u8 *buf, int len) ++{ ++ struct realtek_driver_data *drv = priv; ++ struct iwreq iwr; ++ ++ wpa_printf(MSG_DEBUG, "realtek_set_ssid +++"); ++ ++ memset(&iwr, 0, sizeof(iwr)); ++ strncpy(iwr.ifr_name, ifname, IFNAMSIZ); ++ iwr.u.essid.flags = 1; /* SSID active */ ++ iwr.u.essid.pointer = (caddr_t) buf; ++ iwr.u.essid.length = len + 1; ++#ifdef STAND_ALONE ++ if (ioctl(drv->ioctl_sock, SIOCSIWESSID, &iwr) < 0) { ++ perror("ioctl[SIOCSIWESSID]"); ++ printf("len=%d\n", len); ++ return -1; ++ } ++#endif ++#if defined(INBAND_CTRL) ++ INBAND_IOCTLPKT_DUMP(&iwr,sizeof(iwr)); ++ if (inband_ioctl(SIOCSIWESSID, &iwr) < 0) { ++ perror("inband_ioctl[SIOCSIWESSID]"); ++ printf("len=%d\n", len); ++ return -1; ++ } ++#endif ++ return 0; ++} ++ ++static int ++realtek_get_ssid(const char *ifname, void *priv, u8 *buf, int len) ++{ ++ struct realtek_driver_data *drv = priv; ++ struct iwreq iwr; ++ int ret = 0; ++ ++ wpa_printf(MSG_DEBUG, "realtek_get_ssid +++"); ++ ++ memset(&iwr, 0, sizeof(iwr)); ++ strncpy(iwr.ifr_name, ifname, IFNAMSIZ); ++ iwr.u.essid.pointer = (caddr_t) buf; ++ iwr.u.essid.length = len; ++#ifdef STAND_ALONE ++ if (ioctl(drv->ioctl_sock, SIOCGIWESSID, &iwr) < 0) { ++ perror("ioctl[SIOCGIWESSID]"); ++ ret = -1; ++ } else ++ ret = iwr.u.essid.length; ++#endif ++#if defined(INBAND_CTRL) ++ INBAND_IOCTLPKT_DUMP(&iwr,sizeof(iwr)); ++ if (inband_ioctl(SIOCGIWESSID, &iwr) < 0) { ++ perror("ioctl[SIOCGIWESSID]"); ++ ret = -1; ++ } ++#endif ++ return ret; ++} ++ ++static int ++realtek_set_countermeasures(void *priv, int enabled) ++{ ++ struct realtek_driver_data *drv = priv; ++ wpa_printf(MSG_DEBUG, "realtek_set_countermeasures +++"); ++ wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled); ++ return set80211param(drv->iface,drv, IEEE80211_PARAM_COUNTERMEASURES, enabled); ++} ++ ++#ifdef INBAND_CTRL ++/* inband ioctl start */ ++inline void realtek_priviwr(struct iwreq *iwr, unsigned char *param, void *value) ++{ ++ unsigned char buf[1024] = {0}; ++ ++ sprintf(buf,"%s=%d",param,*(unsigned int *)value); ++ iwr->u.data.length = os_strlen(buf); ++ iwr->u.data.pointer = os_malloc(iwr->u.data.length+1); ++ if( iwr->u.data.pointer ) ++ os_memcpy(iwr->u.data.pointer,buf,iwr->u.data.length+1); ++ else ++ printf("Err: Alloc memory failed while %s\n",__FUNCTION__); ++} ++#endif ++ ++ ++static int ++realtek_commit(void *priv) ++{ ++ struct realtek_driver_data *drv = priv; ++#ifdef RTK_MBSSID ++ struct i802_bss *tbss = &drv->first_bss,*bss; ++ wpa_printf(MSG_DEBUG, "realtek_commit +++"); ++ ++ //up root interface here ++ if(realtek_set_iface_flags(drv->iface,priv, 1) < 0) ++ return -1; ++ //up other VAP ++ while (tbss) { ++ ++ bss = tbss->next; ++ if(bss == NULL) ++ break; ++ ++ if(realtek_set_iface_flags(bss->ifname,priv, 1)<0) ++ return -1; ++ tbss = tbss->next ; ++ } ++ return 0; ++#else ++ return realtek_set_iface_flags(drv->iface,priv, 1); ++#endif ++} ++ ++#ifdef EAP_WPS ++static int ++realtek_set_wps_ie(const char *ifname,void *priv, u8 *iebuf, int iebuflen, u32 frametype) ++{ ++ struct realtek_driver_data *drv = priv; ++ u8 buf[256]; ++ struct ieee80211req_getset_appiebuf * ie; ++ // int i; ++ ++ ie = (struct ieee80211req_getset_appiebuf *) buf; ++ ie->app_frmtype = frametype; ++ ie->app_buflen = iebuflen; ++ if (iebuflen > 0) ++ os_memcpy(&(ie->app_buf[0]), iebuf, iebuflen); ++ ++#ifdef INBAND_CTRL //HOST_LITTLE_ENDIAN ++ // int32 need to swap ++ ie->app_frmtype = htonl(ie->app_frmtype); ++ ie->app_buflen = htonl(ie->app_buflen); ++#endif ++ return set80211priv(ifname,priv, IEEE80211_IOCTL_SET_APPIEBUF, ie, ++ sizeof(struct ieee80211req_getset_appiebuf) + iebuflen); ++} ++ ++ ++static int ++realtek_set_wps_beacon_ie(const char *ifname, void *priv, const u8 *iebuf, size_t iebuflen) ++{ ++ wpa_printf(MSG_DEBUG, "realtek_set_wps_beacon_ie +++"); ++ return realtek_set_wps_ie(ifname,priv, iebuf, iebuflen, ++ IEEE80211_APPIE_FRAME_BEACON); ++} ++ ++ ++static int ++realtek_set_wps_probe_resp_ie(const char *ifname, void *priv, const u8 *iebuf, size_t iebuflen) ++{ ++ wpa_printf(MSG_DEBUG, "realtek_set_wps_probe_resp_ie +++"); ++ return realtek_set_wps_ie(ifname,priv, iebuf, iebuflen, ++ IEEE80211_APPIE_FRAME_PROBE_RESP); ++} ++ ++ ++static int ++realtek_set_wps_assoc_resp_ie(const char *ifname, void *priv, const u8 *iebuf, size_t iebuflen) ++{ ++ wpa_printf(MSG_DEBUG, "realtek_set_wps_assoc_resp_ie +++"); ++ return realtek_set_wps_ie(ifname,priv, iebuf, iebuflen, ++ IEEE80211_APPIE_FRAME_ASSOC_RESP); ++} ++ ++ ++/* Ask to receive copies of all probe requests received. ++ */ ++static int ++realtek_start_receive_prob_req(void *priv) ++{ ++#if 0 //this function is not used now!! ++ struct ieee80211req_set_filter filt; ++ ++ wpa_printf(MSG_DEBUG, "%s Enter\n", __FUNCTION__); ++ filt.app_filterype = IEEE80211_FILTER_TYPE_PROBE_REQ; ++#ifdef INBAND_CTRL //HOST_LITTLE_ENDIAN ++ // int32 need to swap ++ filt.app_filterype = htonl(filt.app_filterype); ++#endif ++ return set80211priv(priv, IEEE80211_IOCTL_FILTERFRAME, &filt, ++ sizeof(struct ieee80211req_set_filter)); ++#endif ++ return 0; ++} ++ ++#endif /* EAP_WPS */ ++ ++#ifdef RTK_HAPD ++//Turn ON|OFF driver for hostapd reload. ++//mark_mbssid , realtek_driver_on , it's only for WPS in root hapd reload ++static int realtek_driver_on(void *priv, int on) ++{ ++ struct realtek_driver_data *drv = priv; ++ struct hostapd_data *hapd = drv->hapd; ++ ++ wpa_printf(MSG_DEBUG, "realtek_driver_on = %d +++", on); ++ ++ if((hapd->conf->wpa == 0) && (hapd->conf->ieee802_1x ==0 ) && (on == 1)) ++ realtek_set_ieee8021x(drv->iface, drv, 0); ++ ++ return realtek_set_iface_flags(drv->iface,priv, on); ++} ++ ++static int realtek_config_rate(int *rate_list, unsigned int *rate_config) ++{ ++ // bit mask value. bit0-bit11 as 1,2,5.5,11,6,9,12,18,24,36,48,54 ++ int temp = 0; ++ ++ while(1) ++ { ++ int rate; ++ rate = rate_list[temp]; ++ if((rate == -1) || (rate == 0)) ++ break; ++ ++ if(rate == 10) ++ *rate_config |= BIT(0); ++ else if(rate == 20) ++ *rate_config |= BIT(1); ++ else if(rate == 55) ++ *rate_config |= BIT(2); ++ else if(rate == 110) ++ *rate_config |= BIT(3); ++ else if(rate == 60) ++ *rate_config |= BIT(4); ++ else if(rate == 90) ++ *rate_config |= BIT(5); ++ else if(rate == 120) ++ *rate_config |= BIT(6); ++ else if(rate == 180) ++ *rate_config |= BIT(7); ++ else if(rate == 240) ++ *rate_config |= BIT(8); ++ else if(rate == 360) ++ *rate_config |= BIT(9); ++ else if(rate == 480) ++ *rate_config |= BIT(10); ++ else if(rate == 540) ++ *rate_config |= BIT(11); ++ ++ temp++; ++ ++ if(temp > 12) ++ { ++ wpa_printf(MSG_ERROR, "Config Rates NUM > 12!!!"); ++ return -1; ++ } ++ ++ } ++ ++ return 0; ++ ++} ++ ++static int realtek_parse_pwrlevel(unsigned char* pwr_list, char *val) ++{ ++ int count; ++ char *pos, *end; ++ ++ pos = val; ++ count = 0; ++ while (*pos != '\0') { ++ if (*pos == ' ') ++ count++; ++ pos++; ++ } ++ ++ pos = val; ++ count = 0; ++ ++ while (*pos != '\0') { ++ end = os_strchr(pos, ' '); ++ if (end) ++ *end = '\0'; ++ ++ pwr_list[count] = atoi(pos); ++ ++ if (!end) ++ break; ++ ++ count ++; ++ if(count >=MAX_2G_CHANNEL_NUM) ++ break; ++ ++ pos = end + 1; ++ } ++ ++ return 0; ++} ++ ++ ++static int realtek_read_hapd_cfg(struct hostapd_data *hapd,void *priv, struct rtk_hapd_config* config) ++{ ++ struct realtek_driver_data *drv = priv; ++ struct hostapd_config *iconf = hapd->iconf; ++ struct hostapd_bss_config *conf = hapd->conf; ++ ++ int temp = 0; ++ ++ wpa_printf(MSG_DEBUG, "realtek_read_hapd_cfg +++"); ++ ++ config->band |= BIT(iconf->hw_mode); ++ if(iconf->ieee80211n) ++ config->band |= BIT(3); ++ ++ config->channel = iconf->channel; ++ ++ config->bcnint = iconf->beacon_int; ++ ++ config->dtimperiod = conf->dtim_period; ++ ++ //if(conf->max_num_sta > RTK_MAX_STA)//mark_mbssid ,issue how to sync conf and rtk real support ++ config->stanum = conf->max_num_sta; ++ ++ config->rtsthres = iconf->rts_threshold; ++ ++ config->fragthres = iconf->fragm_threshold; ++ ++ if(realtek_config_rate(iconf->supported_rates, &(config->oprates))) ++ return -1; ++ ++ if(realtek_config_rate(iconf->basic_rates, &(config->basicrates))) ++ return -1; ++ ++ config->preamble = iconf->preamble; ++ ++ config->aclmode = conf->macaddr_acl; ++ ++ if(config->aclmode == ACCEPT_UNLESS_DENIED) ++ { ++ int x = 0, y =0; ++ config->aclnum = conf->num_deny_mac; ++ ++ if(config->aclnum > 0) ++ { ++ for(x=0; x < config->aclnum; x++) ++ { ++ struct mac_acl_entry *deny_mac = &conf->deny_mac[x]; ++ for(y=0; y<MACADDRLEN; y++) ++ { ++ config->acladdr[x][y] = deny_mac->addr[y]; ++ } ++ wpa_printf(MSG_DEBUG, "DENY ACL# %d = %s", x, ether_sprintf(config->acladdr[x])); ++ } ++ } ++ } ++ else if(config->aclmode == DENY_UNLESS_ACCEPTED) ++ { ++ int x = 0, y = 0; ++ config->aclnum = conf->num_accept_mac; ++ ++ if(config->aclnum > 0) ++ { ++ for(x=0; x<config->aclnum; x++) ++ { ++ struct mac_acl_entry *accept_mac = &conf->accept_mac[x]; ++ for(y=0; y<MACADDRLEN; y++) ++ { ++ config->acladdr[x][y] = accept_mac->addr[y]; ++ } ++ wpa_printf(MSG_DEBUG, "ACCEPT ACL# %d = %s", x, ether_sprintf(config->acladdr[x])); ++ } ++ } ++ } ++ ++ config->hiddenAP = conf->ignore_broadcast_ssid; ++ ++ config->qos_enable = conf->wmm_enabled; ++ ++ config->expired_time = conf->ap_max_inactivity; ++ ++ config->block_relay = iconf->bridge_packets; ++ ++ if(iconf->ht_capab &= HT_CAP_INFO_SHORT_GI20MHZ) ++ config->shortGI20M = 1; ++ ++ if(iconf->ht_capab &= HT_CAP_INFO_SHORT_GI40MHZ) ++ config->shortGI40M = 1; ++ ++ wpa_printf(MSG_DEBUG, "realtek_read_hapd_cfg ---"); ++ ++ return 0; ++ ++} ++ ++static int realtek_read_priv_vap_cfg(const char *ifname,void *priv, struct rtk_hapd_config* config) ++{ ++ ++ struct realtek_driver_data *drv = priv; ++ FILE *f; ++ char buf[256], *pos; ++ int errors = 0; ++ int line = 0; ++ int in_bss_section=0; ++ ++ f = fopen(drv->hapd->iface->config_fname, "r"); ++ if (f == NULL) ++ { ++ wpa_printf(MSG_ERROR, "Could not open configuration file '%s' " ++ "for reading.", drv->hapd->iface->config_fname); ++ return -1; ++ } ++ ++ while (fgets(buf, sizeof(buf), f)) ++ { ++ line++; ++ if (buf[0] == '#') ++ continue; ++ pos = buf; ++ while (*pos != '\0') ++ { ++ if (*pos == '\n') ++ { ++ *pos = '\0'; ++ break; ++ } ++ pos++; ++ } ++ ++ if (buf[0] == '\0') ++ continue; ++ ++ pos = os_strchr(buf, '='); ++ if (pos == NULL) ++ { ++ wpa_printf(MSG_ERROR, "Line %d: invalid line '%s'", line, buf); ++ errors++; ++ continue; ++ } ++ *pos = '\0'; ++ pos++; ++ if (os_strcmp(buf, "bss") == 0) { ++ ++ if(in_bss_section) //already in section , then scan finished; ++ break; ++ if(os_strcmp(pos, ifname) == 0) ++ { ++ in_bss_section = 1; ++ } ++ continue; ++ } ++ //below is the rtk parameter for per VAP ++ if(in_bss_section){ ++ /*else if (os_strcmp(buf, "autorate") == 0) { //mark_issue ++ config->autorate = atoi(pos); ++ }*/ ++ if (os_strcmp(buf, "fixrate") == 0) { ++ unsigned int select=0; ++ select = atoi(pos); ++ if(select == 0) ++ { ++ config->autorate = 1; ++ config->fixrate = 0; ++ } ++ else ++ { ++ config->autorate = 0; ++ config->fixrate = (1 << (select-1)); ++ } ++ //mark_issue , need to validate the rate with hw_mode(G? , N?) ++ }else if (os_strcmp(buf, "guest_access") == 0) { ++ config->guest_access= atoi(pos); ++ } ++ } ++ } ++ ++ fclose(f); ++ ++ if (errors) ++ wpa_printf(MSG_ERROR, "%d errors found in configuration file " ++ "'%s'", errors, drv->hapd->iface->config_fname); ++ ++ return errors; ++ ++} ++ ++ ++static int realtek_read_priv_cfg(void *priv, struct rtk_hapd_config* config) ++{ ++ ++ struct realtek_driver_data *drv = priv; ++ FILE *f; ++ char buf[256], *pos; ++ int errors = 0; ++ int line = 0; ++ ++ wpa_printf(MSG_DEBUG, "realtek_read_priv_cfg +++"); ++ ++ f = fopen(drv->hapd->iface->config_fname, "r"); ++ if (f == NULL) ++ { ++ wpa_printf(MSG_ERROR, "Could not open configuration file '%s' " ++ "for reading.", drv->hapd->iface->config_fname); ++ return -1; ++ } ++ ++ while (fgets(buf, sizeof(buf), f)) ++ { ++ line++; ++ if (buf[0] == '#') ++ continue; ++ pos = buf; ++ while (*pos != '\0') ++ { ++ if (*pos == '\n') ++ { ++ *pos = '\0'; ++ break; ++ } ++ pos++; ++ } ++ ++ if (buf[0] == '\0') ++ continue; ++ ++ pos = os_strchr(buf, '='); ++ if (pos == NULL) ++ { ++ wpa_printf(MSG_ERROR, "Line %d: invalid line '%s'", line, buf); ++ errors++; ++ continue; ++ } ++ *pos = '\0'; ++ pos++; ++ if (os_strcmp(buf, "bss") == 0) { ++ break; //only read interface section ++ } ++ if (os_strcmp(buf, "pwrlevelCCK_A") == 0) { ++ realtek_parse_pwrlevel(config->pwrlevelCCK_A, pos); ++ } ++ else if (os_strcmp(buf, "pwrlevelCCK_B") == 0) { ++ realtek_parse_pwrlevel(config->pwrlevelCCK_B, pos); ++ } ++ else if (os_strcmp(buf, "pwrlevelHT40_1S_A") == 0) { ++ realtek_parse_pwrlevel(config->pwrlevelHT40_1S_A, pos); ++ } ++ else if (os_strcmp(buf, "pwrlevelHT40_1S_B") == 0) { ++ realtek_parse_pwrlevel(config->pwrlevelHT40_1S_B, pos); ++ } ++ else if (os_strcmp(buf, "pwrdiffHT40_2S") == 0) { ++ realtek_parse_pwrlevel(config->pwrdiffHT40_2S, pos); ++ } ++ else if (os_strcmp(buf, "pwrdiffHT20") == 0) { ++ realtek_parse_pwrlevel(config->pwrdiffHT20, pos); ++ } ++ else if (os_strcmp(buf, "pwrdiffOFDM") == 0) { ++ realtek_parse_pwrlevel(config->pwrdiffOFDM, pos); ++ } ++ else if (os_strcmp(buf, "phyBandSelect") == 0) { ++ config->phyBandSelect = atoi(pos); ++ } ++ else if (os_strcmp(buf, "macPhyMode") == 0) { ++ config->macPhyMode = atoi(pos); ++ } ++ else if (os_strcmp(buf, "ther") == 0) { ++ config->ther = atoi(pos); ++ } ++ else if (os_strcmp(buf, "swcrypto") == 0) { ++ config->swcrypto = atoi(pos); ++ } ++ else if (os_strcmp(buf, "regdomain") == 0) { ++ config->regdomain = atoi(pos); ++ } ++ /*else if (os_strcmp(buf, "autorate") == 0) { //mark_issue ++ config->autorate = atoi(pos); ++ }*/ ++ else if (os_strcmp(buf, "fixrate") == 0) { ++ unsigned int select=0; ++ select = atoi(pos); ++ if(select == 0) ++ { ++ config->autorate = 1; ++ config->fixrate = 0; ++ } ++ else ++ { ++ config->autorate = 0; ++ config->fixrate = (1 << (select-1)); ++ } ++ //mark_issue , need to validate the rate with hw_mode(G? , N?) ++ } ++ else if (os_strcmp(buf, "disable_protection") == 0) { ++ config->disable_protection = atoi(pos); ++ } ++ else if (os_strcmp(buf, "disable_olbc") == 0) { ++ config->disable_olbc = atoi(pos); ++ } ++ else if (os_strcmp(buf, "deny_legacy") == 0) { ++ config->deny_legacy = atoi(pos); ++ } ++ else if (os_strcmp(buf, "opmode") == 0) { ++ config->opmode = atoi(pos); ++ } ++ else if (os_strcmp(buf, "vap_enable") == 0) { ++ config->vap_enable = atoi(pos); ++ } ++ else if (os_strcmp(buf, "use40M") == 0) { ++ config->use40M = atoi(pos); ++ } ++ else if (os_strcmp(buf, "2ndchoffset") == 0) { ++ config->_2ndchoffset = atoi(pos); ++ } ++ else if (os_strcmp(buf, "ampdu") == 0) { ++ config->ampdu = atoi(pos); ++ } ++ else if (os_strcmp(buf, "coexist") == 0) { ++ config->coexist = atoi(pos); ++ } ++ else if (os_strcmp(buf, "rssi_dump") == 0) { ++ config->rssi_dump = atoi(pos); ++ } ++ else if (os_strcmp(buf, "mp_specific") == 0) { ++ config->mp_specific = atoi(pos); ++ } ++ else if (os_strcmp(buf, "use_ext_pa") == 0) { ++ config->use_ext_pa = atoi(pos); ++ } ++ else if (os_strcmp(buf, "guest_access") == 0) { ++ config->guest_access= atoi(pos); ++ } ++ ++ } ++ ++ fclose(f); ++ ++ if (errors) ++ wpa_printf(MSG_ERROR, "%d errors found in configuration file " ++ "'%s'", errors, drv->hapd->iface->config_fname); ++ ++ wpa_printf(MSG_DEBUG, "realtek_read_priv_cfg ---"); ++ ++ return errors; ++ ++} ++ ++ ++ ++static int realtek_read_wds_cfg(void *priv, struct rtk_wds_config* wds) ++{ ++ ++ struct realtek_driver_data *drv = priv; ++ FILE *f; ++ char buf[256], *pos; ++ int errors = 0; ++ int line = 0; ++ ++ wpa_printf(MSG_DEBUG, "realtek_read_wds_cfg +++"); ++ ++ f = fopen(drv->hapd->iface->config_fname, "r"); ++ if (f == NULL) ++ { ++ wpa_printf(MSG_ERROR, "Could not open configuration file '%s' " ++ "for reading.", drv->hapd->iface->config_fname); ++ return -1; ++ } ++ ++ while (fgets(buf, sizeof(buf), f)) ++ { ++ line++; ++ if (buf[0] == '#') ++ continue; ++ pos = buf; ++ while (*pos != '\0') ++ { ++ if (*pos == '\n') ++ { ++ *pos = '\0'; ++ break; ++ } ++ pos++; ++ } ++ ++ if (buf[0] == '\0') ++ continue; ++ ++ pos = os_strchr(buf, '='); ++ if (pos == NULL) ++ { ++ wpa_printf(MSG_ERROR, "Line %d: invalid line '%s'", line, buf); ++ errors++; ++ continue; ++ } ++ *pos = '\0'; ++ pos++; ++ ++ if (strcmp(buf, "wds_enable") == 0) { ++ wds->wdsEnabled = atoi(pos); ++ } ++ else if (strcmp(buf, "wds_num") == 0) { ++ wds->wdsNum = atoi(pos); ++ } ++ else if (strcmp(buf, "wds_mac1") == 0) { ++ if (hwaddr_aton(pos, wds->macAddr[0])) { ++ wpa_printf(MSG_ERROR, "Line %d: invalid MAC address '%s'\n", line, pos); ++ errors++; ++ } ++ } ++ else if (strcmp(buf, "wds_mac2") == 0) { ++ if (hwaddr_aton(pos, wds->macAddr[1])) { ++ wpa_printf(MSG_ERROR, "Line %d: invalid MAC address '%s'\n", line, pos); ++ errors++; ++ } ++ } ++ else if (strcmp(buf, "wds_mac3") == 0) { ++ if (hwaddr_aton(pos, wds->macAddr[2])) { ++ wpa_printf(MSG_ERROR, "Line %d: invalid MAC address '%s'\n", line, pos); ++ errors++; ++ } ++ } ++ else if (strcmp(buf, "wds_mac4") == 0) { ++ if (hwaddr_aton(pos, wds->macAddr[3])) { ++ wpa_printf(MSG_ERROR, "Line %d: invalid MAC address '%s'\n", line, pos); ++ errors++; ++ } ++ } ++ else if (strcmp(buf, "wds_ssid") == 0) { ++ int ssid_len = strlen(pos); ++ if (ssid_len > HOSTAPD_MAX_SSID_LEN || ssid_len < 1) { ++ wpa_printf(MSG_ERROR, "Line %d: invalid SSID '%s'\n", line, pos); ++ errors++; ++ } else { ++ memcpy(wds->ssid, pos, ssid_len); ++ wds->ssid[ssid_len] = '\0'; ++ } ++ } ++ else if (strcmp(buf, "wds_enc_type") == 0) { ++ wds->wdsPrivacy = atoi(pos); ++ } ++ else if (strcmp(buf, "wds_wepkey") == 0) { ++ int len = strlen(pos); ++ int tmp_error = 0; ++ ++ //free(wds->wdsWepKey); ++ wds->wdsWepKey = NULL; ++ wds->wdsWepKeyLen = 0; ++ ++ if (pos[0] == '"') { ++ if (len < 2 || pos[len - 1] != '"') ++ tmp_error++; ++ else{ ++ len -= 2; ++ if (len > 0) { ++ wds->wdsWepKey = malloc(len); ++ if (wds->wdsWepKey == NULL) ++ tmp_error++; ++ else ++ memcpy(wds->wdsWepKey, pos + 1, len); ++ } ++ } ++ } ++ else ++ { ++ if (len & 1) ++ tmp_error++; ++ ++ len /= 2; ++ if (len > 0) ++ { ++ wds->wdsWepKey = malloc(len); ++ if (wds->wdsWepKey == NULL) ++ tmp_error++; ++ ++ if (hexstr2bin(pos, wds->wdsWepKey, len) < 0) ++ tmp_error++; ++ } ++ } ++ ++ wds->wdsWepKeyLen = len; ++ ++ if(tmp_error) ++ { ++ wpa_printf(MSG_ERROR, "Line %d: invalid wds_wepkey '%s'\n", line, pos); ++ errors++; ++ } ++ } ++ else if (strcmp(buf, "wds_passphrase") == 0) { ++ int len = strlen(pos); ++ //free(wds->wdsPskPassPhrase); ++ wds->wdsPskPassPhrase = NULL; ++ if (len < 8 || len > 63) { ++ wpa_printf(MSG_ERROR, "Line %d: invalid WPA passphrase length" ++ " %d (expected 8..63)\n", line, len); ++ errors++; ++ } else { ++ if ((wds->wdsPskPassPhrase = strdup(pos)) == NULL) ++ errors++; ++ } ++ } ++ ++ } ++ ++ fclose(f); ++ ++ if (errors) ++ wpa_printf(MSG_ERROR, "%d errors found in configuration file " ++ "'%s'", errors, drv->hapd->iface->config_fname); ++ ++ wpa_printf(MSG_DEBUG, "realtek_read_wds_cfg ---"); ++ ++ return errors; ++ ++} ++ ++static int realtek_hapd_config(void *priv) ++{ ++ struct realtek_driver_data *drv = priv; ++ struct hostapd_data *hapd = drv->hapd; ++ struct rtk_hapd_config *config=&rtk_config; ++ struct rtk_wds_config wds; ++ ++ wpa_printf(MSG_DEBUG, "realtek_hapd_config +++"); ++ ++ memset(config, 0, sizeof(struct rtk_hapd_config)); ++ ++ config->is_hapd = 1; //RTK_WPAS ++ ++ if(realtek_read_hapd_cfg(hapd,priv, config)) ++ return -1; ++ ++ if(realtek_read_priv_cfg(priv, config)) ++ return -1; ++ ++#ifdef INBAND_CTRL //HOST_LITTLE_ENDIAN ++ // rtk_hapd_config need to swap , write a function to do it ++ rtk_cfg_to_bigEndian(config); ++#endif ++ ++ if(set80211priv(drv->iface,drv, HAPD_IOCTL_SETCONFIG, config, sizeof(struct rtk_hapd_config))) ++ { ++ wpa_printf(MSG_ERROR, "%s: Failed to set Configurations", __func__); ++ return -1; ++ } ++ ++ if(realtek_read_wds_cfg(priv, &wds)) //mark_mbssid , wds for vap ?? ++ return -1; ++ ++ /* ++ if(realtek_set_wds(priv, wds)) ++ return -1; ++ */ ++ ++ wpa_printf(MSG_DEBUG, "realtek_hapd_config ---"); ++ ++ return 0; ++ ++} ++ ++ ++#endif ++ ++ ++const struct wpa_driver_ops wpa_driver_realtek_ops = { ++ .name = "realtek", ++ .init = realtek_init, ++ .deinit = realtek_deinit, ++ .set_ieee8021x = realtek_set_ieee8021x, ++ .set_privacy = realtek_set_privacy, ++ .set_encryption = realtek_set_key, ++ .get_seqnum = realtek_get_seqnum, ++ .flush = realtek_flush, ++ .set_generic_elem = realtek_set_opt_ie, ++ .wireless_event_init = realtek_wireless_event_init, ++ .wireless_event_deinit = realtek_wireless_event_deinit, ++ .sta_set_flags = realtek_sta_set_flags, ++ //mark read_sta_data because both ralink & broadcom NOT support ++ //.read_sta_data = realtek_read_sta_driver_data, ++ .send_eapol = realtek_send_eapol, ++ .sta_disassoc = realtek_sta_disassoc, ++ .sta_deauth = realtek_sta_deauth, ++#ifdef RTK_MBSSID ++ .bss_add = realtek_bss_add, ++ .bss_remove = realtek_bss_remove, ++#endif ++#ifdef RTK_HAPD ++ .sta_remove = realtek_sta_remove, ++#endif ++ .set_ssid = realtek_set_ssid, ++ .get_ssid = realtek_get_ssid, ++ .set_countermeasures = realtek_set_countermeasures, ++ //mark sta_clear_stats because both ralink & broadcom NOT support ++ //.sta_clear_stats = realtek_sta_clear_stats, ++ .commit = realtek_commit, ++#ifdef EAP_WPS ++ .set_wps_beacon_ie = realtek_set_wps_beacon_ie, ++ .set_wps_probe_resp_ie = realtek_set_wps_probe_resp_ie, ++ //.set_wps_assoc_resp_ie = realtek_set_wps_assoc_resp_ie, ++#endif /* EAP_WPS */ ++#ifdef RTK_HAPD ++ .driver_on = realtek_driver_on, ++#endif ++}; ++ ++#ifdef MODIFIED_BY_SONY ++int wext_set_key(void *priv, int 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 realtek_driver_data *drv = priv; ++ struct hostapd_data *hapd = drv->hapd; ++ struct hostapd_bss_config *conf = hapd->conf; ++ struct iwreq iwr; ++ int ret = 0; ++ int ioctl_sock; ++ ++ wpa_printf(MSG_DEBUG,"%s: alg=%d key_idx=%d set_tx=%d seq_len=%lu " ++ "key_len=%lu", __FUNCTION__, alg, key_idx, set_tx, ++ (unsigned long) seq_len, (unsigned long) key_len); ++ ++ ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0); ++ if (ioctl_sock < 0) { ++ perror("socket(PF_INET,SOCK_DGRAM)"); ++ return -1; ++ } ++ ++ os_memset(&iwr, 0, sizeof(iwr)); ++ os_strncpy(iwr.ifr_name, drv->iface, IFNAMSIZ); ++ iwr.u.encoding.flags = key_idx + 1; ++ if (alg == WPA_ALG_NONE) ++ iwr.u.encoding.flags |= IW_ENCODE_DISABLED; ++ if (conf->auth_algs & HOSTAPD_AUTH_OPEN) ++ iwr.u.encoding.flags |= IW_ENCODE_OPEN; ++ if (conf->auth_algs & HOSTAPD_AUTH_SHARED_KEY) ++ iwr.u.encoding.flags |= IW_ENCODE_RESTRICTED; ++ iwr.u.encoding.pointer = (caddr_t) key; ++ iwr.u.encoding.length = key_len; ++#ifdef STAND_ALONE ++ if (ioctl(ioctl_sock, SIOCSIWENCODE, &iwr) < 0) { ++ perror("ioctl[SIOCSIWENCODE]"); ++ ret = -1; ++ } ++#endif ++#if defined(INBAND_CTRL) ++ INBAND_IOCTLPKT_DUMP(&iwr,sizeof(iwr)); ++ if (inband_ioctl(&drv->ioctl_ioh_obj,SIOCSIWENCODE, &iwr) < 0) { ++ perror("inband_ioctl[SIOCSIWENCODE]"); ++ ret = -1; ++ } ++#endif ++ ++ if (set_tx && alg != WPA_ALG_NONE) { ++ os_memset(&iwr, 0, sizeof(iwr)); ++ os_strncpy(iwr.ifr_name, drv->iface, IFNAMSIZ); ++ iwr.u.encoding.flags = key_idx + 1; ++ iwr.u.encoding.pointer = (caddr_t) key; ++ iwr.u.encoding.length = 0; ++#ifdef STAND_ALONE ++ if (ioctl(ioctl_sock, SIOCSIWENCODE, &iwr) < 0) { ++ perror("ioctl[SIOCSIWENCODE] (set_tx)"); ++ ret = -1; ++ } ++#endif ++#if defined(INBAND_CTRL) ++ INBAND_IOCTLPKT_DUMP(&iwr,sizeof(iwr)); ++ if (inband_ioctl(&drv->ioctl_ioh_obj,SIOCSIWENCODE, &iwr) < 0) { ++ perror("inband_ioctl[SIOCSIWENCODE] (set_tx)"); ++ ret = -1; ++ } ++#endif ++ ++ } ++ close(ioctl_sock); ++ return ret; ++} ++#endif /* MODIFIED_BY_SONY */ +Index: hostapd-rtk-0.6.10/hostapd/driver_realtek.h +=================================================================== +--- /dev/null ++++ hostapd-rtk-0.6.10/hostapd/driver_realtek.h +@@ -0,0 +1,147 @@ ++ ++#define MACADDRLEN 6 ++#define PROBEIELEN 260 ++ ++#define HAPD_IOCTL_GETWPAIE IEEE80211_IOCTL_GET_APPIEBUF ++#define HAPD_IOCTL_SETCONFIG SIOCIWLASTPRIV ++#define RTL8192CD_IOCTL_DEL_STA 0x89f7 ++#define SIOCGIWIND 0x89ff ++ ++#define HOSTAPD_WPA_VERSION_WPA BIT(0) ++#define HOSTAPD_WPA_VERSION_WPA2 BIT(1) ++ ++#define RTK_MBSSID 1 ++#define RTK_MAX_STA 32 ++#define RTK_MAX_IF_INDEX 16 ++ ++enum HAPD_EVENT{ ++ HAPD_EXIRED = 0, ++ HAPD_REGISTERED = 1, ++ HAPD_MIC_FAILURE = 2, ++ HAPD_TRAFFIC_STAT = 3, ++ HAPD_PUSH_BUTTON = 4, ++ HAPD_WPS_PROBEREQ = 5, ++ HAPD_WDS_SETWPA = 6 ++}; ++ ++enum WIFI_STATUS_CODE { ++ _STATS_SUCCESSFUL_ = 0, // Success. ++ _STATS_FAILURE_ = 1, // Failure. ++ _STATS_CAP_FAIL_ = 10, // Capability too wide, can't support ++ _STATS_NO_ASOC_ = 11, // Denial reassociate ++ _STATS_OTHER_ = 12, // Denial connect, not 802.11 standard. ++ _STATS_NO_SUPP_ALG_ = 13, // Authenticate algorithm not support . ++ _STATS_OUT_OF_AUTH_SEQ_ = 14, // Out of authenticate sequence number. ++ _STATS_CHALLENGE_FAIL_ = 15, // Denial authenticate, Response message fail. ++ _STATS_AUTH_TIMEOUT_ = 16, // Denial authenticate, timeout. ++ _STATS_UNABLE_HANDLE_STA_ = 17, // Denial authenticate, BS resoruce insufficient. ++ _STATS_RATE_FAIL_ = 18, // Denial authenticate, STA not support BSS request datarate. ++ _STATS_REQ_DECLINED_ = 37, ++/*#if defined(CONFIG_RTL_WAPI_SUPPORT)*/ ++ __STATS_INVALID_IE_ = 40, ++ __STATS_INVALID_AKMP_ = 43, ++ __STATS_CIPER_REJECT_ = 46, ++ __STATS_INVALID_USK_ = 47, ++ __STATS_INVALID_MSK_ = 48, ++ __STATS_INVALID_WAPI_VERSION_ = 49, ++ __STATS_INVALID_WAPI_CAPABILITY_ = 50, ++/*#endif*/ ++ ++#ifdef CONFIG_RTK_MESH // CATUTION: below undefine !! (Refer: Draft 1.06, Page 17, 7.3.1.9, Table 7-23, 2007/08/13 by popen) ++ _STATS_MESH_LINK_ESTABLISHED_ = 55, //The mesh peer link has been successfully ++ _STATS_MESH_LINK_CLOSED_ = 56, // The mesh peer link has been closed completely ++ _STATS_MESH_UNDEFINE1_ = 57, // No listed Key Holder Transport type is supported. ++ _STATS_MESH_UNDEFINE2_ = 58, // The Mesh Key Holder Security Handshake message was malformed. ++#endif ++}; ++ ++typedef enum{ ++ DOT11_EVENT_NO_EVENT = 1, ++ DOT11_EVENT_REQUEST = 2, ++ DOT11_EVENT_ASSOCIATION_IND = 3, ++ DOT11_EVENT_ASSOCIATION_RSP = 4, ++ DOT11_EVENT_AUTHENTICATION_IND = 5, ++ DOT11_EVENT_REAUTHENTICATION_IND = 6, ++ DOT11_EVENT_DEAUTHENTICATION_IND = 7, ++ DOT11_EVENT_DISASSOCIATION_IND = 8, ++ DOT11_EVENT_DISCONNECT_REQ = 9, ++ DOT11_EVENT_SET_802DOT11 = 10, ++ DOT11_EVENT_SET_KEY = 11, ++ DOT11_EVENT_SET_PORT = 12, ++ DOT11_EVENT_DELETE_KEY = 13, ++ DOT11_EVENT_SET_RSNIE = 14, ++ DOT11_EVENT_GKEY_TSC = 15, ++ DOT11_EVENT_MIC_FAILURE = 16, ++ DOT11_EVENT_ASSOCIATION_INFO = 17, ++ DOT11_EVENT_INIT_QUEUE = 18, ++ DOT11_EVENT_EAPOLSTART = 19, ++//2003-07-30 ------------ ++ DOT11_EVENT_ACC_SET_EXPIREDTIME = 31, ++ DOT11_EVENT_ACC_QUERY_STATS = 32, ++ DOT11_EVENT_ACC_QUERY_STATS_ALL = 33, ++//----------------------- ++ ++// --- 2003-08-04 --- ++ DOT11_EVENT_REASSOCIATION_IND = 34, ++ DOT11_EVENT_REASSOCIATION_RSP = 35, ++//----------------------- ++ DOT11_EVENT_STA_QUERY_BSSID = 36, ++ DOT11_EVENT_STA_QUERY_SSID = 37, ++ ++// jimmylin: pass EAP packet by event queue ++ DOT11_EVENT_EAP_PACKET = 41, ++ ++#ifdef RTL_WPA2 ++ DOT11_EVENT_EAPOLSTART_PREAUTH = 45, ++ DOT11_EVENT_EAP_PACKET_PREAUTH = 46, ++#endif ++ ++#ifdef RTL_WPA2_CLIENT ++ DOT11_EVENT_WPA2_MULTICAST_CIPHER = 47, ++#endif ++ ++ DOT11_EVENT_WPA_MULTICAST_CIPHER = 48, ++ ++#ifdef AUTO_CONFIG ++ DOT11_EVENT_AUTOCONF_ASSOCIATION_IND = 50, ++ DOT11_EVENT_AUTOCONF_ASSOCIATION_CONFIRM = 51, ++ DOT11_EVENT_AUTOCONF_PACKET = 52, ++ DOT11_EVENT_AUTOCONF_LINK_IND = 53, ++#endif ++ ++#ifdef WIFI_SIMPLE_CONFIG ++ DOT11_EVENT_WSC_SET_IE = 55, ++ DOT11_EVENT_WSC_PROBE_REQ_IND = 56, ++ DOT11_EVENT_WSC_PIN_IND = 57, ++ DOT11_EVENT_WSC_ASSOC_REQ_IE_IND = 58, ++#ifdef CONFIG_IWPRIV_INTF ++ DOT11_EVENT_WSC_START_IND = 70, ++ //EV_MODE, EV_STATUS, EV_MEHOD, EV_STEP, EV_OOB ++ DOT11_EVENT_WSC_MODE_IND = 71, ++ DOT11_EVENT_WSC_STATUS_IND = 72, ++ DOT11_EVENT_WSC_METHOD_IND = 73, ++ DOT11_EVENT_WSC_STEP_IND = 74, ++ DOT11_EVENT_WSC_OOB_IND = 75, ++#endif //ifdef CONFIG_IWPRIV_INTF ++#endif ++ ++ DOT11_EVENT_MAX = 59, ++} DOT11_EVENT; ++ ++ ++typedef struct _DOT11_PROBE_REQUEST_IND{ ++ unsigned char EventId; ++ unsigned char IsMoreEvent; ++ char MACAddr[MACADDRLEN]; ++ unsigned short ProbeIELen; ++ char ProbeIE[PROBEIELEN]; ++}DOT11_PROBE_REQUEST_IND; ++ ++ ++typedef struct _DOT11_ASSOCIATION_RSP{ ++ unsigned char EventId; ++ unsigned char IsMoreEvent; ++ char MACAddr[MACADDRLEN]; ++ unsigned char Status; ++}DOT11_ASSOCIATION_RSP; ++ +Index: hostapd-rtk-0.6.10/hostapd/README-REALTEK_WIFI +=================================================================== +--- /dev/null ++++ hostapd-rtk-0.6.10/hostapd/README-REALTEK_WIFI +@@ -0,0 +1,116 @@ ++================================================================================== ++Introduction ++ This document is the guideline for building/using/porting the Hostapd ++application to support Realtek's Wifi device. ++ ++================================================================================== ++ ++1.Build the hostapd daemon ++----------------------------- ++ If the Wifi device is connected to your platform using GMII/MII interface ++then the inband libary must be built and enabled in hostapd.control. Please follow ++the steps below to build the hostapd daemon.() ++ ++ a. Build the inband libary (#This step can be skipped,if you dont need inband-cotrol) ++ ++ - Enter the inband_dir directory.(default:../../inband_dir) ++ ++ - Modify the definition of CC and LD in /inband_lib/Makefile to fit your ++ toolchain setting. ++ ++ - type make and the inband.a libray will be built on your platform. ++ ++ b. Enable/Disable the inband-control support in Hostapd. ++ ++ - Enable the lines below in hostapd-0.6.10/hostapd/Makefile to enable the ++ inband-support.In the other hand,disable these lines to disable the inband-control. ++ ++ CFLAGS += -DINBAND_CTRL ++ CFLAGS += -I../../inband_lib ++ LIBS += ../../inband_lib/inband.a ++ ++ c. Make the Hostapd ++ ++ - enter the directory : hostapd-0.6.10/hostapd/ ++ ++ - Modify hostapd-0.6.10/hostapd/Makefile to include your openssl libary.Below ++ lines are the default setting in Realtek's WIFI-AP SDK. ++ ++ LIBS += -ldl ../../openssl-0.9.8b/libssl.a ../../openssl-0.9.8b/libcrypto.a ++ LIBS_p += ../../openssl-0.9.8b/libcrypto.a ++ LIBS_h += ../../openssl-0.9.8b/libcrypto.a ++ ++ - Modify the definition of CC and LD in hostapd-0.6.10/hostapd/Makefile to ++ fit your toolchain setting. ++ ++ - type 'make' under hostapd-0.6.10/hostapd ,then the hostapd daemon will be built. ++ ++NOTEs: ++ - Because of the ethernet type 0x8899 and 0x9000 is used for inband control ++ please do not use them in other applications. ++ ++ - The default local interface for inband control is "br0', you can change the definition ++ in drv_realtek.c(the line list below) to fit your MII interface setting. ++ ++ #define INBAND_INTF "br0" ++ ++ - The default MAC address for inband-control is "00:12:34:56:78:99", it ++ can be changed in drv_realtek.c. ++ ++================================================================================== ++ ++2.Realtek proprietary configuration options ++---------------------------- ++ ++ - Please refer to file hostapd.test_conf(under hostapd-0.6.10/hostapd/conf) ++ for detail descriptions about the new added realtek private configurations. All these ++ configurations are directly mapped to realtek WiFi mibs. ++ ++ - Other inherently hostapd configurations are same as before. ++ ++ - 'auth_algs' has new values for supporting Open Networking & WEP+802.1x ++ ## ======== Modify auth_algs support========== ++ ## bit 0 = Open System Authentication ++ ## bit 1 = Shared Key Authentication (requires WEP) ++ ## bit 0 + bit 1 = Auto WEP mode ++ ## bit 2 = WEP + 802.1x ++ ## bit 3 = Open Networking(no security) ++ ++ - These hostapd configuration files(under /hostapd-0.6.10/hostapd/conf) can be examples for testing ++ - hostapd.none_security :WPS configured, Open Networking. ++ - hostapd.wpa_psk :WPS configured, WPA-PSK CCMP. ++ - NOT Supported yet: ++ - Some IEEE 802.11 related configurations ++ - IEEE 802.11r configuration ++ - Passive scanning ++ - Multiple BSSID support ++ ++ ++================================================================================== ++ ++3.Porting notes ++----------------------------- ++ The Hostapd for Realtek WiFi device is based on hostapd 0.6.10 and patch the realtek's implementation. ++Some notes are listed below to help you to port this package to your platform(for example , ++you are using hostapd 0.6.9 on your platform not 0.6.10). ++ ++ - Driver_realtek.c & Driver_realtek.h under /hostapd-0.6.10/hostapd are the main added files ++ for supporting realtek WiFi device. ++ ++ - Other modifications about Hostapd-0.6.10 were labeled with compile tag 'RTK_HAPD'. ++ You can check these patches by searching the keyword 'RTK_HAPD'. ++ ++ - List of modified source files in hostapd v0.6.10: ++ - Config.c ++ - Driver.h ++ - Hostapd.c ++ - Hostapd.h ++ - Iapp.c ++ - Os_unix.c ++ - Wps.h ++ - Wps_hostapd.c ++ - Wps_registrar.c ++ - Wps_upnp_event.c ++ - Wps_upnp_web.c ++ ++================================================================================= |