From 062c1b86b3924993c19502ff5ef456ca291fb993 Mon Sep 17 00:00:00 2001 From: Igor Pecovnik Date: Sat, 16 Apr 2016 20:50:12 +0200 Subject: [PATCH] Added hostapd compilation from sources withing chroot, nano pi m1 --- config/boards/nanopim1.conf | 11 + config/hostapd/config/config_default | 316 ++++ config/hostapd/config/config_realtek | 209 +++ config/hostapd/files/driver_rtl.h | 114 ++ config/hostapd/files/driver_rtw.c | 1993 +++++++++++++++++++++ config/{ => hostapd}/hostapd.conf | 0 config/{ => hostapd}/hostapd.realtek.conf | 0 config/hostapd/patch/300-noscan.patch | 54 + config/hostapd/patch/realtek.patch | 651 +++++++ configuration.sh | 18 +- distributions.sh | 4 +- extras/hostapd.sh | 131 ++ makeboarddeb.sh | 6 +- 13 files changed, 3498 insertions(+), 9 deletions(-) create mode 100644 config/boards/nanopim1.conf create mode 100644 config/hostapd/config/config_default create mode 100644 config/hostapd/config/config_realtek create mode 100644 config/hostapd/files/driver_rtl.h create mode 100644 config/hostapd/files/driver_rtw.c rename config/{ => hostapd}/hostapd.conf (100%) rename config/{ => hostapd}/hostapd.realtek.conf (100%) create mode 100644 config/hostapd/patch/300-noscan.patch create mode 100644 config/hostapd/patch/realtek.patch create mode 100644 extras/hostapd.sh diff --git a/config/boards/nanopim1.conf b/config/boards/nanopim1.conf new file mode 100644 index 000000000..655ec9969 --- /dev/null +++ b/config/boards/nanopim1.conf @@ -0,0 +1,11 @@ +# H3 quad core 1Gb SoC Wifi +KERNEL_TARGET="default,next,dev" +LINUXFAMILY=sun8i +BOOTCONFIG=FriendlyARM_NanoPi_M1_defconfig +MODULES="#gpio_sunxi #w1-sunxi #w1-gpio #w1-therm #ap6211" +MODULES_NEXT="brcmfmac" +CPUMIN="240000" +CPUMAX="1200000" +GOVERNOR=interactive +CLI_TARGET="%,%" +DESKTOP_TARGET="jessie,default" diff --git a/config/hostapd/config/config_default b/config/hostapd/config/config_default new file mode 100644 index 000000000..beb82d4e8 --- /dev/null +++ b/config/hostapd/config/config_default @@ -0,0 +1,316 @@ +# Example hostapd build time configuration +# +# This file lists the configuration options that are used when building the +# hostapd binary. All lines starting with # are ignored. Configuration option +# lines must be commented out complete, if they are not to be included, i.e., +# just setting VARIABLE=n is not disabling that variable. +# +# This file is included in Makefile, so variables like CFLAGS and LIBS can also +# be modified from here. In most cass, these lines should use += in order not +# to override previous values of the variables. + +# Driver interface for Host AP driver +CONFIG_DRIVER_HOSTAP=y + +# Driver interface for wired authenticator +#CONFIG_DRIVER_WIRED=y + +# Driver interface for drivers using the nl80211 kernel interface +CONFIG_DRIVER_NL80211=y + +# driver_nl80211.c requires libnl. If you are compiling it yourself +# you may need to point hostapd to your version of libnl. +# +CFLAGS += -I$/usr/include/libnl3/ +LIBS += -L$/usr/include/libnl3/ + +# Use libnl v2.0 (or 3.0) libraries. +CONFIG_LIBNL20=y + +# Use libnl 3.2 libraries (if this is selected, CONFIG_LIBNL20 is ignored) +CONFIG_LIBNL32=y + + +# Driver interface for FreeBSD net80211 layer (e.g., Atheros driver) +#CONFIG_DRIVER_BSD=y +#CFLAGS += -I/usr/local/include +#LIBS += -L/usr/local/lib +#LIBS_p += -L/usr/local/lib +#LIBS_c += -L/usr/local/lib + +# Driver interface for no driver (e.g., RADIUS server only) +#CONFIG_DRIVER_NONE=y + +# IEEE 802.11F/IAPP +CONFIG_IAPP=y + +# WPA2/IEEE 802.11i RSN pre-authentication +CONFIG_RSN_PREAUTH=y + +# PeerKey handshake for Station to Station Link (IEEE 802.11e DLS) +CONFIG_PEERKEY=y + +# IEEE 802.11w (management frame protection) +CONFIG_IEEE80211W=y + +# Integrated EAP server +CONFIG_EAP=y + +# EAP Re-authentication Protocol (ERP) in integrated EAP server +CONFIG_ERP=y + +# EAP-MD5 for the integrated EAP server +CONFIG_EAP_MD5=y + +# EAP-TLS for the integrated EAP server +CONFIG_EAP_TLS=y + +# EAP-MSCHAPv2 for the integrated EAP server +CONFIG_EAP_MSCHAPV2=y + +# EAP-PEAP for the integrated EAP server +CONFIG_EAP_PEAP=y + +# EAP-GTC for the integrated EAP server +CONFIG_EAP_GTC=y + +# EAP-TTLS for the integrated EAP server +CONFIG_EAP_TTLS=y + +# EAP-SIM for the integrated EAP server +#CONFIG_EAP_SIM=y + +# EAP-AKA for the integrated EAP server +#CONFIG_EAP_AKA=y + +# EAP-AKA' for the integrated EAP server +# This requires CONFIG_EAP_AKA to be enabled, too. +#CONFIG_EAP_AKA_PRIME=y + +# EAP-PAX for the integrated EAP server +#CONFIG_EAP_PAX=y + +# EAP-PSK for the integrated EAP server (this is _not_ needed for WPA-PSK) +#CONFIG_EAP_PSK=y + +# EAP-pwd for the integrated EAP server (secure authentication with a password) +#CONFIG_EAP_PWD=y + +# EAP-SAKE for the integrated EAP server +#CONFIG_EAP_SAKE=y + +# EAP-GPSK for the integrated EAP server +#CONFIG_EAP_GPSK=y +# Include support for optional SHA256 cipher suite in EAP-GPSK +#CONFIG_EAP_GPSK_SHA256=y + +# EAP-FAST for the integrated EAP server +# Note: If OpenSSL is used as the TLS library, OpenSSL 1.0 or newer is needed +# for EAP-FAST support. Older OpenSSL releases would need to be patched, e.g., +# with openssl-0.9.8x-tls-extensions.patch, to add the needed functions. +#CONFIG_EAP_FAST=y + +# Wi-Fi Protected Setup (WPS) +#CONFIG_WPS=y +# Enable UPnP support for external WPS Registrars +#CONFIG_WPS_UPNP=y +# Enable WPS support with NFC config method +#CONFIG_WPS_NFC=y + +# EAP-IKEv2 +#CONFIG_EAP_IKEV2=y + +# Trusted Network Connect (EAP-TNC) +#CONFIG_EAP_TNC=y + +# EAP-EKE for the integrated EAP server +#CONFIG_EAP_EKE=y + +# PKCS#12 (PFX) support (used to read private key and certificate file from +# a file that usually has extension .p12 or .pfx) +CONFIG_PKCS12=y + +# RADIUS authentication server. This provides access to the integrated EAP +# server from external hosts using RADIUS. +#CONFIG_RADIUS_SERVER=y + +# Build IPv6 support for RADIUS operations +CONFIG_IPV6=y + +# IEEE Std 802.11r-2008 (Fast BSS Transition) +#CONFIG_IEEE80211R=y + +# Use the hostapd's IEEE 802.11 authentication (ACL), but without +# the IEEE 802.11 Management capability (e.g., FreeBSD/net80211) +#CONFIG_DRIVER_RADIUS_ACL=y + +# IEEE 802.11n (High Throughput) support +CONFIG_IEEE80211N=y + +# Wireless Network Management (IEEE Std 802.11v-2011) +# Note: This is experimental and not complete implementation. +#CONFIG_WNM=y + +# IEEE 802.11ac (Very High Throughput) support +CONFIG_IEEE80211AC=y + +# Remove debugging code that is printing out debug messages to stdout. +# This can be used to reduce the size of the hostapd considerably if debugging +# code is not needed. +#CONFIG_NO_STDOUT_DEBUG=y + +# Add support for writing debug log to a file: -f /tmp/hostapd.log +# Disabled by default. +#CONFIG_DEBUG_FILE=y + +# Add support for sending all debug messages (regardless of debug verbosity) +# to the Linux kernel tracing facility. This helps debug the entire stack by +# making it easy to record everything happening from the driver up into the +# same file, e.g., using trace-cmd. +#CONFIG_DEBUG_LINUX_TRACING=y + +# Remove support for RADIUS accounting +#CONFIG_NO_ACCOUNTING=y + +# Remove support for RADIUS +#CONFIG_NO_RADIUS=y + +# Remove support for VLANs +#CONFIG_NO_VLAN=y + +# Enable support for fully dynamic VLANs. This enables hostapd to +# automatically create bridge and VLAN interfaces if necessary. +#CONFIG_FULL_DYNAMIC_VLAN=y + +# Use netlink-based kernel API for VLAN operations instead of ioctl() +# Note: This requires libnl 3.1 or newer. +#CONFIG_VLAN_NETLINK=y + +# Remove support for dumping internal state through control interface commands +# This can be used to reduce binary size at the cost of disabling a debugging +# option. +#CONFIG_NO_DUMP_STATE=y + +# Enable tracing code for developer debugging +# This tracks use of memory allocations and other registrations and reports +# incorrect use with a backtrace of call (or allocation) location. +#CONFIG_WPA_TRACE=y +# For BSD, comment out these. +#LIBS += -lexecinfo +#LIBS_p += -lexecinfo +#LIBS_c += -lexecinfo + +# Use libbfd to get more details for developer debugging +# This enables use of libbfd to get more detailed symbols for the backtraces +# generated by CONFIG_WPA_TRACE=y. +#CONFIG_WPA_TRACE_BFD=y +# For BSD, comment out these. +#LIBS += -lbfd -liberty -lz +#LIBS_p += -lbfd -liberty -lz +#LIBS_c += -lbfd -liberty -lz + +# hostapd depends on strong random number generation being available from the +# operating system. os_get_random() function is used to fetch random data when +# needed, e.g., for key generation. On Linux and BSD systems, this works by +# reading /dev/urandom. It should be noted that the OS entropy pool needs to be +# properly initialized before hostapd is started. This is important especially +# on embedded devices that do not have a hardware random number generator and +# may by default start up with minimal entropy available for random number +# generation. +# +# As a safety net, hostapd is by default trying to internally collect +# additional entropy for generating random data to mix in with the data +# fetched from the OS. This by itself is not considered to be very strong, but +# it may help in cases where the system pool is not initialized properly. +# However, it is very strongly recommended that the system pool is initialized +# with enough entropy either by using hardware assisted random number +# generator or by storing state over device reboots. +# +# hostapd can be configured to maintain its own entropy store over restarts to +# enhance random number generation. This is not perfect, but it is much more +# secure than using the same sequence of random numbers after every reboot. +# This can be enabled with -e command line option. The specified +# file needs to be readable and writable by hostapd. +# +# If the os_get_random() is known to provide strong random data (e.g., on +# Linux/BSD, the board in question is known to have reliable source of random +# data from /dev/urandom), the internal hostapd random pool can be disabled. +# This will save some in binary size and CPU use. However, this should only be +# considered for builds that are known to be used on devices that meet the +# requirements described above. +#CONFIG_NO_RANDOM_POOL=y + +# Select TLS implementation +# openssl = OpenSSL (default) +# gnutls = GnuTLS +# internal = Internal TLSv1 implementation (experimental) +# none = Empty template +#CONFIG_TLS=openssl + +# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.1) +# can be enabled to get a stronger construction of messages when block ciphers +# are used. +#CONFIG_TLSV11=y + +# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.2) +# can be enabled to enable use of stronger crypto algorithms. +#CONFIG_TLSV12=y + +# If CONFIG_TLS=internal is used, additional library and include paths are +# needed for LibTomMath. Alternatively, an integrated, minimal version of +# LibTomMath can be used. See beginning of libtommath.c for details on benefits +# and drawbacks of this option. +#CONFIG_INTERNAL_LIBTOMMATH=y +#ifndef CONFIG_INTERNAL_LIBTOMMATH +#LTM_PATH=/usr/src/libtommath-0.39 +#CFLAGS += -I$(LTM_PATH) +#LIBS += -L$(LTM_PATH) +#LIBS_p += -L$(LTM_PATH) +#endif +# At the cost of about 4 kB of additional binary size, the internal LibTomMath +# can be configured to include faster routines for exptmod, sqr, and div to +# speed up DH and RSA calculation considerably +#CONFIG_INTERNAL_LIBTOMMATH_FAST=y + +# Interworking (IEEE 802.11u) +# This can be used to enable functionality to improve interworking with +# external networks. +#CONFIG_INTERWORKING=y + +# Hotspot 2.0 +#CONFIG_HS20=y + +# Enable SQLite database support in hlr_auc_gw, EAP-SIM DB, and eap_user_file +#CONFIG_SQLITE=y + +# Testing options +# This can be used to enable some testing options (see also the example +# configuration file) that are really useful only for testing clients that +# connect to this hostapd. These options allow, for example, to drop a +# certain percentage of probe requests or auth/(re)assoc frames. +# +#CONFIG_TESTING_OPTIONS=y + +# Automatic Channel Selection +# This will allow hostapd to pick the channel automatically when channel is set +# to "acs_survey" or "0". Eventually, other ACS algorithms can be added in +# similar way. +# +# Automatic selection is currently only done through initialization, later on +# we hope to do background checks to keep us moving to more ideal channels as +# time goes by. ACS is currently only supported through the nl80211 driver and +# your driver must have survey dump capability that is filled by the driver +# during scanning. +# +# You can customize the ACS survey algorithm with the hostapd.conf variable +# acs_num_scans. +# +# Supported ACS drivers: +# * ath9k +# * ath5k +# * ath10k +# +# For more details refer to: +# http://wireless.kernel.org/en/users/Documentation/acs +# +#CONFIG_ACS=y diff --git a/config/hostapd/config/config_realtek b/config/hostapd/config/config_realtek new file mode 100644 index 000000000..bd68495be --- /dev/null +++ b/config/hostapd/config/config_realtek @@ -0,0 +1,209 @@ +# Example hostapd build time configuration +# +# This file lists the configuration options that are used when building the +# hostapd binary. All lines starting with # are ignored. Configuration option +# lines must be commented out complete, if they are not to be included, i.e., +# just setting VARIABLE=n is not disabling that variable. +# +# This file is included in Makefile, so variables like CFLAGS and LIBS can also +# be modified from here. In most cass, these lines should use += in order not +# to override previous values of the variables. + +# Driver interface for Host AP driver +#CONFIG_DRIVER_HOSTAP=y +CONFIG_DRIVER_RTW=y + +# Driver interface for wired authenticator +#CONFIG_DRIVER_WIRED=y + +# Driver interface for madwifi driver +#CONFIG_DRIVER_MADWIFI=y +#CFLAGS += -I../../madwifi # change to the madwifi source directory + +# Driver interface for drivers using the nl80211 kernel interface +#CONFIG_DRIVER_NL80211=y + +# Driver interface for FreeBSD net80211 layer (e.g., Atheros driver) +#CONFIG_DRIVER_BSD=y +#CONFIG_SUPPORT_RTW_DRIVER=y +#CFLAGS += -I/usr/local/include +#LIBS += -L/usr/local/lib +#LIBS_p += -L/usr/local/lib +#LIBS_c += -L/usr/local/lib + +# Driver interface for no driver (e.g., RADIUS server only) +#CONFIG_DRIVER_NONE=y + +# IEEE 802.11F/IAPP +#CONFIG_IAPP=y + +# WPA2/IEEE 802.11i RSN pre-authentication +#CONFIG_RSN_PREAUTH=y + +# PeerKey handshake for Station to Station Link (IEEE 802.11e DLS) +#CONFIG_PEERKEY=y + +# IEEE 802.11w (management frame protection) +# This version is an experimental implementation based on IEEE 802.11w/D1.0 +# draft and is subject to change since the standard has not yet been finalized. +# Driver support is also needed for IEEE 802.11w. +#CONFIG_IEEE80211W=y + +# Integrated EAP server +CONFIG_EAP=y + +# EAP-MD5 for the integrated EAP server +#CONFIG_EAP_MD5=y + +# EAP-TLS for the integrated EAP server +#CONFIG_EAP_TLS=y + +# EAP-MSCHAPv2 for the integrated EAP server +#CONFIG_EAP_MSCHAPV2=y + +# EAP-PEAP for the integrated EAP server +#CONFIG_EAP_PEAP=y + +# EAP-GTC for the integrated EAP server +#CONFIG_EAP_GTC=y + +# EAP-TTLS for the integrated EAP server +#CONFIG_EAP_TTLS=y + +# EAP-SIM for the integrated EAP server +#CONFIG_EAP_SIM=y + +# EAP-AKA for the integrated EAP server +#CONFIG_EAP_AKA=y + +# EAP-AKA' for the integrated EAP server +# This requires CONFIG_EAP_AKA to be enabled, too. +#CONFIG_EAP_AKA_PRIME=y + +# EAP-PAX for the integrated EAP server +#CONFIG_EAP_PAX=y + +# EAP-PSK for the integrated EAP server (this is _not_ needed for WPA-PSK) +#CONFIG_EAP_PSK=y + +# EAP-SAKE for the integrated EAP server +#CONFIG_EAP_SAKE=y + +# EAP-GPSK for the integrated EAP server +#CONFIG_EAP_GPSK=y +# Include support for optional SHA256 cipher suite in EAP-GPSK +#CONFIG_EAP_GPSK_SHA256=y + +# EAP-FAST for the integrated EAP server +# Note: Default OpenSSL package does not include support for all the +# functionality needed for EAP-FAST. If EAP-FAST is enabled with OpenSSL, +# the OpenSSL library must be patched (openssl-0.9.9-session-ticket.patch) +# to add the needed functions. +#CONFIG_EAP_FAST=y + +# Wi-Fi Protected Setup (WPS) +CONFIG_WPS=y +# Enable WSC 2.0 support +#CONFIG_WPS2=y +# Enable UPnP support for external WPS Registrars +#CONFIG_WPS_UPNP=y + +CONFIG_TLS=internal +CONFIG_INTERNAL_LIBTOMMATH=y + +# EAP-IKEv2 +#CONFIG_EAP_IKEV2=y + +# Trusted Network Connect (EAP-TNC) +#CONFIG_EAP_TNC=y + +# PKCS#12 (PFX) support (used to read private key and certificate file from +# a file that usually has extension .p12 or .pfx) +#CONFIG_PKCS12=y + +# RADIUS authentication server. This provides access to the integrated EAP +# server from external hosts using RADIUS. +#CONFIG_RADIUS_SERVER=y + +# Build IPv6 support for RADIUS operations +#CONFIG_IPV6=y + +# IEEE Std 802.11r-2008 (Fast BSS Transition) +#CONFIG_IEEE80211R=y + +# Use the hostapd's IEEE 802.11 authentication (ACL), but without +# the IEEE 802.11 Management capability (e.g., madwifi or FreeBSD/net80211) +#CONFIG_DRIVER_RADIUS_ACL=y + +# IEEE 802.11n (High Throughput) support +CONFIG_IEEE80211N=y + +# Remove debugging code that is printing out debug messages to stdout. +# This can be used to reduce the size of the hostapd considerably if debugging +# code is not needed. +#CONFIG_NO_STDOUT_DEBUG=y + +# Add support for writing debug log to a file: -f /tmp/hostapd.log +# Disabled by default. +#CONFIG_DEBUG_FILE=y + +# Remove support for RADIUS accounting +#CONFIG_NO_ACCOUNTING=y + +# Remove support for RADIUS +#CONFIG_NO_RADIUS=y + +# Remove support for VLANs +#CONFIG_NO_VLAN=y + +# Enable support for fully dynamic VLANs. This enables hostapd to +# automatically create bridge and VLAN interfaces if necessary. +#CONFIG_FULL_DYNAMIC_VLAN=y + +# Remove support for dumping state into a file on SIGUSR1 signal +# This can be used to reduce binary size at the cost of disabling a debugging +# option. +#CONFIG_NO_DUMP_STATE=y + +# Enable tracing code for developer debugging +# This tracks use of memory allocations and other registrations and reports +# incorrect use with a backtrace of call (or allocation) location. +#CONFIG_WPA_TRACE=y +# For BSD, comment out these. +#LIBS += -lexecinfo +#LIBS_p += -lexecinfo +#LIBS_c += -lexecinfo + +# Use libbfd to get more details for developer debugging +# This enables use of libbfd to get more detailed symbols for the backtraces +# generated by CONFIG_WPA_TRACE=y. +#CONFIG_WPA_TRACE_BFD=y +# For BSD, comment out these. +#LIBS += -lbfd -liberty -lz +#LIBS_p += -lbfd -liberty -lz +#LIBS_c += -lbfd -liberty -lz + +# hostapd depends on strong random number generation being available from the +# operating system. os_get_random() function is used to fetch random data when +# needed, e.g., for key generation. On Linux and BSD systems, this works by +# reading /dev/urandom. It should be noted that the OS entropy pool needs to be +# properly initialized before hostapd is started. This is important especially +# on embedded devices that do not have a hardware random number generator and +# may by default start up with minimal entropy available for random number +# generation. +# +# As a safety net, hostapd is by default trying to internally collect +# additional entropy for generating random data to mix in with the data +# fetched from the OS. This by itself is not considered to be very strong, but +# it may help in cases where the system pool is not initialized properly. +# However, it is very strongly recommended that the system pool is initialized +# with enough entropy either by using hardware assisted random number +# generatior or by storing state over device reboots. +# +# If the os_get_random() is known to provide strong ramdom data (e.g., on +# Linux/BSD, the board in question is known to have reliable source of random +# data from /dev/urandom), the internal hostapd random pool can be disabled. +# This will save some in binary size and CPU use. However, this should only be +# considered for builds that are known to be used on devices that meet the +# requirements described above. +#CONFIG_NO_RANDOM_POOL=y diff --git a/config/hostapd/files/driver_rtl.h b/config/hostapd/files/driver_rtl.h new file mode 100644 index 000000000..2200e180c --- /dev/null +++ b/config/hostapd/files/driver_rtl.h @@ -0,0 +1,114 @@ + +#ifndef _DRIVER_RTL_H_ +#define _DRIVER_RTL_H_ + + +#define RTL_IOCTL_HOSTAPD (SIOCIWFIRSTPRIV + 28) + +#define IEEE_CRYPT_ALG_NAME_LEN (16) + +/* RTL871X_IOCTL_HOSTAPD ioctl() cmd: */ +enum { + RTL871X_HOSTAPD_FLUSH = 1, + RTL871X_HOSTAPD_ADD_STA = 2, + RTL871X_HOSTAPD_REMOVE_STA = 3, + RTL871X_HOSTAPD_GET_INFO_STA = 4, + /* REMOVED: PRISM2_HOSTAPD_RESET_TXEXC_STA = 5, */ + RTL871X_HOSTAPD_GET_WPAIE_STA = 5, + RTL871X_SET_ENCRYPTION = 6, + RTL871X_GET_ENCRYPTION = 7, + RTL871X_HOSTAPD_SET_FLAGS_STA = 8, + RTL871X_HOSTAPD_GET_RID = 9, + RTL871X_HOSTAPD_SET_RID = 10, + RTL871X_HOSTAPD_SET_ASSOC_AP_ADDR = 11, + RTL871X_HOSTAPD_SET_GENERIC_ELEMENT = 12, + RTL871X_HOSTAPD_MLME = 13, + RTL871X_HOSTAPD_SCAN_REQ = 14, + RTL871X_HOSTAPD_STA_CLEAR_STATS = 15, + RTL871X_HOSTAPD_SET_BEACON = 16, + RTL871X_HOSTAPD_SET_WPS_BEACON = 17, + RTL871X_HOSTAPD_SET_WPS_PROBE_RESP = 18, + RTL871X_HOSTAPD_SET_WPS_ASSOC_RESP = 19, + RTL871X_HOSTAPD_SET_HIDDEN_SSID = 20, +}; + +typedef struct ieee_param { + u32 cmd; + u8 sta_addr[ETH_ALEN]; + union { + struct { + u8 name; + u32 value; + } wpa_param; + struct { + u32 len; + u8 reserved[32]; + u8 data[0]; + } wpa_ie; + struct{ + int command; + int reason_code; + } mlme; + struct { + u8 alg[IEEE_CRYPT_ALG_NAME_LEN]; + u8 set_tx; + u32 err; + u8 idx; + u8 seq[8]; /* sequence counter (set: RX, get: TX) */ + u16 key_len; + u8 key[0]; + } crypt; + struct { + u16 aid; + u16 capability; + int flags; + u8 tx_supp_rates[16]; + //struct ieee80211_ht_capability ht_cap; + struct ieee80211_ht_capabilities ht_cap; + } add_sta; + struct { + u8 reserved[2];//for set max_num_sta + u8 buf[0]; + } bcn_ie; + + } u; + +} ieee_param; + + + +#define IEEE80211_CCK_RATE_LEN 4 +#define IEEE80211_OFDM_RATE_LEN 8 + +#define IEEE80211_CCK_RATE_1MB 0x02 +#define IEEE80211_CCK_RATE_2MB 0x04 +#define IEEE80211_CCK_RATE_5MB 0x0B +#define IEEE80211_CCK_RATE_11MB 0x16 +#define IEEE80211_OFDM_RATE_6MB 0x0C +#define IEEE80211_OFDM_RATE_9MB 0x12 +#define IEEE80211_OFDM_RATE_12MB 0x18 +#define IEEE80211_OFDM_RATE_18MB 0x24 +#define IEEE80211_OFDM_RATE_24MB 0x30 +#define IEEE80211_OFDM_RATE_36MB 0x48 +#define IEEE80211_OFDM_RATE_48MB 0x60 +#define IEEE80211_OFDM_RATE_54MB 0x6C +#define IEEE80211_BASIC_RATE_MASK 0x80 + +#define IEEE80211_CCK_RATE_1MB_MASK (1<<0) +#define IEEE80211_CCK_RATE_2MB_MASK (1<<1) +#define IEEE80211_CCK_RATE_5MB_MASK (1<<2) +#define IEEE80211_CCK_RATE_11MB_MASK (1<<3) +#define IEEE80211_OFDM_RATE_6MB_MASK (1<<4) +#define IEEE80211_OFDM_RATE_9MB_MASK (1<<5) +#define IEEE80211_OFDM_RATE_12MB_MASK (1<<6) +#define IEEE80211_OFDM_RATE_18MB_MASK (1<<7) +#define IEEE80211_OFDM_RATE_24MB_MASK (1<<8) +#define IEEE80211_OFDM_RATE_36MB_MASK (1<<9) +#define IEEE80211_OFDM_RATE_48MB_MASK (1<<10) +#define IEEE80211_OFDM_RATE_54MB_MASK (1<<11) + +#define IEEE80211_CCK_RATES_MASK 0x0000000F +#define IEEE80211_OFDM_RATES_MASK 0x00000FF0 + +#endif + diff --git a/config/hostapd/files/driver_rtw.c b/config/hostapd/files/driver_rtw.c new file mode 100644 index 000000000..436dd1492 --- /dev/null +++ b/config/hostapd/files/driver_rtw.c @@ -0,0 +1,1993 @@ +/* + * hostapd / Driver interface for rtl871x driver + * Copyright (c) 2010, + * + * 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. + */ + +//#define CONFIG_MGNT_L2SOCK 1 +#define CONFIG_MLME_OFFLOAD 1 + + +#include "includes.h" +#include +#include + +#include "common.h" + +/*#include "wireless_copy.h"*/ +#include "linux_wext.h" + +#include "driver.h" +#include "eloop.h" +#include "priv_netlink.h" +#include "l2_packet/l2_packet.h" +#include "common/ieee802_11_defs.h" +#include "netlink.h" +#include "linux_ioctl.h" + +//#include "../src/ap/hostapd.h" +//#include "../src/ap/ap_config.h" +#include "ap/hostapd.h" +#include "ap/ap_config.h" + +#ifdef USE_KERNEL_HEADERS +/* compat-wireless does not include linux/compiler.h to define __user, so + * define it here */ +#ifndef __user +#define __user +#endif /* __user */ +#include +#include +#include /* The L2 protocols */ +#include +#include +#else /* USE_KERNEL_HEADERS */ +#include +#include +//#include "wireless_copy.h" +#endif /* USE_KERNEL_HEADERS */ + +//#include + + +#ifndef ETH_P_80211_RAW +#define ETH_P_80211_RAW 0x0019 +#endif + +#if 0 +#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 "wpa.h" +#include "accounting.h" +#include "ieee802_11.h" +#include "hw_features.h" +#include "radius/radius.h" +#endif + +#include "driver_rtl.h" + + +//static int rtl871x_sta_remove_ops(void *priv, const u8 *addr); + +struct rtl871x_driver_data { + struct hostapd_data *hapd; + + char iface[IFNAMSIZ + 1]; + int ifindex; + struct l2_packet_data *l2_sock;/* socket for sending eapol frames*/ + struct l2_packet_data *l2_sock_recv;/* raw packet recv socket from bridge interface*/ +#ifdef CONFIG_MGNT_L2SOCK + struct l2_packet_data *mgnt_l2_sock; /* socket for tx/rx management frames*/ +#else + int mgnt_sock;/* socket for tx/rx management frames*/ +#endif + int ioctl_sock; /* socket for ioctl() use */ + int wext_sock; /* socket for wireless events */ + + struct netlink_data *netlink; + + int we_version; + + u8 hw_mac[ETH_ALEN]; + + u8 acct_mac[ETH_ALEN]; + + struct hostap_sta_driver_data acct_data; + +}; + +/* +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; +} +*/ + +#ifndef CONFIG_MLME_OFFLOAD +static int rtl871x_set_iface_flags(void *priv, int dev_up) +{ + struct rtl871x_driver_data *drv = priv; + struct ifreq ifr; + + wpa_printf(MSG_DEBUG, "%s: dev_up=%d", __func__, dev_up); + + if (drv->mgnt_sock < 0) + return -1; + + memset(&ifr, 0, sizeof(ifr)); + //os_strlcpy(ifr.ifr_name, drv->iface, IFNAMSIZ); + //os_strlcpy(ifr.ifr_name, "mgnt.wlan", IFNAMSIZ); + snprintf(ifr.ifr_name, IFNAMSIZ, "mgnt.%s", "wlan0"); + + if (ioctl(drv->mgnt_sock, SIOCGIFFLAGS, &ifr) != 0) { + perror("ioctl[SIOCGIFFLAGS]"); + return -1; + } + + if (dev_up) + ifr.ifr_flags |= IFF_UP; + else + ifr.ifr_flags &= ~IFF_UP; + + if (ioctl(drv->mgnt_sock, SIOCSIFFLAGS, &ifr) != 0) { + perror("ioctl[SIOCSIFFLAGS]"); + return -1; + } + +#if 0 + if (dev_up) { + memset(&ifr, 0, sizeof(ifr)); + os_strlcpy(ifr.ifr_name, drv->iface, IFNAMSIZ); + ifr.ifr_mtu = HOSTAPD_MTU; + if (ioctl(drv->ioctl_sock, SIOCSIFMTU, &ifr) != 0) { + perror("ioctl[SIOCSIFMTU]"); + printf("Setting MTU failed - trying to survive with " + "current value\n"); + } + } +#endif + + return 0; +} +#endif + +static int rtl871x_hostapd_ioctl(struct rtl871x_driver_data *drv, ieee_param *param, int len) +{ + struct iwreq iwr; + + memset(&iwr, 0, sizeof(iwr)); + os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ); + iwr.u.data.pointer = (caddr_t) param; + iwr.u.data.length = len; + + if (ioctl(drv->ioctl_sock, RTL_IOCTL_HOSTAPD, &iwr) < 0) { + perror("ioctl[RTL_IOCTL_HOSTAPD]"); + return -1; + } + + return 0; +} + +static int rtl871x_set_mode(struct rtl871x_driver_data *drv, u32 mode) +{ + struct iwreq iwr; + + if (drv->ioctl_sock < 0) + return -1; + + memset(&iwr, 0, sizeof(iwr)); + + os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ); + + //iwr.u.mode = IW_MODE_MASTER; + iwr.u.mode = mode; + + if (ioctl(drv->ioctl_sock, SIOCSIWMODE, &iwr) < 0) { + perror("ioctl[SIOCSIWMODE]"); + printf("Could not set interface to mode(%d)!\n", mode); + return -1; + } + + return 0; + +} + +/* +static int rtl871x_notif_assoc(struct hostapd_data *hapd, const u8 *addr, + const u8 *ie, size_t ielen) +{ + struct sta_info *sta; + int new_assoc, res; + + //hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211, + // HOSTAPD_LEVEL_INFO, "associated"); + + sta = ap_get_sta(hapd, addr); + if (sta) { + accounting_sta_stop(hapd, sta); + } else { + sta = ap_sta_add(hapd, addr); + if (sta == NULL) + { + rtl871x_sta_remove_ops(hapd->drv_priv, addr); + return -1; + } + } + sta->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS); + + if (hapd->conf->wpa) { + if (ie == NULL || ielen == 0) { + if (hapd->conf->wps_state) { + wpa_printf(MSG_DEBUG, "STA did not include " + "WPA/RSN IE in (Re)Association " + "Request - possible WPS use"); + sta->flags |= WLAN_STA_MAYBE_WPS; + goto skip_wpa_check; + } + + wpa_printf(MSG_DEBUG, "No WPA/RSN IE from STA"); + return -1; + } + if (hapd->conf->wps_state && ie[0] == 0xdd && ie[1] >= 4 && + os_memcmp(ie + 2, "\x00\x50\xf2\x04", 4) == 0) { + sta->flags |= WLAN_STA_WPS; + goto skip_wpa_check; + } + + 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; + } + res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm, + ie, ielen, NULL, 0); + if (res != WPA_IE_OK) { + wpa_printf(MSG_DEBUG, "WPA/RSN information element " + "rejected? (res %u)", res); + wpa_hexdump(MSG_DEBUG, "IE", ie, ielen); + return -1; + } + } else if (hapd->conf->wps_state) { + if (ie && ielen > 4 && ie[0] == 0xdd && ie[1] >= 4 && + os_memcmp(ie + 2, "\x00\x50\xf2\x04", 4) == 0) { + sta->flags |= WLAN_STA_WPS; + } else + sta->flags |= WLAN_STA_MAYBE_WPS; + } +skip_wpa_check: + + 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; +} +*/ + +static int rtl871x_get_sta_wpaie(struct rtl871x_driver_data *drv, u8 *iebuf, u8 *addr) +{ + struct ieee_param param; + + printf("+%s, " MACSTR " is sta's address\n", __func__, MAC2STR(addr)); + + memset(¶m, 0, sizeof(param)); + + param.cmd = RTL871X_HOSTAPD_GET_WPAIE_STA; + + memcpy(param.sta_addr, addr, ETH_ALEN); + + if (rtl871x_hostapd_ioctl(drv, ¶m, sizeof(param))) { + printf("Could not get sta wpaie from kernel driver.\n"); + return -1; + } + + + if(param.u.wpa_ie.len > 32) + return -1; + + memcpy(iebuf, param.u.wpa_ie.reserved, param.u.wpa_ie.len); + + return 0; + +} + +static int rtl871x_del_sta(struct rtl871x_driver_data *drv, u8 *addr) +{ + struct hostapd_data *hapd = drv->hapd; + +#if 1 + + //union wpa_event_data event; + //os_memset(&event, 0, sizeof(event)); + //event.disassoc_info.addr = addr; + //wpa_supplicant_event(hapd, EVENT_DISASSOC, &event); + + drv_event_disassoc(hapd, addr); + +#else + + 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); + } + else + { + wpa_printf(MSG_DEBUG, "Disassociation notification for " + "unknown STA " MACSTR, MAC2STR(addr)); + } +#endif + + return 0; + +} + +static int rtl871x_new_sta(struct rtl871x_driver_data *drv, u8 *addr) +{ + struct hostapd_data *hapd = drv->hapd; + //struct ieee80211req_wpaie ie; + int ielen = 0, res=0; + //u8 *iebuf = NULL; + u8 iebuf[32], *piebuf=NULL; + + /* + * Fetch negotiated WPA/RSN parameters from the driver. + */ + //memset(&ie, 0, sizeof(ie)); + //memcpy(ie.wpa_macaddr, addr, IEEE80211_ADDR_LEN); + memset(iebuf, 0 , sizeof(iebuf)); + if (rtl871x_get_sta_wpaie(drv, iebuf, addr)) { + //if (set80211priv(drv, IEEE80211_IOCTL_GETWPAIE, &ie, sizeof(ie))) { + + wpa_printf(MSG_DEBUG, "%s: Failed to get WPA/RSN IE: %s", + __func__, strerror(errno)); + goto no_ie; + } + + //wpa_hexdump(MSG_MSGDUMP, "req WPA IE", + // ie.wpa_ie, IEEE80211_MAX_OPT_IE); + + //wpa_hexdump(MSG_MSGDUMP, "req RSN IE", + // ie.rsn_ie, IEEE80211_MAX_OPT_IE); + + //iebuf = ie.wpa_ie; + +/* + if (iebuf[0] != WLAN_EID_VENDOR_SPECIFIC) + iebuf[1] = 0; + if (iebuf[1] == 0 && ie.rsn_ie[1] > 0) { + iebuf = ie.rsn_ie; + if (iebuf[0] != WLAN_EID_RSN) + iebuf[1] = 0; + } +*/ + + if ((iebuf[0] == WLAN_EID_VENDOR_SPECIFIC) || (iebuf[0] == WLAN_EID_RSN) ) + { + piebuf = iebuf; + ielen = iebuf[1]; + + if (ielen == 0) + piebuf = NULL; + else + ielen += 2; + } + +no_ie: + + //res = rtl871x_notif_assoc(hapd, addr, piebuf, ielen); + //drv_event_assoc(hapd, addr, piebuf, ielen); + drv_event_assoc(hapd, addr, piebuf, ielen, 0); + + if (memcmp(addr, drv->acct_mac, ETH_ALEN) == 0) { + /* Cached accounting data is not valid anymore. */ + memset(drv->acct_mac, 0, ETH_ALEN); + memset(&drv->acct_data, 0, sizeof(drv->acct_data)); + } + + return res; + +} + +static void rtl871x_wireless_event_wireless(struct rtl871x_driver_data *drv, + char *data, int len) +{ + struct iw_event iwe_buf, *iwe = &iwe_buf; + char *pos, *end, *custom, *buf; + + pos = data; + end = data + len; + + while (pos + IW_EV_LCP_LEN <= end) { + /* Event data may be unaligned, so make a local, aligned copy + * before processing. */ + memcpy(&iwe_buf, pos, IW_EV_LCP_LEN); + wpa_printf(MSG_MSGDUMP, "Wireless event: cmd=0x%x len=%d", + iwe->cmd, iwe->len); + if (iwe->len <= IW_EV_LCP_LEN) + return; + + custom = pos + IW_EV_POINT_LEN; + if (drv->we_version > 18 && + (iwe->cmd == IWEVMICHAELMICFAILURE || + iwe->cmd == IWEVCUSTOM)) { + /* WE-19 removed the pointer from struct iw_point */ + char *dpos = (char *) &iwe_buf.u.data.length; + int dlen = dpos - (char *) &iwe_buf; + memcpy(dpos, pos + IW_EV_LCP_LEN, + sizeof(struct iw_event) - dlen); + } else { + memcpy(&iwe_buf, pos, sizeof(struct iw_event)); + custom += IW_EV_POINT_OFF; + } + + //printf("got wireless event, iwe->cmd=%d\n", iwe->cmd); + + switch (iwe->cmd) { + case IWEVEXPIRED: + rtl871x_del_sta(drv, (u8 *)iwe->u.addr.sa_data); + break; + case IWEVREGISTERED: + if(rtl871x_new_sta(drv, (u8 *)iwe->u.addr.sa_data)) + { + printf("Failed to add new sta: "MACSTR" \n", MAC2STR((u8 *)iwe->u.addr.sa_data)); + } + break; + case IWEVCUSTOM: + if (custom + iwe->u.data.length > end) + return; + buf = malloc(iwe->u.data.length + 1); + if (buf == NULL) + return; /* XXX */ + memcpy(buf, custom, iwe->u.data.length); + buf[iwe->u.data.length] = '\0'; + //madwifi_wireless_event_wireless_custom(drv, buf); + free(buf); + break; + } + + pos += iwe->len; + } + +} + +#if 1 +static void rtl871x_wireless_event_rtm_newlink(void *ctx, + struct ifinfomsg *ifi, u8 *buf, size_t len) +{ + struct rtl871x_driver_data *drv = ctx; + int attrlen, rta_len; + struct rtattr *attr; + + if (ifi->ifi_index != drv->ifindex) + return; + + attrlen = len; + attr = (struct rtattr *) buf; + + rta_len = RTA_ALIGN(sizeof(struct rtattr)); + while (RTA_OK(attr, attrlen)) { + if (attr->rta_type == IFLA_WIRELESS) { + rtl871x_wireless_event_wireless( + drv, ((char *) attr) + rta_len, + attr->rta_len - rta_len); + } + attr = RTA_NEXT(attr, attrlen); + } +} + +#else +static void rtl871x_wireless_event_rtm_newlink(struct rtl871x_driver_data *drv, + struct nlmsghdr *h, int len) +{ + struct ifinfomsg *ifi; + int attrlen, nlmsg_len, rta_len; + struct rtattr * attr; + + if (len < (int) sizeof(*ifi)) + return; + + ifi = NLMSG_DATA(h); + + if (ifi->ifi_index != drv->ifindex) + return; + + nlmsg_len = NLMSG_ALIGN(sizeof(struct ifinfomsg)); + + attrlen = h->nlmsg_len - nlmsg_len; + if (attrlen < 0) + return; + + attr = (struct rtattr *) (((char *) ifi) + nlmsg_len); + + rta_len = RTA_ALIGN(sizeof(struct rtattr)); + while (RTA_OK(attr, attrlen)) { + if (attr->rta_type == IFLA_WIRELESS) { + rtl871x_wireless_event_wireless( + drv, ((char *) attr) + rta_len, + attr->rta_len - rta_len); + } + attr = RTA_NEXT(attr, attrlen); + } +} +#endif + +/* +static void rtl871x_wireless_event_receive(int sock, void *eloop_ctx, void *sock_ctx) +{ + char buf[256];//!!! + int left; + struct sockaddr_nl from; + socklen_t fromlen; + struct nlmsghdr *h; + struct rtl871x_driver_data *drv = eloop_ctx; + + //printf("+rtl871x_wireless_event_receive\n"); + + fromlen = sizeof(from); + left = recvfrom(sock, buf, sizeof(buf), MSG_DONTWAIT, + (struct sockaddr *) &from, &fromlen); + if (left < 0) { + if (errno != EINTR && errno != EAGAIN) + perror("recvfrom(netlink)"); + return; + } + + h = (struct nlmsghdr *)buf; + while (left >= (int) sizeof(*h)) { + int len, plen; + + len = h->nlmsg_len; + plen = len - sizeof(*h);//payload len + 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: + rtl871x_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 rtl871x_wireless_event_init(struct rtl871x_driver_data *drv) +{ + struct netlink_config *cfg; + + //madwifi_get_we_version(drv); + + cfg = os_zalloc(sizeof(*cfg)); + if (cfg == NULL) + return -1; + cfg->ctx = drv; + cfg->newlink_cb = rtl871x_wireless_event_rtm_newlink; + drv->netlink = netlink_init(cfg); + if (drv->netlink == NULL) { + os_free(cfg); + return -1; + } + + return 0; +} + +/* +static int rtl871x_wireless_event_init_ops(void *priv) +{ + int s; + struct sockaddr_nl local; + struct rtl871x_driver_data *drv = priv; + + //madwifi_get_we_version(drv); + + drv->wext_sock = -1; + + s = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE); + if (s < 0) { + perror("socket(PF_NETLINK,SOCK_RAW,NETLINK_ROUTE)"); + return -1; + } + + memset(&local, 0, sizeof(local)); + local.nl_family = AF_NETLINK; + local.nl_groups = RTMGRP_LINK; + if (bind(s, (struct sockaddr *) &local, sizeof(local)) < 0) { + perror("bind(netlink)"); + close(s); + return -1; + } + + eloop_register_read_sock(s, rtl871x_wireless_event_receive, drv, NULL); + drv->wext_sock = s; + + return 0; + +} + +static void rtl871x_wireless_event_deinit_ops(void *priv) +{ + struct rtl871x_driver_data *drv = priv; + + if (drv != NULL) { + if (drv->wext_sock < 0) + return; + eloop_unregister_read_sock(drv->wext_sock); + close(drv->wext_sock); + } +} +*/ + +#if 1 +static void rtl871x_handle_read(void *ctx, const u8 *src_addr, const u8 *buf, size_t len) +{ + struct rtl871x_driver_data *drv = ctx; + drv_event_eapol_rx(drv->hapd, src_addr, buf + sizeof(struct l2_ethhdr), + len - sizeof(struct l2_ethhdr)); +} +#else +static void rtl871x_handle_read(void *ctx, const u8 *src_addr, const u8 *buf, size_t len) +{ + struct rtl871x_driver_data *drv = ctx; + struct hostapd_data *hapd = drv->hapd; + struct sta_info *sta; + + sta = ap_get_sta(hapd, src_addr); + if (!sta || !(sta->flags & WLAN_STA_ASSOC)) { + printf("Data frame from not associated STA %s\n", + ether_sprintf(src_addr)); + /* XXX cannot happen */ + return; + } + ieee802_1x_receive(hapd, src_addr, buf + sizeof(struct l2_ethhdr), + len - sizeof(struct l2_ethhdr)); +} +#endif + +static int rtl871x_send_eapol_ops(void *priv, const u8 *addr, const u8 *data, size_t data_len, + int encrypt, const u8 *own_addr, u32 flags) +{ + struct rtl871x_driver_data *drv = priv; + unsigned char buf[3000]; + unsigned char *bp = buf; + struct l2_ethhdr *eth; + size_t len; + int status; + + printf("+rtl871x_send_eapol\n"); + + /* + * 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, own_addr, ETH_ALEN); + eth->h_proto = htons(ETH_P_EAPOL); + memcpy(eth+1, data, data_len); + + wpa_hexdump(MSG_MSGDUMP, "TX EAPOL", bp, len); + + status = l2_packet_send(drv->l2_sock, addr, ETH_P_EAPOL, bp, len); + + if (bp != buf) + free(bp); + + return status; + +} + +#ifndef CONFIG_MLME_OFFLOAD +static void rtl871x_receive_mgnt(struct rtl871x_driver_data *drv , const u8 *buf, size_t len) +{ + const struct ieee80211_mgmt *mgmt; + //const u8 *end, *ie; + u16 fc, type, stype; + //size_t ie_len; + struct hostapd_data *hapd = drv->hapd; + + //printf("+rtl871x_receive_mgnt, " MACSTR " is our address\n", MAC2STR(hapd->own_addr)); + + +#if 0 + { + int i; + for(i=0; iu.probe_req)) + return; + + mgmt = (const struct ieee80211_mgmt *)buf; + + fc = le_to_host16(mgmt->frame_control); + type = WLAN_FC_GET_TYPE(fc); + stype = WLAN_FC_GET_STYPE(fc); + +#if 1 + if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT && + WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_PROBE_RESP) + { + //printf("MGNT Frame - PROBE_RESP Frame\n"); + } +#endif + + //end = buf + len; + //ie = mgmt->u.probe_req.variable; + //ie_len = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req)); + //hostapd_wps_probe_req_rx(drv->hapd, mgmt->sa, ie, ie_len); + + switch (type) { + case WLAN_FC_TYPE_MGMT: + if (stype != WLAN_FC_STYPE_BEACON) + wpa_printf(MSG_MSGDUMP, "MGMT"); + + + + if (stype == WLAN_FC_STYPE_PROBE_REQ) + { + + } + else + { + //printf("rtl871x_receive_mgnt, type=0x%x, stype=0x%x\n", type, stype); + } + + + //ieee802_11_mgmt(hapd, (u8 *)buf, len, stype, NULL); + + break; + case WLAN_FC_TYPE_CTRL: + printf("rtl871x_receive_mgnt, CTRL\n"); + break; + case WLAN_FC_TYPE_DATA: + printf("rtl871x_receive_mgnt, DATA\n"); + //handle_data(hapd, buf, data_len, stype); + break; + default: + printf("unknown frame type %d\n", type); + break; + } + + +} + +#ifdef CONFIG_MGNT_L2SOCK +static void rtl871x_recvive_mgmt_frame(void *ctx, const u8 *src_addr, const u8 *buf, + size_t len) +{ + struct rtl871x_driver_data *drv = ctx; + + rtl871x_receive_mgnt(drv, buf, len); +} +#else +static void rtl871x_recvive_mgmt_frame(int sock, void *eloop_ctx, void *sock_ctx) +{ +#if 0 + int len; + unsigned char buf[1024]; + struct hostapd_data *hapd = (struct hostapd_data *)eloop_ctx; + struct rtl871x_driver_data *drv = (struct rtl871x_driver_data *)hapd->drv_priv; + + len = recv(sock, buf, sizeof(buf), 0); + if (len < 0) { + perror("recv"); + return; + } + + rtl871x_receive_mgnt(drv, buf, len); +#endif +} + +static int rtl871x_mgnt_sock_init(struct rtl871x_driver_data *drv, const char *name) +{ + int sock; + struct ifreq ifr; + struct sockaddr_ll addr; + + sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); + if (sock < 0) { + perror("socket[PF_PACKET,SOCK_RAW]"); + return -1; + } + + if (eloop_register_read_sock(sock, rtl871x_recvive_mgmt_frame, drv->hapd, NULL)) + { + printf("Could not register read socket\n"); + return -1; + } + + memset(&ifr, 0, sizeof(ifr)); + //snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%sap", drv->iface); + os_strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); + if (ioctl(sock, SIOCGIFINDEX, &ifr) != 0) { + perror("ioctl(SIOCGIFINDEX)"); + return -1; + } + + //if (rtl871x_set_iface_flags(drv, 1)) { + // return -1; + //} + + memset(&addr, 0, sizeof(addr)); + addr.sll_family = AF_PACKET; + addr.sll_ifindex = ifr.ifr_ifindex; + wpa_printf(MSG_DEBUG, "Opening raw packet socket for ifindex %d", + addr.sll_ifindex); + + if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + perror("bind"); + return -1; + } + + memset(&ifr, 0, sizeof(ifr)); + os_strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); + if (ioctl(sock, SIOCGIFHWADDR, &ifr) != 0) { + perror("ioctl(SIOCGIFHWADDR)"); + return -1; + } + + + if (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) { + printf("Invalid HW-addr family 0x%04x\n", + ifr.ifr_hwaddr.sa_family); + return -1; + } + + //memcpy(drv->hapd->own_addr, ifr.ifr_hwaddr.sa_data, ETH_ALEN); + + return sock; + +} +#endif +#endif + +static void rtl871x_handle_tx_callback(struct hostapd_data *hapd, u8 *buf, size_t len, + int ok) +{ +#if 0 + struct ieee80211_hdr *hdr; + u16 fc, type, stype; + struct sta_info *sta; + + //printf("%s\n", __func__); + + hdr = (struct ieee80211_hdr *) buf; + fc = le_to_host16(hdr->frame_control); + + type = WLAN_FC_GET_TYPE(fc); + stype = WLAN_FC_GET_STYPE(fc); + + switch (type) { + case WLAN_FC_TYPE_MGMT: + //printf("MGMT (TX callback) %s\n", + // ok ? "ACK" : "fail"); + ieee802_11_mgmt_cb(hapd, buf, len, stype, ok); + break; + case WLAN_FC_TYPE_CTRL: + printf("CTRL (TX callback) %s\n", + ok ? "ACK" : "fail"); + break; + case WLAN_FC_TYPE_DATA: + printf("DATA (TX callback) %s\n", + ok ? "ACK" : "fail"); + sta = ap_get_sta(hapd, hdr->addr1); + if (sta && sta->flags & WLAN_STA_PENDING_POLL) { + wpa_printf(MSG_DEBUG, "STA " MACSTR + " %s pending activity poll", + MAC2STR(sta->addr), + ok ? "ACKed" : "did not ACK"); + if (ok) + sta->flags &= ~WLAN_STA_PENDING_POLL; + } + if (sta) + ieee802_1x_tx_status(hapd, sta, buf, len, ok); + break; + default: + printf("unknown TX callback frame type %d\n", type); + break; + } +#endif +} + +static int rtl871x_send_mgnt(struct rtl871x_driver_data *drv, const void *msg, size_t len) +{ + int res=0; + + return res; +} + +static int rtl871x_send_mgmt_frame_ops(void *priv, const void *msg, size_t len, + int flags) +{ + struct rtl871x_driver_data *drv = priv; + //struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msg; + int res=0; + + //printf("%s\n", __func__); + + + //hdr->frame_control |= host_to_le16(BIT(1));/* Request TX callback */ +#ifdef CONFIG_MGNT_L2SOCK + //res = send(drv->mgnt_l2_sock, msg, len, flags); + //res = l2_packet_send(drv->mgnt_l2_sock, addr, ETH_P_EAPOL, msg, len); + if(drv->mgnt_l2_sock == NULL) + return res; + + res = l2_packet_send(drv->mgnt_l2_sock, NULL, ETH_P_80211_RAW, msg, len); +#else + + if(drv->mgnt_sock < 0) + return res; + + res = send(drv->mgnt_sock, msg, len, flags); +#endif + //hdr->frame_control &= ~host_to_le16(BIT(1)); + + + rtl871x_send_mgnt(drv, msg, len); + + rtl871x_handle_tx_callback(drv->hapd, (u8*)msg, len, 1); + + return res; + +} + +/* +static int rtl871x_driver_send_ether_ops(void *priv, const u8 *dst, const u8 *src, + u16 proto, const u8 *data, size_t data_len) +{ + return 0; +} +*/ + +static struct hostapd_hw_modes *rtl871x_get_hw_feature_data_ops(void *priv, + u16 *num_modes, + u16 *flags) +{ + +#define MAX_NUM_CHANNEL (14) +#define MAX_NUM_CHANNEL_5G (24) + + struct hostapd_hw_modes *modes; + size_t i; + int k; + + *num_modes = 3; + *flags = 0; + + modes = os_zalloc(*num_modes * sizeof(struct hostapd_hw_modes)); + if (modes == NULL) + return NULL; + + //.1 + modes[0].mode = HOSTAPD_MODE_IEEE80211G; + modes[0].num_channels = MAX_NUM_CHANNEL; + modes[0].num_rates = 12; + modes[0].channels = + os_zalloc(MAX_NUM_CHANNEL * sizeof(struct hostapd_channel_data)); + modes[0].rates = os_zalloc(modes[0].num_rates * sizeof(int)); + if (modes[0].channels == NULL || modes[0].rates == NULL) + goto fail; + for (i = 0; i < MAX_NUM_CHANNEL; i++) { + modes[0].channels[i].chan = i + 1; + modes[0].channels[i].freq = 2412 + 5 * i; + modes[0].channels[i].flag = 0; + if (i >= 13) + modes[0].channels[i].flag = HOSTAPD_CHAN_DISABLED; + } + modes[0].rates[0] = 10; + modes[0].rates[1] = 20; + modes[0].rates[2] = 55; + modes[0].rates[3] = 110; + modes[0].rates[4] = 60; + modes[0].rates[5] = 90; + modes[0].rates[6] = 120; + modes[0].rates[7] = 180; + modes[0].rates[8] = 240; + modes[0].rates[9] = 360; + modes[0].rates[10] = 480; + modes[0].rates[11] = 540; + + + //.2 + modes[1].mode = HOSTAPD_MODE_IEEE80211B; + modes[1].num_channels = MAX_NUM_CHANNEL; + modes[1].num_rates = 4; + modes[1].channels = + os_zalloc(MAX_NUM_CHANNEL * sizeof(struct hostapd_channel_data)); + modes[1].rates = os_zalloc(modes[1].num_rates * sizeof(int)); + if (modes[1].channels == NULL || modes[1].rates == NULL) + goto fail; + for (i = 0; i < MAX_NUM_CHANNEL; i++) { + modes[1].channels[i].chan = i + 1; + modes[1].channels[i].freq = 2412 + 5 * i; + modes[1].channels[i].flag = 0; + if (i >= 11) + modes[1].channels[i].flag = HOSTAPD_CHAN_DISABLED; + } + modes[1].rates[0] = 10; + modes[1].rates[1] = 20; + modes[1].rates[2] = 55; + modes[1].rates[3] = 110; + + + //.3 + modes[2].mode = HOSTAPD_MODE_IEEE80211A; +#ifdef CONFIG_DRIVER_RTL_DFS + modes[2].num_channels = MAX_NUM_CHANNEL_5G; +#else /* CONFIG_DRIVER_RTL_DFS */ + modes[2].num_channels = 9; +#endif /* CONFIG_DRIVER_RTL_DFS */ + + modes[2].num_rates = 8; + modes[2].channels = os_zalloc(modes[2].num_channels * sizeof(struct hostapd_channel_data)); + modes[2].rates = os_zalloc(modes[2].num_rates * sizeof(int)); + if (modes[2].channels == NULL || modes[2].rates == NULL) + goto fail; + + + k = 0; + // 5G band1 Channel: 36, 40, 44, 48 + for (i=0; i < 4; i++) { + modes[2].channels[k].chan = 36+(i*4); + modes[2].channels[k].freq = 5180+(i*20); + modes[2].channels[k].flag = 0; + k++; + } + +#ifdef CONFIG_DRIVER_RTL_DFS + // 5G band2 Channel: 52, 56, 60, 64 + for (i=0; i < 4; i++) { + modes[2].channels[k].chan = 52+(i*4); + modes[2].channels[k].freq = 5260+(i*20); + modes[2].channels[k].flag = 0; + k++; + } + + // 5G band3 Channel: 100, 104, 108. 112, 116, 120, 124, 128, 132, 136, 140 + for (i=0; i < 11; i++) { + modes[2].channels[k].chan = 100+(i*4); + modes[2].channels[k].freq = 5500+(i*20); + modes[2].channels[k].flag = 0; + k++; + } +#endif /* CONFIG_DRIVER_RTL_DFS */ + + // 5G band4 Channel: 149, 153, 157, 161, 165 + for (i=0; i < 5; i++) { + modes[2].channels[k].chan = 149+(i*4); + modes[2].channels[k].freq = 5745+(i*20); + modes[2].channels[k].flag = 0; + k++; + } + + modes[2].rates[0] = 60; + modes[2].rates[1] = 90; + modes[2].rates[2] = 120; + modes[2].rates[3] = 180; + modes[2].rates[4] = 240; + modes[2].rates[5] = 360; + modes[2].rates[6] = 480; + modes[2].rates[7] = 540; + + + // +#if 0 +#define HT_CAP_INFO_LDPC_CODING_CAP ((u16) BIT(0)) +#define HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET ((u16) BIT(1)) +#define HT_CAP_INFO_SMPS_MASK ((u16) (BIT(2) | BIT(3))) +#define HT_CAP_INFO_SMPS_STATIC ((u16) 0) +#define HT_CAP_INFO_SMPS_DYNAMIC ((u16) BIT(2)) +#define HT_CAP_INFO_SMPS_DISABLED ((u16) (BIT(2) | BIT(3))) +#define HT_CAP_INFO_GREEN_FIELD ((u16) BIT(4)) +#define HT_CAP_INFO_SHORT_GI20MHZ ((u16) BIT(5)) +#define HT_CAP_INFO_SHORT_GI40MHZ ((u16) BIT(6)) +#define HT_CAP_INFO_TX_STBC ((u16) BIT(7)) +#define HT_CAP_INFO_RX_STBC_MASK ((u16) (BIT(8) | BIT(9))) +#define HT_CAP_INFO_RX_STBC_1 ((u16) BIT(8)) +#define HT_CAP_INFO_RX_STBC_12 ((u16) BIT(9)) +#define HT_CAP_INFO_RX_STBC_123 ((u16) (BIT(8) | BIT(9))) +#define HT_CAP_INFO_DELAYED_BA ((u16) BIT(10)) +#define HT_CAP_INFO_MAX_AMSDU_SIZE ((u16) BIT(11)) +#define HT_CAP_INFO_DSSS_CCK40MHZ ((u16) BIT(12)) +#define HT_CAP_INFO_PSMP_SUPP ((u16) BIT(13)) +#define HT_CAP_INFO_40MHZ_INTOLERANT ((u16) BIT(14)) +#define HT_CAP_INFO_LSIG_TXOP_PROTECT_SUPPORT ((u16) BIT(15)) +#endif + + //HOSTAPD_MODE_IEEE80211G + modes[0].ht_capab = HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET|HT_CAP_INFO_SHORT_GI20MHZ| + HT_CAP_INFO_SHORT_GI40MHZ|HT_CAP_INFO_MAX_AMSDU_SIZE|HT_CAP_INFO_DSSS_CCK40MHZ; + + modes[0].mcs_set[0]= 0xff; + modes[0].mcs_set[1]= 0xff; + + //HOSTAPD_MODE_IEEE80211B + modes[1].ht_capab = 0; + + //HOSTAPD_MODE_IEEE80211A + modes[2].ht_capab = modes[0].ht_capab; + + modes[2].mcs_set[0]= 0xff; + modes[2].mcs_set[1]= 0xff; + + return modes; + +fail: + if (modes) { + for (i = 0; i < *num_modes; i++) { + os_free(modes[i].channels); + os_free(modes[i].rates); + } + os_free(modes); + } + + return NULL; + +} + +#if 0 +static int rtl871x_sta_add_ops(const char *ifname, void *priv, const u8 *addr, + u16 aid, u16 capability, u8 *supp_rates, + size_t supp_rates_len, int flags, + u16 listen_interval) +{ + +#if 1 + printf("+%s, " MACSTR " is new sta address added\n", __func__, MAC2STR(addr)); + return 0; +#else + struct hostap_driver_data *drv = priv; + struct prism2_hostapd_param param; + int tx_supp_rates = 0; + size_t i; + +#define WLAN_RATE_1M BIT(0) +#define WLAN_RATE_2M BIT(1) +#define WLAN_RATE_5M5 BIT(2) +#define WLAN_RATE_11M BIT(3) + + for (i = 0; i < supp_rates_len; i++) { + if ((supp_rates[i] & 0x7f) == 2) + tx_supp_rates |= WLAN_RATE_1M; + if ((supp_rates[i] & 0x7f) == 4) + tx_supp_rates |= WLAN_RATE_2M; + if ((supp_rates[i] & 0x7f) == 11) + tx_supp_rates |= WLAN_RATE_5M5; + if ((supp_rates[i] & 0x7f) == 22) + tx_supp_rates |= WLAN_RATE_11M; + } + + memset(¶m, 0, sizeof(param)); + param.cmd = PRISM2_HOSTAPD_ADD_STA; + memcpy(param.sta_addr, addr, ETH_ALEN); + param.u.add_sta.aid = aid; + param.u.add_sta.capability = capability; + param.u.add_sta.tx_supp_rates = tx_supp_rates; + return hostapd_ioctl(drv, ¶m, sizeof(param)); +#endif +} + +static int rtl871x_sta_add2_ops(const char *ifname, void *priv, + struct hostapd_sta_add_params *params) +{ +#if 0 + ieee_param param; + //int i, tx_supp_rates = 0; + struct rtl871x_driver_data *drv = priv; + + printf("%s\n", __func__); + + memset(¶m, 0, sizeof(param)); + param.cmd = RTL871X_HOSTAPD_ADD_STA; + memcpy(param.sta_addr, params->addr, ETH_ALEN); + param.u.add_sta.aid = params->aid; + param.u.add_sta.capability = params->capability; + param.u.add_sta.flags = params->flags; + + memcpy(param.u.add_sta.tx_supp_rates, params->supp_rates, params->supp_rates_len); + +/* + for (i = 0; i < params->supp_rates_len; i++) + { + if ((params->supp_rates[i] & 0x7f) == IEEE80211_CCK_RATE_1MB) + tx_supp_rates |= IEEE80211_CCK_RATE_1MB_MASK; + if ((params->supp_rates[i] & 0x7f) == IEEE80211_CCK_RATE_2MB) + tx_supp_rates |= IEEE80211_CCK_RATE_2MB_MASK; + if ((params->supp_rates[i] & 0x7f) == IEEE80211_CCK_RATE_5MB) + tx_supp_rates |= IEEE80211_CCK_RATE_5MB_MASK; + if ((params->supp_rates[i] & 0x7f) == IEEE80211_CCK_RATE_11MB) + tx_supp_rates |= IEEE80211_CCK_RATE_11MB_MASK; + + if ((params->supp_rates[i] & 0x7f) == IEEE80211_OFDM_RATE_6MB) + tx_supp_rates |= IEEE80211_OFDM_RATE_6MB_MASK; + if ((params->supp_rates[i] & 0x7f) == IEEE80211_OFDM_RATE_9MB) + tx_supp_rates |= IEEE80211_OFDM_RATE_9MB_MASK; + if ((params->supp_rates[i] & 0x7f) == IEEE80211_OFDM_RATE_12MB) + tx_supp_rates |= IEEE80211_OFDM_RATE_12MB_MASK; + if ((params->supp_rates[i] & 0x7f) == IEEE80211_OFDM_RATE_18MB) + tx_supp_rates |= IEEE80211_OFDM_RATE_18MB_MASK; + + if ((params->supp_rates[i] & 0x7f) == IEEE80211_OFDM_RATE_24MB) + tx_supp_rates |= IEEE80211_OFDM_RATE_24MB_MASK; + if ((params->supp_rates[i] & 0x7f) == IEEE80211_OFDM_RATE_36MB) + tx_supp_rates |= IEEE80211_OFDM_RATE_36MB_MASK; + if ((params->supp_rates[i] & 0x7f) == IEEE80211_OFDM_RATE_48MB) + tx_supp_rates |= IEEE80211_OFDM_RATE_48MB_MASK; + if ((params->supp_rates[i] & 0x7f) == IEEE80211_OFDM_RATE_54MB) + tx_supp_rates |= IEEE80211_OFDM_RATE_54MB_MASK; + + } + + param.u.add_sta.tx_supp_rates = tx_supp_rates; +*/ + +#ifdef CONFIG_IEEE80211N + if (params->ht_capabilities && params->ht_capabilities->length>0) + { + struct ieee80211_ht_capability *pht_cap = (struct ieee80211_ht_capability *)¶ms->ht_capabilities->data; + memcpy((u8*)¶m.u.add_sta.ht_cap, (u8*)pht_cap, sizeof(struct ieee80211_ht_capability)); + + } +#endif /* CONFIG_IEEE80211N */ + + return rtl871x_hostapd_ioctl(drv, ¶m, sizeof(param)); +#else + return 0; +#endif +} +#endif + +static int rtl871x_sta_remove_ops(void *priv, const u8 *addr) +{ + struct rtl871x_driver_data *drv = priv; + struct ieee_param param; + + printf("+%s, " MACSTR " is sta address removed\n", __func__, MAC2STR(addr)); + + //hostap_sta_set_flags(drv, addr, 0, 0, ~WLAN_STA_AUTHORIZED); + + memset(¶m, 0, sizeof(param)); + param.cmd = RTL871X_HOSTAPD_REMOVE_STA; + memcpy(param.sta_addr, addr, ETH_ALEN); + if (rtl871x_hostapd_ioctl(drv, ¶m, sizeof(param))) { + printf("Could not remove station from kernel driver.\n"); + return -1; + } + + return 0; + +} + +#define RTL871X_HIDDEN_SSID_SUPPORT +#ifdef RTL871X_HIDDEN_SSID_SUPPORT +static int rtl871x_set_hidden_ssid_ops(const char *iface, void *priv, u8 value) +{ + int ret; + ieee_param pparam; + struct rtl871x_driver_data *drv = priv; + struct hostapd_data *hapd = drv->hapd; + + printf("%s\n", __func__); + + pparam.cmd = RTL871X_HOSTAPD_SET_HIDDEN_SSID; + pparam.u.wpa_param.name = 0; + pparam.u.wpa_param.value = value; + + ret = rtl871x_hostapd_ioctl(drv, &pparam, sizeof(ieee_param)); + + return ret; +} + +static const u8 * get_ie(u8 *ies, size_t ies_len, u8 id) +{ + const u8 *end, *pos; + + pos = ies; + end = pos + ies_len; + + while (pos + 1 < end) { + if (pos + 2 + pos[1] > end) + break; + + //printf("id:%u, clen:%u\n", pos[0], pos[1]); + + if (pos[0] == id) + return pos; + pos += 2 + pos[1]; + } + + return NULL; +} +#endif //RTL871X_HIDDEN_SSID_SUPPORT + +static int rtl871x_set_beacon_ops(void *priv, struct wpa_driver_ap_params *params) +{ + int ret; + size_t sz; + ieee_param *pparam; + struct rtl871x_driver_data *drv = priv; + struct hostapd_data *hapd = drv->hapd; + + u8 *ssid_ie; + u8 ssid_len; + u8 expend_len = 0; + + if((params->head_len<24) ||(!params->head)) + return -1; + + printf("%s\n", __func__); + + +#ifdef RTL871X_HIDDEN_SSID_SUPPORT + rtl871x_set_hidden_ssid_ops(drv->iface, priv, hapd->conf->ignore_broadcast_ssid); + + ssid_ie = get_ie((params->head+24+12), (params->head_len-24-12), WLAN_EID_SSID); + + if(hapd->conf->ignore_broadcast_ssid == 2) + { + ssid_len = ssid_ie[1]; + + //confirm the ssid_len + if(ssid_len != hapd->conf->ssid.ssid_len) + { + printf("%s ssid_len(%u) != hapd->conf->ssid.ssid_len(%u)!!\n", __func__ + , ssid_len, hapd->conf->ssid.ssid_len + ); + } + + memcpy(ssid_ie+2, hapd->conf->ssid.ssid, ssid_len); + } + else if(hapd->conf->ignore_broadcast_ssid == 1) + { + expend_len = hapd->conf->ssid.ssid_len; + printf("%s ignore_broadcast_ssid:%d, %s,%d, expend_len:%u\n", __func__ + , hapd->conf->ignore_broadcast_ssid + , hapd->conf->ssid.ssid + , hapd->conf->ssid.ssid_len + , expend_len + ); + } +#endif //RTL871X_HIDDEN_SSID_SUPPORT + + sz = params->head_len+params->tail_len+12-24 + 2 + expend_len;// 12+2 = cmd+sta_addr+reserved, sizeof(ieee_param)=64, no packed + pparam = os_zalloc(sz); + if (pparam == NULL) { + return -ENOMEM; + } + + pparam->cmd = RTL871X_HOSTAPD_SET_BEACON; + + memcpy(pparam->u.bcn_ie.reserved, &hapd->conf->max_num_sta, 2);//for set max_num_sta + +#ifdef RTL871X_HIDDEN_SSID_SUPPORT + if(hapd->conf->ignore_broadcast_ssid == 1) + { + u8 *ssid_ie_next = params->head+24+12+2; + size_t head_remain_len = params->head_len-24-12-2; + + memcpy(pparam->u.bcn_ie.buf, (params->head+24), 12); + + pparam->u.bcn_ie.buf[12] = WLAN_EID_SSID; + pparam->u.bcn_ie.buf[13] = expend_len; + memcpy(pparam->u.bcn_ie.buf+12+2, hapd->conf->ssid.ssid, expend_len); + + memcpy(pparam->u.bcn_ie.buf+12+2+expend_len, ssid_ie_next, head_remain_len);// 24=beacon header len. + memcpy(&pparam->u.bcn_ie.buf[params->head_len-24+expend_len], params->tail, params->tail_len); + } + else +#endif //RTL871X_HIDDEN_SSID_SUPPORT + { + memcpy(pparam->u.bcn_ie.buf, (params->head+24), (params->head_len-24));// 24=beacon header len. + memcpy(&pparam->u.bcn_ie.buf[params->head_len-24], params->tail, params->tail_len); + } + + ret = rtl871x_hostapd_ioctl(drv, pparam, sz); + + os_free(pparam); + + //rtl871x_set_max_num_sta(drv); + + return ret; + +} + +/* +enum wpa_alg { + WPA_ALG_NONE, + WPA_ALG_WEP, + WPA_ALG_TKIP, + WPA_ALG_CCMP, + WPA_ALG_IGTK, + WPA_ALG_PMK +}; +*/ +static int rtl871x_set_key_ops(const char *ifname, void *priv, enum wpa_alg alg, + const u8 *addr, int idx, int txkey, const u8 *seq, + size_t seq_len, const u8 *key, size_t key_len) +{ + ieee_param *param; + u8 *buf; + char *alg_str; + size_t blen; + int ret = 0; + struct rtl871x_driver_data *drv = priv; + + printf("%s\n", __func__); + + blen = sizeof(*param) + key_len; + buf = os_zalloc(blen); + if (buf == NULL) + return -1; + + param = (ieee_param *)buf; + param->cmd = RTL871X_SET_ENCRYPTION; + if (addr == NULL) + memset(param->sta_addr, 0xff, ETH_ALEN); + else + memcpy(param->sta_addr, addr, ETH_ALEN); + + + switch (alg) { + case WPA_ALG_NONE: + alg_str = "none"; + break; + case WPA_ALG_WEP: + //cipher = IEEE80211_CIPHER_WEP; + alg_str = "WEP"; + break; + case WPA_ALG_TKIP: + //cipher = IEEE80211_CIPHER_TKIP; + alg_str = "TKIP"; + break; + case WPA_ALG_CCMP: + //cipher = IEEE80211_CIPHER_AES_CCM; + alg_str = "CCMP"; + break; + default: + printf("%s: unknown/unsupported algorithm %d\n", + __func__, alg); + return -1; + } + + os_strlcpy((char *) param->u.crypt.alg, alg_str, + IEEE_CRYPT_ALG_NAME_LEN); + + //param->u.crypt.flags = txkey ? HOSTAP_CRYPT_FLAG_SET_TX_KEY : 0; + param->u.crypt.set_tx = txkey ? 1 : 0; + param->u.crypt.idx = idx; + param->u.crypt.key_len = key_len; + + //memcpy((u8 *) (param + 1), key, key_len); + memcpy(param->u.crypt.key, key, key_len); + + if (rtl871x_hostapd_ioctl(drv, param, blen)) { + printf("Failed to set encryption.\n"); + ret = -1; + } + + os_free(buf); + + return ret; + +} + +/* +static int rtl871x_set_encryption_ops(const char *ifname, void *priv, + const char *alg, const u8 *addr, + int idx, const u8 *key, size_t key_len, + int txkey) +{ + ieee_param *param; + u8 *buf; + size_t blen; + int ret = 0; + struct rtl871x_driver_data *drv = priv; + + printf("%s\n", __func__); +#if 0 + blen = sizeof(*param) + key_len; + buf = os_zalloc(blen); + if (buf == NULL) + return -1; + + param = (ieee_param *)buf; + param->cmd = RTL871X_SET_ENCRYPTION; + if (addr == NULL) + memset(param->sta_addr, 0xff, ETH_ALEN); + else + memcpy(param->sta_addr, addr, ETH_ALEN); + + os_strlcpy((char *) param->u.crypt.alg, alg, + IEEE_CRYPT_ALG_NAME_LEN); + + //param->u.crypt.flags = txkey ? HOSTAP_CRYPT_FLAG_SET_TX_KEY : 0; + param->u.crypt.set_tx = txkey ? 1 : 0; + param->u.crypt.idx = idx; + param->u.crypt.key_len = key_len; + + //memcpy((u8 *) (param + 1), key, key_len); + memcpy(param->u.crypt.key, key, key_len); + + if (rtl871x_hostapd_ioctl(drv, param, blen)) { + printf("Failed to set encryption.\n"); + ret = -1; + } + + os_free(buf); +#endif + return ret; + +} +*/ + +//static int rtl871x_sta_deauth_ops(void *priv, const u8 *addr, int reason) +static int rtl871x_sta_deauth_ops(void *priv, const u8 *own_addr, const u8 *addr, + int reason) +{ + printf("+%s, " MACSTR " is deauth, reason=%d\n", __func__, MAC2STR(addr), reason); + + //struct hostap_driver_data *drv = priv; + struct rtl871x_driver_data *drv = priv; + struct ieee80211_mgmt mgmt; + + memset(&mgmt, 0, sizeof(mgmt)); + mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, + WLAN_FC_STYPE_DEAUTH); + + memcpy(mgmt.da, addr, ETH_ALEN); + //memcpy(mgmt.sa, drv->hapd->own_addr, ETH_ALEN); + //memcpy(mgmt.bssid, drv->hapd->own_addr, ETH_ALEN); + memcpy(mgmt.sa, own_addr, ETH_ALEN); + memcpy(mgmt.bssid, own_addr, ETH_ALEN); + mgmt.u.deauth.reason_code = host_to_le16(reason); + + return rtl871x_send_mgmt_frame_ops(drv, &mgmt, IEEE80211_HDRLEN + + sizeof(mgmt.u.deauth), 0); + +} + + +//static int rtl871x_sta_disassoc_ops(void *priv, const u8 *addr, int reason) +static int rtl871x_sta_disassoc_ops(void *priv, const u8 *own_addr, const u8 *addr, + int reason) +{ + printf("+%s, " MACSTR " is disassoc, reason=%d\n", __func__, MAC2STR(addr), reason); + + struct rtl871x_driver_data *drv = priv; + struct ieee80211_mgmt mgmt; + + memset(&mgmt, 0, sizeof(mgmt)); + mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, + WLAN_FC_STYPE_DISASSOC); + + memcpy(mgmt.da, addr, ETH_ALEN); + //memcpy(mgmt.sa, drv->hapd->own_addr, ETH_ALEN); + //memcpy(mgmt.bssid, drv->hapd->own_addr, ETH_ALEN); + memcpy(mgmt.sa, own_addr, ETH_ALEN); + memcpy(mgmt.bssid, own_addr, ETH_ALEN); + + mgmt.u.disassoc.reason_code = host_to_le16(reason); + + return rtl871x_send_mgmt_frame_ops(drv, &mgmt, IEEE80211_HDRLEN + + sizeof(mgmt.u.disassoc), 0); + +} + +static int rtl871x_set_wps_assoc_resp_ie(struct rtl871x_driver_data *drv, const void *ie, size_t len) +{ + int ret; + size_t sz; + ieee_param *pparam; + + + printf("%s\n", __func__); + + sz = len + 12 + 2;// 12+2 = cmd+sta_addr+reserved, sizeof(ieee_param)=64, no packed + pparam = os_zalloc(sz); + if (pparam == NULL) { + return -ENOMEM; + } + + pparam->cmd = RTL871X_HOSTAPD_SET_WPS_ASSOC_RESP; + + if(ie && len>0) + { + memcpy(pparam->u.bcn_ie.buf, ie, len); + } + + ret = rtl871x_hostapd_ioctl(drv, pparam, sz); + + os_free(pparam); + + return ret; + +} + +static int rtl871x_set_wps_beacon_ie(struct rtl871x_driver_data *drv, const void *ie, size_t len) +{ + int ret; + size_t sz; + ieee_param *pparam; + + + printf("%s\n", __func__); + + sz = len + 12 + 2;// 12+2 = cmd+sta_addr+reserved, sizeof(ieee_param)=64, no packed + pparam = os_zalloc(sz); + if (pparam == NULL) { + return -ENOMEM; + } + + pparam->cmd = RTL871X_HOSTAPD_SET_WPS_BEACON; + + if(ie && len>0) + { + memcpy(pparam->u.bcn_ie.buf, ie, len); + } + + ret = rtl871x_hostapd_ioctl(drv, pparam, sz); + + os_free(pparam); + + return ret; + +} + +static int rtl871x_set_wps_probe_resp_ie(struct rtl871x_driver_data *drv, const void *ie, size_t len) +{ + int ret; + size_t sz; + ieee_param *pparam; + + + printf("%s\n", __func__); + + sz = len + 12 + 2;// 12+2 = cmd+sta_addr+reserved, sizeof(ieee_param)=64, no packed + pparam = os_zalloc(sz); + if (pparam == NULL) { + return -ENOMEM; + } + + pparam->cmd = RTL871X_HOSTAPD_SET_WPS_PROBE_RESP; + + if(ie && len>0) + { + memcpy(pparam->u.bcn_ie.buf, ie, len); + } + + ret = rtl871x_hostapd_ioctl(drv, pparam, sz); + + os_free(pparam); + + return ret; + +} + +static int rtl871x_set_ap_wps_ie(void *priv, const struct wpabuf *beacon, + const struct wpabuf *proberesp, const struct wpabuf *assocresp) +{ + struct rtl871x_driver_data *drv = priv; + + if (rtl871x_set_wps_assoc_resp_ie(drv, assocresp ? wpabuf_head(assocresp) : NULL, + assocresp ? wpabuf_len(assocresp) : 0)) + return -1; + + if (rtl871x_set_wps_beacon_ie(drv, beacon ? wpabuf_head(beacon) : NULL, + beacon ? wpabuf_len(beacon) : 0)) + return -1; + + return rtl871x_set_wps_probe_resp_ie(drv, + proberesp ? wpabuf_head(proberesp) : NULL, + proberesp ? wpabuf_len(proberesp): 0); + +} + +static int rtl871x_sta_flush_ops(void *priv) +{ + ieee_param param; + struct rtl871x_driver_data *drv = priv; + + memset(¶m, 0, sizeof(param)); + + param.cmd = RTL871X_HOSTAPD_FLUSH; + + return rtl871x_hostapd_ioctl(drv, ¶m, sizeof(param)); +} + +static void *rtl871x_driver_init_ops(struct hostapd_data *hapd, struct wpa_init_params *params) +{ + struct rtl871x_driver_data *drv; + struct ifreq ifr; + //struct iwreq iwr; + char ifrn_name[IFNAMSIZ + 1];//for mgnt_l2_sock/mgnt_sock + char brname[IFNAMSIZ]; + + drv = os_zalloc(sizeof(struct rtl871x_driver_data)); + if (drv == NULL) { + printf("Could not allocate memory for rtl871x driver data\n"); + return NULL; + } + + 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; + } + os_memcpy(drv->iface, params->ifname, sizeof(drv->iface)); + + linux_set_iface_flags(drv->ioctl_sock, drv->iface, 1);/*set interface up*/ + + os_memset(&ifr, 0, sizeof(ifr)); + os_strlcpy(ifr.ifr_name, drv->iface, sizeof(ifr.ifr_name)); + if (ioctl(drv->ioctl_sock, SIOCGIFINDEX, &ifr) != 0) { + perror("ioctl(SIOCGIFINDEX)"); + goto bad; + } + drv->ifindex = ifr.ifr_ifindex; + printf("drv->ifindex=%d\n", drv->ifindex); + + drv->l2_sock = l2_packet_init(drv->iface, NULL, ETH_P_EAPOL, + rtl871x_handle_read, drv, 1); + + if (drv->l2_sock == NULL) + goto bad; + + if (l2_packet_get_own_addr(drv->l2_sock, params->own_addr)) + goto bad; + + + if (params->bridge[0]) { + wpa_printf(MSG_DEBUG, "Configure bridge %s for EAPOL traffic.", + params->bridge[0]); + drv->l2_sock_recv = l2_packet_init(params->bridge[0], NULL, + ETH_P_EAPOL, rtl871x_handle_read, drv, + 1); + if (drv->l2_sock_recv == NULL) + { + //goto bad; + drv->l2_sock_recv = drv->l2_sock; + printf("no br0 interface , let l2_sock_recv==l2_sock_xmit=0x%p\n", drv->l2_sock); + } + + } else if (linux_br_get(brname, drv->iface) == 0) { + wpa_printf(MSG_DEBUG, "Interface in bridge %s; configure for " + "EAPOL receive", brname); + drv->l2_sock_recv = l2_packet_init(brname, NULL, ETH_P_EAPOL, + rtl871x_handle_read, drv, 1); + if (drv->l2_sock_recv == NULL) + goto bad; + } + else + { + drv->l2_sock_recv = drv->l2_sock; + printf("l2_sock_recv==l2_sock_xmit=0x%p\n", drv->l2_sock); + } + + + os_memset(ifrn_name, 0, sizeof(ifrn_name)); + //snprintf(ifrn_name, sizeof(ifrn_name), "mgnt.%s_rena", drv->iface); + snprintf(ifrn_name, sizeof(ifrn_name), "mgnt.%s", "wlan0"/*drv->iface*/); +#ifdef CONFIG_MGNT_L2SOCK + drv->mgnt_l2_sock = NULL; + drv->mgnt_l2_sock = l2_packet_init(ifrn_name, NULL, ETH_P_80211_RAW, + rtl871x_recvive_mgmt_frame, drv, 1); + if (drv->mgnt_l2_sock == NULL) + goto bad; + +#else + +#ifdef CONFIG_MLME_OFFLOAD + drv->mgnt_sock = -1; +#else + drv->mgnt_sock = rtl871x_mgnt_sock_init(drv, ifrn_name); + if (drv->mgnt_sock < 0) { + goto bad; + } +#endif + +#endif + + + //madwifi_set_iface_flags(drv, 0); /* mark down during setup */ + //madwifi_set_privacy(drv->iface, drv, 0); /* default to no privacy */ + + + //linux_set_iface_flags(drv->ioctl_sock, drv->iface, 1);/*set interface up*/ + + + //enter MASTER MODE when init. + if(rtl871x_set_mode(drv, IW_MODE_MASTER)<0) + { + printf("Could not set interface to master mode!\n"); + goto bad; + } + +/* + memset(&iwr, 0, sizeof(iwr)); + os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ); + iwr.u.mode = IW_MODE_MASTER; + if (ioctl(drv->ioctl_sock, SIOCSIWMODE, &iwr) < 0) { + perror("ioctl[SIOCSIWMODE]"); + printf("Could not set interface to master mode!\n"); + goto bad; + } +*/ + +#ifndef CONFIG_MLME_OFFLOAD + rtl871x_set_iface_flags(drv, 1); /*set mgnt interface up*/ +#endif + + + if (rtl871x_wireless_event_init(drv)) + goto bad; + + + os_memcpy(drv->hw_mac, params->own_addr, ETH_ALEN); + + return drv; + +bad: + + if (drv->l2_sock_recv != NULL && drv->l2_sock_recv != drv->l2_sock) + l2_packet_deinit(drv->l2_sock_recv); + + if (drv->l2_sock != NULL) + l2_packet_deinit(drv->l2_sock); + + if (drv->ioctl_sock >= 0) + close(drv->ioctl_sock); + +#ifdef CONFIG_MGNT_L2SOCK + if ( drv->mgnt_l2_sock != NULL) + l2_packet_deinit(drv->mgnt_l2_sock); +#else + if (drv->mgnt_sock >= 0) + close(drv->mgnt_sock); +#endif + + if (drv != NULL) + free(drv); + + return NULL; + +} + +static void rtl871x_driver_deinit_ops(void *priv) +{ + //struct iwreq iwr; + struct rtl871x_driver_data *drv = priv; + + //back to INFRA MODE when exit. +/* + memset(&iwr, 0, sizeof(iwr)); + os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ); + iwr.u.mode = IW_MODE_INFRA; + if (ioctl(drv->ioctl_sock, SIOCSIWMODE, &iwr) < 0) { + perror("ioctl[SIOCSIWMODE]"); + } +*/ + rtl871x_set_mode(drv, IW_MODE_INFRA); + + + if (drv->ioctl_sock >= 0) + close(drv->ioctl_sock); + + + if (drv->l2_sock_recv != NULL && drv->l2_sock_recv != drv->l2_sock) + l2_packet_deinit(drv->l2_sock_recv); + + if(drv->l2_sock) + l2_packet_deinit(drv->l2_sock); + + //if (drv->sock_xmit != NULL) + // l2_packet_deinit(drv->sock_xmit); + +#ifdef CONFIG_MGNT_L2SOCK + if (drv->mgnt_l2_sock) + l2_packet_deinit(drv->mgnt_l2_sock); +#else + if (drv->mgnt_sock >= 0) + close(drv->mgnt_sock); +#endif + + os_free(drv); + +} + + +const struct wpa_driver_ops wpa_driver_rtw_ops = { + .name = "rtl871xdrv", + //.init = rtl871x_driver_init_ops, + //.deinit = rtl871x_driver_deinit_ops, + .hapd_init = rtl871x_driver_init_ops, + .hapd_deinit = rtl871x_driver_deinit_ops, + //.wireless_event_init = rtl871x_wireless_event_init_ops, + //.wireless_event_deinit = rtl871x_wireless_event_deinit_ops, + //.send_eapol = rtl871x_send_eapol_ops, + .hapd_send_eapol = rtl871x_send_eapol_ops, + //.send_ether = rtl871x_driver_send_ether_ops, + //.send_mgmt_frame = rtl871x_send_mgmt_frame_ops, + .get_hw_feature_data = rtl871x_get_hw_feature_data_ops, + //.sta_add = rtl871x_sta_add_ops, + //.sta_add2 = rtl871x_sta_add2_ops, + .sta_remove = rtl871x_sta_remove_ops, + .set_ap = rtl871x_set_beacon_ops, + //.set_encryption = rtl871x_set_encryption_ops, + .set_key = rtl871x_set_key_ops, + .sta_deauth = rtl871x_sta_deauth_ops, + .sta_disassoc = rtl871x_sta_disassoc_ops, + //.set_wps_beacon_ie = rtl871x_set_wps_beacon_ie_ops, + //.set_wps_probe_resp_ie = rtl871x_set_wps_probe_resp_ie_ops, + .set_ap_wps_ie = rtl871x_set_ap_wps_ie, + .flush = rtl871x_sta_flush_ops, +}; + diff --git a/config/hostapd.conf b/config/hostapd/hostapd.conf similarity index 100% rename from config/hostapd.conf rename to config/hostapd/hostapd.conf diff --git a/config/hostapd.realtek.conf b/config/hostapd/hostapd.realtek.conf similarity index 100% rename from config/hostapd.realtek.conf rename to config/hostapd/hostapd.realtek.conf diff --git a/config/hostapd/patch/300-noscan.patch b/config/hostapd/patch/300-noscan.patch new file mode 100644 index 000000000..5b30abcc6 --- /dev/null +++ b/config/hostapd/patch/300-noscan.patch @@ -0,0 +1,54 @@ +--- a/hostapd/config_file.c ++++ b/hostapd/config_file.c +@@ -2771,6 +2771,8 @@ static int hostapd_config_fill(struct ho + } + #endif /* CONFIG_IEEE80211W */ + #ifdef CONFIG_IEEE80211N ++ } else if (os_strcmp(buf, "noscan") == 0) { ++ conf->noscan = atoi(pos); + } else if (os_strcmp(buf, "ieee80211n") == 0) { + conf->ieee80211n = atoi(pos); + } else if (os_strcmp(buf, "ht_capab") == 0) { +--- a/src/ap/ap_config.h ++++ b/src/ap/ap_config.h +@@ -619,6 +619,7 @@ struct hostapd_config { + + int ht_op_mode_fixed; + u16 ht_capab; ++ int noscan; + int ieee80211n; + int secondary_channel; + int require_ht; +--- a/src/ap/hw_features.c ++++ b/src/ap/hw_features.c +@@ -461,7 +461,7 @@ static int ieee80211n_check_40mhz(struct + struct wpa_driver_scan_params params; + int ret; + +- if (!iface->conf->secondary_channel) ++ if (!iface->conf->secondary_channel || iface->conf->noscan) + return 0; /* HT40 not used */ + + hostapd_set_state(iface, HAPD_IFACE_HT_SCAN); +--- a/src/ap/ieee802_11_ht.c ++++ b/src/ap/ieee802_11_ht.c +@@ -221,6 +221,9 @@ void hostapd_2040_coex_action(struct hos + if (!(iface->conf->ht_capab & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET)) + return; + ++ if (iface->conf->noscan) ++ return; ++ + if (len < IEEE80211_HDRLEN + 2 + sizeof(*bc_ie)) + return; + +@@ -346,6 +349,9 @@ void ht40_intolerant_add(struct hostapd_ + if (iface->current_mode->mode != HOSTAPD_MODE_IEEE80211G) + return; + ++ if (iface->conf->noscan) ++ return; ++ + wpa_printf(MSG_INFO, "HT: Forty MHz Intolerant is set by STA " MACSTR + " in Association Request", MAC2STR(sta->addr)); + diff --git a/config/hostapd/patch/realtek.patch b/config/hostapd/patch/realtek.patch new file mode 100644 index 000000000..f6052e99d --- /dev/null +++ b/config/hostapd/patch/realtek.patch @@ -0,0 +1,651 @@ +diff --git a/hostapd/main.c b/hostapd/main.c +index a9d7da5..2457f95 100644 +--- a/hostapd/main.c ++++ b/hostapd/main.c +@@ -412,7 +412,7 @@ static int hostapd_global_run(struct hapd_interfaces *ifaces, int daemonize, + static void show_version(void) + { + fprintf(stderr, +- "hostapd v" VERSION_STR "\n" ++ "hostapd v" VERSION_STR " for Realtek rtl871xdrv\n" + "User space daemon for IEEE 802.11 AP management,\n" + "IEEE 802.1X/WPA/WPA2/EAP/RADIUS Authenticator\n" + "Copyright (c) 2002-2014, Jouni Malinen " +diff --git a/src/ap/beacon.c b/src/ap/beacon.c +index 2a4acf2..20d7451 100644 +--- a/src/ap/beacon.c ++++ b/src/ap/beacon.c +@@ -810,6 +810,11 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd, + #ifdef CONFIG_IEEE80211N + tailpos = hostapd_eid_ht_capabilities(hapd, tailpos); + tailpos = hostapd_eid_ht_operation(hapd, tailpos); ++ ++ //DRIVER_RTW ADD ++ if(hapd->iconf->ieee80211n) ++ hapd->conf->wmm_enabled = 1; ++ + #endif /* CONFIG_IEEE80211N */ + + tailpos = hostapd_eid_ext_capab(hapd, tailpos); +diff --git a/src/ap/hw_features.c b/src/ap/hw_features.c +index 4e66d1b..620f246 100644 +--- a/src/ap/hw_features.c ++++ b/src/ap/hw_features.c +@@ -712,7 +712,10 @@ static int ieee80211n_check_40mhz(struct hostapd_iface *iface) + iface->num_ht40_scan_tries = 1; + eloop_cancel_timeout(ap_ht40_scan_retry, iface, NULL); + eloop_register_timeout(1, 0, ap_ht40_scan_retry, iface, NULL); +- return 1; ++ ++ //DRIVER_RTW Modify ++ //return -1; ++ return 0;//ignore this error + } + + if (ret < 0) { +diff --git a/src/drivers/driver_bsd.c b/src/drivers/driver_bsd.c +index ca64d5c..05606f0 100644 +--- a/src/drivers/driver_bsd.c ++++ b/src/drivers/driver_bsd.c +@@ -47,6 +47,12 @@ + + #include "l2_packet/l2_packet.h" + ++#ifdef HOSTAPD ++#ifdef CONFIG_SUPPORT_RTW_DRIVER ++#define RTW_BSD_HOSTAPD_SET_BEACON (1100) ++#endif ++#endif ++ + struct bsd_driver_data { + struct hostapd_data *hapd; /* back pointer */ + +@@ -792,6 +798,296 @@ handle_read(void *ctx, const u8 *src_addr, const u8 *buf, size_t len) + drv_event_eapol_rx(drv->hapd, src_addr, buf, len); + } + ++#ifdef CONFIG_SUPPORT_RTW_DRIVER ++static int rtw_set_beacon_ops(void *priv, const u8 *head, size_t head_len, ++ const u8 *tail, size_t tail_len, int dtim_period, ++ int beacon_int) ++{ ++ int ret=0; ++ u8 *pbuf; ++ size_t sz; ++ struct bsd_driver_data *drv = priv; ++ ++ if((head_len<24) ||(!head)) ++ return -1; ++ ++ sz = head_len+tail_len - 24; // 24 = wlan hdr ++ ++ printf("%s, beacon_sz=%d\n", __func__, sz); ++ ++ pbuf = os_zalloc(sz); ++ if (pbuf == NULL) { ++ return -ENOMEM; ++ } ++ ++ os_memcpy(pbuf, (head+24), (head_len-24));// 24=beacon header len. ++ ++ os_memcpy(&pbuf[head_len-24], tail, tail_len); ++ ++ ret = set80211var(drv, RTW_BSD_HOSTAPD_SET_BEACON, pbuf, sz); ++ ++ os_free(pbuf); ++ ++ return ret; ++ ++} ++ ++static struct hostapd_hw_modes *rtw_get_hw_feature_data_ops( ++ void *priv, u16 *num_modes, u16 *flags) ++{ ++ ++#define MAX_NUM_CHANNEL (14) ++#define MAX_NUM_CHANNEL_5G (24) ++ ++ struct hostapd_hw_modes *modes; ++ size_t i; ++ int k; ++ ++ printf("%s\n", __func__); ++ ++ *num_modes = 3; ++ *flags = 0; ++ ++ modes = os_zalloc(*num_modes * sizeof(struct hostapd_hw_modes)); ++ if (modes == NULL) ++ return NULL; ++ ++ //.1 ++ modes[0].mode = HOSTAPD_MODE_IEEE80211G; ++ modes[0].num_channels = MAX_NUM_CHANNEL; ++ modes[0].num_rates = 12; ++ modes[0].channels = ++ os_zalloc(MAX_NUM_CHANNEL * sizeof(struct hostapd_channel_data)); ++ modes[0].rates = os_zalloc(modes[0].num_rates * sizeof(int)); ++ if (modes[0].channels == NULL || modes[0].rates == NULL) ++ goto fail; ++ for (i = 0; i < MAX_NUM_CHANNEL; i++) { ++ modes[0].channels[i].chan = i + 1; ++ modes[0].channels[i].freq = 2412 + 5 * i; ++ modes[0].channels[i].flag = 0; ++ if (i >= 13) ++ modes[0].channels[i].flag = HOSTAPD_CHAN_DISABLED; ++ } ++ modes[0].rates[0] = 10; ++ modes[0].rates[1] = 20; ++ modes[0].rates[2] = 55; ++ modes[0].rates[3] = 110; ++ modes[0].rates[4] = 60; ++ modes[0].rates[5] = 90; ++ modes[0].rates[6] = 120; ++ modes[0].rates[7] = 180; ++ modes[0].rates[8] = 240; ++ modes[0].rates[9] = 360; ++ modes[0].rates[10] = 480; ++ modes[0].rates[11] = 540; ++ ++ ++ //.2 ++ modes[1].mode = HOSTAPD_MODE_IEEE80211B; ++ modes[1].num_channels = MAX_NUM_CHANNEL; ++ modes[1].num_rates = 4; ++ modes[1].channels = ++ os_zalloc(MAX_NUM_CHANNEL * sizeof(struct hostapd_channel_data)); ++ modes[1].rates = os_zalloc(modes[1].num_rates * sizeof(int)); ++ if (modes[1].channels == NULL || modes[1].rates == NULL) ++ goto fail; ++ for (i = 0; i < MAX_NUM_CHANNEL; i++) { ++ modes[1].channels[i].chan = i + 1; ++ modes[1].channels[i].freq = 2412 + 5 * i; ++ modes[1].channels[i].flag = 0; ++ if (i >= 11) ++ modes[1].channels[i].flag = HOSTAPD_CHAN_DISABLED; ++ } ++ modes[1].rates[0] = 10; ++ modes[1].rates[1] = 20; ++ modes[1].rates[2] = 55; ++ modes[1].rates[3] = 110; ++ ++ ++ //.3 ++ modes[2].mode = HOSTAPD_MODE_IEEE80211A; ++#ifdef CONFIG_DRIVER_RTL_DFS ++ modes[2].num_channels = MAX_NUM_CHANNEL_5G; ++#else /* CONFIG_DRIVER_RTL_DFS */ ++ modes[2].num_channels = 9; ++#endif /* CONFIG_DRIVER_RTL_DFS */ ++ ++ modes[2].num_rates = 8; ++ modes[2].channels = os_zalloc(modes[2].num_channels * sizeof(struct hostapd_channel_data)); ++ modes[2].rates = os_zalloc(modes[2].num_rates * sizeof(int)); ++ if (modes[2].channels == NULL || modes[2].rates == NULL) ++ goto fail; ++ ++ ++ k = 0; ++ // 5G band1 Channel: 36, 40, 44, 48 ++ for (i=0; i < 4; i++) { ++ modes[2].channels[k].chan = 36+(i*4); ++ modes[2].channels[k].freq = 5180+(i*20); ++ modes[2].channels[k].flag = 0; ++ k++; ++ } ++ ++#ifdef CONFIG_DRIVER_RTL_DFS ++ // 5G band2 Channel: 52, 56, 60, 64 ++ for (i=0; i < 4; i++) { ++ modes[2].channels[k].chan = 52+(i*4); ++ modes[2].channels[k].freq = 5260+(i*20); ++ modes[2].channels[k].flag = 0; ++ k++; ++ } ++ ++ // 5G band3 Channel: 100, 104, 108. 112, 116, 120, 124, 128, 132, 136, 140 ++ for (i=0; i < 11; i++) { ++ modes[2].channels[k].chan = 100+(i*4); ++ modes[2].channels[k].freq = 5500+(i*20); ++ modes[2].channels[k].flag = 0; ++ k++; ++ } ++#endif /* CONFIG_DRIVER_RTL_DFS */ ++ ++ // 5G band4 Channel: 149, 153, 157, 161, 165 ++ for (i=0; i < 5; i++) { ++ modes[2].channels[k].chan = 149+(i*4); ++ modes[2].channels[k].freq = 5745+(i*20); ++ modes[2].channels[k].flag = 0; ++ k++; ++ } ++ ++ modes[2].rates[0] = 60; ++ modes[2].rates[1] = 90; ++ modes[2].rates[2] = 120; ++ modes[2].rates[3] = 180; ++ modes[2].rates[4] = 240; ++ modes[2].rates[5] = 360; ++ modes[2].rates[6] = 480; ++ modes[2].rates[7] = 540; ++ ++ ++ // ++#if 0 ++#define HT_CAP_INFO_LDPC_CODING_CAP ((u16) BIT(0)) ++#define HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET ((u16) BIT(1)) ++#define HT_CAP_INFO_SMPS_MASK ((u16) (BIT(2) | BIT(3))) ++#define HT_CAP_INFO_SMPS_STATIC ((u16) 0) ++#define HT_CAP_INFO_SMPS_DYNAMIC ((u16) BIT(2)) ++#define HT_CAP_INFO_SMPS_DISABLED ((u16) (BIT(2) | BIT(3))) ++#define HT_CAP_INFO_GREEN_FIELD ((u16) BIT(4)) ++#define HT_CAP_INFO_SHORT_GI20MHZ ((u16) BIT(5)) ++#define HT_CAP_INFO_SHORT_GI40MHZ ((u16) BIT(6)) ++#define HT_CAP_INFO_TX_STBC ((u16) BIT(7)) ++#define HT_CAP_INFO_RX_STBC_MASK ((u16) (BIT(8) | BIT(9))) ++#define HT_CAP_INFO_RX_STBC_1 ((u16) BIT(8)) ++#define HT_CAP_INFO_RX_STBC_12 ((u16) BIT(9)) ++#define HT_CAP_INFO_RX_STBC_123 ((u16) (BIT(8) | BIT(9))) ++#define HT_CAP_INFO_DELAYED_BA ((u16) BIT(10)) ++#define HT_CAP_INFO_MAX_AMSDU_SIZE ((u16) BIT(11)) ++#define HT_CAP_INFO_DSSS_CCK40MHZ ((u16) BIT(12)) ++#define HT_CAP_INFO_PSMP_SUPP ((u16) BIT(13)) ++#define HT_CAP_INFO_40MHZ_INTOLERANT ((u16) BIT(14)) ++#define HT_CAP_INFO_LSIG_TXOP_PROTECT_SUPPORT ((u16) BIT(15)) ++#endif ++ ++ //HOSTAPD_MODE_IEEE80211G ++ modes[0].ht_capab = HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET|HT_CAP_INFO_SHORT_GI20MHZ| ++ HT_CAP_INFO_SHORT_GI40MHZ|HT_CAP_INFO_MAX_AMSDU_SIZE|HT_CAP_INFO_DSSS_CCK40MHZ; ++ ++ modes[0].mcs_set[0]= 0xff; ++ modes[0].mcs_set[1]= 0xff; ++ ++ //HOSTAPD_MODE_IEEE80211B ++ modes[1].ht_capab = 0; ++ ++ //HOSTAPD_MODE_IEEE80211A ++ modes[2].ht_capab = modes[0].ht_capab; ++ ++ modes[2].mcs_set[0]= 0xff; ++ modes[2].mcs_set[1]= 0xff; ++ ++ return modes; ++ ++fail: ++ if (modes) { ++ for (i = 0; i < *num_modes; i++) { ++ os_free(modes[i].channels); ++ os_free(modes[i].rates); ++ } ++ os_free(modes); ++ } ++ ++ return NULL; ++ ++} ++ ++#if 0 ++#define IEEE80211_FC0_TYPE_MASK 0x0c ++#define IEEE80211_FC0_TYPE_SHIFT 2 ++#define IEEE80211_FC0_TYPE_MGT 0x00 ++#define IEEE80211_FC0_TYPE_CTL 0x04 ++#define IEEE80211_FC0_TYPE_DATA 0x08 ++#define IEEE80211_FC0_SUBTYPE_MASK 0xf0 ++#define IEEE80211_FC0_SUBTYPE_SHIFT 4 ++#define IEEE80211_FC0_SUBTYPE_ASSOC_REQ 0x00 ++#define IEEE80211_FC0_SUBTYPE_ASSOC_RESP 0x10 ++#define IEEE80211_FC0_SUBTYPE_REASSOC_REQ 0x20 ++#define IEEE80211_FC0_SUBTYPE_REASSOC_RESP 0x30 ++#define IEEE80211_FC0_SUBTYPE_PROBE_REQ 0x40 ++#define IEEE80211_FC0_SUBTYPE_PROBE_RESP 0x50 ++#define IEEE80211_FC0_SUBTYPE_BEACON 0x80 ++#define IEEE80211_FC0_SUBTYPE_ATIM 0x90 ++#define IEEE80211_FC0_SUBTYPE_DISASSOC 0xa0 ++#define IEEE80211_FC0_SUBTYPE_AUTH 0xb0 ++#define IEEE80211_FC0_SUBTYPE_DEAUTH 0xc0 ++#define IEEE80211_FC0_SUBTYPE_ACTION 0xd0 ++#define IEEE80211_FC0_SUBTYPE_ACTION_NOACK 0xe0 ++ ++#define IEEE80211_APPIE_WPA (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_BEACON | \ ++ IEEE80211_FC0_SUBTYPE_PROBE_RESP) ++ ++#endif ++ ++#define RTW_IEEE80211_APPIE_BEACON (IEEE80211_FC0_TYPE_MGT|IEEE80211_FC0_SUBTYPE_BEACON) ++#define RTW_IEEE80211_APPIE_PROBE_RESP (IEEE80211_FC0_TYPE_MGT|IEEE80211_FC0_SUBTYPE_PROBE_RESP) ++#define RTW_IEEE80211_APPIE_ASSOC_RESP (IEEE80211_FC0_TYPE_MGT|IEEE80211_FC0_SUBTYPE_ASSOC_RESP) ++ ++ ++static int rtw_set_wps_assoc_resp_ie(void *priv, const void *ie, size_t len) ++{ ++ return bsd_set80211(priv, IEEE80211_IOC_APPIE, RTW_IEEE80211_APPIE_ASSOC_RESP, ++ ie, len); ++} ++ ++static int rtw_set_wps_beacon_ie(void *priv, const void *ie, size_t len) ++{ ++ return bsd_set80211(priv, IEEE80211_IOC_APPIE, RTW_IEEE80211_APPIE_BEACON, ++ ie, len); ++} ++ ++static int rtw_set_wps_probe_resp_ie(void *priv, const void *ie, size_t len) ++{ ++ return bsd_set80211(priv, IEEE80211_IOC_APPIE, RTW_IEEE80211_APPIE_PROBE_RESP, ++ ie, len); ++} ++ ++static int rtw_set_ap_wps_ie_ops(void *priv, const struct wpabuf *beacon, ++ const struct wpabuf *proberesp, const struct wpabuf *assocresp) ++{ ++ if (rtw_set_wps_assoc_resp_ie(priv, assocresp ? wpabuf_head(assocresp) : NULL, ++ assocresp ? wpabuf_len(assocresp) : 0)) ++ return -1; ++ ++ if (rtw_set_wps_beacon_ie(priv, beacon ? wpabuf_head(beacon) : NULL, ++ beacon ? wpabuf_len(beacon) : 0)) ++ return -1; ++ ++ return rtw_set_wps_probe_resp_ie(priv, ++ proberesp ? wpabuf_head(proberesp) : NULL, ++ proberesp ? wpabuf_len(proberesp): 0); ++ ++} ++#endif ++ ++ + static void * + bsd_init(struct hostapd_data *hapd, struct wpa_init_params *params) + { +@@ -844,6 +1140,12 @@ bsd_init(struct hostapd_data *hapd, struct wpa_init_params *params) + goto bad; + } + ++#ifdef CONFIG_SUPPORT_RTW_DRIVER ++ /* mark up after init */ ++ if (bsd_ctrl_iface(drv, 1) < 0) ++ goto bad; ++#endif ++ + return drv; + bad: + if (drv->sock_xmit != NULL) +@@ -1282,6 +1584,15 @@ wpa_driver_bsd_event_receive(int sock, void *ctx, void *sock_ctx) + event.interface_status.ifname); + wpa_supplicant_event(ctx, EVENT_INTERFACE_STATUS, &event); + } ++ else{ ++ os_strlcpy(event.interface_status.ifname, drv->ifname, ++ sizeof(event.interface_status.ifname)); ++ event.interface_status.ievent = EVENT_INTERFACE_ADDED; ++ wpa_printf(MSG_DEBUG, "RTM_IFINFO: Interface '%s' UP", ++ event.interface_status.ifname); ++ wpa_supplicant_event(ctx, EVENT_INTERFACE_STATUS, &event); ++ } ++ + break; + } + } +@@ -1594,7 +1905,52 @@ wpa_driver_bsd_get_capa(void *priv, struct wpa_driver_capa *capa) + } + #endif /* HOSTAPD */ + +- ++#ifdef CONFIG_SUPPORT_RTW_DRIVER ++const struct wpa_driver_ops wpa_driver_bsd_ops = { ++ .name = "bsd", ++ .desc = "BSD 802.11 support", ++#ifdef HOSTAPD ++ .hapd_init = bsd_init, ++ .hapd_deinit = bsd_deinit, ++ .set_privacy = bsd_set_privacy,//del ? ++ .get_seqnum = bsd_get_seqnum,//del ? ++ .flush = bsd_flush, ++ .read_sta_data = bsd_read_sta_driver_data,//del ? ++ .sta_disassoc = bsd_sta_disassoc, ++ .sta_deauth = bsd_sta_deauth, ++ .get_hw_feature_data = rtw_get_hw_feature_data_ops,//add ++ //.sta_remove = rtl871x_sta_remove_ops,//add ++ .set_beacon = rtw_set_beacon_ops, //add ++ .set_ap_wps_ie = rtw_set_ap_wps_ie_ops,//add ++#else /* HOSTAPD */ ++ .init = wpa_driver_bsd_init, ++ .deinit = wpa_driver_bsd_deinit, ++ .get_bssid = wpa_driver_bsd_get_bssid, ++ .get_ssid = wpa_driver_bsd_get_ssid, ++ .set_countermeasures = wpa_driver_bsd_set_countermeasures, ++ .scan2 = wpa_driver_bsd_scan, ++ .get_scan_results2 = wpa_driver_bsd_get_scan_results2, ++ .deauthenticate = wpa_driver_bsd_deauthenticate, ++ .disassociate = wpa_driver_bsd_disassociate, ++ .associate = wpa_driver_bsd_associate, ++ .get_capa = wpa_driver_bsd_get_capa, ++ .set_freq = bsd_set_freq, //only for wpa_supplicant ++ .set_ieee8021x = bsd_set_ieee8021x,//only for wpa_supplicant ++ .hapd_set_ssid = bsd_set_ssid,//only for wpa_supplicant ++ .hapd_get_ssid = bsd_get_ssid,//only for wpa_supplicant ++ .sta_set_flags = bsd_set_sta_authorized, //only for wpa_supplicant ++ .set_generic_elem = bsd_set_opt_ie, //only for wpa_supplicant ++#endif /* HOSTAPD */ ++ //.set_freq = bsd_set_freq, //only for wpa_supplicant ++ .set_key = bsd_set_key, ++ //.set_ieee8021x = bsd_set_ieee8021x, //only for wpa_supplicant ++ //.hapd_set_ssid = bsd_set_ssid, //only for wpa_supplicant ++ //.hapd_get_ssid = bsd_get_ssid, //only for wpa_supplicant ++ .hapd_send_eapol = bsd_send_eapol, //only for wpa_supplicant ++ //.sta_set_flags = bsd_set_sta_authorized, //only for wpa_supplicant ++ //.set_generic_elem = bsd_set_opt_ie, //only for wpa_supplicant ++}; ++#else + const struct wpa_driver_ops wpa_driver_bsd_ops = { + .name = "bsd", + .desc = "BSD 802.11 support", +@@ -1629,3 +1985,4 @@ const struct wpa_driver_ops wpa_driver_bsd_ops = { + .hapd_send_eapol = bsd_send_eapol, + .set_generic_elem = bsd_set_opt_ie, + }; ++#endif +diff --git a/src/drivers/driver_wext.c b/src/drivers/driver_wext.c +index e5734bd..80f073d 100644 +--- a/src/drivers/driver_wext.c ++++ b/src/drivers/driver_wext.c +@@ -990,6 +990,38 @@ void wpa_driver_wext_scan_timeout(void *eloop_ctx, void *timeout_ctx) + wpa_supplicant_event(timeout_ctx, EVENT_SCAN_RESULTS, NULL); + } + ++//added for wps2.0 @20110519 ++static int wpa_driver_wext_set_probe_req_ie(struct wpa_driver_wext_data *drv, const u8 *extra_ies, ++ size_t extra_ies_len) ++{ ++ unsigned char *pbuf; ++ struct iwreq iwr; ++ int ret = 0; ++ ++ pbuf = os_malloc(extra_ies_len); ++ os_memset(pbuf, 0, extra_ies_len); ++ ++ os_memset(&iwr, 0, sizeof(iwr)); ++ os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); ++ ++ os_memcpy(pbuf, extra_ies, extra_ies_len); ++ ++ iwr.u.data.pointer = (caddr_t)pbuf; ++ iwr.u.data.length = extra_ies_len; ++ iwr.u.data.flags = 0x8766;//magic number ++ ++ if (ioctl(drv->ioctl_sock, SIOCSIWPRIV, &iwr) < 0) { ++ perror("ioctl[SIOCSIWMLME]"); ++ ret = -1; ++ } ++ ++ if(pbuf) ++ os_free(pbuf); ++ ++ return ret; ++ ++} ++ + + /** + * wpa_driver_wext_scan - Request the driver to initiate scan +@@ -1012,6 +1044,10 @@ int wpa_driver_wext_scan(void *priv, struct wpa_driver_scan_params *params) + return -1; + } + ++ //added for wps2.0 @20110519 ++ wpa_driver_wext_set_probe_req_ie(drv, params->extra_ies, ++ params->extra_ies_len); ++ + os_memset(&iwr, 0, sizeof(iwr)); + os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); + +@@ -2315,6 +2351,28 @@ static const char * wext_get_radio_name(void *priv) + return drv->phyname; + } + ++// Aries 20120120, append rssi information at the end of "status" command ++int wext_signal_poll(void *priv, struct wpa_signal_info *signal_info) ++{ ++ struct wpa_driver_wext_data *drv = priv; ++ struct iwreq iwr; ++ struct iw_statistics stat; ++ int ret = 0; ++ ++ os_memset(&iwr, 0, sizeof(iwr)); ++ os_memset(&stat, 0, sizeof(stat)); ++ os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); ++ iwr.u.data.pointer = (caddr_t) &stat; ++ iwr.u.data.length = sizeof(struct iw_statistics); ++ iwr.u.data.flags = 1; ++ if (ioctl(drv->ioctl_sock, SIOCGIWSTATS, &iwr) < 0) { ++ perror("ioctl[SIOCGIWSTATS] fail\n"); ++ ret = -1; ++ } ++ signal_info->current_signal = stat.qual.level; ++ signal_info->current_noise = stat.qual.noise; ++ return ret; ++} + + const struct wpa_driver_ops wpa_driver_wext_ops = { + .name = "wext", +diff --git a/src/drivers/drivers.c b/src/drivers/drivers.c +index d0e42ec..d413c00 100644 +--- a/src/drivers/drivers.c ++++ b/src/drivers/drivers.c +@@ -51,6 +51,9 @@ extern struct wpa_driver_ops wpa_driver_atheros_ops; /* driver_atheros.c */ + #ifdef CONFIG_DRIVER_NONE + extern struct wpa_driver_ops wpa_driver_none_ops; /* driver_none.c */ + #endif /* CONFIG_DRIVER_NONE */ ++#ifdef CONFIG_DRIVER_RTW ++extern struct wpa_driver_ops wpa_driver_rtw_ops; /* driver_rtw.c */ ++#endif /* CONFIG_DRIVER_RTW */ + + + struct wpa_driver_ops *wpa_drivers[] = +@@ -94,5 +97,8 @@ struct wpa_driver_ops *wpa_drivers[] = + #ifdef CONFIG_DRIVER_NONE + &wpa_driver_none_ops, + #endif /* CONFIG_DRIVER_NONE */ ++#ifdef CONFIG_DRIVER_RTW ++ &wpa_driver_rtw_ops, ++#endif /* CONFIG_DRIVER_RTW */ + NULL + }; +diff --git a/src/drivers/drivers.mak b/src/drivers/drivers.mak +index 7e175f4..b5881db 100644 +--- a/src/drivers/drivers.mak ++++ b/src/drivers/drivers.mak +@@ -58,6 +58,10 @@ DRV_CFLAGS += -DCONFIG_DRIVER_BSD + DRV_OBJS += ../src/drivers/driver_bsd.o + CONFIG_L2_FREEBSD=y + CONFIG_DNET_PCAP=y ++ifdef CONFIG_SUPPORT_RTW_DRIVER ++DRV_CFLAGS += -DCONFIG_SUPPORT_RTW_DRIVER -DCONFIG_DRIVER_RTL_DFS ++NEED_AP_MLME=y ++endif + endif + + ifdef CONFIG_DRIVER_OPENBSD +@@ -74,6 +78,17 @@ DRV_OBJS += ../src/drivers/driver_test.o + NEED_AP_MLME=y + endif + ++ifdef CONFIG_DRIVER_RTW ++#CFLAGS += -DCONFIG_DRIVER_RTL ++#OBJS += driver_rtl.o ++DRV_AP_CFLAGS += -DCONFIG_DRIVER_RTW -DCONFIG_DRIVER_RTL_DFS ++DRV_AP_OBJS += ../src/drivers/driver_rtw.o ++CONFIG_L2_PACKET=linux ++NEED_NETLINK=y ++NEED_LINUX_IOCTL=y ++NEED_AP_MLME=y ++endif ++ + ifdef CONFIG_DRIVER_NONE + DRV_CFLAGS += -DCONFIG_DRIVER_NONE + DRV_OBJS += ../src/drivers/driver_none.o +diff --git a/src/eap_peer/eap_wsc.c b/src/eap_peer/eap_wsc.c +index 23e9823..173e71d 100644 +--- a/src/eap_peer/eap_wsc.c ++++ b/src/eap_peer/eap_wsc.c +@@ -566,8 +566,13 @@ send_msg: + r = eap_wsc_build_msg(data, ret, id); + if (data->state == FAIL && ret->methodState == METHOD_DONE) { + /* Use reduced client timeout for WPS to avoid long wait */ ++#if 0 /* Aries add, 2012/06/12, extend timeout for AP IOT */ ++ if (sm->ClientTimeout > 4) ++ sm->ClientTimeout = 4; ++#else + if (sm->ClientTimeout > 2) + sm->ClientTimeout = 2; ++#endif + } + return r; + } +diff --git a/src/wps/wps.c b/src/wps/wps.c +index 648cfd1..0a74d0c 100644 +--- a/src/wps/wps.c ++++ b/src/wps/wps.c +@@ -320,11 +320,15 @@ int wps_is_addr_authorized(const struct wpabuf *msg, const u8 *addr, + if (wps_parse_msg(msg, &attr) < 0) + return 0; + ++ return is_selected_pin_registrar(&attr); ++// Marked by Albert 2011/11/17 ++// Some APs won't carry the AuthorizedMACs in the probe response. ++// So, skip this check will speed up the process to find the current AP out for WPS handshake. ++/* + if (!attr.version2 && ver1_compat) { + /* + * Version 1.0 AP - AuthorizedMACs not used, so revert back to + * old mechanism of using SelectedRegistrar. +- */ + return is_selected_pin_registrar(&attr); + } + +@@ -341,6 +345,7 @@ int wps_is_addr_authorized(const struct wpabuf *msg, const u8 *addr, + } + + return 0; ++*/ + } + + +diff --git a/src/wps/wps_registrar.c b/src/wps/wps_registrar.c +index b917e6b..4738fd5 100644 +--- a/src/wps/wps_registrar.c ++++ b/src/wps/wps_registrar.c +@@ -589,9 +589,10 @@ static int wps_build_probe_config_methods(struct wps_registrar *reg, + * These are the methods that the AP supports as an Enrollee for adding + * external Registrars. + */ +- methods = reg->wps->config_methods & ~WPS_CONFIG_PUSHBUTTON; +- methods &= ~(WPS_CONFIG_VIRT_PUSHBUTTON | +- WPS_CONFIG_PHY_PUSHBUTTON); ++ methods = reg->wps->config_methods; ++ //methods = reg->wps->config_methods & ~WPS_CONFIG_PUSHBUTTON; ++ //methods &= ~(WPS_CONFIG_VIRT_PUSHBUTTON | ++ // WPS_CONFIG_PHY_PUSHBUTTON); + wpa_printf(MSG_DEBUG, "WPS: * Config Methods (%x)", methods); + wpabuf_put_be16(msg, ATTR_CONFIG_METHODS); + wpabuf_put_be16(msg, 2); diff --git a/configuration.sh b/configuration.sh index f632d3032..d51970962 100644 --- a/configuration.sh +++ b/configuration.sh @@ -256,6 +256,20 @@ case $BOARD in DESKTOP_TARGET="jessie,default" ;; + nanopim1)#enabled + #description H3 quad core 512Mb SoC + #build 6wip + LINUXFAMILY="sun8i" + BOOTCONFIG="FriendlyARM_NanoPi_M1_defconfig" + MODULES="#gpio_sunxi #w1-sunxi #w1-gpio #w1-therm #ap6211" + MODULES_NEXT="brcmfmac" + CPUMIN="240000" + CPUMAX="1200000" + GOVERNOR="interactive" + CLI_TARGET="%,%" + DESKTOP_TARGET="jessie,default" + ;; + cubox-i)#enabled #description Freescale iMx dual/quad core Wifi #build 6 @@ -648,12 +662,12 @@ PACKAGE_LIST_ADDITIONAL="alsa-utils btrfs-tools bluez hddtemp i2c-tools iperf ir # Release specific packages case $RELEASE in wheezy) - PACKAGE_LIST_RELEASE="less makedev kbd libnl-dev acpid acpi-support-base" + PACKAGE_LIST_RELEASE="less makedev kbd libnl-3-dev acpid acpi-support-base libnl-genl-3-dev" PACKAGE_LIST_EXCLUDE="" ;; jessie) PACKAGE_LIST_RELEASE="less makedev kbd thin-provisioning-tools libnl-3-dev libnl-genl-3-dev libpam-systemd \ - software-properties-common python-software-properties libnss-myhostname f2fs-tools" + software-properties-common python-software-properties libnss-myhostname f2fs-tools libnl-genl-3-dev" PACKAGE_LIST_EXCLUDE="" ;; trusty) diff --git a/distributions.sh b/distributions.sh index 9c0730003..17c2f9f19 100644 --- a/distributions.sh +++ b/distributions.sh @@ -187,8 +187,8 @@ xenial) esac # copy hostapd configurations -install -m 755 $SRC/lib/config/hostapd.conf $CACHEDIR/sdcard/etc/hostapd.conf -install -m 755 $SRC/lib/config/hostapd.realtek.conf $CACHEDIR/sdcard/etc/hostapd.conf-rt +install -m 755 $SRC/lib/config/hostapd/hostapd.conf $CACHEDIR/sdcard/etc/hostapd.conf +install -m 755 $SRC/lib/config/hostapd/hostapd.realtek.conf $CACHEDIR/sdcard/etc/hostapd.conf-rt # console fix due to Debian bug sed -e 's/CHARMAP=".*"/CHARMAP="'$CONSOLE_CHAR'"/g' -i $CACHEDIR/sdcard/etc/default/console-setup diff --git a/extras/hostapd.sh b/extras/hostapd.sh new file mode 100644 index 000000000..198e06405 --- /dev/null +++ b/extras/hostapd.sh @@ -0,0 +1,131 @@ +#!/bin/bash +# +# Copyright (c) 2015 Igor Pecovnik, igor.pecovnik@gma**.com +# +# This file is licensed under the terms of the GNU General Public +# License version 2. This program is licensed "as is" without any +# warranty of any kind, whether express or implied. +# +# This file is a part of tool chain https://github.com/igorpecovnik/lib +# + + +compile_hostapd () +{ + sync + echo "Building hostapd" > $DEST/debug/hostapd-build.log 2>&1 + display_alert "Building deb" "hostapd" "info" + + local tmpdir="sdcard/tmp/hostap" + + if [ -d "$CACHEDIR/$tmpdir" ]; then + cd $CACHEDIR/$tmpdir + git checkout -f -q master >> $DEST/debug/hostapd-build.log 2>&1 + git pull -q + display_alert "Updating sources" "hostapd" "info" + else + display_alert "Downloading sources" "hostapd" "info" + git clone -q git://w1.fi/hostap.git $CACHEDIR/$tmpdir >> $DEST/debug/hostapd-build.log 2>&1 + fi + + + pack_to_deb () + { + cd $CACHEDIR/sdcard/tmp + apt-get -qq -d install hostapd + dpkg-deb -R /var/cache/apt/archives/hostapd* armbian-hostapd${TARGET}"_"${REVISION}_${ARCH} + + # set up control file +cat < armbian-hostapd${TARGET}_${REVISION}_${ARCH}/DEBIAN/control +Package: armbian-hostapd$TARGET +Version: $REVISION +Architecture: $ARCH +Maintainer: $MAINTAINER <$MAINTAINERMAIL> +Installed-Size: 1 +Section: kernel +Conflicts: hostapd +Priority: optional +Description: Patched hostapd +END +# + + cp "$CACHEDIR/$tmpdir/hostapd/hostapd" armbian-hostapd${TARGET}_${REVISION}_${ARCH}/usr/sbin + cp "$CACHEDIR/$tmpdir/hostapd/hostapd-rt" armbian-hostapd${TARGET}_${REVISION}_${ARCH}/usr/sbin + cp "$CACHEDIR/$tmpdir/hostapd/hostapd_cli" armbian-hostapd${TARGET}_${REVISION}_${ARCH}/usr/sbin + cp "$CACHEDIR/$tmpdir/hostapd/hostapd_cli-rt" armbian-hostapd${TARGET}_${REVISION}_${ARCH}/usr/sbin + + cd armbian-hostapd${TARGET}_${REVISION}_${ARCH} + find . -type f ! -regex '.*.hg.*' ! -regex '.*?debian-binary.*' ! -regex '.*?DEBIAN.*' -printf '%P ' | xargs md5sum > DEBIAN/md5sums + cd .. + dpkg -b armbian-hostapd${TARGET}_${REVISION}_${ARCH} >/dev/null 2>&1 + rm -rf armbian-hostapd${TARGET}_${REVISION}_${ARCH} + } + + + compiling () + { + chroot $CACHEDIR/sdcard /bin/bash -c "cd /tmp/hostap/hostapd; make clean" >> $DEST/debug/hostapd-build.log 2>&1 + chroot $CACHEDIR/sdcard /bin/bash -c "cd /tmp/hostap/hostapd; make $CTHREADS" >> $DEST/debug/hostapd-build.log 2>&1 + if [ $? -ne 0 ] || [ ! -f $CACHEDIR/$tmpdir/hostapd/hostapd ]; then + display_alert "Not built" "hostapd" "err" + exit 1 + fi + } + + + patching () + { + # Other usefull patches: + # https://dev.openwrt.org/browser/trunk/package/network/services/hostapd/patches?order=name + + cp $SRC/lib/config/hostapd/files/*.* $CACHEDIR/$tmpdir/src/drivers/ + + # brute force for 40Mhz + if [ "$(patch --dry-run -t -p1 < $SRC/lib/config/hostapd/patch/300-noscan.patch | grep previ)" == "" ]; then + patch --batch -f -p1 < $SRC/lib/config/hostapd/patch/300-noscan.patch >> $DEST/debug/hostapd-build.log 2>&1 + fi + # patch for realtek + if [ "$1" == "realtek" ]; then + cp $SRC/lib/config/hostapd/config/config_realtek $CACHEDIR/$tmpdir/hostapd/.config + patch --batch -f -p1 < $SRC/lib/config/hostapd/patch/realtek.patch >> $DEST/debug/hostapd-build.log 2>&1 + else + cp $SRC/lib/config/hostapd/config/config_default $CACHEDIR/$tmpdir/hostapd/.config + if [ "$(cat $CACHEDIR/$tmpdir/hostapd/main.c | grep rtl871)" != "" ]; then + patch --batch -t -p1 < $SRC/lib/config/hostapd/patch/realtek.patch >> $DEST/debug/hostapd-build.log 2>&1 + fi + fi + } + + + checkout () + { + if [ "$1" == "stable" ]; then + cd $CACHEDIR/$tmpdir + git checkout -f -q "hostap_2_5" >> ../build.log 2>&1 + else + git checkout -f -q >> ../build.log 2>&1 + fi + } + + + + checkout "stable" + local apver=$(cat $CACHEDIR/$tmpdir/src/common/version.h | grep "#define VERSION_STR " | awk '{ print $3 }' | sed 's/\"//g') + + display_alert "Compiling" "v$apver" "info" + + patching + compiling + mv $CACHEDIR/$tmpdir/hostapd/hostapd $CACHEDIR/$tmpdir/hostapd/hostapd-rt + mv $CACHEDIR/$tmpdir/hostapd/hostapd_cli $CACHEDIR/$tmpdir/hostapd/hostapd_cli-rt + checkout "stable" + patching + compiling + pack_to_deb + + display_alert "Installing" "armbian-hostapd${TARGET}_${REVISION}_${ARCH}.deb" "info" + chroot $CACHEDIR/sdcard /bin/bash -c "dpkg -i /tmp/armbian-hostapd${TARGET}_${REVISION}_${ARCH}.deb" >> $DEST/debug/hostapd-build.log 2>&1 + mv $CACHEDIR/sdcard/tmp/armbian-hostapd${TARGET}_${REVISION}_${ARCH}.deb $DEST/debs +} + +compile_hostapd \ No newline at end of file diff --git a/makeboarddeb.sh b/makeboarddeb.sh index 25bbd0779..c64a02676 100644 --- a/makeboarddeb.sh +++ b/makeboarddeb.sh @@ -86,16 +86,12 @@ create_board_package (){ # armbianmonitor (currently only to toggle boot verbosity and log upload) install -m 755 $SRC/lib/scripts/armbianmonitor/armbianmonitor $destination/usr/local/bin - # replace hostapd from latest self compiled & patched - mkdir -p $destination/usr/sbin/ - tar xfz $SRC/lib/bin/hostapd25-rt.tgz -C $destination/usr/sbin/ - tar xfz $SRC/lib/bin/hostapd25.tgz -C $destination/usr/sbin/ - # module evbug is loaded automagically at boot time but we don't want that mkdir -p $destination/etc/modprobe.d/ echo "blacklist evbug" > $destination/etc/modprobe.d/ev-debug-blacklist.conf # script to install to SATA + mkdir -p $destination/usr/sbin/ cp -R $SRC/lib/scripts/nand-sata-install/usr $destination/ chmod +x $destination/usr/lib/nand-sata-install/nand-sata-install.sh ln -s ../lib/nand-sata-install/nand-sata-install.sh $destination/usr/sbin/nand-sata-install