diff --git a/package/lean/mt/drivers/mt7615d/files/lib/netifd/wireless/mt_dbdc.sh b/package/lean/mt/drivers/mt7615d/files/lib/netifd/wireless/mt_dbdc.sh index 394544f52..d6f5ed195 100644 --- a/package/lean/mt/drivers/mt7615d/files/lib/netifd/wireless/mt_dbdc.sh +++ b/package/lean/mt/drivers/mt7615d/files/lib/netifd/wireless/mt_dbdc.sh @@ -5,8 +5,9 @@ # Copyright (c) 2013, Hoowa # Copyright (c) 2015-2017, GuoGuo # Copyright (c) 2020, jjm2473 +# Copyright (c) 2022, nanchuci # -# netifd config script for MT7615 DBDC mode. +# netifd config script for MT7615/MT7915 DBDC mode. # # 嘿,对着屏幕的哥们,为了表示对原作者辛苦工作的尊重,任何引用跟借用都不允许你抹去所有作者的信息,请保留这段话。 # @@ -68,7 +69,10 @@ drv_mt_dbdc_init_device_config() { drv_mt_dbdc_init_iface_config() { config_add_boolean disabled config_add_string mode bssid ssid encryption + config_add_boolean hidden isolate doth ieee80211k + config_add_boolean hidden isolate doth ieee80211v config_add_boolean hidden isolate doth ieee80211r + config_add_boolean hidden isolate doth ieee80211w config_add_string key key1 key2 key3 key4 config_add_string wps config_add_string pin @@ -97,7 +101,7 @@ mt_dbdc_ap_vif_pre_config() { local name="$1" json_select config - json_get_vars disabled encryption key key1 key2 key3 key4 ssid mode wps pin isolate doth hidden disassoc_low_ack rssiassoc ieee80211r macfilter + json_get_vars disabled encryption key key1 key2 key3 key4 ssid mode wps pin isolate doth hidden disassoc_low_ack rssiassoc ieee80211k ieee80211v ieee80211r ieee80211w macfilter json_get_values maclist maclist json_select .. [ "$disabled" == "1" ] && return @@ -192,7 +196,7 @@ mt_dbdc_ap_vif_pre_config() { mt_cmd echo "Interface $ifname now up." mt_cmd iwpriv $ifname set NoForwarding=${isolate:-0} mt_cmd iwpriv $ifname set IEEE80211H=${doth:-0} - if [ "$wps" == "pbc" ] && [ "$encryption" != "none" ]; then + if [ "$wps" == "pbc" ] || [ "$wps" == "pin" ] && [ "$encryption" != "none" ]; then echo "Enable WPS for ${ifname}." mt_cmd iwpriv $ifname set WscConfMode=4 mt_cmd iwpriv $ifname set WscConfStatus=2 @@ -203,7 +207,10 @@ mt_dbdc_ap_vif_pre_config() { fi [ -n "$disassoc_low_ack" ] && [ "$disassoc_low_ack" != "0" ] && mt_cmd iwpriv $ifname set KickStaRssiLow=$disassoc_low_ack [ -n "$rssiassoc" ] && [ "$rssiassoc" != "0" ] && mt_cmd iwpriv $ifname set AssocReqRssiThres=$rssiassoc + [ -n "$ieee80211k" ] && [ "$ieee80211k" != "0" ] && mt_cmd iwpriv $ifname set rrmenable=1 + [ -n "$ieee80211v" ] && [ "$ieee80211v" != "0" ] && mt_cmd iwpriv $ifname set wnmenable=1 [ -n "$ieee80211r" ] && [ "$ieee80211r" != "0" ] && mt_cmd iwpriv $ifname set ftenable=1 + [ -n "$ieee80211w" ] && [ "$ieee80211w" != "0" ] && mt_cmd iwpriv $ifname set pmfenable=1 } mt_dbdc_wds_vif_pre_config() { @@ -272,7 +279,7 @@ mt_dbdc_ap_vif_post_config() { local name="$1" json_select config - json_get_vars disabled encryption key key1 key2 key3 key4 ssid mode wps pin isolate doth hidden disassoc_low_ack rssiassoc ieee80211r + json_get_vars disabled encryption key key1 key2 key3 key4 ssid mode wps pin isolate doth hidden disassoc_low_ack rssiassoc ieee80211k ieee80211v ieee80211r ieee80211w json_select .. [ "$disabled" == "1" ] && return @@ -532,6 +539,10 @@ MacAddress=${macaddr} CountryRegion=${countryregion:-5} CountryRegionABand=${countryregion_a:-7} CountryCode=${country:-CN} +RRMEnable=${RRMEnable:-0};${RRMEnable:-0};${RRMEnable:-0};${RRMEnable:-0} +WNMEnable=${WNMEnable:-0};${WNMEnable:-0};${WNMEnable:-0};${WNMEnable:-0} +FTEnable=${FTEnable:-0};${FTEnable:-0};${FTEnable:-0};${FTEnable:-0} +PMFenable=${PMFenable:-0};${PMFenable:-0};${PMFenable:-0};${PMFenable:-0} WirelessMode=${WirelessMode} G_BAND_256QAM=1 FixedTxMode= @@ -547,8 +558,8 @@ BFBACKOFFenable=0 CalCacheApply=0 DisableOLBC=0 BGProtection=0 -TxAntenna= -RxAntenna= +TxAntenna=${TxAntenna:-2};${TxAntenna:-2};${TxAntenna:-4};${TxAntenna:-4} +RxAntenna=${RxAntenna:-2};${RxAntenna:-2};${RxAntenna:-4};${RxAntenna:-4} TxPreamble=1 RTSThreshold=${rts:-2347} FragThreshold=${frag:-2346} @@ -677,8 +688,8 @@ VHT_STBC=${tx_stbc:-1} VHT_BW_SIGNAL=0 VHT_DisallowNonVHT=${VHT_DisallowNonVHT:-0} VHT_LDPC=${ldpc:-1} -#HT_TxStream=2 -#HT_RxStream=2 +HT_TxStream=2;2;2;2 +HT_RxStream=2;2;2;2 HT_PROTECT=0 HT_DisallowTKIP=${HT_DisallowTKIP:-0} HT_BSSCoexistence=${HT_CE:-1} diff --git a/package/lean/mt/mtkiappd/Makefile b/package/lean/mt/mtkiappd/Makefile new file mode 100644 index 000000000..eb26558ec --- /dev/null +++ b/package/lean/mt/mtkiappd/Makefile @@ -0,0 +1,56 @@ +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=mtkiappd +PKG_VERSION:=1 +PKG_RELEASE:=1 + +PKG_CONFIG_DEPENDS := \ + CONFIG_MTK_CHIP_MT7615E_DBDC \ + CONFIG_PACKAGE_mtkiappd_DUAL_BAND + +include $(INCLUDE_DIR)/package.mk + +define Package/mtkiappd + SECTION:=net + CATEGORY:=Network + TITLE:=MTK 802.11f supporting daemon + DEPENDS:=@TARGET_ramips + SUBMENU:=Wireless +endef + +define Package/mtkiappd/description + Mtkiappd is an optional user space component for MT76xx SoftAP driver. +endef + +define Package/mtkiappd/config +config PACKAGE_mtkiappd_DUAL_BAND + bool "dual band" + depends on MTK_CHIP_MT7615E + default y if TARGET_ramips_mt7621_DEVICE_phicomm_k2p + default y if TARGET_ramips_mt7621_DEVICE_raisecom_msg1500-x-00 + default n +endef + +ifeq ($(CONFIG_PACKAGE_mtkiappd_DUAL_BAND),y) + WIRELESS_IOCTL_PARAM:=-wi ra0 -wi rax0 +else + WIRELESS_IOCTL_PARAM:=-wi ra0 +endif + +define Package/mtkiappd/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_DIR) $(1)/usr/share/mtkiappd + + $(INSTALL_BIN) $(PKG_BUILD_DIR)/mtkiappd $(1)/usr/sbin/ + $(INSTALL_BIN) ./files/mtkiappd.sh $(1)/etc/init.d/mtkiappd + sed -i 's/WIRELESS_IOCTL_PARAM/$(WIRELESS_IOCTL_PARAM)/' $(1)/etc/init.d/mtkiappd + $(INSTALL_DATA) ./files/firewall.include $(1)/usr/share/mtkiappd/ +endef + +$(eval $(call BuildPackage,mtkiappd)) diff --git a/package/lean/mt/mtkiappd/files/README b/package/lean/mt/mtkiappd/files/README new file mode 100644 index 000000000..4f2cce308 --- /dev/null +++ b/package/lean/mt/mtkiappd/files/README @@ -0,0 +1,49 @@ +mtkiappd - user space daemon supported 802.11f protocol + for RTxxxx a/b/g/n SoftAP driver, Ralink Technology, Corp. +================================================================= + +This is the README file for the 802.11f/802.11r/802.11k daemon - mtkiappd, +which comes with RTxxxx SoftAP driver. + + +I. Introduction +================================================================= +mtkiappd is an optional user space component for RTxxxx SoftAP driver. + + +II. 802.11f features in mtkiappd +================================================================= +IEEE Std 802.11F-2003 is a standard for inter-access point protocol(IAPP). +It can handle issues on multi-verder access point interoperability. + +There are three major topics which 802.11f supported, +1. ADD-notify +2. MOVE-notify +3. CACHE-notify + +mtkiappd only supports ADD-notify in current phase due to lack of support from radius server + +There are three major topics which 802.11r supported, +1. Key Distribution Protocol + +There are three major topics which 802.11k supported, +1. Neighbor Report + +Some ethernet card needs special configuration to support multicasting. +Make sure your ethernet card support multicasting + + +III. How to start mtkiappd +================================================================= +Note: the broadcast/netmask address of all AP must be the same. +1. If you want to debug mtkiappd, add CFLAGS with DBG. +2. If you want to extend wifi control interface, + modify "MAX_WIFI_COUNT" in rtmpiapp.h. (default setting is 2) +3. First we need to compile the source code using 'make' command +4. Load RTxxxx SoftAP driver - ex: rt2860ap.ko +5. Manually start mtkiappd, type $mtkiappd +6. For wifi multi-interface, type $mtkiappd -wi ra0 -wi rai0 + + +IV. Reference +IEEE Std 802.11F-2003, IEEE802.11r, IEEE802.11k \ No newline at end of file diff --git a/package/lean/mt/mtkiappd/files/firewall.include b/package/lean/mt/mtkiappd/files/firewall.include new file mode 100644 index 000000000..dd5d387c6 --- /dev/null +++ b/package/lean/mt/mtkiappd/files/firewall.include @@ -0,0 +1,2 @@ +-A INPUT -i br-lan -p tcp --dport 3517 -j ACCEPT +-A INPUT -i br-lan -p udp --dport 3517 -j ACCEPT diff --git a/package/lean/mt/mtkiappd/files/mtkiappd.defaults b/package/lean/mt/mtkiappd/files/mtkiappd.defaults new file mode 100644 index 000000000..183a87133 --- /dev/null +++ b/package/lean/mt/mtkiappd/files/mtkiappd.defaults @@ -0,0 +1,12 @@ +#!/bin/sh + +uci -q batch <<-EOT + delete firewall.mtkiappd + set firewall.mtkiappd=include + set firewall.mtkiappd.type=restore + set firewall.mtkiappd.path=/usr/share/mtkiappd/firewall.include + set firewall.mtkiappd.reload=1 + commit firewall +EOT + +exit 0 diff --git a/package/lean/mt/mtkiappd/files/mtkiappd.sh b/package/lean/mt/mtkiappd/files/mtkiappd.sh new file mode 100644 index 000000000..8c553bdf2 --- /dev/null +++ b/package/lean/mt/mtkiappd/files/mtkiappd.sh @@ -0,0 +1,20 @@ +#!/bin/sh /etc/rc.common + +START=99 +STOP=01 + +USE_PROCD=1 + +start_service() { + procd_open_instance mtkiappd + procd_set_param command /usr/sbin/mtkiappd -e br-lan WIRELESS_IOCTL_PARAM + procd_set_param respawn + procd_set_param netdev br-lan + procd_set_param netdev ra0 + procd_close_instance +} + +reload_service() { + stop + start +} diff --git a/package/lean/mt/mtkiappd/src/Makefile b/package/lean/mt/mtkiappd/src/Makefile new file mode 100644 index 000000000..35cea3e25 --- /dev/null +++ b/package/lean/mt/mtkiappd/src/Makefile @@ -0,0 +1,10 @@ +OBJS = rtmpiapp.o mt_iapp_util.o + +# If you want to debug daemon, uncomment following line +# CFLAGS += -ggdb3 -DDBG + +mtkiappd: $(OBJS) + $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LDLIBS) + +clean: + rm -f core *.o mtkiappd diff --git a/package/lean/mt/mtkiappd/src/iappdefs.h b/package/lean/mt/mtkiappd/src/iappdefs.h new file mode 100644 index 000000000..03a519502 --- /dev/null +++ b/package/lean/mt/mtkiappd/src/iappdefs.h @@ -0,0 +1,128 @@ +/**************************************************************************** + * Ralink Tech Inc. + * Taiwan, R.O.C. + * + * (c) Copyright 2002, Ralink Technology, Inc. + * + * All rights reserved. Ralink's source code is an unpublished work and the + * use of a copyright notice does not imply otherwise. This source code + * contains confidential trade secret material of Ralink Tech. Any attemp + * or participation in deciphering, decoding, reverse engineering or in any + * way altering the source code is stricitly prohibited, unless the prior + * written consent of Ralink Technology, Inc. is obtained. + ***************************************************************************/ + +/**************************************************************************** + + Abstract: + + All related IEEE802.11f IAPP + IEEE802.11r IAPP extension. + +***************************************************************************/ + +#ifndef __IAPP_DEF_H__ +#define __IAPP_DEF_H__ + +/* Some Notes */ + +#define IAPP_DS_LINK_LOST +/* + When an AP continues to accept associations without a link to the DS, + it is a black hole in the WLAN, where STAs associate and cannot + communicate with anything beyond the AP’s BSS. When an AP loses its link + to the DS, it should cease transmitting Beacons, disassociate all + associated stations, and cease responding to Probe Request, + Authentication, and Association Request frames. +*/ + +/* Local use file */ +#define PROC_NET_ARP_PATH "/proc/net/arp" +#define IAPP_PID_BACKUP_FILE "/var/run/mtkiappd.pid" + +/* Definition of IAPP */ +#define IAPP_DAEMON_VERSION "v1.1.0" +#define IAPP_VERSION 0 +//#define IAPP_MULTICAST_ADDR "224.0.1.178" /* used in +// ADD-req frame*/ #define IAPP_MULTICAST_ADDR +//"192.168.15.255" /* used in ADD-req frame*/ + +/* + The UDP Port parameter is the UDP port number to be opened for the IAPP + for transmission and reception of IAPP packets. +*/ +#define IAPP_UDP_PORT 3517 /* used in UDP connection */ + +/* + The TCP Port parameter is the TCP port number that the IAPP entity opens + to listen for new IAPP TCP connections from the IAPP entities of other + APs. +*/ +#define IAPP_TCP_PORT 3517 /* used in TCP connection */ + +/* Message type */ +#define IAPP_ETH_PRO 0xEEEE +#define IAPPMSGQUEID 1 +#define RADIUSMSGQUEID 2 +#define RRB_ETH_PRO 0x890D + +/* Message subtype */ +#define IAPP_OPEN_SERVICE_REQ 0 +#define IAPP_OPEN_SERVICE_RSP 1 +#define IAPP_CLOSE_SERVICE_REQ 2 +#define IAPP_SIGNAL_REQ 3 +#define IAPP_SET_OID_REQ 4 +#define IAPP_QUERY_OID_REQ 5 +#define IAPP_QUERY_OID_RSP 6 + +/* Definition of signal */ +#define IAPP_SIG_NONE 0 +#define IAPP_SIG_ASSOCIATION 1 +#define IAPP_SIG_REASSOCIATION 2 +#define IAPP_SIG_TERMINATE 3 + +/* Definition of IAPP command */ /* reference to IEEE802.11f page 50 */ +#define IAPP_CMD_ADD_NOTIFY 0 /* ADD-notify */ +#define IAPP_CMD_MOVE_NOTIFY 1 /* MOVE-notify */ +#define IAPP_CMD_MOVE_RESPONSE 2 /* MOVE-response */ +#define IAPP_CMD_SEND_SECURITY_BLOCK 3 /* Send-Security-Block */ +#define IAPP_CMD_ACK_SECURITY_BLOCK 4 /* ACK-Security-Block */ +#define IAPP_CMD_CACHE_NOTIFY 5 /* CACHE-notify */ +#define IAPP_CMD_CACHE_RESPONSE 6 /* CACHE-response */ + +#define IAPP_CMD_FT_SEND_SECURITY_BLOCK \ + 50 /* proprietary FT Send-Security-Block */ +#define IAPP_CMD_FT_ACK_SECURITY_BLOCK \ + 51 /* proprietary FT ACK-Security-Block */ + +#define IAPP_CMD_INFO_BROADCAST 60 /* proprietary INFO broadcast */ +#define IAPP_CMD_INFO_REQUEST 61 /* proprietary INFO request */ +#define IAPP_CMD_INFO_RESPONSE 62 /* proprietary INFO response */ + +#define IAPP_CMD_SECURITY_MONITOR 128 /* proprietary, for SM broadcast */ + +/* Definition of event log */ +#define IAPP_MAX_SIZE_OF_EVENT_LOG 1024 + +/* Definition of general */ +#define IAPP_SELECT_TIMEOUT 5 /* unit: second */ + +#define IAPP_MAX_RCV_PKT_SIZE 1600 +#define IAPP_MAX_RCV_PKT_SIZE_SAFE 100 + +#define IAPP_IP_HEADER_OFFSET 14 /* skip MAC header */ +#define IAPP_IP_PROTO_OFFSET 9 +#define IAPP_IP_PROTO_UDP 17 +#define IAPP_UDP_DST_PORT_OFFSET (20 + 2) + +#define IAPP_MAC_IP_UDP_LEN (14 + 20 + 8) + +/* 16 for extra 8B encryption & 8B-align, other 16B for safe */ +#define IAPP_SECURITY_EXTEND_LEN 32 + +#define IAPP_IN +#define IAPP_OUT +#define IAPP_INOUT + +#endif /* __IAPP_DEF_H__ */ + +/* End of iapp_def.h */ diff --git a/package/lean/mt/mtkiappd/src/mt_iapp_util.c b/package/lean/mt/mtkiappd/src/mt_iapp_util.c new file mode 100644 index 000000000..dc5e4b5e2 --- /dev/null +++ b/package/lean/mt/mtkiappd/src/mt_iapp_util.c @@ -0,0 +1,234 @@ +/**************************************************************************** + * Ralink Tech Inc. + * Taiwan, R.O.C. + * + * (c) Copyright 2002, Ralink Technology, Inc. + * + * All rights reserved. Ralink's source code is an unpublished work and the + * use of a copyright notice does not imply otherwise. This source code + * contains confidential trade secret material of Ralink Tech. Any attemp + * or participation in deciphering, decoding, reverse engineering or in any + * way altering the source code is stricitly prohibited, unless the prior + * written consent of Ralink Technology, Inc. is obtained. + ***************************************************************************/ + +/**************************************************************************** + + Abstract: + + All related IEEE802.11f IAPP + IEEE802.11r/11k IAPP extension. + +***************************************************************************/ + +/* Include */ + +#include "iappdefs.h" +#include "rt_config.h" +#include "rt_typedef.h" +#include "rtmpiapp.h" + +VOID os_alloc_mem(UCHAR *pAd, UCHAR **ppMem, UINT32 Size) { + *ppMem = (UCHAR *)malloc(Size); +} + +VOID os_free_mem(UCHAR *pAd, VOID *pMem) { free(pMem); } + +BOOLEAN mt_iapp_get_wifi_iface_mac(RTMP_IAPP *pCtrlBK) { +#ifdef IAPP_OS_LINUX + INT idx; + for (idx = 0; idx < pCtrlBK->IfNameWlanCount; idx++) { + struct ifreq ReqIf; + + NdisZeroMemory(pCtrlBK->IfNameWlanMAC[idx], ETH_ALEN); + NdisCopyMemory(ReqIf.ifr_name, pCtrlBK->IfNameWlanIoctl[idx], IFNAMSIZ); + /* get mac address of the interface */ + if (ioctl(pCtrlBK->SocketIoctl, SIOCGIFHWADDR, &ReqIf) < 0) { + DBGPRINT(RT_DEBUG_ERROR, + ("iapp> %s - Fail to get MAC of IfName[%d]: %s\n", __FUNCTION__, + idx, pCtrlBK->IfNameWlanIoctl[idx])); + return FALSE; + } else { + NdisCopyMemory(pCtrlBK->IfNameWlanMAC[idx], + &ReqIf.ifr_ifru.ifru_hwaddr.sa_data[0], ETH_ALEN); + DBGPRINT(RT_DEBUG_OFF, ("iapp> %s - IfName[%d]: %s\n", __FUNCTION__, idx, + pCtrlBK->IfNameWlanIoctl[idx])); + IAPP_HEX_DUMP("MAC", pCtrlBK->IfNameWlanMAC[idx], ETH_ALEN); + } + } + return TRUE; +#else + return FALSE; +#endif +} + +INT32 mt_iapp_find_ifidx_by_mac(RTMP_IAPP *pCtrlBK, UCHAR *WifiMAC) { + INT32 idx = 0; + + if (WifiMAC == NULL) { + DBGPRINT(RT_DEBUG_OFF, ("iapp> %s - WifiMAC is null.\n", __FUNCTION__)); + return -1; + } + + if (pCtrlBK->IfNameWlanCount < MAX_WIFI_COUNT) { + DBGPRINT(RT_DEBUG_OFF, + ("iapp> %s - pCtrlBK->IfNameWlanCount (%d) is less than %d.\n", + __FUNCTION__, pCtrlBK->IfNameWlanCount, MAX_WIFI_COUNT)); + } + + for (idx = 0; idx < MAX_WIFI_COUNT; idx++) { + if (NdisCompareMemory(WifiMAC, pCtrlBK->IfNameWlanMAC[idx], ETH_ALEN) == + 0) { + return idx; + } + } + + return -1; +} + +VOID mt_iapp_set_daemon_information(RTMP_IAPP *pCtrlBK, pid_t *pPidAuth) { + INT32 ComLen = 0; + INT32 idx = 0; + + for (idx = 0; idx < pCtrlBK->IfNameWlanCount; idx++) { + ComLen = sizeof(INT32); + IAPP_IOCTL_TO_WLAN(pCtrlBK, RT_IOCTL_IAPP, pPidAuth, &ComLen, idx, + RT_SET_IAPP_PID | OID_GET_SET_TOGGLE); +#ifdef FT_KDP_KEY_FROM_DAEMON + ComLen = strlen(pCtrlBK->CommonKey); + IAPP_IOCTL_TO_WLAN(pCtrlBK, RT_IOCTL_IAPP, pCtrlBK->CommonKey, &ComLen, idx, + RT_FT_KEY_SET | OID_GET_SET_TOGGLE); +#endif /* FT_KDP_KEY_FROM_DAEMON */ + } + return; +} + +VOID mt_iapp_ft_client_table_init(RTMP_IAPP *pCtrlBK) { + INT i; + NdisZeroMemory(&pCtrlBK->SelfFtStaTable, sizeof(pCtrlBK->SelfFtStaTable)); + for (i = 0; i < HASH_TABLE_SIZE; i++) + pCtrlBK->SelfFtStaTable.hash[i] = NULL; + return; +} + +FT_CLIENT_INFO *mt_iapp_ft_client_look_up(FT_CLIENT_TABLE *pFtTable, + UCHAR *pAddr) { + ULONG HashIdx; + FT_CLIENT_INFO *ft_entry = NULL; + + HashIdx = MAC_ADDR_HASH_INDEX(pAddr); + ft_entry = pFtTable->hash[HashIdx]; + + while (ft_entry) { + if (NdisCompareMemory(ft_entry->sta_mac, pAddr, ETH_ALEN) == 0) + break; + else + ft_entry = ft_entry->next; + } + + return ft_entry; +} + +FT_CLIENT_INFO *mt_iapp_ft_client_insert(FT_CLIENT_TABLE *pFtTable, + UCHAR *pStaAddr, UCHAR *pApAddr, + INT32 ApIfIdx) { + UCHAR HashIdx; + INT idx = 0; + FT_CLIENT_INFO *ft_entry = NULL; + FT_CLIENT_INFO *current_ft_entry = NULL; + + ft_entry = mt_iapp_ft_client_look_up(pFtTable, pStaAddr); + if (ft_entry) { + /* Update information */ + if (pApAddr) + NdisCopyMemory(ft_entry->ap_mac, pApAddr, ETH_ALEN); + ft_entry->if_idx = ApIfIdx; + ft_entry->used = 1; + return ft_entry; + } + + if (pFtTable->ft_sta_table_size >= MAX_NUM_OF_CLIENT) { + DBGPRINT(RT_DEBUG_ERROR, + ("iapp> %s - FT client table is full. (FtStaTableSize=%d)\n", + __FUNCTION__, pFtTable->ft_sta_table_size)); + return NULL; + } + + for (idx = 0; idx < MAX_NUM_OF_CLIENT; idx++) { + ft_entry = &pFtTable->ft_sta_info[idx]; + if (ft_entry->used) + continue; + if (pStaAddr) + NdisCopyMemory(ft_entry->sta_mac, pStaAddr, ETH_ALEN); + if (pApAddr) + NdisCopyMemory(ft_entry->ap_mac, pApAddr, ETH_ALEN); + ft_entry->if_idx = ApIfIdx; + ft_entry->used = 1; + break; + } + pFtTable->ft_sta_table_size++; + + HashIdx = MAC_ADDR_HASH_INDEX(pStaAddr); + ft_entry->hash_idx = HashIdx; + if (pFtTable->hash[HashIdx] == NULL) + pFtTable->hash[HashIdx] = ft_entry; + else { + current_ft_entry = pFtTable->hash[HashIdx]; + while (current_ft_entry->next != NULL) + current_ft_entry = current_ft_entry->next; + current_ft_entry->next = ft_entry; + } + return ft_entry; +} + +VOID mt_iapp_ft_client_delete(FT_CLIENT_TABLE *pFtTable, UCHAR *pStaAddr) { + UCHAR HashIdx = 0xFF; + FT_CLIENT_INFO *ft_entry = NULL; + FT_CLIENT_INFO *hash_ft_entry = NULL; + FT_CLIENT_INFO *pre_hash_ft_entry = NULL; + + ft_entry = mt_iapp_ft_client_look_up(pFtTable, pStaAddr); + + if (ft_entry == NULL) { + DBGPRINT( + RT_DEBUG_TRACE, + ("iapp> %s - cannot find this entry (%02x:%02x:%02x:%02x:%02x:%02x)\n", + __FUNCTION__, pStaAddr[0], pStaAddr[1], pStaAddr[2], pStaAddr[3], + pStaAddr[4], pStaAddr[5])); + return; + } + + ft_entry->used = 0; + NdisZeroMemory(ft_entry->ap_mac, ETH_ALEN); + NdisZeroMemory(ft_entry->sta_mac, ETH_ALEN); + ft_entry->if_idx = -1; + + HashIdx = ft_entry->hash_idx; + hash_ft_entry = pFtTable->hash[HashIdx]; + pre_hash_ft_entry = NULL; + if (hash_ft_entry != NULL) { + /* update Hash list*/ + do { + if (hash_ft_entry == ft_entry) { + if (pre_hash_ft_entry == NULL) + pFtTable->hash[HashIdx] = ft_entry->next; + else + pre_hash_ft_entry->next = ft_entry->next; + break; + } + + pre_hash_ft_entry = hash_ft_entry; + hash_ft_entry = hash_ft_entry->next; + } while (hash_ft_entry); + } + pFtTable->ft_sta_table_size--; +} + +INT32 mt_iapp_find_ifidx_by_sta_mac(FT_CLIENT_TABLE *pFtTable, UCHAR *pStaMAC) { + FT_CLIENT_INFO *ft_entry = NULL; + ft_entry = mt_iapp_ft_client_look_up(pFtTable, pStaMAC); + if (ft_entry) + return ft_entry->if_idx; + else + return -1; +} +/* End of mt_iapp_util.c */ diff --git a/package/lean/mt/mtkiappd/src/rt_config.h b/package/lean/mt/mtkiappd/src/rt_config.h new file mode 100644 index 000000000..b6e3fdc19 --- /dev/null +++ b/package/lean/mt/mtkiappd/src/rt_config.h @@ -0,0 +1,187 @@ +/**************************************************************************** + * Ralink Tech Inc. + * Taiwan, R.O.C. + * + * (c) Copyright 2002, Ralink Technology, Inc. + * + * All rights reserved. Ralink's source code is an unpublished work and the + * use of a copyright notice does not imply otherwise. This source code + * contains confidential trade secret material of Ralink Tech. Any attemp + * or participation in deciphering, decoding, reverse engineering or in any + * way altering the source code is stricitly prohibited, unless the prior + * written consent of Ralink Technology, Inc. is obtained. + ***************************************************************************/ + +/**************************************************************************** + + Abstract: + + All related IEEE802.11f IAPP + IEEE802.11r IAPP extension. + +***************************************************************************/ + +#ifndef __RT_CONFIG_H__ +#define __RT_CONFIG_H__ + +/* Include Kernel file */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "rt_typedef.h" + +/* Definition of OID to RALINK AP driver */ +#define OID_GET_SET_TOGGLE 0x8000 +#define RT_QUERY_SIGNAL_CONTEXT 0x0402 +#define RT_SET_IAPP_PID 0x0404 +#define RT_SET_APD_PID 0x0405 +#define RT_SET_DEL_MAC_ENTRY 0x0406 +#define RT_QUERY_EVENT_TABLE 0x0407 + +#define RT_SET_FT_STATION_NOTIFY 0x0408 +#define RT_SET_FT_KEY_REQ 0x0409 +#define RT_SET_FT_KEY_RSP 0x040a + +#define RT_FT_KEY_SET 0x040b +#define RT_FT_DATA_ENCRYPT 0x040c +#define RT_FT_DATA_DECRYPT 0x040d +#define RT_FT_NEIGHBOR_REPORT 0x040e +#define RT_FT_NEIGHBOR_REQUEST 0x040f +#define RT_FT_NEIGHBOR_RESPONSE 0x0410 +#define RT_FT_ACTION_FORWARD 0x0411 + +/* File path */ +// #define MSG_FILE "/etc/wireless/mt7615/mtkiappd.dat" +#define EVENT_LOG_FILE "/var/log/mtkiappd.log" + +/* ReDefinition */ +#define NdisZeroMemory(__Dst, __Len) memset(__Dst, 0, __Len) +#define NdisFillMemory(__Dst, __Len, __Val) memset(__Dst, __Val, __Len) +#define NdisMoveMemory(__Dst, __Src, __Len) memmove(__Dst, __Src, __Len) +#define NdisCopyMemory(__Dst, __Src, __Len) memcpy(__Dst, __Src, __Len) +#define NdisCompareMemory(__Dst, __Src, __Len) memcmp(__Dst, __Src, __Len) + +VOID os_alloc_mem(UCHAR *pAd, UCHAR **ppMem, UINT32 Size); +VOID os_free_mem(UCHAR *pAd, VOID *pMem); + +/* Debug flag */ +#define RT_DEBUG_OFF 0 +#define RT_DEBUG_ERROR 1 +#define RT_DEBUG_WARN 2 +#define RT_DEBUG_TRACE 3 +#define RT_DEBUG_INFO 4 + +#define NIC_DBG_STRING (" ") + +#ifdef DBG +#define DBGPRINT(Level, Fmt) \ + { \ + if (Level <= RTDebugLevel) { \ + printf Fmt; \ + } \ + } +#else + +/* no debug information */ +#define DBGPRINT(Level, Fmt) +#endif + +#define MAX_NUM_OF_EVENT 30 /* entry # in EVENT table */ + +typedef struct _RT_802_11_EVENT_LOG { + + ULONG SystemTime; /* timestammp (jiffies) */ + UCHAR TriggerAddr[ETH_ALEN]; + UCHAR DetectorAddr[ETH_ALEN]; + UINT16 Event; /* EVENT_xxx */ +} RT_802_11_EVENT_LOG, *PRT_802_11_EVENT_LOG; + +typedef struct _RT_802_11_EVENT_TABLE { + + ULONG Num; + RT_802_11_EVENT_LOG Log[MAX_NUM_OF_EVENT]; +} RT_802_11_EVENT_TABLE, *PRT_802_11_EVENT_TABLE; + +#define PACKED __attribute__((packed)) + +typedef struct PACKED _FT_KDP_EVT_HEADER { + + UINT32 EventLen; + UINT32 PeerIpAddr; + +} FT_KDP_EVT_HEADER; + +typedef struct PACKED _RT_SIGNAL_STRUC { + + VOID *pNext; /* point to next signal */ + + UINT16 Sequence; + UCHAR MacAddr[ETH_ALEN]; + UCHAR CurrAPAddr[ETH_ALEN]; + +#define FT_KDP_SIG_NOTHING 0x00 /* no signal */ +#define FT_KDP_SIG_IAPP_ASSOCIATION 0x01 /* A station has associated */ +#define FT_KDP_SIG_IAPP_REASSOCIATION 0x02 /* A station has re-associated */ +#define FT_KDP_SIG_TERMINATE 0x03 /* terminate the daemon */ + +#define FT_KDP_SIG_FT_ASSOCIATION 0x50 /* A FT station has associated */ +#define FT_KDP_SIG_FT_REASSOCIATION 0x51 /* A FT station has re-associated */ +#define FT_KDP_SIG_KEY_TIMEOUT 0x52 /* PMK-R1 KEY Timeout */ +#define FT_KDP_SIG_KEY_REQ 0x53 /* Request PMK-R1 KEY from R0KH */ +#define FT_KDP_SIG_ACTION 0x54 /* Forward FT Action frame to DS */ + +#define FT_KDP_SIG_AP_INFO_REQ 0x70 /* request neighbor AP info. */ +#define FT_KDP_SIG_AP_INFO_RSP 0x71 /* response my AP info. */ + +/* FT KDP internal use */ +#define FT_KDP_SIG_KEY_REQ_AUTO 0xA0 /* Request PMK-R1 KEY from R0KH */ +#define FT_KDP_SIG_KEY_RSP_AUTO 0xA1 /* Response PMK-R1 KEY to R1KH */ +#define FT_KDP_SIG_INFO_BROADCAST 0xB0 /* broadcast our AP information */ + +#define FT_KSP_SIG_DEBUG_TRACE 0xC0 /* enable debug flag to TRACE */ + UCHAR Sig; + + UCHAR MacAddrSa[ETH_ALEN]; + + /* IEEE80211R_SUPPORT */ + /* the first 6B are FT_KDP_EVT_HEADER */ + /* + For FT_KDP_SIG_NOTHING: nothing + For FT_KDP_SIG_IAPP_ASSOCIATION:nothing + For FT_KDP_SIG_REASSOCIATION: nothing + For FT_KDP_SIG_TERMINATE: nothing + For FT_KDP_SIG_FT_ASSOCIATION: nothing + FT_KDP_SIG_FT_REASSOCIATION: nothing + For FT_KDP_SIG_KEY_TIMEOUT: it is + For FT_KDP_SIG_KEY_REQ_AUTO: it is FT_KDP_EVT_KEY_REQ + For FT_KDP_SIG_KEY_RSP_AUTO: it is FT_KDP_SIG_KEY_RSP + */ + UCHAR Reserved[3]; /* let Content address four-byte align */ + UCHAR Content[1024]; /* signal content */ + +#define RT_SIGNAL_STRUC_HDR_SIZE (sizeof(RT_SIGNAL_STRUC) - 1024) +} RT_SIGNAL_STRUC, *PRT_SIGNAL_STRUC; + +static INT32 RTDebugLevel = RT_DEBUG_ERROR; + +#endif /* __RT_CONFIG_H__ */ + +/* End of rt_config.h */ diff --git a/package/lean/mt/mtkiappd/src/rt_typedef.h b/package/lean/mt/mtkiappd/src/rt_typedef.h new file mode 100644 index 000000000..e23e035b6 --- /dev/null +++ b/package/lean/mt/mtkiappd/src/rt_typedef.h @@ -0,0 +1,22 @@ +#ifndef __RT_TYPEDEF_H__ +#define __RT_TYPEDEF_H__ + +#include + +typedef enum _BOOLEAN { FALSE = 0, TRUE = 1 } BOOLEAN; + +typedef char CHAR; +typedef int INT; + +typedef int INT32; +typedef int16_t INT16; +typedef uint8_t UCHAR; +typedef uint16_t UINT16; +typedef uint32_t UINT; +typedef uint32_t ULONG; +typedef uint32_t UINT32; + +typedef void VOID; +typedef void *PVOID; + +#endif diff --git a/package/lean/mt/mtkiappd/src/rtmpiapp.c b/package/lean/mt/mtkiappd/src/rtmpiapp.c new file mode 100644 index 000000000..b676c49e9 --- /dev/null +++ b/package/lean/mt/mtkiappd/src/rtmpiapp.c @@ -0,0 +1,3946 @@ +/**************************************************************************** + * Ralink Tech Inc. + * Taiwan, R.O.C. + * + * (c) Copyright 2002, Ralink Technology, Inc. + * + * All rights reserved. Ralink's source code is an unpublished work and the + * use of a copyright notice does not imply otherwise. This source code + * contains confidential trade secret material of Ralink Tech. Any attemp + * or participation in deciphering, decoding, reverse engineering or in any + * way altering the source code is stricitly prohibited, unless the prior + * written consent of Ralink Technology, Inc. is obtained. + ***************************************************************************/ + +/**************************************************************************** + + Abstract: + + All related IEEE802.11f IAPP + IEEE802.11r/11k IAPP extension. + +***************************************************************************/ + +//#define IAPP_EVENT_LOG +//#define IAPP_TEST + +/* Include */ +#include "rtmpiapp.h" +#include "iappdefs.h" +#include "rt_config.h" +#include "rt_typedef.h" + +/* Local Variable */ +#define IAPP_SHOW_IP_HTONL(__IP) \ + (htonl(__IP) >> 24) & 0xFF, (htonl(__IP) >> 16) & 0xFF, \ + (htonl(__IP) >> 8) & 0xFF, (htonl(__IP) & 0xFF) + +#define IAPP_SHOW_IP(__IP) \ + (__IP) & 0xFF, ((__IP) >> 8) & 0xFF, ((__IP) >> 16) & 0xFF, \ + ((__IP) >> 24) & 0xFF + +#define IAPP_IDENTIFIER_GET(__CB) (__CB)->PacketIdentifier++ + +#define IAPP_CMD_BUF_ALLOCATE(__pCmdBuf, __pBufMsg, __BufLen) \ + { \ + if ((__BufLen) > IAPP_MAX_RCV_PKT_SIZE) { \ + printf("iapp> Command Length is too large!\n"); \ + __pBufMsg = NULL; \ + } else \ + __pBufMsg = __pCmdBuf; \ + } + +#define IAPP_RSP_BUF_ALLOCATE(__pRspBuf, __pBufMsg, __BufLen) \ + { \ + if ((__BufLen) > IAPP_MAX_RCV_PKT_SIZE) { \ + printf("iapp> Response Length is too large!\n"); \ + __pBufMsg = NULL; \ + } else \ + __pBufMsg = __pRspBuf; \ + } + +static RTMP_IAPP IAPP_Ctrl_Block; +static UINT32 IAPP_MemAllocNum, IAPP_MemFreeNum; + +/* Local Function */ +#ifdef IAPP_EVENT_LOG +static BOOLEAN IAPP_EventLogClean(VOID); +static BOOLEAN IAPP_EventLogHandle(IAPP_IN PRT_802_11_EVENT_TABLE pEvtTab); +static VOID IAPP_EventLog_Query(VOID); +static VOID IAPP_SM_InfoHandle(IAPP_IN CHAR *pMsg); +#endif // IAPP_EVENT_LOG // + +#if 0 +static BOOLEAN IAPP_IP2MACTransfer( + IAPP_IN UCHAR *pMac, + IAPP_OUT struct in_addr *pApInfo); +#endif + +static BOOLEAN IAPP_ArgumentParse(IAPP_IN RTMP_IAPP *pCtrlBK, + IAPP_IN INT32 Argc, IAPP_IN CHAR *pArgv[]); + +static BOOLEAN IAPP_DSIfInfoGet(IAPP_IN RTMP_IAPP *pCtrlBK); + +BOOLEAN IAPP_IoctlToWLAN(IAPP_IN RTMP_IAPP *pCtrlBK, IAPP_IN INT32 Param, + IAPP_IN CHAR *pData, IAPP_IN INT32 *pDataLen, + IAPP_IN UCHAR ApIdx, IAPP_IN INT32 Flags); +static INT32 IAPP_IPC_MSG_Init(IAPP_IN RTMP_IAPP *pCtrlBK); +static BOOLEAN IAPP_L2UpdateFrameSend(IAPP_IN RTMP_IAPP *pCtrlBK, + IAPP_IN UCHAR *pMac); + +static BOOLEAN IAPP_MsgProcess(IAPP_IN RTMP_IAPP *pCtrlBK, + IAPP_IN INT32 MsgSubType, IAPP_IN UCHAR *pMsg, + IAPP_IN INT32 Len, IAPP_IN INT32 if_idx); + +static VOID IAPP_PID_Backup(IAPP_IN pid_t PID); +static VOID IAPP_PID_Kill(VOID); + +static BOOLEAN IAPP_SIG_Process(IAPP_IN RTMP_IAPP *pCtrlBK, + IAPP_IN UCHAR *WiFiMAC, + IAPP_IN RT_SIGNAL_STRUC *pSig, + IAPP_IN INT32 Len, IAPP_IN UCHAR *pCmdBuf, + IAPP_IN UCHAR *pRspBuf); + +static BOOLEAN IAPP_SocketClose(IAPP_IN RTMP_IAPP *pCtrlBK); +static BOOLEAN IAPP_SocketOpen(IAPP_IN RTMP_IAPP *pCtrlBK); + +static VOID IAPP_Start(IAPP_IN RTMP_IAPP *pCtrlBK); + +#define IAPP_UDP_PACKET_SEND(__pCtrlBK, __pPkt, __Len, __pRspBuf, __IfIdx) \ + IAPP_UDP_PacketSend(__pCtrlBK, (UCHAR *)(__pPkt), (UINT32)(__Len), \ + __pRspBuf, __IfIdx) +static BOOLEAN IAPP_UDP_PacketSend(IAPP_IN RTMP_IAPP *pCtrlBK, + IAPP_IN UCHAR *pPkt, IAPP_IN UINT32 PktLen, + IAPP_IN UCHAR *pRspBuf, + IAPP_IN INT32 if_idx); + +#define IAPP_TCP_PACKET_SEND(__pCtrlBK, __pPkt, __Len, __PeerIP, __FlgUdp, \ + __pRspBuf, __IfIdx) \ + IAPP_TCP_PacketSend(__pCtrlBK, (UCHAR *)(__pPkt), (UINT32)(__Len), __PeerIP, \ + __FlgUdp, __pRspBuf, __IfIdx) +static BOOLEAN IAPP_TCP_PacketSend(IAPP_IN RTMP_IAPP *pCtrlBK, + IAPP_IN UCHAR *pPkt, IAPP_IN UINT32 PktLen, + IAPP_IN UINT32 PeerIP, + IAPP_IN BOOLEAN FlgUsingUdpWhenNoIP, + IAPP_IN UCHAR *pRspBuf, + IAPP_IN INT32 if_idx); + +static VOID IAPP_RcvHandler(IAPP_IN RTMP_IAPP *pCtrlBK, IAPP_IN INT32 Sig); + +#ifdef FT_KDP_FUNC_SOCK_COMM +static VOID IAPP_RcvHandlerRawDrv(IAPP_IN RTMP_IAPP *pCtrlBK, + IAPP_IN UCHAR *pPktBuf, + IAPP_IN UCHAR *pCmdBuf, + IAPP_IN UCHAR *pRspBuf); +static VOID IAPP_RcvHandlerRawRRB(IAPP_IN RTMP_IAPP *pCtrlBK, + IAPP_IN UCHAR *pPktBuf, + IAPP_IN UCHAR *pCmdBuf, + IAPP_IN UCHAR *pRspBuf); + +#ifdef IAPP_OS_VXWORKS +BOOLEAN IAPP_RcvHandlerRawDrvVxWorks(IAPP_IN VOID *pCookie, IAPP_IN long Type, + IAPP_IN M_BLK_ID pMblk, + IAPP_IN LL_HDR_INFO *pLinkHdrInfo, + IAPP_IN VOID *pSpare); +BOOLEAN IAPP_RcvHandlerRawRRBVxWorks(IAPP_IN VOID *pCookie, IAPP_IN long Type, + IAPP_IN M_BLK_ID pMblk, + IAPP_IN LL_HDR_INFO *pLinkHdrInfo, + IAPP_IN VOID *pSpare); +#endif // IAPP_OS_VXWORKS // +#endif // FT_KDP_FUNC_SOCK_COMM // + +static VOID IAPP_RcvHandlerUdp(IAPP_IN RTMP_IAPP *pCtrlBK, + IAPP_IN UCHAR *pPktBuf, IAPP_IN UCHAR *pCmdBuf, + IAPP_IN UCHAR *pRspBuf); +static VOID IAPP_RcvHandlerTcp(IAPP_IN RTMP_IAPP *pCtrlBK, + IAPP_IN UCHAR *pPktBuf, IAPP_IN UCHAR *pCmdBuf, + IAPP_IN UCHAR *pRspBuf); + +static VOID IAPP_RcvHandlerMoveReq(IAPP_IN RTMP_IAPP *pCtrlBK, + IAPP_IN UCHAR *pPktBuf, + IAPP_IN UINT32 PeerIP, + IAPP_IN UCHAR *pCmdBuf, + IAPP_IN UCHAR *pRspBuf); +static VOID IAPP_RcvHandlerSSB(IAPP_IN RTMP_IAPP *pCtrlBK, + IAPP_IN UCHAR *pPktBuf, IAPP_IN UINT32 PeerIP, + IAPP_IN UCHAR *pCmdBuf); +static VOID IAPP_RcvHandlerApInfor(IAPP_IN RTMP_IAPP *pCtrlBK, + IAPP_IN UCHAR Type, IAPP_IN UCHAR *pPktBuf, + IAPP_IN UINT32 PeerIP, + IAPP_IN UCHAR *pCmdBuf, + IAPP_IN INT32 if_idx); + +static VOID IAPP_Usage(VOID); +static VOID IAPP_USR2Handle(IAPP_IN INT32 Sig); +static VOID IAPP_TerminateHandle(IAPP_IN INT32 Sig); + +static VOID FT_KDP_SecurityBlockSend(IAPP_IN RTMP_IAPP *pCtrlBK, + IAPP_IN FT_KDP_EVT_HEADER *pEvtHdr, + IAPP_IN VOID *pEvt, IAPP_IN UCHAR *pRspBuf, + IAPP_IN UCHAR *WifiMAC, + IAPP_IN INT32 if_idx); +static VOID FT_KDP_SecurityBlockAck(IAPP_IN RTMP_IAPP *pCtrlBK, + IAPP_IN FT_KDP_EVT_HEADER *pEvtHdr, + IAPP_IN VOID *pEvt, IAPP_IN UCHAR *pRspBuf, + IAPP_IN INT32 if_idx); +static VOID FT_KDP_InformationRequestSend(IAPP_IN RTMP_IAPP *pCtrlBK, + IAPP_IN FT_KDP_EVT_HEADER *pEvtHdr, + IAPP_IN VOID *pEvt, + IAPP_IN UCHAR *pRspBuf, + IAPP_IN INT32 if_idx); +static VOID FT_KDP_InformationResponseSend(IAPP_IN RTMP_IAPP *pCtrlBK, + IAPP_IN FT_KDP_EVT_HEADER *pEvtHdr, + IAPP_IN VOID *pEvt, + IAPP_IN UCHAR *pRspBuf, + IAPP_IN INT32 if_idx); +static VOID FT_KDP_InformationReportSend(IAPP_IN RTMP_IAPP *pCtrlBK, + IAPP_IN FT_KDP_EVT_HEADER *pEvtHdr, + IAPP_IN VOID *pEvt, + IAPP_IN UCHAR *pRspBuf, + IAPP_IN INT32 if_idx); +static VOID FT_RRB_ActionForward(IAPP_IN RTMP_IAPP *pCtrlBK, + IAPP_IN FT_KDP_EVT_HEADER *pEvtHdr, + IAPP_IN VOID *pEvt, IAPP_IN UINT16 PacketType, + IAPP_IN UCHAR *pMacDa, IAPP_IN UCHAR *pMacSa, + IAPP_IN UCHAR *pMacAp, IAPP_IN UCHAR *pRspBuf, + IAPP_IN INT32 if_idx); + +/* ---------------------------- No Use Function (Backup Use) ---------------- */ + +#ifdef IAPP_EVENT_LOG +/* +======================================================================== +Routine Description: + Clean event log file content. + +Arguments: + None + +Return Value: + None + +Note: + EVENT_LOG_FILE = "/etc/Wireless/RT61AP/RT61APEvt.dat" +======================================================================== +*/ +static BOOLEAN IAPP_EventLogClean(VOID) { + FILE *pFile; + + /* re-open and truncate file to zero length by using "wb" */ + pFile = fopen(EVENT_LOG_FILE, "wb"); + + if (pFile == NULL) { + DBGPRINT(RT_DEBUG_ERROR, + ("iapp> Open eventlog file %s failed!\n", EVENT_LOG_FILE)); + return FALSE; + } /* End of if */ + + fclose(pFile); + return TRUE; +} /* End of IAPP_EventLogClean */ + +/* +======================================================================== +Routine Description: + Write a list events to event log file. + +Arguments: + pEvtTab - event list + +Return Value: + TRUE - write successfully + FALSE - write fail + +Note: +======================================================================== +*/ +static BOOLEAN IAPP_EventLogHandle(IAPP_IN PRT_802_11_EVENT_TABLE pEvtTab) { + FILE *pFile; + INT32 FileLen; + INT32 IdEvt; + + /* for append binary file format */ + pFile = fopen(EVENT_LOG_FILE, "ab"); + if (pFile == NULL) { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> Open eventlog file failed!\n")); + return FALSE; + } /* End of if */ + + FileLen = ftell(pFile); + + if (FileLen > IAPP_MAX_SIZE_OF_EVENT_LOG) { + DBGPRINT(RT_DEBUG_ERROR, + ("iapp> eventlog file size exceeds limitation(FileLen=%d)!\n", + FileLen)); + fclose(pFile); + return FALSE; + } /* End of if */ + + if (pEvtTab->Num > MAX_NUM_OF_EVENT) { + DBGPRINT(RT_DEBUG_ERROR, + ("iapp> eventlog Num exceeds limitation(pEventTab->Num=%d)!\n", + pEvtTab->Num)); + fclose(pFile); + return FALSE; + } /* End of if */ + + for (IdEvt = 0; IdEvt < pEvtTab->Num; IdEvt++) { + if (fwrite(&pEvtTab->Log[IdEvt], sizeof(RT_802_11_EVENT_LOG), 1, pFile) != + 1) { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> File write error!\n")); + } /* End of if */ + + DBGPRINT( + RT_DEBUG_TRACE, + ("iapp> (%d/%d): (Event=0x%x) (D:%02x:%02x:%02x:%02x:%02x:%02x) " + "(T:%02x:%02x:%02x:%02x:%02x:%02x)\n", + IdEvt, pEvtTab->Num, pEvtTab->Log[IdEvt].Event, + pEvtTab->Log[IdEvt].DetectorAddr[0], + pEvtTab->Log[IdEvt].DetectorAddr[1], + pEvtTab->Log[IdEvt].DetectorAddr[2], + pEvtTab->Log[IdEvt].DetectorAddr[3], + pEvtTab->Log[IdEvt].DetectorAddr[4], + pEvtTab->Log[IdEvt].DetectorAddr[5], + pEvtTab->Log[IdEvt].TriggerAddr[0], pEvtTab->Log[IdEvt].TriggerAddr[1], + pEvtTab->Log[IdEvt].TriggerAddr[2], pEvtTab->Log[IdEvt].TriggerAddr[3], + pEvtTab->Log[IdEvt].TriggerAddr[4], + pEvtTab->Log[IdEvt].TriggerAddr[5])); + } /* End of for */ + + fclose(pFile); + return TRUE; +} /* End of IAPP_EventLogHandle */ + +/* +======================================================================== +Routine Description: + Query event log content. + +Arguments: + *pCtrlBK - IAPP control block + +Return Value: + None + +Note: +======================================================================== +*/ +static VOID IAPP_EventLog_Query(IAPP_IN RTMP_IAPP *pCtrlBK) { + CHAR *pEvtBuf; + POID_REQ pOidReq; + + IAPP_MEM_ALLOC(pEvtBuf, sizeof(RT_802_11_EVENT_TABLE)); + if (pEvtBuf == NULL) { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> Out of memory!\n")); + return; + } /* End of if */ + + pOidReq = (POID_REQ)pEvtBuf; + pOidReq->OID = RT_QUERY_EVENT_TABLE; + pOidReq->Len = sizeof(RT_802_11_EVENT_TABLE); + + IAPP_MsgProcess(pCtrlBK, IAPP_QUERY_OID_REQ, pEvtBuf, + sizeof(RT_802_11_EVENT_TABLE)); + IAPP_MEM_FREE(pEvtBuf); +} /* End of IAPP_EventLog_Query */ + +/* +======================================================================== +Routine Description: + Send out private IAPP packet with security management information and + log current security management information to file. + +Arguments: + *pCtrlBK - IAPP control blcok + *pMsg - security management information + +Return Value: + None + +Note: +======================================================================== +*/ +static VOID IAPP_SM_InfoHandle(IAPP_IN RTMP_IAPP *pCtrlBK, IAPP_IN CHAR *pMsg) { + PRT_802_11_EVENT_TABLE pEvtTab; + POID_REQ OID_req_p; + INT32 PktLen; + + OID_req_p = (POID_REQ)pMsg; + + DBGPRINT(RT_DEBUG_TRACE, ("iapp> (Receive IAPP_QUERY_OID_REQ)\n")); + + /* IAPP_IOCTL_TO_WLAN(pCtrlBK, RT_IOCTL_IAPP, + OID_req_p->Buf, &OID_req_p->Len, 0, OID_req_p->OID); */ + + pEvtTab = (PRT_802_11_EVENT_TABLE)OID_req_p->Buf; + + if (OID_req_p->OID == RT_QUERY_EVENT_TABLE) { + if ((OID_req_p->Len == sizeof(RT_802_11_EVENT_TABLE)) && + (pEvtTab->Num != 0)) { + RT_IAPP_SECURITY_MONITOR SM; + + /* just send valid Data, not whole structure */ + PktLen = sizeof(UINT32) + (pEvtTab->Num * sizeof(RT_802_11_EVENT_LOG)); + + SM.IappHeader.Version = 0; + SM.IappHeader.Command = IAPP_CMD_SECURITY_MONITOR; + + /* will be update before send out */ + SM.IappHeader.Identifier = 0; + SM.IappHeader.Length = SWAP_16(sizeof(RT_IAPP_HEADER) + PktLen); + IAPP_MEM_MOVE(&SM.EvtTab, OID_req_p->Buf, PktLen); + + /* send our events to all RALINK IAPP daemons in other AP */ + IAPP_UDP_PACKET_SEND(pCtrlBK, &SM, + (sizeof(RT_IAPP_HEADER) + PktLen, pRspBuf)); + + /* log our events */ + IAPP_EventLogHandle((PRT_802_11_EVENT_TABLE)OID_req_p->Buf); + } else { + DBGPRINT(RT_DEBUG_INFO, + ("iapp> RT_QUERY_EVENT_TABLE invalid or zero in length!\n")); + } /* End of if */ + } /* End of if */ +} /* End of IAPP_SM_InfoHandle */ +#endif // IAPP_EVENT_LOG // + +#if 0 /* no use */ +/* +======================================================================== +Routine Description: + Find the IP address by the AP MAC address. + +Arguments: + *pCtrlBK - IAPP control block + *pMac - the AP MAC address pointer + *pApInfo - the AP address information pointer + +Return Value: + TRUE - open IP/MAC mapping file successfully + FAIL - open fail + +Note: +======================================================================== +*/ +static BOOLEAN IAPP_IP2MACTransfer( + IAPP_IN RTMP_IAPP *pCtrlBK, + IAPP_IN UCHAR *pMac, + IAPP_OUT struct in_addr *pApInfo) +{ + FILE *Fd; + CHAR Buffer[200], Mask[32], DevName[32], Hwa[50], IP[50]; + INT32 Type, Flags, Num; + UCHAR AddrMac[ETH_ALEN]; + + + /* init */ + IAPP_MEM_MOVE(AddrMac, pMac, ETH_ALEN); + + /* + ping to broadcast address to get all neighboring AP MAC address/IP + address (bad method ??? use IARP or Radius Server or manual). + */ + sprintf(Buffer, "%s %d.%d.%d.%d %s %s %s %s", "ping", + IAPP_SHOW_IP_HTONL(pCtrlBK->AddrOwn.s_addr), + "-b", "-q", "-w", "2"); + system(Buffer); + sleep(3); + + /* open proc file: arp table */ + if ((Fd = fopen(PROC_NET_ARP_PATH, "r")) == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> Open proc file failed!\n")); + return FALSE; + } /* End of if */ + + /* bypass header -- read until newline */ + if (fgets(Buffer, sizeof(Buffer), Fd) != (CHAR *) NULL) + { + /* read the ARP cache entries */ + for(; fgets(Buffer, sizeof(Buffer), Fd);) + { + Num = sscanf(Buffer, "%s 0x%x 0x%x %s %s %s\n", + IP, &Type, &Flags, Hwa, Mask, DevName); + if (Num < 4) + break; + /* End of if */ + + /* if device differs, just skip it */ + if (strcmp(DevName, pCtrlBK->IfNameEth) != 0) + continue; /* not same network interface */ + /* End of if */ + + /* compare to find out the match one */ + { + UINT32 Mac0, Mac1, Mac2, Mac3, Mac4, Mac5; /* MAC[0] ~ MAC[5] */ + INT32 Ip0, Ip1, Ip2, Ip3; /* IP[0] ~ IP[3] */ + + sscanf(Hwa, "%x:%x:%x:%x:%x:%x\n", + &Mac0, &Mac1, &Mac2, &Mac3, &Mac4, &Mac5); + + if ((AddrMac[0] == (UCHAR)Mac0) && + (AddrMac[1] == (UCHAR)Mac1) && + (AddrMac[2] == (UCHAR)Mac2) && + (AddrMac[3] == (UCHAR)Mac3) && + (AddrMac[4] == (UCHAR)Mac4) && + (AddrMac[5] == (UCHAR)Mac5)) + { + sscanf(IP, "%d.%d.%d.%d\n", &Ip0, &Ip1, &Ip2, &Ip3); + + pApInfo->s_addr = Ip0 + + (Ip1 << 8) + + (Ip2 << 16) + + (Ip3 << 24); + + DBGPRINT(RT_DEBUG_INFO, ("iapp> Found the ARP entry.\n")); + break; + } /* End of if */ + } + + DBGPRINT(RT_DEBUG_INFO, + ("iapp> IP = %s Type = %d Flags = %d Hwa = %s " + "Mask = %s dev = %s\n", + IP, Type, Flags, Hwa, Mask, DevName)); + } /* End of for(; fgets(Buffer, sizeof(Buffer), Fd);) */ + } /* End of if (fgets(Buffer, sizeof(Buffer), Fd) != (CHAR *) NULL) */ + + /* close proc file */ + fclose(Fd); + return TRUE; +} /* End of IAPP_IP2MACTransfer */ +#endif // #if 0 */ + +/* ---------------------------- PRIVATE Function ---------------------------- */ +/* +======================================================================== +Routine Description: + Dump a buffer content. + +Arguments: + pPromptStr - prompt string + *pSrcBufVA - buffer content + SrcBufLen - display length + +Return Value: + None + +Note: + debug use +======================================================================== +*/ +VOID IAPP_HexDump(IAPP_IN CHAR *pPromptStr, IAPP_IN CHAR *pSrcBufVA, + IAPP_IN UINT32 SrcBufLen) { + CHAR *pChar; + UINT32 IdDump; + + pChar = pSrcBufVA; + printf("%s: %p, len = %d\n", pPromptStr, pSrcBufVA, SrcBufLen); + + for (IdDump = 0; IdDump < SrcBufLen; IdDump++) { + if ((IdDump & 0x0F) == 0) + printf("0x%04x : ", IdDump); + /* End of if */ + + printf("%02x ", ((UCHAR)pChar[IdDump])); + + if ((IdDump & 0x0F) == 15) + printf("\n"); + /* End of if */ + } /* End of for */ + + printf("\n"); +} /* End of IAPP_HexDump */ + +/* +======================================================================== +Routine Description: + Parse SysCmd arguments. + +Arguments: + *pCtrlBK - IAPP Control Block + Argc - argument number + *pArgv[] - arguments + +Return Value: + None + +Note: +======================================================================== +*/ +static BOOLEAN IAPP_ArgumentParse(IAPP_IN RTMP_IAPP *pCtrlBK, + IAPP_IN INT32 Argc, IAPP_IN CHAR *pArgv[]) { +#define IAPP_AGP_CMD_PARSE_NEXT_ONE \ + { \ + Argc--; \ + pArgv++; \ + } + + INT i = 0; + + /* init */ + strcpy(pCtrlBK->IfNameEth, FT_KDP_DEFAULT_IF_ETH); + strcpy(pCtrlBK->IfNameWlan, FT_KDP_DEFAULT_IF_WLAN); + strcpy(pCtrlBK->IfNameWlanIoctl[0], FT_KDP_DEFAULT_IF_WLAN_IOCTL); + +#ifdef FT_KDP_FUNC_PKT_ENCRYPT +#ifdef FT_KDP_KEY_FROM_DAEMON + strcpy(pCtrlBK->CommonKey, FT_KDP_DEFAULT_PTK); +#endif // FT_KDP_KEY_FROM_DAEMON // +#endif // FT_KDP_FUNC_PKT_ENCRYPT // + + /* sanity check */ + if (Argc == 0) + goto label_exit; + /* End of if */ + + /* parse command */ + IAPP_AGP_CMD_PARSE_NEXT_ONE; + + while (Argc > 0) { + if (strncmp(pArgv[0], "-h", 2) == 0) { + IAPP_AGP_CMD_PARSE_NEXT_ONE; + IAPP_Usage(); + return FALSE; + } /* End of if */ + + if (strncmp(pArgv[0], "-e", 2) == 0) { + /* ethernet interface */ + IAPP_AGP_CMD_PARSE_NEXT_ONE; + + if (Argc > 0) { + strcpy(pCtrlBK->IfNameEth, pArgv[0]); + IAPP_AGP_CMD_PARSE_NEXT_ONE; + } /* End of if */ + } else if (strncmp(pArgv[0], "-wi", 3) == 0) { + /* wireless ioctl interface */ + IAPP_AGP_CMD_PARSE_NEXT_ONE; + + if (Argc > 0) { + strcpy(pCtrlBK->IfNameWlanIoctl[pCtrlBK->IfNameWlanCount++], pArgv[0]); + IAPP_AGP_CMD_PARSE_NEXT_ONE; + } /* End of if */ + } else if (strncmp(pArgv[0], "-w", 2) == 0) { + /* wireless interface */ + IAPP_AGP_CMD_PARSE_NEXT_ONE; + + if (Argc > 0) { + strcpy(pCtrlBK->IfNameWlan, pArgv[0]); + IAPP_AGP_CMD_PARSE_NEXT_ONE; + } /* End of if */ + } +#ifdef FT_KDP_FUNC_PKT_ENCRYPT +#ifdef FT_KDP_KEY_FROM_DAEMON + else if (strncmp(pArgv[0], "-k", 2) == 0) { + /* encrypt/decrypt key */ + IAPP_AGP_CMD_PARSE_NEXT_ONE; + + if (Argc > 0) { + if (strlen(pArgv[0]) > IAPP_ENCRYPT_KEY_MAX_SIZE) { + pArgv[0][IAPP_ENCRYPT_KEY_MAX_SIZE] = 0x00; + + DBGPRINT(RT_DEBUG_TRACE, + ("iapp> key length can not be larger than %d!", + IAPP_ENCRYPT_KEY_MAX_SIZE)); + } /* End of if */ + + strcpy(pCtrlBK->CommonKey, pArgv[0]); + IAPP_AGP_CMD_PARSE_NEXT_ONE; + } /* End of if */ + } +#endif // FT_KDP_KEY_FROM_DAEMON // +#endif // FT_KDP_FUNC_PKT_ENCRYPT // + else if (strncmp(pArgv[0], "-d", 2) == 0) { + IAPP_AGP_CMD_PARSE_NEXT_ONE; + RTDebugLevel = atoi(pArgv[0]); + IAPP_AGP_CMD_PARSE_NEXT_ONE; + } else { + IAPP_AGP_CMD_PARSE_NEXT_ONE; + } /* End of if */ + } /* End of while */ + +label_exit: + if (pCtrlBK->IfNameWlanCount == 0) + pCtrlBK->IfNameWlanCount = 1; + DBGPRINT(RT_DEBUG_TRACE, + ("iapp> -e=%s, -w=%s", pCtrlBK->IfNameEth, pCtrlBK->IfNameWlan)); + + for (i = 0; i < pCtrlBK->IfNameWlanCount; i++) { + DBGPRINT(RT_DEBUG_TRACE, (", -wi=%s", pCtrlBK->IfNameWlanIoctl[i])); + } + DBGPRINT(RT_DEBUG_TRACE, + (", IfNameWlanCount = %d\n", pCtrlBK->IfNameWlanCount)); + return TRUE; +} /* End of IAPP_ArgumentParse */ + +/* +======================================================================== +Routine Description: + Get interface information, such as IP, AddrNetmask, broadcast addr, etc. + +Arguments: + *pCtrlBK - IAPP control block + +Return Value: + TRUE - get successfully + FAIL - get fail + +Note: + Only for Ethernet interface of DS (distribution system). +======================================================================== +*/ +static BOOLEAN IAPP_DSIfInfoGet(IAPP_IN RTMP_IAPP *pCtrlBK) { + INT32 SockIf; + struct ifreq ReqIf; + + /* init */ + IAPP_MEM_MOVE(ReqIf.ifr_name, pCtrlBK->IfNameEth, IFNAMSIZ); + + /* open a UDP socket */ + if ((SockIf = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> Open socket failed!\n")); + return FALSE; + } /* End of if */ + + /* get own addr */ + if (ioctl(SockIf, SIOCGIFADDR, (int)&ReqIf) < 0) { + DBGPRINT(RT_DEBUG_ERROR, + ("iapp> Get own address of %s failed!\n", ReqIf.ifr_name)); + goto label_fail; + } /* End of if */ + + IAPP_MEM_MOVE(&pCtrlBK->AddrOwn, + &((struct sockaddr_in *)&ReqIf.ifr_addr)->sin_addr, + sizeof(pCtrlBK->AddrOwn)); + + DBGPRINT(RT_DEBUG_TRACE, ("iapp> own address (%d.%d.%d.%d)\n", + IAPP_SHOW_IP_HTONL(pCtrlBK->AddrOwn.s_addr))); + + /* get broadcast address */ + if (ioctl(SockIf, SIOCGIFBRDADDR, (int)&ReqIf) < 0) { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> Get broadcast address failed!\n")); + goto label_fail; + } /* End of if */ + + IAPP_MEM_MOVE(&pCtrlBK->AddrBroadcast, + &((struct sockaddr_in *)&ReqIf.ifr_addr)->sin_addr, + sizeof(pCtrlBK->AddrBroadcast)); + + /* can not use 255.255.255.255 or we can not send any packet */ + // NdisFillMemory(&pCtrlBK->AddrBroadcast, sizeof(pCtrlBK->AddrBroadcast), + // 0xFF); + + DBGPRINT(RT_DEBUG_TRACE, ("iapp> broadcast address (%d.%d.%d.%d)\n", + IAPP_SHOW_IP_HTONL(pCtrlBK->AddrBroadcast.s_addr))); + + /* get network Mask */ + if (ioctl(SockIf, SIOCGIFNETMASK, (int)&ReqIf) < 0) { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> Get network Mask failed!\n")); + goto label_fail; + } /* End of if */ + + IAPP_MEM_MOVE(&pCtrlBK->AddrNetmask, + &((struct sockaddr_in *)&ReqIf.ifr_addr)->sin_addr, + sizeof(pCtrlBK->AddrNetmask)); + + DBGPRINT(RT_DEBUG_TRACE, ("iapp> network Mask address (%d.%d.%d.%d)\n", + IAPP_SHOW_IP_HTONL(pCtrlBK->AddrNetmask.s_addr))); + + close(SockIf); + return TRUE; + +label_fail: + close(SockIf); + return FALSE; +} /* End of IAPP_DSIfInfoGet */ + +/* +======================================================================== +Routine Description: + Issue a SysCmd to RALINK AP driver. + +Arguments: + *pCtrlBK - the IAPP control block + Param - IOCTL command + *pData - command + *pDataLen - command length + ApIdx - BSS index + Flags - IOCTL sub-command + +Return Value: + Ret + +Note: +======================================================================== +*/ +BOOLEAN IAPP_IoctlToWLAN(IAPP_IN RTMP_IAPP *pCtrlBK, IAPP_IN INT32 Param, + IAPP_IN CHAR *pData, IAPP_IN INT32 *pDataLen, + IAPP_IN UCHAR ApIdx, IAPP_IN INT32 Flags) { + CHAR IfName[12]; /* in VxWorks, no iwreq.ifr_name */ + struct iwreq Wrq; + +#ifdef IAPP_OS_LINUX + if (strlen(pCtrlBK->IfNameWlanIoctl[ApIdx]) >= sizeof(IfName)) + strcpy(IfName, FT_KDP_DEFAULT_IF_WLAN_IOCTL); + else + strcpy(IfName, pCtrlBK->IfNameWlanIoctl[ApIdx]); + /* End of if */ + + /* sprintf(IfName, "ra%d", ApIdx); + IfName[3] = '\0'; */ + strcpy(Wrq.ifr_name, IfName); +#endif + + Wrq.u.data.flags = Flags; + Wrq.u.data.length = *pDataLen; + Wrq.u.data.pointer = (caddr_t)pData; + + DBGPRINT(RT_DEBUG_ERROR, ("iapp>[%s]IOCTL Flags = 0x%x!\n", IfName, Flags)); + +#ifdef IAPP_OS_LINUX + if (ioctl(pCtrlBK->SocketIoctl, Param, (int)&Wrq) < 0) { + DBGPRINT(RT_DEBUG_ERROR, + ("iapp> IOCTL 0x%x to wlan %s failed!\n", Flags, IfName)); + return FALSE; + } /* End of if */ +#endif // IAPP_OS_LINUX // + +#ifdef IAPP_OS_VXWORKS + if (muxIoctl(pCtrlBK->pDrvCookieTo, Param, (caddr_t)&Wrq) == ERROR) { + DBGPRINT(RT_DEBUG_ERROR, + ("iapp> IOCTL 0x%x to wlan %s failed!\n", Param, IfName)); + return FALSE; + } /* End of if */ +#endif // IAPP_OS_VXWORKS // + + *pDataLen = Wrq.u.data.length; + return TRUE; +} /* End of IAPP_IoctlToWLAN */ + +/* +======================================================================== +Routine Description: + Initialize IPC message control. + +Arguments: + *pCtrlBK - IAPP control blcok + +Return Value: + TRUE - always successfully + +Note: + IPC related SysCmd- + ipcs, ipcrm, msgget, msgsnd, msgrcv, msgctl +======================================================================== +*/ +static INT32 IAPP_IPC_MSG_Init(IAPP_IN RTMP_IAPP *pCtrlBK) { +#if 0 + INT32 Key = 0x55116604; + + + /* + Translate an unique Key from our dat file, the Key is fixed for + a fixed file content. + */ + if ((Key = ftok(MSG_FILE, 0xf)) == -1) + { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> ftok Error!\n")); + exit(-1); + } /* End of if */ + + if ((pCtrlBK->MsgId = msgget(Key, 0)) == -1) + { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> msgget Error:%s\n", strerror(errno))); + exit(-1); + } /* End of if */ + + pCtrlBK->FlgIsMsgReady = FALSE; +#endif + + pCtrlBK->PacketIdentifier = 0; + return TRUE; +} /* End of IAPP_IPC_MSG_Init */ + +/* +======================================================================== +Routine Description: + Send Layer 2 Update Frame to update forwarding table in Layer 2 devices. + +Arguments: + *pCtrlBK - IAPP control blcok + *pMac - the STATION MAC address pointer + +Return Value: + TRUE - send successfully + FAIL - send fail + +Note: +======================================================================== +*/ +static BOOLEAN IAPP_L2UpdateFrameSend(IAPP_IN RTMP_IAPP *pCtrlBK, + IAPP_IN UCHAR *pMac) { + RT_IAPP_L2_UPDATE_FRAME FrameBody, *pFrameL2; + INT32 Status; + + /* init the update frame body */ + pFrameL2 = &FrameBody; + + IAPP_MEM_ZERO(pFrameL2, sizeof(FrameBody)); + IAPP_MEM_FILL(pFrameL2->ETH.DA, 0xFF, ETH_ALEN); + IAPP_MEM_MOVE(pFrameL2->ETH.SA, pMac, ETH_ALEN); + + pFrameL2->ETH.Len = htons(8); + pFrameL2->DSAP = 0; + pFrameL2->SSAP = 0x01; + pFrameL2->Control = 0xAF; + + pFrameL2->XIDInfo[0] = 0x81; + pFrameL2->XIDInfo[1] = 1; + pFrameL2->XIDInfo[2] = 1 << 1; + +#ifdef IAPP_OS_LINUX + /* send the update frame */ + Status = send(pCtrlBK->SocketRawBr, pFrameL2, sizeof(FrameBody), 0); + if (Status < 0) { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> Send L2 packet failed %d!\n", Status)); + return FALSE; + } /* End of if */ +#endif + +#ifdef IAPP_OS_VXWORKS + { + M_BLK_ID pUpdatePkt; + UINT32 IdIfNum; + + /* loop for eth0, eth1, eth2...... */ + for (IdIfNum = 0; IdIfNum < FT_KDP_BR_ETH_IF_NUM; IdIfNum++) { + if ((pUpdatePkt = netTupleGet(_pNetDpool, sizeof(FrameBody), M_DONTWAIT, + MT_DATA, TRUE)) == NULL) { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> Get packet buffer fail!\n")); + return FALSE; + } /* End of if */ + + pUpdatePkt->mBlkHdr.mFlags |= M_PKTHDR; + pUpdatePkt->m_len = sizeof(FrameBody); + + IAPP_MEM_MOVE(pUpdatePkt->m_data, pFrameL2, sizeof(FrameBody)); + + if (muxSend(pCtrlBK->pBcCookie[IdIfNum], pUpdatePkt) == ERROR) { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> Send L2 packet failed!\n")); + netMblkClChainFree(pUpdatePkt); + return FALSE; + } /* End of if */ + } /* End of for */ + + DBGPRINT(RT_DEBUG_TRACE, ("iapp> Send L2 packet OK!\n")); + } +#endif + + return TRUE; +} /* End of IAPP_L2UpdateFrameSend */ + +/* +======================================================================== +Routine Description: + Process received message, such as rcv ADD-notify and inform AP to del +STA. + +Arguments: + *pCtrlBK - the IAPP control block pointer + MsgSubType - message Type + *pMsg - message + Len - message length + +Return Value: + TRUE - always successfully + +Note: +======================================================================== +*/ +static BOOLEAN IAPP_MsgProcess(IAPP_IN RTMP_IAPP *pCtrlBK, + IAPP_IN INT32 MsgSubType, IAPP_IN UCHAR *pMsg, + IAPP_IN INT32 Len, IAPP_IN INT32 if_idx) { + switch (MsgSubType) { + case IAPP_OPEN_SERVICE_REQ: + DBGPRINT(RT_DEBUG_TRACE, ("iapp> (FlgIsMsgReady is TRUE)\n")); + break; + + case IAPP_CLOSE_SERVICE_REQ: + DBGPRINT(RT_DEBUG_TRACE, ("iapp> (FlgIsMsgReady is FALSE)\n")); + break; + + case IAPP_SET_OID_REQ: { + POID_REQ OID_req_p; + + OID_req_p = (POID_REQ)pMsg; + + DBGPRINT(RT_DEBUG_TRACE, ("iapp> Command to WLAN (OID=%x, LEN=%d)\n", + OID_req_p->OID, OID_req_p->Len)); + + IAPP_IOCTL_TO_WLAN(pCtrlBK, RT_IOCTL_IAPP, OID_req_p->Buf, &OID_req_p->Len, + if_idx, OID_req_p->OID); + } /* case IAPP_SET_OID_REQ */ + break; + + case IAPP_QUERY_OID_REQ: /* old SysCmd from 8021X deamon */ + // IAPP_SM_InfoHandle(pMsg); + break; + + default: + DBGPRINT(RT_DEBUG_ERROR, ("iapp> (unknown subtype)\n")); + break; + } /* End of switch */ + + return TRUE; +} /* End of IAPP_MsgProcess */ + +/* +======================================================================== +Routine Description: + Open a file with filename = our PID. + +Arguments: + PID - our background process ID + +Return Value: + None + +Note: + Why to backup PID? + + Because always we will restart new IAPP daemon but forget to destroy + the old IAPP daemon, many IAPP daemons will exist in kernel. + + So we will delete old IAPP daemon whenever you start a new IAPP daemon. +======================================================================== +*/ +static VOID IAPP_PID_Backup(IAPP_IN pid_t PID) { +#ifdef IAPP_OS_LINUX + FILE *pFile; + CHAR Buffer[30]; + + /* prepare PID file content */ + IAPP_MEM_ZERO(Buffer, sizeof(Buffer)); + sprintf(Buffer, "PID = %d\n", PID); + + /* re-open and truncate file to zero length by using "wb" */ + /* write new PID in the file */ + pFile = fopen(IAPP_PID_BACKUP_FILE, "wb"); + if (pFile) { + fwrite(Buffer, strlen(Buffer), 1, pFile); + fclose(pFile); + } else { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> File open error.\n")); + } +#endif // IAPP_OS_LINUX // +} /* End of IAPP_PID_Backup */ + +/* +======================================================================== +Routine Description: + Kill running IAPP daemon if exists. + +Arguments: + None + +Return Value: + None + +Note: +======================================================================== +*/ +static VOID IAPP_PID_Kill(VOID) { +#ifdef IAPP_OS_LINUX + FILE *pFile; + pid_t PID; + CHAR SysCmd[30]; + + /* get last PID */ + pFile = fopen(IAPP_PID_BACKUP_FILE, "rb"); + if (pFile == NULL) + return; + /* End of if */ + fscanf(pFile, "PID = %d\n", &PID); + DBGPRINT(RT_DEBUG_OFF, ("iapp> Found PID=%d\n", PID)); + fclose(pFile); + + /* kill old IAPP daemon */ + sprintf(SysCmd, "kill %d\n", PID); + system(SysCmd); + + /* sleep for a where to kill old daemon */ + sleep(2); +#endif // IAPP_OS_LINUX // +} /* End of IAPP_PID_Kill */ + +/* +======================================================================== +Routine Description: + Process received signal, such as STA ASSOCIATION and send a ADD-notify. + +Arguments: + *pCtrlBK - IAPP control blcok + *pSig - signal + Len - message length + *pCmdBuf - used to issue command to WLAN driver + *pRspBuf - used to issue response to the peer + +Return Value: + TRUE - always successfully + +Note: +======================================================================== +*/ +static BOOLEAN IAPP_SIG_Process(IAPP_IN RTMP_IAPP *pCtrlBK, + IAPP_IN UCHAR *WifiMAC, + IAPP_IN RT_SIGNAL_STRUC *pSig, + IAPP_IN INT32 Len, IAPP_IN UCHAR *pCmdBuf, + IAPP_IN UCHAR *pRspBuf) { + FT_KDP_EVT_HEADER *pEvtHeader; + INT32 if_idx = -1; + + if_idx = mt_iapp_find_ifidx_by_mac(pCtrlBK, WifiMAC); + if (if_idx == -1) { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> %s - cannot find this wifi interface " + "(%02x:%02x:%02x:%02x:%02x:%02x)\n", + __FUNCTION__, WifiMAC[0], WifiMAC[1], WifiMAC[2], + WifiMAC[3], WifiMAC[4], WifiMAC[5])); + return FALSE; + } + + pEvtHeader = (FT_KDP_EVT_HEADER *)(pSig->Content); + + DBGPRINT(RT_DEBUG_TRACE, ("iapp> Sig = 0x%02x, pEvtHeader->EventLen = %d, " + "Peer IP = %d.%d.%d.%d\n", + pSig->Sig, pEvtHeader->EventLen, + IAPP_SHOW_IP_HTONL(pEvtHeader->PeerIpAddr))); + + switch (pSig->Sig) { + case FT_KDP_SIG_NOTHING: + DBGPRINT(RT_DEBUG_TRACE, ("iapp> NO event to handle.\n")); + break; + case FT_KDP_SIG_IAPP_ASSOCIATION: { +#if 1 + DBGPRINT(RT_DEBUG_TRACE, ("iapp> FT_KDP_SIG_IAPP_ASSOCIATION.\n")); +#else + + /* + This service primitive is used when a STA associates with the + AP using an 802.11 association request frame. + + One purpose of this primitive is to cause the forwarding + tables of layer 2 internetworking devices, e.g. bridges + and switches, to be updated. + + The second purpose of this primitive is to notify other APs + within the multicast domain, i.e., that portion of a network + in which a layer two frame addressed to a multicast address + can be received, of the STA’s new association, to allow those + APs to clean up context information left behind by STAs that + do not properly reassociate when moving from one AP to another, + but rather only use the 802.11 Association Request. + */ + RT_IAPP_ADD_NOTIFY IappAddNotify, *pFrameNotify; + UINT32 DataLen; + + /* pSig->MacAddr[] is the associated STATION MAC address */ + + /* init */ + IAPP_MEM_ZERO(&IappAddNotify, sizeof(IappAddNotify)); + + /* make up the frame content */ + pFrameNotify = &IappAddNotify; + pFrameNotify->IappHeader.Version = 0; + pFrameNotify->IappHeader.Command = IAPP_CMD_ADD_NOTIFY; + pFrameNotify->IappHeader.Identifier = 0; + + DataLen = sizeof(RT_IAPP_ADD_NOTIFY); + + pFrameNotify->IappHeader.Length = SWAP_16(DataLen); + pFrameNotify->Sequence = SWAP_16(pSig->Sequence); + + pFrameNotify->AddressLen = ETH_ALEN; + IAPP_MEM_MOVE(pFrameNotify->MacAddr, pSig->MacAddr, ETH_ALEN); + + mt_iapp_ft_client_insert(&pCtrlBK->SelfFtStaTable, pSig->MacAddr, WifiMAC, + if_idx); + /* +Send the ADD-notify with multicast address & +send the L2 update frame with broadcast address. +*/ + /* + An ESS is a set of Basic Service Sets (BSSs) that form a + single LAN, allowing an STA to move transparently from one + BSS to another throughout the ESS. + + Because this packet is addressed to the IAPP multicast + address, this packet may not reach all APs in an ESS. + In particular, if the ESS spans multiple subnets, neither + the ADD-notify packet nor the Layer 2 Update frame is likely + to reach the APs on subnets other than the one on which + the transmissions originate. + + Note that purpose of the IAPP ADD-notify packet is to remove + stale associations, not to modify the learning table. + The learning table update is done by the Layer 2 Update frame. + + This should allow for more efficient management of AP resources. + + There is no security provided for the Layer 2 Update frame. + + The Layer 2 Update frame does not open new potentials for + attacks against the WLAN or the STAs. However, the ADD-notify + is a UDP IP frame that COULD be sent from anywhere in the DS + and attack the AP’s state for the STA. + */ + IAPP_UDP_PACKET_SEND(pCtrlBK, pFrameNotify, DataLen, pRspBuf); + IAPP_L2UpdateFrameSend(pCtrlBK, pSig->MacAddr); + + DBGPRINT(RT_DEBUG_TRACE, + ("iapp> (IAPP_SIG_ASSOCIATION), Rcv assoc signal, and send out " + "IAPP add-notify\n")); +#endif + } /* case IAPP_SIG_ASSOCIATION */ + break; + + case IAPP_SIG_REASSOCIATION: + /* test only, not support currently */ +#if 0 + { + struct in_addr IP; + + /* UCHAR mac[ETH_ALEN] = {0x00,0x0c,0x43,0x26,0x65,0x09}; + + if (IAPP_IP2MACTransfer(&IP, mac) >= 0) + { + DBGPRINT(RT_DEBUG_TRACE, ("iapp> (IAPP_SIG_REASSOCIATION), " + "IP: %d.%d.%d.%d\n", IP.s_addr & 0xFF, + (IP.s_addr >> 8) & 0xFF, + (IP.s_addr >> 16) & 0xFF, + (IP.s_addr >> 24) & 0xFF)); + }*/ + + IP.s_addr = 0; + + if (IAPP_IP2MACTransfer(pSig->CurrAPAddr, &IP) == TRUE) + { + DBGPRINT(RT_DEBUG_TRACE, + ("iapp> (IAPP_SIG_REASSOCIATION), IP=%d.%d.%d.%d\n", + IAPP_SHOW_IP_HTONL(IP.s_addr))); + } /* End of if */ + } /* case IAPP_SIG_REASSOCIATION */ +#endif // #if 0 // + break; + + case FT_KDP_SIG_FT_ASSOCIATION: { + /* a station has already associated with us */ + /* so prepare and send out ADD_notify packet, L2 update frame */ + RT_IAPP_ADD_NOTIFY IappAddNotify, *pFrameNotify; + UINT32 DataLen; + + /* init */ + IAPP_MEM_ZERO(&IappAddNotify, sizeof(IappAddNotify)); + + /* make up the frame content */ + pFrameNotify = &IappAddNotify; + pFrameNotify->IappHeader.Version = 0; + pFrameNotify->IappHeader.Command = IAPP_CMD_ADD_NOTIFY; + pFrameNotify->IappHeader.Identifier = 0; + + DataLen = sizeof(RT_IAPP_ADD_NOTIFY); + + pFrameNotify->IappHeader.Length = SWAP_16(DataLen); + pFrameNotify->Sequence = SWAP_16(pSig->Sequence); + + pFrameNotify->AddressLen = ETH_ALEN; + IAPP_MEM_MOVE(pFrameNotify->MacAddr, pSig->MacAddr, ETH_ALEN); + + mt_iapp_ft_client_insert(&pCtrlBK->SelfFtStaTable, pSig->MacAddr, WifiMAC, + if_idx); + + /* mark the notify is for 11r station */ + pFrameNotify->Rsvd |= FT_KDP_ADD_NOTIFY_RSVD_11R_SUPPORT; + + /* + Send the ADD-notify with multicast address & + send the L2 update frame with broadcast address. + */ + DBGPRINT( + RT_DEBUG_TRACE, + ("iapp> (FT_KDP_SIG_FT_ASSOCIATION) Rcv a assoc signal and send out " + "IAPP add-notify!\n")); + + IAPP_UDP_PACKET_SEND(pCtrlBK, pFrameNotify, DataLen, pRspBuf, if_idx); + IAPP_L2UpdateFrameSend(pCtrlBK, pSig->MacAddr); + } break; + + case FT_KDP_SIG_FT_REASSOCIATION: { + /* + This primitive should be issued by the APME when it receives + an MLME-REASSOCIATE.indication from the MLME indicating that + an STA has reassociated with the AP. + + In IAPP, If the APME is utilizing caching, then the APME should + first lookup the STA’s context in the IAPP cache using the + STA’s MAC Address. If found (a cache hit), then an + IAPP-MOVE.request does not have to be issued until after an + 802.11 Reassociation Response frame. If the STA context is + not found in the cache (a cache miss), then the APME should + issue an IAPP-MOVE.request as usual. + + In IEEE802.11r, we just send MOVE-notify to inform the peer. + */ + RT_IAPP_MOVE_NOTIFY IappMoveNotify, *pFrameNotify; + UINT32 DataLen; + + /* init */ + IAPP_MEM_ZERO(&IappMoveNotify, sizeof(IappMoveNotify)); + + /* make up the frame content */ + pFrameNotify = &IappMoveNotify; + pFrameNotify->IappHeader.Version = 0; + pFrameNotify->IappHeader.Command = IAPP_CMD_MOVE_NOTIFY; + pFrameNotify->IappHeader.Identifier = 0; + + DataLen = sizeof(RT_IAPP_MOVE_NOTIFY); + + pFrameNotify->IappHeader.Length = SWAP_16(DataLen); + pFrameNotify->Sequence = SWAP_16(pSig->Sequence); + + pFrameNotify->AddressLen = ETH_ALEN; + IAPP_MEM_MOVE(pFrameNotify->MacAddr, pSig->MacAddr, ETH_ALEN); + + mt_iapp_ft_client_insert(&pCtrlBK->SelfFtStaTable, pSig->MacAddr, WifiMAC, + if_idx); + + /* + Send the MOVE-notify with multicast address & + send the L2 update frame with broadcast address. + */ + IAPP_TCP_PACKET_SEND(pCtrlBK, pFrameNotify, sizeof(RT_IAPP_MOVE_NOTIFY), + pEvtHeader->PeerIpAddr, TRUE, pRspBuf, if_idx); + IAPP_L2UpdateFrameSend(pCtrlBK, pSig->MacAddr); + + DBGPRINT(RT_DEBUG_TRACE, + ("iapp> (IAPP_SIG_REASSOCIATION) Rcv a reassoc signal and " + "send out IAPP move-notify!\n")); + } break; + + case IAPP_SIG_TERMINATE: { + /* terminate the daemon */ + IAPP_TerminateHandle(0); + } break; + + case FT_KDP_SIG_KEY_TIMEOUT: { + /* inform other APs the key timeouts */ + } break; + + case FT_KDP_SIG_KEY_REQ: + case FT_KDP_SIG_KEY_REQ_AUTO: + /* request PMK-R1 from the R0KH */ + FT_KDP_SecurityBlockSend(pCtrlBK, pEvtHeader, + pSig->Content + FT_KDP_EVT_HEADER_SIZE, pRspBuf, + WifiMAC, if_idx); + break; + + case FT_KDP_SIG_ACTION: + /* forward FT Action Req/Rsp for the peer */ + FT_RRB_ActionForward(pCtrlBK, pEvtHeader, + pSig->Content + FT_KDP_EVT_HEADER_SIZE, pSig->Sequence, + pSig->MacAddr, pSig->MacAddrSa, pSig->CurrAPAddr, + pRspBuf, if_idx); + break; + + case FT_KDP_SIG_KEY_RSP_AUTO: + /* response PMK-R1 to the R1KH */ + FT_KDP_SecurityBlockAck(pCtrlBK, pEvtHeader, + pSig->Content + FT_KDP_EVT_HEADER_SIZE, pRspBuf, + if_idx); + break; + + case FT_KDP_SIG_INFO_BROADCAST: + /* send my AP information to the ESS */ + FT_KDP_InformationReportSend(pCtrlBK, pEvtHeader, + pSig->Content + FT_KDP_EVT_HEADER_SIZE, + pRspBuf, if_idx); + break; + + case FT_KDP_SIG_AP_INFO_REQ: + /* request other AP information in the ESS */ + FT_KDP_InformationRequestSend(pCtrlBK, pEvtHeader, + pSig->Content + FT_KDP_EVT_HEADER_SIZE, + pRspBuf, if_idx); + break; + + case FT_KDP_SIG_AP_INFO_RSP: + /* response my AP information to a AP */ + FT_KDP_InformationResponseSend(pCtrlBK, pEvtHeader, + pSig->Content + FT_KDP_EVT_HEADER_SIZE, + pRspBuf, if_idx); + break; + + case FT_KSP_SIG_DEBUG_TRACE: + /* change debug level */ + RTDebugLevel = *(INT32 *)(pSig->Content + FT_KDP_EVT_HEADER_SIZE); + DBGPRINT(RT_DEBUG_OFF, ("iapp> Change debug level to %d!\n", RTDebugLevel)); + break; + + default: + DBGPRINT(RT_DEBUG_ERROR, + ("iapp> Signal %d is not supported!\n", pSig->Sig)); + return FALSE; + } /* End of switch(pSig->Sig) */ + + return TRUE; +} /* End of IAPP_SIG_Process */ + +/* +======================================================================== +Routine Description: + Close TCP/UDP socket. + +Arguments: + *pCtrlBK - IAPP control blcok + +Return Value: + TRUE - always successfully + +Note: +======================================================================== +*/ +static BOOLEAN IAPP_SocketClose(IAPP_IN RTMP_IAPP *pCtrlBK) { + /* struct ip_mreq MReq;*/ + + DBGPRINT(RT_DEBUG_TRACE, ("iapp> Close TCP/UDP socket.\n")); + +#if 0 + MReq.imr_multiaddr.s_addr = inet_addr(IAPP_MULTICAST_ADDR); + MReq.imr_interface.s_addr = htonl(INADDR_ANY); + + if (setsockopt(pCtrlBK->SocketUdpSend, + IPPROTO_IP, + IP_DROP_MEMBERSHIP, + &MReq, + sizeof(MReq)) < 0) + { + DBGPRINT(RT_DEBUG_TRACE, ("iapp> setsockopt-IP_DROP_MEMBERSHIP failed!\n")); + } /* End of if */ +#endif // #if 0 // + + if (pCtrlBK->SocketUdpSend >= 0) + close(pCtrlBK->SocketUdpSend); + /* End of if */ + + if (pCtrlBK->SocketTcpRcv >= 0) + close(pCtrlBK->SocketTcpRcv); + /* End of if */ + + if (pCtrlBK->SocketRawBr >= 0) + close(pCtrlBK->SocketRawBr); + /* End of if */ + + if (pCtrlBK->SocketIoctl >= 0) + close(pCtrlBK->SocketIoctl); + /* End of if */ + + if (pCtrlBK->SocketRawRRB >= 0) + close(pCtrlBK->SocketRawRRB); + /* End of if */ + +#ifdef FT_KDP_FUNC_SOCK_COMM + if (pCtrlBK->SocketRawDrv >= 0) + close(pCtrlBK->SocketRawDrv); + /* End of if */ +#endif // FT_KDP_FUNC_SOCK_COMM // + +#ifndef FT_KDP_FUNC_SOCK_COMM +#ifdef IAPP_OS_LINUX + if (pCtrlBK->PipeRawDrv[FT_KDP_PIPE_ID_READ] >= 0) + close(pCtrlBK->PipeRawDrv[FT_KDP_PIPE_ID_READ]); + /* End of if */ + + if (pCtrlBK->PipeRawDrv[FT_KDP_PIPE_ID_WRITE] >= 0) + close(pCtrlBK->PipeRawDrv[FT_KDP_PIPE_ID_WRITE]); + /* End of if */ +#endif // IAPP_OS_LINUX // +#endif // FT_KDP_FUNC_SOCK_COMM // + + pCtrlBK->FlgIsRcvRunning = FALSE; + return TRUE; +} /* End of IAPP_SocketClose */ + +/* +======================================================================== +Routine Description: + Open TCP/UDP socket. + +Arguments: + *pCtrlBK - IAPP control blcok + +Return Value: + TRUE - open successfully + FAIL - open fail + +Note: +======================================================================== +*/ +static BOOLEAN IAPP_SocketOpen(IAPP_IN RTMP_IAPP *pCtrlBK) { + INT32 FlgIsLoop, FlgIsReUsed, FlgIsBroadcast; +#if 0 + struct hostent *SerHostName; +#endif + /* struct ip_mreq MReq;*/ + struct sockaddr_in AddrUdp, AddrTcp; +#ifdef IAPP_OS_LINUX + struct ifreq ReqIf; + struct sockaddr_ll AddrRaw; +#endif +#if 0 + struct sigaction HandlerUdp; +#endif +#ifdef IAPP_OS_VXWORKS + struct in_addr AddrIf; +#endif + + /* init */ + pCtrlBK->SocketUdpSend = -1; + pCtrlBK->SocketTcpRcv = -1; + pCtrlBK->SocketRawBr = -1; + pCtrlBK->SocketIoctl = -1; + pCtrlBK->SocketRawRRB = -1; + +#ifdef FT_KDP_FUNC_SOCK_COMM + pCtrlBK->SocketRawDrv = -1; +#endif // FT_KDP_FUNC_SOCK_COMM // + +#ifndef FT_KDP_FUNC_SOCK_COMM +#ifdef IAPP_OS_LINUX + pCtrlBK->PipeRawDrv[FT_KDP_PIPE_ID_READ] = -1; + pCtrlBK->PipeRawDrv[FT_KDP_PIPE_ID_WRITE] = -1; +#endif // IAPP_OS_LINUX // +#endif // FT_KDP_FUNC_SOCK_COMM // + +#ifdef IAPP_OS_VXWORKS + /* muxBind a cookie for receiving commands from wireless driver */ + pCtrlBK->pDrvCookieFrom = muxBind( + FT_KDP_BR_NAME, FT_KDP_BR_UNIT, (FUNCPTR)IAPP_RcvHandlerRawDrvVxWorks, + (FUNCPTR)NULL, (FUNCPTR)NULL, (VOIDFUNCPTR)NULL, IAPP_ETH_PRO, + "IAPP IO FROM", (VOID *)pCtrlBK); + + if (pCtrlBK->pDrvCookieFrom == NULL) { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> muxBind device failed!\n")); + goto label_fail; + } /* End of if */ + + /* muxBind a cookie for issuing commands to wireless driver */ + pCtrlBK->pDrvCookieTo = + muxBind(FT_KDP_WLAN_NAME, FT_KDP_WLAN_UNIT, (FUNCPTR)NULL, (FUNCPTR)NULL, + (FUNCPTR)NULL, (VOIDFUNCPTR)NULL, 0, "IAPP IO TO", NULL); + + if (pCtrlBK->pDrvCookieTo == NULL) { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> muxBind device failed!\n")); + goto label_fail; + } /* End of if */ +#endif // IAPP_OS_VXWORKS // + +#if 0 + /* get IP address */ + if ((SerHostName = gethostbyname(IAPP_MULTICAST_ADDR)) == 0) + { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> gethostbyname failed!\n")); + goto label_fail; + } /* End of if */ +#endif + + /* open a Send UDP socket */ + if ((pCtrlBK->SocketUdpSend = socket(PF_INET, SOCK_DGRAM, 0)) < 0) { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> Open UDP socket failed!\n")); + goto label_fail; + } /* End of if */ + + /* set socket reusable */ + FlgIsReUsed = 1; + if (setsockopt(pCtrlBK->SocketUdpSend, SOL_SOCKET, SO_REUSEADDR, &FlgIsReUsed, + sizeof(FlgIsReUsed)) < 0) { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> setsockopt-SO_REUSEADDR failed!\n")); + goto label_fail; + } /* End of if */ + + /* bind the Send UDP socket */ + IAPP_MEM_ZERO(&AddrUdp, sizeof(AddrUdp)); + AddrUdp.sin_family = AF_INET; + /* + We can not use multicast address or in vxWorks, it will use the + multicast address as the source IP address. + + And you will suffer "Address load Exception" in IAPP_Task(). + + And you also can not use unicast address, or you can not receive + any broadcast packet. + + So must use INADDR_ANY. + */ + // AddrUdp.sin_addr.s_addr = inet_addr(IAPP_MULTICAST_ADDR); + AddrUdp.sin_addr.s_addr = INADDR_ANY; + AddrUdp.sin_port = htons(IAPP_UDP_PORT); + + if (bind(pCtrlBK->SocketUdpSend, (struct sockaddr *)&AddrUdp, + sizeof(AddrUdp)) < 0) { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> Bind Send UDP failed!\n")); + goto label_fail; + } /* End of if */ + +#ifdef IAPP_OS_VXWORKS + /* support multicast packet sent */ + AddrIf.s_addr = pCtrlBK->AddrOwn.s_addr; + + if (setsockopt(pCtrlBK->SocketUdpSend, IPPROTO_IP, IP_MULTICAST_IF, + (char *)&AddrIf, sizeof(AddrIf)) == ERROR) { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> iapp> setsockopt error!\n")); + goto label_fail; + } /* End of if */ +#endif // IAPP_OS_VXWORKS // + + /* no loopback support */ + FlgIsLoop = 0; + if (setsockopt(pCtrlBK->SocketUdpSend, IPPROTO_IP, IP_MULTICAST_LOOP, + &FlgIsLoop, sizeof(FlgIsLoop)) < 0) { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> setsockopt-multicast failed!\n")); + goto label_fail; + } /* End of if */ + +#if 0 + IAPP_MEM_ZERO(&MReq, sizeof(MReq)); + MReq.imr_multiaddr.s_addr = inet_addr(IAPP_MULTICAST_ADDR); + MReq.imr_interface.s_addr = pCtrlBK->AddrOwn.s_addr; + if (MReq.imr_multiaddr.s_addr == -1) + { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> Illegal multicast address!\n")); + goto label_fail; + } /* End of if */ + +#ifndef RTL865X_SOC + /* register with kernel which addr support multicast */ + if (setsockopt(pCtrlBK->SocketUdpSend, + IPPROTO_IP, + IP_ADD_MEMBERSHIP, + &MReq, + sizeof(MReq)) < 0) + { + /* + 1. Your machine doesn't have multicast support enabled. For example, + on Linux and FreeBSD it is possible to compile a kernel which + doesn't support multicast. + 2. You don't have a route for multicast traffic. Some systems don't + add this by default, and you need to run. + route add -net 224.0.0.0 AddrNetmask 224.0.0.0 eth0 + + Because we bind the socket on multicast address, OS will not know + what interface it will send any multicast packet to. + */ + + DBGPRINT(RT_DEBUG_ERROR, ("iapp> setsockopt-IP_ADD_MEMBERSHIP failed!\n")); + goto label_fail; + } /* End of if */ +#endif // RTL865X_SOC // +#endif // #if 0 // + + /* use broadcast address */ + FlgIsBroadcast = 1; + if (setsockopt(pCtrlBK->SocketUdpSend, SOL_SOCKET, SO_BROADCAST, + &FlgIsBroadcast, sizeof(FlgIsBroadcast)) < 0) { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> setsockopt-SO_BROADCAST failed!\n")); + goto label_fail; + } /* End of if */ + +#ifdef IAPP_OS_LINUX + /* + Retrieve the interface index of the interface into ifr_ifindex by + ReqIf.ifr_name + */ + IAPP_MEM_MOVE(ReqIf.ifr_name, pCtrlBK->IfNameEth, IFNAMSIZ); + + DBGPRINT(RT_DEBUG_TRACE, + ("iapp> Register ethernet interface as (%s)\n", ReqIf.ifr_name)); + + if (ioctl(pCtrlBK->SocketUdpSend, SIOCGIFINDEX, &ReqIf) != 0) { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> ioctl(SIOCGIFINDEX) failed!\n")); + goto label_fail; + } /* End of if */ +#endif // IAPP_OS_LINUX // + + /* setup non-blocking RCV UDP */ +#if 0 + HandlerUdp.sa_handler = IAPP_RcvHandler; + + /* init signal set */ + if (sigfillset(&HandlerUdp.sa_mask) < 0) + { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> sigfillset failed!\n")); + goto label_fail; + } /* End of if */ + + HandlerUdp.sa_flags = 0; + if (sigaction(SIGIO, &HandlerUdp, 0) < 0) + { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> sigaction failed!\n")); + goto label_fail; + } /* End of if */ +#endif + +#ifdef IAPP_OS_LINUX + /* open RAW socket */ + if ((pCtrlBK->SocketRawBr = socket( + PF_PACKET, SOCK_RAW, + // htons(ETH_P_ALL))) + //< 0) + htons(0x0008))) < 0) { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> Open RAW socket failed!\n")); + goto label_fail; + } /* End of if */ + + /* bind RAW socket to pCtrlBK->IfNameEth (br-lan) */ + IAPP_MEM_ZERO(&AddrRaw, sizeof(AddrRaw)); + AddrRaw.sll_family = AF_PACKET; + AddrRaw.sll_ifindex = ReqIf.ifr_ifindex; + + if (bind(pCtrlBK->SocketRawBr, (struct sockaddr *)&AddrRaw, sizeof(AddrRaw)) < + 0) { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> Bind RAW socket failed!\n")); + goto label_fail; + } /* End of if */ + + /* open RAW socket */ + if ((pCtrlBK->SocketRawRRB = + socket(PF_PACKET, SOCK_RAW, htons(RRB_ETH_PRO))) < 0) { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> open RRB RAW socket failed!\n")); + goto label_fail; + } /* End of if */ + + /* bind RAW socket to pCtrlBK->IfNameEth (br-lan) */ + IAPP_MEM_ZERO(&AddrRaw, sizeof(AddrRaw)); + AddrRaw.sll_family = AF_PACKET; + AddrRaw.sll_ifindex = ReqIf.ifr_ifindex; + + if (bind(pCtrlBK->SocketRawRRB, (struct sockaddr *)&AddrRaw, + sizeof(AddrRaw)) < 0) { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> Bind RRB RAW socket failed!\n")); + goto label_fail; + } /* End of if */ +#endif // IAPP_OS_LINUX // + +#ifdef IAPP_OS_VXWORKS + { + UINT32 IdIfNum = 0; + CHAR BindNameBc[20]; + CHAR BindNameRrb[20]; + + /* open RAW socket */ + IAPP_MEM_ZERO(BindNameBc, sizeof(BindNameBc)); + + for (IdIfNum = 0; IdIfNum < FT_KDP_BR_ETH_IF_NUM; IdIfNum++) { + sprintf(BindNameBc, "IAPP KDP BC%d", IdIfNum); + sprintf(BindNameRrb, "IAPP KDP RRB%d", IdIfNum); + + pCtrlBK->pBcCookie[IdIfNum] = + muxBind(FT_KDP_ETH_NAME, IdIfNum, (FUNCPTR)NULL, (FUNCPTR)NULL, + (FUNCPTR)NULL, (VOIDFUNCPTR)NULL, 0, BindNameBc, NULL); + + if (pCtrlBK->pBcCookie[IdIfNum] == NULL) { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> muxBind BC failed!\n")); + goto label_fail; + } /* End of if */ + + pCtrlBK->pRrbCookieTo[IdIfNum] = muxBind( + FT_KDP_ETH_NAME, IdIfNum, (FUNCPTR)NULL, (FUNCPTR)NULL, (FUNCPTR)NULL, + (VOIDFUNCPTR)NULL, RRB_ETH_PRO, BindNameRrb, NULL); + + if (pCtrlBK->pRrbCookieTo[IdIfNum] == NULL) { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> iapp> muxBind RRB failed!\n")); + goto label_fail; + } /* End of if */ + } /* End of for */ + + pCtrlBK->pRrbCookieFrom = muxBind( + FT_KDP_BR_NAME, FT_KDP_BR_UNIT, (FUNCPTR)IAPP_RcvHandlerRawRRBVxWorks, + (FUNCPTR)NULL, (FUNCPTR)NULL, (VOIDFUNCPTR)NULL, RRB_ETH_PRO, + "IAPP RRB FROM", (VOID *)pCtrlBK); + + if (pCtrlBK->pRrbCookieFrom == NULL) { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> muxBind RRB failed!\n")); + goto label_fail; + } /* End of if */ + + if ((pCtrlBK->SocketRawBr = socket(PF_PACKET, SOCK_RAW, 0)) < 0) { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> Open RAW socket failed!\n")); + goto label_fail; + } /* End of if */ + + pipeDevCreate(IAPP_KDP_PIPE_DRV, 5, sizeof(RT_SIGNAL_STRUC)); + pCtrlBK->SocketRawDrv = open(IAPP_KDP_PIPE_DRV, O_RDWR, 0); + if (pCtrlBK->SocketRawDrv < 0) { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> Open a PIPE DRV failed!\n")); + goto label_fail; + } /* End of if */ + + pipeDevCreate(IAPP_KDP_PIPE_ETH, 5, IAPP_MAX_RCV_PKT_SIZE); + pCtrlBK->SocketRawRRB = open(IAPP_KDP_PIPE_ETH, O_RDWR, 0); + if (pCtrlBK->SocketRawRRB < 0) { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> Open a PIPE RRB failed!\n")); + goto label_fail; + } /* End of if */ + } +#endif // IAPP_OS_VXWORKS // + + /* open IOCTL socket */ + if ((pCtrlBK->SocketIoctl = socket(PF_INET, SOCK_DGRAM, 0)) < 0) { + goto label_fail; + } /* End of if */ + + /* Open TCP socket for accepting connection from other AP */ + if ((pCtrlBK->SocketTcpRcv = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> Open TcpSocketForOtherAP failed!\n")); + goto label_fail; + } /* End of if */ + + /* bind the Rcv TCP socket */ + IAPP_MEM_ZERO(&AddrTcp, sizeof(AddrTcp)); + AddrTcp.sin_family = AF_INET; + AddrTcp.sin_addr.s_addr = htonl(INADDR_ANY); + AddrTcp.sin_port = htons(IAPP_TCP_PORT); + + if (bind(pCtrlBK->SocketTcpRcv, (struct sockaddr *)&AddrTcp, + sizeof(AddrTcp)) < 0) { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> Bind Rcv TCP failed!\n")); + goto label_fail; + } /* End of if */ + + listen(pCtrlBK->SocketTcpRcv, 10); /* max 10 TCP connections simultaneously */ + +#ifdef FT_KDP_FUNC_SOCK_COMM +#ifdef IAPP_OS_LINUX + /* open a socket receiving message from driver */ + if ((pCtrlBK->SocketRawDrv = + socket(PF_PACKET, SOCK_RAW, htons(IAPP_ETH_PRO))) < 0) { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> Open RAW DRV socket failed!\n")); + goto label_fail; + } /* End of if */ + + /* bind RAW socket to pCtrlBK->IfNameEth (br-lan) */ + IAPP_MEM_MOVE(ReqIf.ifr_name, pCtrlBK->IfNameWlan, IFNAMSIZ); + + if (ioctl(pCtrlBK->SocketRawDrv, SIOCGIFINDEX, &ReqIf) != 0) { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> ioctl(SIOCGIFINDEX) failed 2!\n")); + goto label_fail; + } /* End of if */ + + IAPP_MEM_ZERO(&AddrRaw, sizeof(AddrRaw)); + AddrRaw.sll_family = AF_PACKET; + AddrRaw.sll_ifindex = ReqIf.ifr_ifindex; + + if (bind(pCtrlBK->SocketRawDrv, (struct sockaddr *)&AddrRaw, + sizeof(AddrRaw)) < 0) { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> Bind RAW DRV socket failed!\n")); + goto label_fail; + } /* End of if */ +#endif // IAPP_OS_LINUX // +#endif // FT_KDP_FUNC_SOCK_COMM // + +#ifndef FT_KDP_FUNC_SOCK_COMM +#ifdef IAPP_OS_LINUX + pipe(pCtrlBK->PipeRawDrv); + + if ((pCtrlBK->PipeRawDrv[FT_KDP_PIPE_ID_READ] < 0) || + (pCtrlBK->PipeRawDrv[FT_KDP_PIPE_ID_WRITE] < 0)) { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> Open raw drv pipe failed!\n")); + goto label_fail; + } /* End of if */ +#endif // IAPP_OS_LINUX // +#endif // FT_KDP_FUNC_SOCK_COMM // + + return TRUE; + +label_fail: + IAPP_SocketClose(pCtrlBK); + return FALSE; +} /* End of IAPP_SocketOpen */ + +/* +======================================================================== +Routine Description: + Start IAPP daemon. + +Arguments: + *pCtrlBK - IAPP control blcok + +Return Value: + None + +Note: +======================================================================== +*/ +static VOID IAPP_Start(IAPP_IN RTMP_IAPP *pCtrlBK) { +#ifdef IAPP_EVENT_LOG + struct timeval now, backuptime, res; + MsgSubType msg; + INT32 flag = IPC_NOWAIT; + INT32 msglen; +#endif // IAPP_EVENT_LOG // + + /* init */ + pCtrlBK->FlgIsTerminated = 0; + +#ifdef IAPP_EVENT_LOG + gettimeofday(&backuptime, NULL); + IAPP_EventLogClean(); +#endif // IAPP_EVENT_LOG // + + mt_iapp_ft_client_table_init(pCtrlBK); + + /* waiting for local AP SysCmd or peer AP IAPP packets */ + while (!pCtrlBK->FlgIsTerminated) { +#ifdef IAPP_EVENT_LOG + /* check for message from 8021X daemon (no sleep) */ + if ((msglen = msgrcv(rtmpiapp.MsgId, &msg, sizeof(MsgSubType), + RADIUSMSGQUEID, flag)) > 0) { + IAPP_MsgProcess(&msg, msglen); + } /* End of if */ + + /* implement timer function */ + gettimeofday(&now, NULL); + timersub(&now, &backuptime, &res); + + /* 1s periodic timer to write events */ + if ((res.tv_sec >= 1000) /* || (res.tv_usec >= 100000)*/) { + backuptime = now; + IAPP_EventLog_Query(); + } /* End of if */ +#endif // IAPP_EVENT_LOG // + + /* CPU suspend will be done in IAPP_RcvHandler() */ + IAPP_RcvHandler(pCtrlBK, 0); + } /* End of while */ + +#ifdef IAPP_EVENT_LOG + /* clean all events */ + IAPP_EventLogClean(); +#endif // IAPP_EVENT_LOG // +} /* End of IAPP_Start */ + +/* +======================================================================== +Routine Description: + Send out a IAPP UDP packet. + +Arguments: + *pCtrlBK - IAPP control blcok + *pPkt - the UDP packet + PktLen - the packet size + *pRspBuf - used to issue response to the peer + +Return Value: + TRUE - send successfully + FAIL - send fail + +Note: +======================================================================== +*/ +static BOOLEAN IAPP_UDP_PacketSend(IAPP_IN RTMP_IAPP *pCtrlBK, + IAPP_IN UCHAR *pPkt, IAPP_IN UINT32 PktLen, + IAPP_IN UCHAR *pRspBuf, + IAPP_IN INT32 if_idx) { + struct sockaddr_in AddrMulticast; + RT_IAPP_HEADER *pIappHdr; + UINT16 Identifier; + UCHAR *pBufEncrypt; + BOOLEAN Status; + UINT32 total_len; + + /* init */ + pIappHdr = (RT_IAPP_HEADER *)pPkt; + Status = TRUE; + + /* for identification of the request/response packet */ + Identifier = IAPP_IDENTIFIER_GET(pCtrlBK); + pIappHdr->Identifier = SWAP_16(Identifier); + + pCtrlBK->PacketIdentifier++; + + IAPP_MEM_ZERO(&AddrMulticast, sizeof(AddrMulticast)); + AddrMulticast.sin_family = AF_INET; + // AddrMulticast.sin_addr.s_addr = inet_addr(IAPP_MULTICAST_ADDR); + AddrMulticast.sin_addr.s_addr = pCtrlBK->AddrBroadcast.s_addr; + AddrMulticast.sin_port = htons(IAPP_UDP_PORT); + + IAPP_RSP_BUF_ALLOCATE(pRspBuf, pBufEncrypt, + PktLen + IAPP_SECURITY_EXTEND_LEN + ETH_ALEN); + if (pBufEncrypt == NULL) + return FALSE; + /* End of if */ + IAPP_MEM_MOVE(pBufEncrypt, pPkt, PktLen); + IAPP_MEM_MOVE(pBufEncrypt + PktLen, pCtrlBK->IfNameWlanMAC[if_idx], ETH_ALEN); + total_len = PktLen + ETH_ALEN; + +#ifdef FT_KDP_FUNC_PKT_ENCRYPT + /* ioctl to encrypt */ + IAPP_IOCTL_TO_WLAN(pCtrlBK, RT_IOCTL_IAPP, pBufEncrypt, &total_len, if_idx, + RT_FT_DATA_ENCRYPT); +#endif // FT_KDP_FUNC_PKT_ENCRYPT // + + /* send out the packet */ + if (sendto(pCtrlBK->SocketUdpSend, pBufEncrypt, total_len, 0, + (struct sockaddr *)&AddrMulticast, + sizeof(AddrMulticast)) != (total_len)) { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> Send UDP packet failed!\n")); + Status = FALSE; + } /* End of if */ + + DBGPRINT(RT_DEBUG_TRACE, + ("iapp> Send UDP packet ok (Len = %d)\n\n", total_len)); + return Status; +} /* End of IAPP_UDP_PacketSend */ + +/* +======================================================================== +Routine Description: + Handle received IAPP UDP packets. + +Arguments: + *pCtrlBK - IAPP control blcok + Sig - no use + +Return Value: + None + +Note: +======================================================================== +*/ +VOID IAPP_RcvHandler(IAPP_IN RTMP_IAPP *pCtrlBK, IAPP_IN INT32 Sig) { + UCHAR *pPktBuf, *pCmdBuf, *pRspBuf; +#if 0 + UCHAR *pIpHdr; +#endif + fd_set FdSet; + INT32 SockMax; +#ifdef FT_KDP_SELECT_TIMEOUT + struct timeval Timeout; +#endif // FT_KDP_SELECT_TIMEOUT // + + /* sanity check */ + if (pCtrlBK->FlgIsRcvRunning == TRUE) + return; /* the handler function is running */ + /* End of if */ + + /* init */ + pPktBuf = NULL; + pCmdBuf = NULL; + pRspBuf = NULL; + + /* allocate packet & cmd Buffer */ + IAPP_MEM_ALLOC(pPktBuf, IAPP_MAX_RCV_PKT_SIZE + IAPP_MAX_RCV_PKT_SIZE_SAFE); + if (pPktBuf == NULL) { + printf("Allocate packet buffer fail!\n"); + goto LabelExit; + } /* End of if */ + + IAPP_MEM_ALLOC(pCmdBuf, IAPP_MAX_RCV_PKT_SIZE + IAPP_MAX_RCV_PKT_SIZE_SAFE); + if (pCmdBuf == NULL) { + printf("Allocate command buffer fail!\n"); + goto LabelExit; + } /* End of if */ + + IAPP_MEM_ALLOC(pRspBuf, IAPP_MAX_RCV_PKT_SIZE + IAPP_MAX_RCV_PKT_SIZE_SAFE); + if (pRspBuf == NULL) { + printf("Allocate response buffer fail!\n"); + goto LabelExit; + } /* End of if */ + + /* init */ + pCtrlBK->FlgIsRcvRunning = TRUE; + SockMax = pCtrlBK->SocketUdpSend; + + if (pCtrlBK->SocketTcpRcv > pCtrlBK->SocketUdpSend) + SockMax = pCtrlBK->SocketTcpRcv; + /* End of if */ + +#ifdef FT_KDP_FUNC_SOCK_COMM + if (pCtrlBK->SocketRawDrv > SockMax) + SockMax = pCtrlBK->SocketRawDrv; + /* End of if */ +#endif // FT_KDP_FUNC_SOCK_COMM // + + if (pCtrlBK->SocketRawRRB > SockMax) + SockMax = pCtrlBK->SocketRawRRB; + /* End of if */ + +#ifndef FT_KDP_FUNC_SOCK_COMM +#ifdef IAPP_OS_LINUX + if (pCtrlBK->PipeRawDrv[FT_KDP_PIPE_ID_READ] > SockMax) + SockMax = pCtrlBK->PipeRawDrv[FT_KDP_PIPE_ID_READ]; + /* End of if */ +#endif // IAPP_OS_LINUX // +#endif // FT_KDP_FUNC_SOCK_COMM // + + /* waiting for any UDP packet */ + while (1) { + /* must re- FD_SET before each select() */ + FD_ZERO(&FdSet); + + FD_SET(pCtrlBK->SocketUdpSend, &FdSet); + FD_SET(pCtrlBK->SocketTcpRcv, &FdSet); + FD_SET(pCtrlBK->SocketRawRRB, &FdSet); + +#ifdef FT_KDP_FUNC_SOCK_COMM + FD_SET(pCtrlBK->SocketRawDrv, &FdSet); +#endif // FT_KDP_FUNC_SOCK_COMM // + +#ifndef FT_KDP_FUNC_SOCK_COMM +#ifdef IAPP_OS_LINUX + FD_SET(pCtrlBK->PipeRawDrv[FT_KDP_PIPE_ID_READ], &FdSet); +#endif // IAPP_OS_LINUX // +#endif // FT_KDP_FUNC_SOCK_COMM // + +#ifdef FT_KDP_SELECT_TIMEOUT + IAPP_MEM_ZERO(&Timeout, sizeof(Timeout)); + Timeout.tv_sec = IAPP_SELECT_TIMEOUT; + Timeout.tv_usec = 0; + + if (select(SockMax + 1, &FdSet, NULL, NULL, &Timeout) < 0) + break; + /* End of if */ +#else + + /* must use SockMax+1, not SockMax */ + if (select(SockMax + 1, &FdSet, NULL, NULL, NULL) < 0) + break; + /* End of if */ +#endif // FT_KDP_SELECT_TIMEOUT // + + /* handle packets from UDP layer */ + if (FD_ISSET(pCtrlBK->SocketUdpSend, &FdSet)) + IAPP_RcvHandlerUdp(pCtrlBK, pPktBuf, pCmdBuf, pRspBuf); + /* End of if */ + + /* handle packets from TCP layer */ + if (FD_ISSET(pCtrlBK->SocketTcpRcv, &FdSet)) + IAPP_RcvHandlerTcp(pCtrlBK, pPktBuf, pCmdBuf, pRspBuf); + /* End of if */ + + if (FD_ISSET(pCtrlBK->SocketRawRRB, &FdSet)) + IAPP_RcvHandlerRawRRB(pCtrlBK, pPktBuf, pCmdBuf, pRspBuf); + /* End of if */ + +#ifdef FT_KDP_FUNC_SOCK_COMM + if (FD_ISSET(pCtrlBK->SocketRawDrv, &FdSet)) + IAPP_RcvHandlerRawDrv(pCtrlBK, pPktBuf, pCmdBuf, pRspBuf); + /* End of if */ +#endif // FT_KDP_FUNC_SOCK_COMM // + +#ifndef FT_KDP_FUNC_SOCK_COMM +#ifdef IAPP_OS_LINUX + if (FD_ISSET(pCtrlBK->PipeRawDrv[FT_KDP_PIPE_ID_READ], &FdSet)) { + UINT32 CmdLen; + + CmdLen = read(pCtrlBK->PipeRawDrv[FT_KDP_PIPE_ID_READ], pPktBuf, + IAPP_MAX_RCV_PKT_SIZE); + if (CmdLen > 0) { + /* handle the signal context, assoicate or reassociate or terminate */ + IAPP_SIG_Process((RT_SIGNAL_STRUC *)pPktBuf, CmdLen, pCmdBuf, pRspBuf); + } /* End of if */ + } /* End of if */ +#endif // IAPP_OS_LINUX // +#endif // FT_KDP_FUNC_SOCK_COMM // + }; + +LabelExit: + if (pPktBuf != NULL) + IAPP_MEM_FREE(pPktBuf); + /* End of if */ + if (pCmdBuf != NULL) + IAPP_MEM_FREE(pCmdBuf); + /* End of if */ + if (pRspBuf != NULL) + IAPP_MEM_FREE(pRspBuf); + /* End of if */ + pCtrlBK->FlgIsRcvRunning = FALSE; +} /* End of IAPP_RcvHandler */ + +/* +======================================================================== +Routine Description: + Handle received IAPP TCP packets. + +Arguments: + *pCtrlBK - IAPP control blcok + *pPktBuf - packet buffer + *pCmdBuf - used to issue command to WLAN driver + *pRspBuf - used to issue response to the peer + +Return Value: + None + +Note: +======================================================================== +*/ +static VOID IAPP_RcvHandlerTcp(IAPP_IN RTMP_IAPP *pCtrlBK, + IAPP_IN UCHAR *pPktBuf, IAPP_IN UCHAR *pCmdBuf, + IAPP_IN UCHAR *pRspBuf) { + struct sockaddr_in AddrPeer; + RT_IAPP_HEADER *pIappHdr; + INT32 SockNew; + socklen_t Length; + INT32 SizeRcvMsg; + INT32 if_idx = 0; + // UCHAR WifiMAC[ETH_ALEN] = {0}; + + /* init */ + IAPP_MEM_ZERO(&AddrPeer, sizeof(AddrPeer)); + Length = sizeof(struct sockaddr_in); + + SockNew = + accept(pCtrlBK->SocketTcpRcv, (struct sockaddr *)&AddrPeer, &Length); + if (SockNew < 0) + return; /* no any new connection */ + /* End of if */ + + /* handle the packet */ + SizeRcvMsg = read(SockNew, pPktBuf, IAPP_MAX_RCV_PKT_SIZE); + close(SockNew); + + if (SizeRcvMsg > 0) { + DBGPRINT(RT_DEBUG_TRACE, ("iapp> Recv TCP successfully from %d.%d.%d.%d\n", + IAPP_SHOW_IP(AddrPeer.sin_addr.s_addr))); + +#ifdef FT_KDP_FUNC_PKT_ENCRYPT + /* ioctl to decrypt */ + IAPP_IOCTL_TO_WLAN(pCtrlBK, RT_IOCTL_IAPP, pPktBuf, &SizeRcvMsg, 0, + RT_FT_DATA_DECRYPT); +#endif // FT_KDP_FUNC_PKT_ENCRYPT // + + /* get IAPP frame body */ + pIappHdr = (RT_IAPP_HEADER *)(pPktBuf); + + if (pIappHdr->Version != IAPP_VERSION) { + DBGPRINT(RT_DEBUG_TRACE, + ("iapp> IAPP version not match %d!\n", pIappHdr->Version)); + IAPP_HEX_DUMP("Wrong TCP Frame Content: ", pPktBuf, SizeRcvMsg); + return; /* version not match */ + } /* End of if */ + + DBGPRINT(RT_DEBUG_TRACE, ("iapp> IAPP SysCmd = %d\n", pIappHdr->Command)); + + switch (pIappHdr->Command) { + case IAPP_CMD_MOVE_NOTIFY: + IAPP_RcvHandlerMoveReq(pCtrlBK, (UCHAR *)pIappHdr, + AddrPeer.sin_addr.s_addr, pCmdBuf, pRspBuf); + break; + + case IAPP_CMD_MOVE_RESPONSE: { + /* + If the received sequence number does not represent a more + recent association than that at the AP where the + IAPPMOVE.indication is received, the APME should ignore the + indicated reassociation, the APME should issue an + IAPP-MOVE.response with a status of STALE_MOVE that will + cause an IAPP MOVE-response packet to be sent to the AP + that originated the IAPP MOVE-notify packet, and the APME + should issue an IAPPADD.request primitive of its own to + ensure that all Layer 2 devices are properly informed of + the correct location of the STA’s most recent association. + */ + + DBGPRINT( + RT_DEBUG_TRACE, + ("iapp> Receive IAPP_CMD_MOVE_RESPONSE! (size = %d)\n", SizeRcvMsg)); + + /* not yet implement */ + } break; + + case IAPP_CMD_FT_SEND_SECURITY_BLOCK: + IAPP_RcvHandlerSSB(pCtrlBK, (UCHAR *)pIappHdr, AddrPeer.sin_addr.s_addr, + pCmdBuf); + break; + + case IAPP_CMD_FT_ACK_SECURITY_BLOCK: { + RT_IAPP_SEND_SECURITY_BLOCK *pAckSB; + UCHAR *pBufMsg; + UINT32 BufLen; + POID_REQ OidReq; + INT32 idx; + + /* init */ + pAckSB = (RT_IAPP_SEND_SECURITY_BLOCK *)pIappHdr; + + BufLen = sizeof(OID_REQ); + BufLen += FT_IP_ADDRESS_SIZE + IAPP_SB_INIT_VEC_SIZE + pAckSB->Length; + + IAPP_CMD_BUF_ALLOCATE(pCmdBuf, pBufMsg, BufLen); + if (pBufMsg == NULL) + break; + /* End of if */ + + /* command to notify that a Key Req is received */ + DBGPRINT(RT_DEBUG_TRACE, ("iapp> IAPP_CMD_FT_ACK_SECURITY_BLOCK\n")); + + OidReq = (POID_REQ)pBufMsg; + OidReq->OID = (RT_SET_FT_KEY_RSP | OID_GET_SET_TOGGLE); + + /* peer IP address */ + IAPP_MEM_MOVE(OidReq->Buf, &(AddrPeer.sin_addr.s_addr), + FT_IP_ADDRESS_SIZE); + + /* IP & nonce & security block */ + IAPP_MEM_MOVE(OidReq->Buf + FT_IP_ADDRESS_SIZE, pAckSB->InitVec, + IAPP_SB_INIT_VEC_SIZE); + IAPP_MEM_MOVE(OidReq->Buf + FT_IP_ADDRESS_SIZE + IAPP_SB_INIT_VEC_SIZE, + pAckSB->SB, pAckSB->Length); + + OidReq->Len = BufLen - sizeof(OID_REQ); + + /* + send to all wifi 11r interface. + */ + for (idx = 0; idx < pCtrlBK->IfNameWlanCount; idx++) { + IAPP_MsgProcess(pCtrlBK, IAPP_SET_OID_REQ, pBufMsg, BufLen, idx); + } + } break; + + case IAPP_CMD_INFO_RESPONSE: + IAPP_RcvHandlerApInfor(pCtrlBK, IAPP_INFO_TYPE_RSP, (UCHAR *)pIappHdr, + AddrPeer.sin_addr.s_addr, pCmdBuf, if_idx); + break; + + default: + IAPP_HEX_DUMP("Wrong TCP Frame Content: ", pPktBuf, SizeRcvMsg); + break; + } + } /* End of if */ +} /* End of IAPP_RcvHandlerTcp */ + +/* +======================================================================== +Routine Description: + Handle received IAPP Move Request packet. + +Arguments: + *pCtrlBK - IAPP control blcok + *pPktBuf - packet buffer + PeerIP - the peer IP address + *pCmdBuf - used to issue command to WLAN driver + *pRspBuf - used to issue response to the peer + +Return Value: + None + +Note: +======================================================================== +*/ +static VOID IAPP_RcvHandlerMoveReq(IAPP_IN RTMP_IAPP *pCtrlBK, + IAPP_IN UCHAR *pPktBuf, + IAPP_IN UINT32 PeerIP, + IAPP_IN UCHAR *pCmdBuf, + IAPP_IN UCHAR *pRspBuf) { + /* + In IAPP, when the Status is not SUCCESSFUL, the APME should + disassociate the STA indicated by the MAC Address + parameter, using the 802.11 MLME-DISASSOCIATE.request + primitive with a Reason Code of 1, meaning "Unspecified + Reason." Future revisions of the IEEE Std 802.11 may define + a new Reason Code that means "Old AP did not verify + previous association." + */ + RT_IAPP_MOVE_NOTIFY *pNotify; + RT_IAPP_MOVE_RSP *pRsp; + UCHAR *pBufMsg; + UINT32 BufLen; + POID_REQ OidReq; + INT32 if_idx; + + /* sanity check */ + pNotify = (RT_IAPP_MOVE_NOTIFY *)pPktBuf; + + if (SWAP_16(pNotify->IappHeader.Length) != sizeof(RT_IAPP_MOVE_NOTIFY)) { + DBGPRINT(RT_DEBUG_TRACE, ("iapp> Len %d != Move Request Len %d!\n", + SWAP_16(pNotify->IappHeader.Length), + sizeof(RT_IAPP_MOVE_NOTIFY))); + return; + } /* End of if */ + + /* delete MAC Entry when receive a add-notify packet */ + BufLen = sizeof(OID_REQ); + BufLen += ETH_ALEN; + + IAPP_CMD_BUF_ALLOCATE(pCmdBuf, pBufMsg, BufLen); + if (pBufMsg == NULL) + return; + /* End of if */ + + OidReq = (POID_REQ)pBufMsg; + OidReq->OID = (RT_SET_DEL_MAC_ENTRY | OID_GET_SET_TOGGLE); + IAPP_MEM_MOVE(OidReq->Buf, pNotify->MacAddr, ETH_ALEN); + OidReq->Len = BufLen - sizeof(OID_REQ); + + if_idx = + mt_iapp_find_ifidx_by_sta_mac(&pCtrlBK->SelfFtStaTable, pNotify->MacAddr); + if (if_idx < 0) { + DBGPRINT(RT_DEBUG_TRACE, + ("iapp> %s: cannot find wifi interface.\n", __FUNCTION__)); + return; + } + + /* + Note: RALINK AP driver delete the STATION MAC by MAC + address, do NOT care which BSS index. + */ + IAPP_MsgProcess(pCtrlBK, IAPP_SET_OID_REQ, pBufMsg, BufLen, if_idx); + + DBGPRINT(RT_DEBUG_TRACE, + ("iapp> (Receive IAPP_CMD_MOVE_NOTIFY for " + "%02x:%02x:%02x:%02x:%02x:%02x)\n", + pNotify->MacAddr[0], pNotify->MacAddr[1], pNotify->MacAddr[2], + pNotify->MacAddr[3], pNotify->MacAddr[4], pNotify->MacAddr[5])); + + /* reponse the MOVE request */ + pRsp = (RT_IAPP_MOVE_RSP *)pNotify; + pRsp->IappHeader.Command = IAPP_CMD_MOVE_RESPONSE; + pRsp->Status = IAPP_MOVE_RSP_STATUS_SUCCESS; + + IAPP_TCP_PACKET_SEND(pCtrlBK, pRsp, sizeof(RT_IAPP_MOVE_RSP), PeerIP, TRUE, + pRspBuf, if_idx); + + mt_iapp_ft_client_delete(&pCtrlBK->SelfFtStaTable, pNotify->MacAddr); + +} /* End of IAPP_RcvHandlerMoveReq */ + +/* +======================================================================== +Routine Description: + Handle received IAPP Security Send Block packet. + +Arguments: + *pCtrlBK - IAPP control blcok + *pPktBuf - packet buffer + PeerIP - the peer IP address + *pCmdBuf - used to issue command to WLAN driver + +Return Value: + None + +Note: +======================================================================== +*/ +static VOID IAPP_RcvHandlerSSB(IAPP_IN RTMP_IAPP *pCtrlBK, + IAPP_IN UCHAR *pPktBuf, IAPP_IN UINT32 PeerIP, + IAPP_IN UCHAR *pCmdBuf) { + RT_IAPP_SEND_SECURITY_BLOCK *pSendSB; + UCHAR *pBufMsg; + UINT32 BufLen, if_idx; + POID_REQ OidReq; + FT_KDP_EVT_KEY_ELM kdp_info; + + /* init */ + pSendSB = (RT_IAPP_SEND_SECURITY_BLOCK *)pPktBuf; + + BufLen = sizeof(OID_REQ); + BufLen += FT_IP_ADDRESS_SIZE + IAPP_SB_INIT_VEC_SIZE + pSendSB->Length; + + IAPP_CMD_BUF_ALLOCATE(pCmdBuf, pBufMsg, BufLen); + if (pBufMsg == NULL) + return; + /* End of if */ + + /* command to notify that a Key Req is received */ + DBGPRINT(RT_DEBUG_TRACE, ("iapp> IAPP_RcvHandlerSSB\n")); + + OidReq = (POID_REQ)pBufMsg; + OidReq->OID = (RT_SET_FT_KEY_REQ | OID_GET_SET_TOGGLE); + + /* peer IP address */ + IAPP_MEM_MOVE(OidReq->Buf, &PeerIP, FT_IP_ADDRESS_SIZE); + + /* nonce & security block */ + IAPP_MEM_MOVE(OidReq->Buf + FT_IP_ADDRESS_SIZE, pSendSB->InitVec, + IAPP_SB_INIT_VEC_SIZE); + IAPP_MEM_MOVE(OidReq->Buf + FT_IP_ADDRESS_SIZE + IAPP_SB_INIT_VEC_SIZE, + pSendSB->SB, pSendSB->Length); + IAPP_MEM_MOVE(&kdp_info, pSendSB->SB, pSendSB->Length); + IAPP_HEX_DUMP("kdp_info.MacAddr", kdp_info.MacAddr, ETH_ALEN); + if_idx = + mt_iapp_find_ifidx_by_sta_mac(&pCtrlBK->SelfFtStaTable, kdp_info.MacAddr); + if (if_idx < 0) { + DBGPRINT(RT_DEBUG_TRACE, + ("iapp> %s: cannot find wifi interface\n", __FUNCTION__)); + return; + } + + OidReq->Len = BufLen - sizeof(OID_REQ); + + IAPP_MsgProcess(pCtrlBK, IAPP_SET_OID_REQ, pBufMsg, BufLen, if_idx); + +#ifndef FT_KDP_FUNC_SOCK_COMM + /* + Note: in VxWorks, we can not send any signal to same task + which issues a ioctl path. + + So we poll the event automatically. + */ + /* receive event */ + IAPP_USR2Handle(0, if_idx); +#endif // FT_KDP_FUNC_SOCK_COMM // +} /* End of IAPP_RcvHandlerSSB */ + +/* +======================================================================== +Routine Description: + Handle received IAPP AP Information BC/REQ/RSP packet. + +Arguments: + *pCtrlBK - IAPP control blcok + Type - IAPP_INFO_TYPE_BC, IAPP_INFO_TYPE_REQ, +IAPP_INFO_TYPE_RSP *pPktBuf - packet buffer PeerIP - the peer IP +address *pCmdBuf - used to issue command to WLAN driver + +Return Value: + None + +Note: +======================================================================== +*/ +static VOID IAPP_RcvHandlerApInfor(IAPP_IN RTMP_IAPP *pCtrlBK, + IAPP_IN UCHAR Type, IAPP_IN UCHAR *pPktBuf, + IAPP_IN UINT32 PeerIP, + IAPP_IN UCHAR *pCmdBuf, + IAPP_IN INT32 if_idx) { + RT_IAPP_INFORMATION *pApIB; + UCHAR *pBufMsg; + UINT32 BufLen; + POID_REQ OidReq; + INT32 OID[IAPP_INFO_TYPE_MAX_NUM] = { + RT_FT_NEIGHBOR_REPORT, RT_FT_NEIGHBOR_REQUEST, RT_FT_NEIGHBOR_RESPONSE}; + + /* sanity check */ + if (Type >= IAPP_INFO_TYPE_MAX_NUM) { + DBGPRINT(RT_DEBUG_TRACE, ("iapp> Wrong Info Type %d\n", Type)); + return; + } /* End of if */ + + /* init */ + pApIB = (RT_IAPP_INFORMATION *)pPktBuf; + + BufLen = sizeof(OID_REQ); + BufLen += FT_IP_ADDRESS_SIZE + pApIB->Length; + + IAPP_CMD_BUF_ALLOCATE(pCmdBuf, pBufMsg, BufLen); + if (pBufMsg == NULL) + return; + /* End of if */ + + /* command to notify that a Key Req is received */ + DBGPRINT(RT_DEBUG_TRACE, ("iapp> IAPP_RcvHandlerApInfor %d\n", Type)); + + OidReq = (POID_REQ)pBufMsg; + OidReq->OID = (OID[Type] | OID_GET_SET_TOGGLE); + + /* peer IP address & information block */ + IAPP_MEM_MOVE(OidReq->Buf, &PeerIP, FT_IP_ADDRESS_SIZE); + IAPP_MEM_MOVE(OidReq->Buf + FT_IP_ADDRESS_SIZE, pApIB->IB, pApIB->Length); + OidReq->Len = BufLen - sizeof(OID_REQ); + + IAPP_MsgProcess(pCtrlBK, IAPP_SET_OID_REQ, pBufMsg, BufLen, if_idx); + +#ifndef FT_KDP_FUNC_SOCK_COMM + /* + Note: in VxWorks, we can not send any signal to same task + which issues a ioctl path. + + So we poll the event automatically. + */ + /* receive event */ + IAPP_USR2Handle(0, if_idx); +#endif // FT_KDP_FUNC_SOCK_COMM // +} /* End of IAPP_RcvHandlerApInfor */ + +#ifdef FT_KDP_FUNC_SOCK_COMM +/* +======================================================================== +Routine Description: + Handle received IAPP RAW packets from WLAN driver. + +Arguments: + *pCtrlBK - IAPP control blcok + *pPktBuf - packet buffer + *pCmdBuf - used to issue command to WLAN driver + *pRspBuf - used to issue response to the peer + +Return Value: + None + +Note: +======================================================================== +*/ +static VOID IAPP_RcvHandlerRawDrv(IAPP_IN RTMP_IAPP *pCtrlBK, + IAPP_IN UCHAR *pPktBuf, + IAPP_IN UCHAR *pCmdBuf, + IAPP_IN UCHAR *pRspBuf) { + RT_SIGNAL_STRUC *pSignal; + INT32 SizeRcvMsg; + +#ifdef IAPP_OS_LINUX + struct sockaddr_in AddrPeer; + socklen_t Length; + + /* init */ + IAPP_MEM_ZERO(&AddrPeer, sizeof(AddrPeer)); + Length = sizeof(struct sockaddr_in); + + SizeRcvMsg = recvfrom(pCtrlBK->SocketRawDrv, pPktBuf, IAPP_MAX_RCV_PKT_SIZE, + 0, (struct sockaddr *)&AddrPeer, &Length); +#endif // IAPP_OS_LINUX // + +#ifdef IAPP_OS_VXWORKS + SizeRcvMsg = + read(pCtrlBK->SocketRawDrv, (CHAR *)pPktBuf, IAPP_MAX_RCV_PKT_SIZE); +#endif // IAPP_OS_VXWORKS // + + /* handle the packet */ + if (SizeRcvMsg > 0) { + UCHAR WifiMAC[ETH_ALEN]; + + DBGPRINT(RT_DEBUG_TRACE, ("iapp> Recvfrom RAW CMD successfully (%d, %d)!\n", + IAPP_MemAllocNum, IAPP_MemFreeNum)); + + NdisZeroMemory(WifiMAC, ETH_ALEN); + NdisCopyMemory(WifiMAC, pPktBuf, ETH_ALEN); + + /* handle the signal context, assoicate or reassociate or terminate */ + pSignal = (RT_SIGNAL_STRUC *)(pPktBuf + sizeof(FT_ETH_HEADER)); + IAPP_SIG_Process(pCtrlBK, WifiMAC, pSignal, SizeRcvMsg, pCmdBuf, pRspBuf); + } /* End of if */ +} /* End of IAPP_RcvHandlerRawDrv */ + +/* +======================================================================== +Routine Description: + Handle received RRB RAW packets from LAN. + +Arguments: + *pCtrlBK - IAPP control blcok + *pPktBuf - packet buffer + *pCmdBuf - used to issue command to WLAN driver + *pRspBuf - used to issue response to the peer + +Return Value: + None + +Note: +======================================================================== +*/ +static VOID IAPP_RcvHandlerRawRRB(IAPP_IN RTMP_IAPP *pCtrlBK, + IAPP_IN UCHAR *pPktBuf, + IAPP_IN UCHAR *pCmdBuf, + IAPP_IN UCHAR *pRspBuf) { + INT32 SizeRcvMsg; + UCHAR *pBufMsg; + POID_REQ OidReq; + FT_RRB_FRAME *pFrameRRB; + +#ifdef IAPP_OS_LINUX + struct sockaddr_in AddrPeer; + socklen_t Length; + + /* init */ + IAPP_MEM_ZERO(&AddrPeer, sizeof(AddrPeer)); + Length = sizeof(struct sockaddr_in); + + SizeRcvMsg = recvfrom(pCtrlBK->SocketRawRRB, pPktBuf, IAPP_MAX_RCV_PKT_SIZE, + 0, (struct sockaddr *)&AddrPeer, &Length); +#endif // IAPP_OS_LINUX // + +#ifdef IAPP_OS_VXWORKS + SizeRcvMsg = + read(pCtrlBK->SocketRawRRB, (CHAR *)pPktBuf, IAPP_MAX_RCV_PKT_SIZE); +#endif // IAPP_OS_VXWORKS // + + /* handle the packet */ + if (SizeRcvMsg > 0) { + INT32 wifi_if_idx = 0; + UCHAR WifiMAC[ETH_ALEN]; + + DBGPRINT(RT_DEBUG_TRACE, + ("iapp> Recvfrom RRB RAW successfully! (len = %d)\n", SizeRcvMsg)); + +#ifdef FT_KDP_FUNC_PKT_ENCRYPT + /* ioctl to decrypt */ + pFrameRRB = (FT_RRB_FRAME *)pPktBuf; + + if ((wifi_if_idx = mt_iapp_find_ifidx_by_mac(pCtrlBK, pPktBuf)) == -1) { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> %s - Daemon doesn't hook this wifi " + "interface. Ignore this packet.\n", + __FUNCTION__)); + IAPP_HEX_DUMP("802.3 Hdr: ", pPktBuf, 14); + return; + } + NdisZeroMemory(WifiMAC, ETH_ALEN); + NdisCopyMemory(WifiMAC, pPktBuf, ETH_ALEN); + + /* + Note: Can not use "SizeRcvMsg - FT_RRB_HEADER_SIZE" to get the + encrypted data length, because when the ethernet frame length + < 64B and ethernet driver will fill 0 to the end of the frame, + we will get the wrong the encrypted data length. + */ + SizeRcvMsg = pFrameRRB->FTActionLength; + IAPP_ENCRYPTED_DATA_SIZE_CAL(SizeRcvMsg); + + IAPP_IOCTL_TO_WLAN(pCtrlBK, RT_IOCTL_IAPP, pPktBuf + FT_RRB_HEADER_SIZE, + &SizeRcvMsg, wifi_if_idx, RT_FT_DATA_DECRYPT); + + SizeRcvMsg += FT_RRB_HEADER_SIZE; +#endif // FT_KDP_FUNC_PKT_ENCRYPT // + + IAPP_CMD_BUF_ALLOCATE(pCmdBuf, pBufMsg, (sizeof(OID_REQ) + SizeRcvMsg)); + if (pBufMsg == NULL) + return; + /* End of if */ + + OidReq = (POID_REQ)pBufMsg; + OidReq->OID = (RT_FT_ACTION_FORWARD | OID_GET_SET_TOGGLE); + + /* nonce & security block */ + IAPP_MEM_MOVE(OidReq->Buf, pPktBuf, SizeRcvMsg); + OidReq->Len = SizeRcvMsg; + + IAPP_MsgProcess(pCtrlBK, IAPP_SET_OID_REQ, pBufMsg, + (sizeof(OID_REQ) + SizeRcvMsg), wifi_if_idx); + } /* End of if */ +} /* End of IAPP_RcvHandlerRawRRB */ + +#ifdef IAPP_OS_VXWORKS +/* +======================================================================== +Routine Description: + Handle received IAPP RAW packets from WLAN driver. + +Arguments: + *pCookie - protocol/device binding from muxBind() + Type - Protocol type + *pMblk - The whole packet + *pSpareData - pointer to link level header info + *pSpare - spare pointer from muxBind() + +Return Value: + None + +Note: +======================================================================== +*/ +BOOLEAN IAPP_RcvHandlerRawDrvVxWorks(IAPP_IN void *pCookie, IAPP_IN long Type, + IAPP_IN M_BLK_ID pMblk, + IAPP_IN LL_HDR_INFO *pLinkHdrInfo, + IAPP_IN void *pSpare) { + RTMP_IAPP *pCtrlBK = (RTMP_IAPP *)pSpare; + + if ((pCtrlBK != NULL) && (pMblk != NULL)) { + /* handle the signal context, assoicate or reassociate or terminate */ + write(pCtrlBK->SocketRawDrv, (CHAR *)pMblk->mBlkHdr.mData, + pMblk->mBlkHdr.mLen); + + /* free the Mblk */ + netMblkClChainFree(pMblk); + } /* End of if */ + + return TRUE; +} /* End of IAPP_RcvHandlerRawDrvVxWorks */ + +/* +======================================================================== +Routine Description: + Handle received IAPP RAW RRB packets from ethernet driver. + +Arguments: + *pCookie - protocol/device binding from muxBind() + Type - Protocol type + *pMblk - The whole packet + *pSpareData - pointer to link level header info + *pSpare - spare pointer from muxBind() + +Return Value: + None + +Note: +======================================================================== +*/ +BOOLEAN IAPP_RcvHandlerRawRRBVxWorks(IAPP_IN void *pCookie, IAPP_IN long Type, + IAPP_IN M_BLK_ID pMblk, + IAPP_IN LL_HDR_INFO *pLinkHdrInfo, + IAPP_IN void *pSpare) { + RTMP_IAPP *pCtrlBK = (RTMP_IAPP *)pSpare; + + if ((pCtrlBK != NULL) && (pMblk != NULL)) { + /* handle the signal context, assoicate or reassociate or terminate */ + write(pCtrlBK->SocketRawRRB, (CHAR *)pMblk->mBlkHdr.mData, + pMblk->mBlkHdr.mLen); + + /* free the Mblk */ + netMblkClChainFree(pMblk); + } /* End of if */ + + return TRUE; +} /* End of IAPP_RcvHandlerRawRRBVxWorks */ +#endif // IAPP_OS_VXWORKS // +#endif // FT_KDP_FUNC_SOCK_COMM // + +/* +======================================================================== +Routine Description: + Handle received IAPP UDP packets. + +Arguments: + *pCtrlBK - IAPP control blcok + *pPktBuf - packet buffer + *pCmdBuf - used to issue command to WLAN driver + *pRspBuf - used to issue response to the peer + +Return Value: + None + +Note: +======================================================================== +*/ +static VOID IAPP_RcvHandlerUdp(IAPP_IN RTMP_IAPP *pCtrlBK, + IAPP_IN UCHAR *pPktBuf, IAPP_IN UCHAR *pCmdBuf, + IAPP_IN UCHAR *pRspBuf) { + struct sockaddr_in AddrPeer; + RT_IAPP_HEADER *pIappHdr; + INT32 SizeRcvMsg; +#if 0 + UCHAR *pIpHdr; +#endif + socklen_t Length; + INT32 if_idx = -1, idx; + + /* init */ + IAPP_MEM_ZERO(&AddrPeer, sizeof(AddrPeer)); + Length = sizeof(struct sockaddr_in); + + SizeRcvMsg = recvfrom(pCtrlBK->SocketUdpSend, pPktBuf, IAPP_MAX_RCV_PKT_SIZE, + 0, (struct sockaddr *)&AddrPeer, &Length); + + /* handle the packet */ + if (SizeRcvMsg > 0) { + DBGPRINT(RT_DEBUG_TRACE, + ("iapp> Recvfrom UDP (len%d) successfully from %d.%d.%d.%d\n", + SizeRcvMsg, IAPP_SHOW_IP(AddrPeer.sin_addr.s_addr))); + +#ifndef IAPP_TEST + if (AddrPeer.sin_addr.s_addr == pCtrlBK->AddrOwn.s_addr) { + DBGPRINT(RT_DEBUG_TRACE, ("iapp> Skip packet from us!\n\n")); + return; /* same IP source address */ + } /* End of if */ +#endif // IAPP_TEST // + +#if 0 + /* find the IP header */ + pIpHdr = pPktBuf + IAPP_IP_HEADER_OFFSET; + + /* skip non UDP packets */ + if (pIpHdr[IAPP_IP_PROTO_OFFSET] != IAPP_IP_PROTO_UDP) + continue; /* the IP packet is not UDP */ + /* End of if */ + + /* + Because we dont bind RCV port to 3517, so we need to + its check UDP dest port, must be 3517. + */ + if (*((UINT16 *)(pIpHdr+IAPP_UDP_DST_PORT_OFFSET)) != + ntohs(IAPP_UDP_PORT)) + { + continue; /* not for us */ + } /* End of if */ + + /* get IAPP frame body */ + pIappHdr = (RT_IAPP_HEADER *)(pPktBuf + IAPP_MAC_IP_UDP_LEN); +#endif + +#ifdef FT_KDP_FUNC_PKT_ENCRYPT + /* ioctl to decrypt */ + IAPP_IOCTL_TO_WLAN(pCtrlBK, RT_IOCTL_IAPP, pPktBuf, &SizeRcvMsg, 0, + RT_FT_DATA_DECRYPT); +#endif // FT_KDP_FUNC_PKT_ENCRYPT // + + /* get IAPP frame body */ + pIappHdr = (RT_IAPP_HEADER *)(pPktBuf); + + if (pIappHdr->Version != IAPP_VERSION) { + DBGPRINT(RT_DEBUG_TRACE, + ("iapp> IAPP version not match %d!\n", pIappHdr->Version)); + IAPP_HEX_DUMP("Wrong UDP Frame Content: ", pPktBuf, SizeRcvMsg); + return; /* version not match */ + } /* End of if */ + + // IAPP_HEX_DUMP("UDP Frame Content: ", pPktBuf, SizeRcvMsg); + + /* handle the IAPP */ + DBGPRINT(RT_DEBUG_TRACE, ("iapp> IAPP SysCmd = %d\n", pIappHdr->Command)); + + switch (pIappHdr->Command) { + case IAPP_CMD_ADD_NOTIFY: { + RT_IAPP_ADD_NOTIFY *pNotify; + UCHAR *pBufMsg; + UINT32 BufLen; + POID_REQ OidReq; + + /* sanity check for frame length */ + pNotify = (RT_IAPP_ADD_NOTIFY *)pIappHdr; + + if (SWAP_16(pIappHdr->Length) != sizeof(RT_IAPP_ADD_NOTIFY)) { + DBGPRINT(RT_DEBUG_TRACE, + ("iapp> Len 0x%x != ADD Notify Len %d!\n", + SWAP_16(pIappHdr->Length), sizeof(RT_IAPP_ADD_NOTIFY))); + break; + } /* End of if */ + + /* + Upon receipt of this service primitive the APME should + determine if the STA indicated by the MAC Address is shown + to be associated with the AP receiving the + IAPP-ADD.indication, with a sequence number older than that + in the IAPP ADD-notify packet. + + If so, this service primitive should cause the generation + of an 802.11 MLME-DISASSOCIATE.request by the APME. + + If the sequence number received in the IAPP ADD-notify + packet is older than that received from the STA when it + associated with the AP receiving the IAPP ADD-notify packet, + the APME should ignore the indicated association and issue + an IAPPADD.request. + + Implementers of STA MAC entities are advised of the + importance of continuing the sequential assignment of + sequence numbers for outgoing MPDUs and MMPDUs throughout + STA operation, as required by 802.11. + */ + /* not yet implement */ + + BufLen = sizeof(OID_REQ) + FT_IP_ADDRESS_SIZE + ETH_ALEN; + IAPP_CMD_BUF_ALLOCATE(pCmdBuf, pBufMsg, BufLen); + if (pBufMsg == NULL) + break; + + if_idx = mt_iapp_find_ifidx_by_sta_mac(&pCtrlBK->SelfFtStaTable, + pNotify->MacAddr); + + if (if_idx >= 0) { + /* delete MAC Entry when receive a add-notify packet */ + OidReq = (POID_REQ)pBufMsg; + OidReq->OID = (RT_SET_DEL_MAC_ENTRY | OID_GET_SET_TOGGLE); + IAPP_MEM_MOVE(OidReq->Buf, pNotify->MacAddr, ETH_ALEN); + OidReq->Len = ETH_ALEN; + + /* + Note: RALINK AP driver delete the STATION MAC by MAC + address, do NOT care which BSS index. + */ + IAPP_MsgProcess(pCtrlBK, IAPP_SET_OID_REQ, pBufMsg, + (sizeof(INT32) + sizeof(INT32) + ETH_ALEN), if_idx); + } + + DBGPRINT(RT_DEBUG_TRACE, + ("iapp> Receive IAPP_CMD_ADD_NOTIFY for " + "%02x:%02x:%02x:%02x:%02x:%02x (size = %d)\n", + pNotify->MacAddr[0], pNotify->MacAddr[1], pNotify->MacAddr[2], + pNotify->MacAddr[3], pNotify->MacAddr[4], pNotify->MacAddr[5], + SizeRcvMsg)); + + /* command to notify that this is for 11r station */ + if (pNotify->Rsvd & FT_KDP_ADD_NOTIFY_RSVD_11R_SUPPORT) { + OidReq = (POID_REQ)pBufMsg; + OidReq->OID = (RT_SET_FT_STATION_NOTIFY | OID_GET_SET_TOGGLE); + + /* peer IP address */ + IAPP_MEM_MOVE(OidReq->Buf, &(AddrPeer.sin_addr.s_addr), + FT_IP_ADDRESS_SIZE); + + /* station MAC */ + IAPP_MEM_MOVE(OidReq->Buf + FT_IP_ADDRESS_SIZE, pNotify->MacAddr, + ETH_ALEN); + + OidReq->Len = FT_IP_ADDRESS_SIZE + ETH_ALEN; + + /* + Send notify to all 11r interface. + */ + for (idx = 0; idx < pCtrlBK->IfNameWlanCount; idx++) { + IAPP_MsgProcess( + pCtrlBK, IAPP_SET_OID_REQ, pBufMsg, + (sizeof(INT32) + sizeof(INT32) + FT_IP_ADDRESS_SIZE + ETH_ALEN), + idx); + } + +#ifndef FT_KDP_FUNC_SOCK_COMM + /* + Note: in VxWorks, we can not send any signal to same task + which issues a ioctl path. + + So we poll the event automatically. + */ + /* receive event */ + IAPP_USR2Handle(0, if_idx); +#endif // FT_KDP_FUNC_SOCK_COMM // + } /* End of if */ + } /* IAPP_CMD_ADD_NOTIFY */ + break; + +#ifdef IAPP_EVENT_LOG + case IAPP_CMD_SECURITY_MONITOR: { + PRT_IAPP_SECURITY_MONITOR SM_p; + + SM_p = (PRT_IAPP_SECURITY_MONITOR)pIappHdr; + + DBGPRINT(RT_DEBUG_TRACE, ("iapp> pkt = IAPP_CMD_SECURITY_MONITOR\n")); + + IAPP_EventLogHandle(&SM_p->EvtTab); + } /* IAPP_CMD_SECURITY_MONITOR */ + break; +#endif // IAPP_EVENT_LOG // + + case IAPP_CMD_MOVE_NOTIFY: + IAPP_RcvHandlerMoveReq(pCtrlBK, (UCHAR *)pIappHdr, + AddrPeer.sin_addr.s_addr, pCmdBuf, pRspBuf); + break; + + case IAPP_CMD_FT_SEND_SECURITY_BLOCK: + IAPP_RcvHandlerSSB(pCtrlBK, (UCHAR *)pIappHdr, AddrPeer.sin_addr.s_addr, + pCmdBuf); + break; + + case IAPP_CMD_INFO_BROADCAST: + IAPP_RcvHandlerApInfor(pCtrlBK, IAPP_INFO_TYPE_BC, (UCHAR *)pIappHdr, + AddrPeer.sin_addr.s_addr, pCmdBuf, if_idx); + break; + + case IAPP_CMD_INFO_REQUEST: + IAPP_RcvHandlerApInfor(pCtrlBK, IAPP_INFO_TYPE_REQ, (UCHAR *)pIappHdr, + AddrPeer.sin_addr.s_addr, pCmdBuf, if_idx); + break; + + default: + DBGPRINT(RT_DEBUG_TRACE, + ("iapp> Unknown IAPP command %d!\n", pIappHdr->Command)); + break; + } /* End of switch(pIappHdr->Command) */ + } /* End of if (SizeRcvMsg > 0) */ +} /* End of IAPP_RcvHandlerUdp */ + +/* +======================================================================== +Routine Description: + Print IAPP deamon usage. + +Arguments: + None + +Return Value: + None + +Note: +======================================================================== +*/ +static VOID IAPP_Usage(VOID) { + printf("\tUSAGE:\t\tmtkiappd <-e eth_if_name> <-w wireless_if_name>\n"); + printf("\t\t\t\t<-k security_key> <-d debug level>\n"); + printf("\tDefault:\tmtkiappd -e br-lan -w ra0 -k zpxrjs9uo2kvbuqo -d 3\n"); +} /* End of IAPP_Usage */ + +/* +======================================================================== +Routine Description: + Handle driver commands from RALINK AP. + +Arguments: + Sig - no use + +Return Value: + None + +Note: + When a station associates or re-associates to RALINK AP, RALINK AP will + use kill_proc() to send SIGUSR2 signal to us. + + Then we should to get the Data content from RALINK AP. +======================================================================== +*/ +static VOID IAPP_USR2Handle(IAPP_IN INT32 Sig) { +#ifndef FT_KDP_FUNC_SOCK_COMM + RT_SIGNAL_STRUC *pSigBuf; + INT32 DataLen; + INT32 if_idx = 0; + + /* get signal context from AP driver */ + DataLen = sizeof(RT_SIGNAL_STRUC); + IAPP_MEM_ALLOC(pSigBuf, DataLen); + if (pSigBuf == NULL) { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> Allocate signal buffer fail!\n")); + return; + } /* End of if */ + + IAPP_IOCTL_TO_WLAN(&IAPP_Ctrl_Block, RT_IOCTL_IAPP, pSigBuf, &DataLen, if_idx, + RT_QUERY_SIGNAL_CONTEXT); + + DBGPRINT(RT_DEBUG_TRACE, ("iapp> Receive a signal (Len = %d)!\n", DataLen)); + + /* pass event to raw drv socket */ + if (DataLen > 0) + write(pCtrlBK->PipeRawDrv[FT_KDP_PIPE_ID_WRITE], pSigBuf, DataLen); + /* End of if */ + + IAPP_MEM_FREE(pSigBuf); +#endif // FT_KDP_FUNC_SOCK_COMM // +} /* End of IAPP_USR2Handle */ + +/* +======================================================================== +Routine Description: + Handle termination signal. And we will close IAPP deamon at main(). + +Arguments: + Sig - no use + +Return Value: + None + +Note: + The APME should terminate operation of the local BSS, including + disassociation of any associated STAs and ceasing of beacon +transmissions, prior to terminating IAPP operation. + + The UDP and TCP ports for the IAPP should be closed and the IAPP entity + should cease operations. +======================================================================== +*/ +static VOID IAPP_TerminateHandle(IAPP_IN INT32 Sig) { + /* close all used sockets */ + IAPP_SocketClose(&IAPP_Ctrl_Block); + IAPP_Ctrl_Block.FlgIsTerminated = 1; +} /* End of IAPP_TerminateHandle */ + +/* +======================================================================== +Routine Description: + Main task. + +Arguments: + *pContext - IAPP control block + +Return Value: + None + +Note: +======================================================================== +*/ +VOID IAPP_Task(IAPP_IN VOID *pContext) { + // INT idx = 0; + RTMP_IAPP *pCtrlBK = (RTMP_IAPP *)pContext; + pid_t PidAuth; +//#ifdef IAPP_OS_LINUX +#if 0 + CHAR RouteAddCmd[64]; + CHAR RouteDelCmd[64]; +#endif + + DBGPRINT(RT_DEBUG_TRACE, + ("iapp> (ver.%s) task start...\n", IAPP_DAEMON_VERSION)); + + /* here is the child background process */ + if (IAPP_DSIfInfoGet(pCtrlBK) != TRUE) { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> Get interfce information failed\n")); + goto label_err; + } /* End of if */ + + /* init IPC message queue with 8021X deamon (obsolete) */ + if (IAPP_IPC_MSG_Init(pCtrlBK) != TRUE) { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> Setup message failed\n")); + goto label_err; + } /* End of if */ + +//#ifdef IAPP_OS_LINUX +#if 0 + /* add multicast route path, use SysCmd 'route' to show */ + /* + Destination Gateway Genmask Flags Metric Ref Use Iface + 224.0.1.178 * 255.255.255.255 UH 0 0 0 br-lan + */ + sprintf(RouteAddCmd, "route add %s %s\n", + IAPP_MULTICAST_ADDR, pCtrlBK->IfNameEth); + + sprintf(RouteDelCmd, "route del %s %s\n", + IAPP_MULTICAST_ADDR, pCtrlBK->IfNameEth); + + system(RouteAddCmd); +#endif + + /* init RV/TX Sockets */ + /* setup the message queue to be synchronous */ + IAPP_MsgProcess(pCtrlBK, IAPP_OPEN_SERVICE_REQ, NULL, 0, 0); + + pCtrlBK->FlgIsRcvRunning = FALSE; + if (IAPP_SocketOpen(pCtrlBK) == FALSE) { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> Open Socket failed\n")); +//#ifdef IAPP_OS_LINUX +#if 0 + system(RouteDelCmd); +#endif + goto label_err; + } /* End of if */ + + if (mt_iapp_get_wifi_iface_mac(pCtrlBK) == FALSE) { + goto label_err; + } + + /* init signal functions, driver will use SIGUSR1/2 to inform us */ + signal(SIGINT, IAPP_TerminateHandle); + signal(SIGTERM, IAPP_TerminateHandle); + + /* + Keep IAPP_USR2Handle() even you do not enable FT_KDP_FUNC_SOCK_COMM; + Or when driver send a signal SIGUSR2 and we have not registered it, + IAPP daemon will be closed by kernel automatically. + */ + signal(SIGUSR2, IAPP_USR2Handle); /* handle message from AP driver */ + + /* when RALINK AP (re)start up, move the line to 8021x deamon */ + /* signal(SIGUSR1, IAPP_USR1_Handle); */ + + /* set our PID to RALINK WLAN driver so WLAN driver can send Data to us */ +#ifdef IAPP_OS_LINUX + PidAuth = getpid(); +#endif // IAPP_OS_LINUX // +#ifdef IAPP_OS_VXWORKS + PidAuth = pCtrlBK->PID; +#endif // IAPP_OS_VXWORKS // + + pCtrlBK->PID = PidAuth; + + DBGPRINT(RT_DEBUG_TRACE, ("iapp> Process ID = 0x%x (%d %d)\n", PidAuth, + IAPP_MemAllocNum, IAPP_MemFreeNum)); + + mt_iapp_set_daemon_information(pCtrlBK, &PidAuth); + + IAPP_PID_Backup(PidAuth); + + /* start IAPP function (while FlgIsLoop in the function) */ + IAPP_Start(pCtrlBK); + + /* will not be here except terminate signal */ +//#ifdef IAPP_OS_LINUX +#if 0 + system(RouteDelCmd); +#endif + + DBGPRINT(RT_DEBUG_TRACE, ("iapp> IAPP_Task ends (%d, %d)!\n", + IAPP_MemAllocNum, IAPP_MemFreeNum)); + +label_err: + return; +} /* End of IAPP_Task */ + +/* +======================================================================== +Routine Description: + User space main function. + +Arguments: + Argc - argument number + *pArgv[] - arguments + +Return Value: + 0 - exit daemon + -1 - fork fail + +Note: +======================================================================== +*/ +#ifdef IAPP_OS_LINUX +INT32 main(INT32 Argc, CHAR *pArgv[]) +#endif // IAPP_OS_LINUX // +#ifdef IAPP_OS_VXWORKS + STATUS IAPP_Init(INT32 Argc, CHAR *pArgv[]) +#endif // IAPP_OS_VXWORKS // +{ + RTMP_IAPP *pCtrlBK = &IAPP_Ctrl_Block; +#ifdef IAPP_OS_LINUX + pid_t PID; +#endif // IAPP_OS_LINUX // + + /* init */ + IAPP_MEM_ZERO(pCtrlBK, sizeof(RTMP_IAPP)); + + /* kill old IAPP daemon if exists */ + IAPP_PID_Kill(); + + /* parse arguments from SysCmd line */ + if (IAPP_ArgumentParse(pCtrlBK, Argc, pArgv) == FALSE) + return 0; + /* End of if */ + +#ifdef IAPP_OS_LINUX + IAPP_Task((VOID *)pCtrlBK); +#endif + +#ifdef IAPP_OS_VXWORKS + pCtrlBK->PID = taskSpawn("tIappFt", 100, 0, 5000, (FUNCPTR)IAPP_Task, + (INT32)pCtrlBK, 0, 0, 0, 0, 0, 0, 0, 0, 0); + if (pCtrlBK->PID == ERROR) { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> Task spawn failed\n")); + goto label_err; + } /* End of if */ +#endif + + DBGPRINT(RT_DEBUG_TRACE, ("iapp> Exit daemon!\n")); + return 0; + +label_err: +#ifdef IAPP_OS_LINUX + exit(-1); +#endif + return 0; +} /* End of main */ + +/* +======================================================================== +Routine Description: + Send the IAPP move notify frame. + +Arguments: + *pCtrlBK - IAPP control blcok + *pPkt - the UDP packet + PktLen - the packet size + PeerIP - the IP of peer device + FlgUsingUdpWhenNoIP - TRUE: use UDP broadcast to send when PeerIP == 0 + *pRspBuf - used to issue response to the peer + +Return Value: + TRUE - send successfully + FAIL - send fail + +Note: + If PeerIP is 0, the func will use UDP broadcast frame. +======================================================================== +*/ +static BOOLEAN IAPP_TCP_PacketSend(IAPP_IN RTMP_IAPP *pCtrlBK, + /* IAPP_IN UCHAR *WifiMAC,*/ + IAPP_IN UCHAR *pPkt, IAPP_IN UINT32 PktLen, + IAPP_IN UINT32 PeerIP, + IAPP_IN BOOLEAN FlgUsingUdpWhenNoIP, + IAPP_IN UCHAR *pRspBuf, + IAPP_IN INT32 if_idx) { + INT32 SocketPeer; + struct sockaddr_in AddrSockConn; + UCHAR *pBufEncrypt; + BOOLEAN FuncStatus; + + /* sanity check */ + if ((FlgUsingUdpWhenNoIP == FALSE) && (PeerIP == 0)) + return FALSE; + /* End of if */ + + /* init */ + DBGPRINT(RT_DEBUG_TRACE, ("iapp> IAPP_TCP_PacketSend %x\n", PeerIP)); + FuncStatus = FALSE; + + if (PeerIP != 0) { + /* use TCP to send the packet */ + SocketPeer = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); + if (SocketPeer < 0) { + DBGPRINT(RT_DEBUG_TRACE, ("iapp> Open TCP socket fail!\n")); + return FALSE; + } /* End of if */ + + IAPP_MEM_ZERO(&AddrSockConn, sizeof(AddrSockConn)); + AddrSockConn.sin_family = AF_INET; + AddrSockConn.sin_addr.s_addr = PeerIP; + AddrSockConn.sin_port = htons(IAPP_TCP_PORT); + + if (connect(SocketPeer, (struct sockaddr *)&AddrSockConn, + sizeof(AddrSockConn)) < 0) { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> Connect socket failed %d.%d.%d.%d!\n", + IAPP_SHOW_IP(AddrSockConn.sin_addr.s_addr))); + goto label_fail; + } /* End of if */ + } /* End of if */ + + IAPP_RSP_BUF_ALLOCATE(pRspBuf, pBufEncrypt, + PktLen + IAPP_SECURITY_EXTEND_LEN); + if (pBufEncrypt == NULL) { + if (PeerIP != 0) + close(SocketPeer); + /* End of if */ + return FuncStatus; + } /* End of if */ + IAPP_MEM_MOVE(pBufEncrypt, pPkt, PktLen); + + if (PeerIP != 0) { +#ifdef FT_KDP_FUNC_PKT_ENCRYPT + /* ioctl to encrypt */ + IAPP_IOCTL_TO_WLAN(pCtrlBK, RT_IOCTL_IAPP, pBufEncrypt, &PktLen, if_idx, + RT_FT_DATA_ENCRYPT); +#endif // FT_KDP_FUNC_PKT_ENCRYPT // + + IAPP_HEX_DUMP("Send Content: ", pPkt, PktLen); // snowpin test + + if (send(SocketPeer, pBufEncrypt, PktLen, 0) < 0) { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> Send socket failed %d.%d.%d.%d!\n", + IAPP_SHOW_IP(AddrSockConn.sin_addr.s_addr))); + goto label_fail; + } /* End of if */ + } else { + /* use broadcast UDP packet but UDP can not be guaranted, no retry */ + IAPP_UDP_PACKET_SEND(pCtrlBK, pBufEncrypt, PktLen, pRspBuf, if_idx); + } /* End of if */ + + FuncStatus = TRUE; + +label_fail: + if (PeerIP != 0) + close(SocketPeer); + /* End of if */ + return FuncStatus; +} /* End of IAPP_TCP_PacketSend */ + +/* +======================================================================== +Routine Description: + Send the IAPP send security block frame. + +Arguments: + *pCtrlBK - IAPP control blcok + *pEvtHdr - event header + *pEvt - event + *pRspBuf - used to issue response to the peer + +Return Value: + None + +Note: + If PeerIP is 0, the func will use UDP broadcast frame. +======================================================================== +*/ +static VOID FT_KDP_SecurityBlockSend(IAPP_IN RTMP_IAPP *pCtrlBK, + IAPP_IN FT_KDP_EVT_HEADER *pEvtHdr, + IAPP_IN VOID *pEvt, IAPP_IN UCHAR *pRspBuf, + IAPP_IN UCHAR *WifiMAC, + IAPP_IN INT32 if_idx) { + INT32 SocketPeer; + struct sockaddr_in AddrSockConn; + UCHAR *pBufFrame; + RT_IAPP_SEND_SECURITY_BLOCK *pIappSendSB; + UINT32 PktLen, buf_len = 0; + + /* init */ + DBGPRINT(RT_DEBUG_TRACE, ("iapp> FT_KDP_SecurityBlockSend to %d.%d.%d.%d\n\n", + IAPP_SHOW_IP_HTONL(pEvtHdr->PeerIpAddr))); + + SocketPeer = 0; + pBufFrame = NULL; + + /* sanity check */ + if (pEvtHdr->PeerIpAddr != 0) { + /* use TCP to send the packet */ + SocketPeer = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); + if (SocketPeer < 0) { + DBGPRINT(RT_DEBUG_TRACE, ("iapp> Open TCP socket fail!\n")); + return; + } /* End of if */ + + IAPP_MEM_ZERO(&AddrSockConn, sizeof(AddrSockConn)); + AddrSockConn.sin_family = AF_INET; +#ifndef IAPP_TEST + AddrSockConn.sin_addr.s_addr = pEvtHdr->PeerIpAddr; +#else + AddrSockConn.sin_addr.s_addr = inet_addr("127.0.0.1"); /* test use */ +#endif + AddrSockConn.sin_port = htons(IAPP_TCP_PORT); + + if (connect(SocketPeer, (struct sockaddr *)&AddrSockConn, + sizeof(AddrSockConn)) < 0) { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> Connect socket failed %d.%d.%d.%d!\n", + IAPP_SHOW_IP(AddrSockConn.sin_addr.s_addr))); + goto label_fail; + } /* End of if */ + } /* End of if */ + + /* init frame buffer */ + buf_len = sizeof(RT_IAPP_SEND_SECURITY_BLOCK) + pEvtHdr->EventLen + + ETH_ALEN; /* ETH_ALEN is the length of WIFI Interface MAC. */ + + IAPP_RSP_BUF_ALLOCATE(pRspBuf, pBufFrame, buf_len); + if (pBufFrame == NULL) + goto label_fail; + /* End of if */ + + IAPP_PKT_ZERO(pBufFrame, buf_len); + + /* init the Security-Block-Send frame */ + pIappSendSB = (RT_IAPP_SEND_SECURITY_BLOCK *)pBufFrame; + pIappSendSB->IappHeader.Version = 0; + pIappSendSB->IappHeader.Command = IAPP_CMD_FT_SEND_SECURITY_BLOCK; + pIappSendSB->IappHeader.Identifier = SWAP_16(IAPP_IDENTIFIER_GET(pCtrlBK)); + PktLen = sizeof(RT_IAPP_SEND_SECURITY_BLOCK) + pEvtHdr->EventLen; + pIappSendSB->IappHeader.Length = SWAP_16(PktLen); + + pIappSendSB->Length = pEvtHdr->EventLen; + IAPP_MEM_MOVE(pIappSendSB->SB, pEvt, pEvtHdr->EventLen); + IAPP_MEM_MOVE(pIappSendSB->SB + pEvtHdr->EventLen, WifiMAC, ETH_ALEN); + + /* send out the frame */ + if (pEvtHdr->PeerIpAddr != 0) { +#ifdef FT_KDP_FUNC_PKT_ENCRYPT + /* ioctl to encrypt */ + IAPP_IOCTL_TO_WLAN(pCtrlBK, RT_IOCTL_IAPP, pBufFrame, &buf_len, if_idx, + RT_FT_DATA_ENCRYPT); +#endif // FT_KDP_FUNC_PKT_ENCRYPT // + + if (send(SocketPeer, pBufFrame, buf_len, 0) < 0) { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> Send socket failed %d.%d.%d.%d!\n", + IAPP_SHOW_IP(AddrSockConn.sin_addr.s_addr))); + goto label_fail; + } /* End of if */ + } else { + /* use broadcast UDP packet but UDP can not be guaranted, no retry */ + IAPP_UDP_PACKET_SEND(pCtrlBK, pBufFrame, buf_len, pRspBuf, if_idx); + } /* End of if */ + +label_fail: + if (SocketPeer > 0) + close(SocketPeer); + /* End of if */ + return; +} /* End of FT_KDP_SecurityBlockSend */ + +/* +======================================================================== +Routine Description: + Send the IAPP ack security block frame. + +Arguments: + *pCtrlBK - IAPP control blcok + *pEvtHdr - event header + *pEvt - event + +Return Value: + None + +Note: +======================================================================== +*/ +static VOID FT_KDP_SecurityBlockAck(IAPP_IN RTMP_IAPP *pCtrlBK, + IAPP_IN FT_KDP_EVT_HEADER *pEvtHdr, + IAPP_IN VOID *pEvt, IAPP_IN UCHAR *pRspBuf, + IAPP_IN INT32 if_idx) { + INT32 SocketPeer; + struct sockaddr_in AddrSockConn; + UCHAR *pBufFrame; + RT_IAPP_SEND_SECURITY_BLOCK *pIappSendSB; + UINT32 PktLen; + + /* init */ + DBGPRINT(RT_DEBUG_TRACE, ("iapp> FT_KDP_SecurityBlockAck\n")); + + SocketPeer = 0; + pBufFrame = NULL; + + /* open TCP socket to the peer */ + SocketPeer = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); + if (SocketPeer < 0) { + DBGPRINT(RT_DEBUG_TRACE, ("iapp> Open TCP socket fail!\n")); + return; + } /* End of if */ + + IAPP_MEM_ZERO(&AddrSockConn, sizeof(AddrSockConn)); + AddrSockConn.sin_family = AF_INET; +#ifndef IAPP_TEST + AddrSockConn.sin_addr.s_addr = pEvtHdr->PeerIpAddr; +#else + AddrSockConn.sin_addr.s_addr = inet_addr("127.0.0.1"); /* test use */ +#endif + AddrSockConn.sin_port = htons(IAPP_TCP_PORT); + + if (connect(SocketPeer, (struct sockaddr *)&AddrSockConn, + sizeof(AddrSockConn)) < 0) { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> Connect socket failed %d.%d.%d.%d!\n", + IAPP_SHOW_IP(AddrSockConn.sin_addr.s_addr))); + goto label_fail; + } /* End of if */ + + /* init frame buffer */ + PktLen = sizeof(RT_IAPP_SEND_SECURITY_BLOCK) + pEvtHdr->EventLen; + + IAPP_RSP_BUF_ALLOCATE(pRspBuf, pBufFrame, PktLen); + if (pBufFrame == NULL) + goto label_fail; + /* End of if */ + IAPP_PKT_ZERO(pBufFrame, PktLen); + + /* init the Security-Block-Ack frame */ + pIappSendSB = (RT_IAPP_SEND_SECURITY_BLOCK *)pBufFrame; + pIappSendSB->IappHeader.Version = 0; + pIappSendSB->IappHeader.Command = IAPP_CMD_FT_ACK_SECURITY_BLOCK; + pIappSendSB->IappHeader.Identifier = SWAP_16(IAPP_IDENTIFIER_GET(pCtrlBK)); + + pIappSendSB->IappHeader.Length = SWAP_16(PktLen); + + pIappSendSB->Length = pEvtHdr->EventLen; + IAPP_MEM_MOVE(pIappSendSB->SB, pEvt, pEvtHdr->EventLen); + +#ifdef FT_KDP_FUNC_PKT_ENCRYPT + /* ioctl to encrypt */ + IAPP_IOCTL_TO_WLAN(pCtrlBK, RT_IOCTL_IAPP, pBufFrame, &PktLen, if_idx, + RT_FT_DATA_ENCRYPT); +#endif // FT_KDP_FUNC_PKT_ENCRYPT // + + /* send out the frame */ + if (send(SocketPeer, pBufFrame, PktLen, 0) < 0) { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> Send socket failed %d.%d.%d.%d!\n", + IAPP_SHOW_IP(AddrSockConn.sin_addr.s_addr))); + goto label_fail; + } /* End of if */ + +label_fail: + if (SocketPeer > 0) + close(SocketPeer); + /* End of if */ + return; +} /* End of FT_KDP_SecurityBlockAck */ + +/* +======================================================================== +Routine Description: + Send the Information Request frame. + +Arguments: + *pCtrlBK - IAPP control blcok + *pEvtHdr - event header + *pEvt - event + *pRspBuf - used to issue response to the peer + +Return Value: + None + +Note: +======================================================================== +*/ +static VOID FT_KDP_InformationRequestSend(IAPP_IN RTMP_IAPP *pCtrlBK, + IAPP_IN FT_KDP_EVT_HEADER *pEvtHdr, + IAPP_IN VOID *pEvt, + IAPP_IN UCHAR *pRspBuf, + IAPP_IN INT32 if_idx) { + UCHAR *pBufFrame; + RT_IAPP_INFORMATION *pIappInfor; + UINT32 PktLen; + + /* init */ + DBGPRINT(RT_DEBUG_TRACE, ("iapp> FT_KDP_InformationRequestSend\n")); + + pBufFrame = NULL; + + /* init frame buffer */ + PktLen = sizeof(RT_IAPP_INFORMATION) + pEvtHdr->EventLen; + + IAPP_RSP_BUF_ALLOCATE(pRspBuf, pBufFrame, PktLen); + if (pBufFrame == NULL) + return; + /* End of if */ + + IAPP_PKT_ZERO(pBufFrame, PktLen); + pIappInfor = (RT_IAPP_INFORMATION *)pBufFrame; + + /* init the AP Information frame */ + pIappInfor->IappHeader.Version = 0; + pIappInfor->IappHeader.Command = IAPP_CMD_INFO_REQUEST; + pIappInfor->IappHeader.Identifier = SWAP_16(IAPP_IDENTIFIER_GET(pCtrlBK)); + + pIappInfor->IappHeader.Length = SWAP_16(PktLen); + + pIappInfor->Length = pEvtHdr->EventLen; + IAPP_MEM_MOVE(pIappInfor->IB, pEvt, pEvtHdr->EventLen); + + /* use broadcast UDP packet but UDP can not be guaranted, no retry */ + IAPP_UDP_PACKET_SEND(pCtrlBK, pBufFrame, PktLen, pRspBuf, if_idx); +} /* End of FT_KDP_InformationRequestSend */ + +/* +======================================================================== +Routine Description: + Send the Information Response frame. + +Arguments: + *pCtrlBK - IAPP control blcok + *pEvtHdr - event header + *pEvt - event + *pRspBuf - used to issue response to the peer + +Return Value: + None + +Note: +======================================================================== +*/ +static VOID FT_KDP_InformationResponseSend(IAPP_IN RTMP_IAPP *pCtrlBK, + IAPP_IN FT_KDP_EVT_HEADER *pEvtHdr, + IAPP_IN VOID *pEvt, + IAPP_IN UCHAR *pRspBuf, + IAPP_IN INT32 if_idx) { + INT32 SocketPeer; + struct sockaddr_in AddrSockConn; + UCHAR *pBufFrame; + RT_IAPP_INFORMATION *pIappInfor; + UINT32 PktLen; + + /* init */ + DBGPRINT(RT_DEBUG_TRACE, + ("iapp> FT_KDP_InformationResponseSend to %d.%d.%d.%d\n", + IAPP_SHOW_IP_HTONL(pEvtHdr->PeerIpAddr))); + + if (pEvtHdr->PeerIpAddr == 0) + return; + /* End of if */ + + SocketPeer = 0; + pBufFrame = NULL; + + /* open TCP socket to the peer */ + SocketPeer = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); + if (SocketPeer < 0) { + DBGPRINT(RT_DEBUG_TRACE, ("iapp> Open TCP socket fail!\n")); + return; + } /* End of if */ + + IAPP_MEM_ZERO(&AddrSockConn, sizeof(AddrSockConn)); + AddrSockConn.sin_family = AF_INET; +#ifndef IAPP_TEST + AddrSockConn.sin_addr.s_addr = pEvtHdr->PeerIpAddr; +#else + AddrSockConn.sin_addr.s_addr = inet_addr("127.0.0.1"); /* test use */ +#endif + AddrSockConn.sin_port = htons(IAPP_TCP_PORT); + + if (connect(SocketPeer, (struct sockaddr *)&AddrSockConn, + sizeof(AddrSockConn)) < 0) { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> Connect socket failed %d.%d.%d.%d!\n", + IAPP_SHOW_IP(AddrSockConn.sin_addr.s_addr))); + goto label_fail; + } /* End of if */ + + /* init frame buffer */ + PktLen = sizeof(RT_IAPP_INFORMATION) + pEvtHdr->EventLen; + + IAPP_RSP_BUF_ALLOCATE(pRspBuf, pBufFrame, PktLen); + if (pBufFrame == NULL) + goto label_fail; + /* End of if */ + IAPP_PKT_ZERO(pBufFrame, PktLen); + + /* init the Security-Block-Ack frame */ + pIappInfor = (RT_IAPP_INFORMATION *)pBufFrame; + pIappInfor->IappHeader.Version = 0; + pIappInfor->IappHeader.Command = IAPP_CMD_INFO_RESPONSE; + pIappInfor->IappHeader.Identifier = SWAP_16(IAPP_IDENTIFIER_GET(pCtrlBK)); + + pIappInfor->IappHeader.Length = SWAP_16(PktLen); + + pIappInfor->Length = pEvtHdr->EventLen; + IAPP_MEM_MOVE(pIappInfor->IB, pEvt, pEvtHdr->EventLen); + +#ifdef FT_KDP_FUNC_PKT_ENCRYPT + /* ioctl to encrypt */ + IAPP_IOCTL_TO_WLAN(pCtrlBK, RT_IOCTL_IAPP, pBufFrame, &PktLen, if_idx, + RT_FT_DATA_ENCRYPT); +#endif // FT_KDP_FUNC_PKT_ENCRYPT // + + /* send out the frame */ + if (send(SocketPeer, pBufFrame, PktLen, 0) < 0) { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> Send socket failed %d.%d.%d.%d!\n", + IAPP_SHOW_IP(AddrSockConn.sin_addr.s_addr))); + goto label_fail; + } /* End of if */ + +label_fail: + if (SocketPeer > 0) + close(SocketPeer); + /* End of if */ + return; +} /* End of FT_KDP_InformationResponseSend */ + +/* +======================================================================== +Routine Description: + Send the Information Report frame. + +Arguments: + *pCtrlBK - IAPP control blcok + *pEvtHdr - event header + *pEvt - event + *pRspBuf - used to issue response to the peer + +Return Value: + None + +Note: +======================================================================== +*/ +static VOID FT_KDP_InformationReportSend(IAPP_IN RTMP_IAPP *pCtrlBK, + IAPP_IN FT_KDP_EVT_HEADER *pEvtHdr, + IAPP_IN VOID *pEvt, + IAPP_IN UCHAR *pRspBuf, + IAPP_IN INT32 if_idx) { + UCHAR *pBufFrame; + RT_IAPP_INFORMATION *pIappInfor; + UINT32 PktLen; + + /* init */ + DBGPRINT(RT_DEBUG_TRACE, + ("iapp> FT_KDP_InformationReportSend to %d.%d.%d.%d\n", + IAPP_SHOW_IP_HTONL(pEvtHdr->PeerIpAddr))); + + pBufFrame = NULL; + + /* init frame buffer */ + PktLen = sizeof(RT_IAPP_INFORMATION) + pEvtHdr->EventLen; + + IAPP_RSP_BUF_ALLOCATE(pRspBuf, pBufFrame, PktLen); + if (pBufFrame == NULL) + return; + /* End of if */ + + IAPP_PKT_ZERO(pBufFrame, PktLen); + pIappInfor = (RT_IAPP_INFORMATION *)pBufFrame; + + /* init the AP Information frame */ + pIappInfor->IappHeader.Version = 0; + pIappInfor->IappHeader.Command = IAPP_CMD_INFO_BROADCAST; + pIappInfor->IappHeader.Identifier = SWAP_16(IAPP_IDENTIFIER_GET(pCtrlBK)); + + pIappInfor->IappHeader.Length = SWAP_16(PktLen); + + pIappInfor->Length = pEvtHdr->EventLen; + IAPP_MEM_MOVE(pIappInfor->IB, pEvt, pEvtHdr->EventLen); + + /* use broadcast UDP packet but UDP can not be guaranted, no retry */ + IAPP_UDP_PACKET_SEND(pCtrlBK, pBufFrame, PktLen, pRspBuf, if_idx); +} /* End of FT_KDP_InformationReportSend */ + +/* +======================================================================== +Routine Description: + Forward the FT Action frame to the peer. + +Arguments: + *pCtrlBK - IAPP control blcok + *pEvtHdr - event header + *pEvt - event + PacketType - 0 for Remote Request, and to 1 for Remote Response + *pMacDa - DA MAC + *pMacSa - SA MAC + *pRspBuf - used to issue response to the peer + +Return Value: + None + +Note: +======================================================================== +*/ +static VOID FT_RRB_ActionForward(IAPP_IN RTMP_IAPP *pCtrlBK, + IAPP_IN FT_KDP_EVT_HEADER *pEvtHdr, + IAPP_IN VOID *pEvt, IAPP_IN UINT16 PacketType, + IAPP_IN UCHAR *pMacDa, IAPP_IN UCHAR *pMacSa, + IAPP_IN UCHAR *pMacAp, IAPP_IN UCHAR *pRspBuf, + IAPP_IN INT32 if_idx) { + UCHAR *pBufFrame; + FT_RRB_FRAME *pFrameRRB; + INT32 Status; + UINT32 PktLen; + UINT32 EvtLen; + + /* init the update frame body */ + DBGPRINT(RT_DEBUG_TRACE, ("iapp> Forward a RRB packet (len = %d) to " + "%02x:%02x:%02x:%02x:%02x:%02x!\n", + pEvtHdr->EventLen, pMacDa[0], pMacDa[1], pMacDa[2], + pMacDa[3], pMacDa[4], pMacDa[5])); + + PktLen = sizeof(FT_RRB_FRAME) + pEvtHdr->EventLen; + + IAPP_RSP_BUF_ALLOCATE(pRspBuf, pBufFrame, PktLen); + if (pBufFrame == NULL) + return; + /* End of if */ + IAPP_PKT_ZERO(pBufFrame, PktLen); + + pFrameRRB = (FT_RRB_FRAME *)pBufFrame; + IAPP_MEM_MOVE(pFrameRRB->ETH.DA, pMacDa, sizeof(pFrameRRB->ETH.DA)); + IAPP_MEM_MOVE(pFrameRRB->ETH.SA, pMacSa, sizeof(pFrameRRB->ETH.SA)); + pFrameRRB->ETH.Len = htons(RRB_ETH_PRO); + + pFrameRRB->RemoteFrameType = FT_RRB_FRAME_TYPE; + pFrameRRB->FTPacketType = PacketType; + pFrameRRB->FTActionLength = pEvtHdr->EventLen; + IAPP_MEM_MOVE(pFrameRRB->ApAddress, pMacAp, sizeof(pFrameRRB->ApAddress)); + + IAPP_MEM_MOVE(pFrameRRB->FTActionFrame, pEvt, pEvtHdr->EventLen); + +#ifdef FT_KDP_FUNC_PKT_ENCRYPT + /* ioctl to encrypt */ + + /* the address of pEvtHdr->EventLen is not 4B align */ + EvtLen = pEvtHdr->EventLen; + + IAPP_IOCTL_TO_WLAN(pCtrlBK, RT_IOCTL_IAPP, pFrameRRB->FTActionFrame, &EvtLen, + if_idx, RT_FT_DATA_ENCRYPT); + + /* reassign the packet length due to changed pEvtHdr->EventLen */ + PktLen = sizeof(FT_RRB_FRAME) + EvtLen; +#endif // FT_KDP_FUNC_PKT_ENCRYPT // + +#ifdef IAPP_OS_LINUX + { + /* send the RRB frame */ + Status = send(pCtrlBK->SocketRawRRB, pBufFrame, PktLen, 0); + if (Status < 0) { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> Send RRB packet failed %d!\n", Status)); + goto LabelFail; + } /* End of if */ + } +#endif // IAPP_OS_LINUX // + +#ifdef IAPP_OS_VXWORKS + { + M_BLK_ID pUpdatePkt; + UINT32 IdIfNum; + + /* loop for eth0, eth1, eth2...... */ + for (IdIfNum = 0; IdIfNum < FT_KDP_BR_ETH_IF_NUM; IdIfNum++) { + if ((pUpdatePkt = netTupleGet(_pNetDpool, PktLen, M_DONTWAIT, MT_DATA, + TRUE)) == NULL) { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> iapp> Get packet buffer fail!\n")); + goto LabelFail; + } /* End of if */ + + pUpdatePkt->mBlkHdr.mFlags |= M_PKTHDR; + pUpdatePkt->m_len = PktLen; + + IAPP_MEM_MOVE(pUpdatePkt->m_data, pBufFrame, PktLen); + + if (muxSend(pCtrlBK->pRrbCookieTo[IdIfNum], pUpdatePkt) == ERROR) { + DBGPRINT(RT_DEBUG_ERROR, ("iapp> Send RRB packet failed!\n")); + netMblkClChainFree(pUpdatePkt); + goto LabelFail; + } /* End of if */ + } /* End of for */ + } +#endif // IAPP_OS_VXWORKS // + + DBGPRINT(RT_DEBUG_TRACE, ("iapp> Send RRB packet OK!\n")); + +LabelFail: + return; +} /* End of FT_RRB_ActionForward */ + +/* End of rtmpiapp.c */ diff --git a/package/lean/mt/mtkiappd/src/rtmpiapp.h b/package/lean/mt/mtkiappd/src/rtmpiapp.h new file mode 100644 index 000000000..7fa503a35 --- /dev/null +++ b/package/lean/mt/mtkiappd/src/rtmpiapp.h @@ -0,0 +1,580 @@ +/**************************************************************************** + * Ralink Tech Inc. + * Taiwan, R.O.C. + * + * (c) Copyright 2002, Ralink Technology, Inc. + * + * All rights reserved. Ralink's source code is an unpublished work and the + * use of a copyright notice does not imply otherwise. This source code + * contains confidential trade secret material of Ralink Tech. Any attemp + * or participation in deciphering, decoding, reverse engineering or in any + * way altering the source code is stricitly prohibited, unless the prior + * written consent of Ralink Technology, Inc. is obtained. + ***************************************************************************/ + +/**************************************************************************** + + Abstract: + + All related IEEE802.11f IAPP + IEEE802.11r IAPP extension. + +***************************************************************************/ + +#ifndef __RTMP_IAPP_H__ +#define __RTMP_IAPP_H__ + +#include "rt_config.h" +#include "rt_typedef.h" + +#define IAPP_OS_LINUX +//#define IAPP_OS_VXWORKS + +/* + IAPP issues: + + 1. Lack of fast roaming support, particularly required for voice; + 2. Only supports use of RADIUS (in a non-standard way); +*/ + +/* + Three levels of support for ESS formation are possible with the IAPP + capabilities described here: + + Level 1: no administrative or security support; + Level 2: support for dynamic mapping of BSSID to IP addresses; and + Level 3: support for encryption and authentication of IAPP messages. + + Level 1 support can be achieved by configuring each AP in the ESS with + the BSSID to IP address mapping for all other APs in the ESS. This may + be acceptable for a small ESS. + + Many ESS providers will need levels 2 or 3, which require RADIUS + support. +*/ + +/* + Note with RALINK driver: + + 1. OID to RALINK AP driver; + 2. RT_SIGNAL_STRUC + 3. IAPP daemon must be run after br-lan & ra0 built up. +*/ + +/* ---------------------------- User Definition ------------------------ */ + +#define FT_KDP_FUNC_SOCK_COMM /* use socket to communicate with driver */ +#define FT_KDP_FUNC_PKT_ENCRYPT /* do encryption for each IAPP packet */ +#define FT_KDP_SELECT_TIMEOUT /* use timeout to wait for any packet */ +#define FT_KDP_KEY_FROM_DAEMON /* key is set in daemon */ +#define FT_KDP_DEFAULT_IF_ETH "br-lan" +#define FT_KDP_DEFAULT_IF_WLAN \ + "br-lan" /* used to receive command from WLAN \ + */ +#define FT_KDP_DEFAULT_IF_WLAN_IOCTL "ra0" /* ioctl command to WLAN */ + +/* + Inter-AP communications present opportunities to an attacker. + The attacker can use IAPP or forged 802.11 MAC management frames as a + Denial-of-Service (DoS) attack against a STA state in its AP. + It can capture MOVE packets to gather information on the STA that is + roaming. It can act as a rogue AP in the ESS. + + If use RADIUS server, the IAPP entity sends the RADIUS Initiate-Request + and receives the RADIUS Initiate-Accept or Initiate-Reject. + If the Initiate-Accept is received, then the IAPP entity initializes + its data structures, functions, and protocols. If an Initiate-Reject + is received, the IAPP does not start. + + The RADIUS servers provide two functions, mapping the BSSID of an AP to + its IP address on the DSM and distribution of keys to the APs to allow + the encryption of the communications between the APs. + + The function of mapping the BSSID of an AP to its IP address on the DSM + can also be accomplished by local configuration information or the IETF + Inverse Address Resolution Protocol (RFC 2390:1998). + + We don't support RADIUS server so we use a fixed PSK key to encrypt. +*/ +#define FT_KDP_DEFAULT_PTK "zpxrjs9uo2kvbuqo" + +#ifdef IAPP_OS_LINUX +#define RT_IOCTL_IAPP (SIOCIWFIRSTPRIV + 0x01) +#endif // IAPP_OS_LINUX // + +#ifdef IAPP_OS_VXWORKS +#define PF_PACKET AF_INET +#define RT_IOCTL_IAPP VX_RT_PRIV_IOCTL +#define FT_KDP_WLAN_NAME "ra" +#define FT_KDP_WLAN_UNIT 0 +#define FT_KDP_ETH_NAME "eth" /* must not use mirror */ +#define FT_KDP_BR_ETH_IF_NUM 2 /* eth0 and eth1 */ +#define FT_KDP_BR_NAME "mirror" +#define FT_KDP_BR_UNIT 0 +#endif // IAPP_OS_VXWORKS // + +#define HASH_TABLE_SIZE 128 +#define MAX_NUM_OF_CLIENT 64 + +#define MAC_ADDR_HASH(Addr) \ + (Addr[0] ^ Addr[1] ^ Addr[2] ^ Addr[3] ^ Addr[4] ^ Addr[5]) +#define MAC_ADDR_HASH_INDEX(Addr) (MAC_ADDR_HASH(Addr) & (HASH_TABLE_SIZE - 1)) + +/* ---------------------------- MACRO Definition ---------------------------- */ +#define IAPP_LITTLE_ENDIAN /* __BIG_ENDIAN */ + +#ifdef IAPP_LITTLE_ENDIAN +#define SWAP_16(x) \ + ((UINT16)((((UINT16)(x) & (UINT16)0x00ffU) << 8) | \ + (((UINT16)(x) & (UINT16)0xff00U) >> 8))) +#else + +#define SWAP_16(x) x +#endif + +/* 16 for extra 8B encryption & 8B-align */ +#define IAPP_PKT_ALLOCATE(__pPkt, __Len) \ + IAPP_MEM_ALLOC(__pPkt, __Len + IAPP_SECURITY_EXTEND_LEN) +#define IAPP_PKT_ZERO(__pPkt, __Len) \ + IAPP_MEM_ZERO(__pPkt, __Len + IAPP_SECURITY_EXTEND_LEN) + +#define IAPP_MEM_ALLOC(__pMem, __Size) \ + { \ + os_alloc_mem(NULL, (UCHAR **)(&__pMem), __Size); \ + IAPP_MemAllocNum++; \ + } +#define IAPP_MEM_FREE(__Mem) \ + { \ + os_free_mem(NULL, __Mem); \ + IAPP_MemFreeNum++; \ + } + +/* calculate the size to the multiple of 8 */ +#define IAPP_ENCRYPTED_DATA_SIZE_CAL(__LenOfAction) \ + if ((__LenOfAction)&0x07) \ + (__LenOfAction) += 8 - ((__LenOfAction)&0x07); \ + __LenOfAction += 8; + +#define IAPP_MEM_ZERO(__Dst, __Len) NdisZeroMemory(__Dst, __Len) +#define IAPP_MEM_FILL(__Dst, __Val, __Len) NdisFillMemory(__Dst, __Len, __Val) +#define IAPP_MEM_MOVE(__Dst, __Src, __Len) NdisMoveMemory(__Dst, __Src, __Len) + +#define IAPP_HEX_DUMP(__pPrompt, __pBuf, __Len) \ + IAPP_HexDump((CHAR *)__pPrompt, (CHAR *)__pBuf, __Len) + +#define IAPP_IOCTL_TO_WLAN(__pCtrlBK, __Param, __pData, __pLen, __ApIdx, \ + __Flags) \ + { \ + IAPP_IoctlToWLAN(__pCtrlBK, __Param, (CHAR *)(__pData), (INT32 *)(__pLen), \ + __ApIdx, __Flags); \ + } + +/* ---------------------------- Structure Definition ------------------------ */ + +/* + IAPP supports three protocol sequences. + + One is initiated by invoking the IAPP-ADD.request after the APME + receives an MLME-ASSOCIATE.indication. + + The second is initiated by invoking the IAPPMOVE.request after the APME + receives an MLME-REASSOCIATE.indication. + + The third is initiated by invoking the IAPP-CACHE.request to cache + context in neighboring APs to facilitate fast roaming. +*/ + +/* event log */ +#define FT_IP_ADDRESS_SIZE 4 + +/* IAPP header in the frame body, 6B */ +typedef struct PACKED _RT_IAPP_HEADER { + + UCHAR Version; /* indicates the protocol version of the IAPP */ + UCHAR Command; /* ADD-notify, MOVE-notify, etc. */ + UINT16 Identifier; /* aids in matching requests and responses */ + UINT16 Length; /* indicates the length of the entire packet */ +} RT_IAPP_HEADER; + +/* IAPP Action Frame */ +/* ADD notify frame */ +typedef struct PACKED _RT_IAPP_ADD_NOTIFY { + + RT_IAPP_HEADER IappHeader; + + /* the number of octets in the MAC Address */ + UCHAR AddressLen; + + /* should be sent with a value of zero */ +#define FT_KDP_ADD_NOTIFY_RSVD_11R_SUPPORT 0x01 + UCHAR Rsvd; + + /* the MAC address of the STA that has associated */ + UCHAR MacAddr[ETH_ALEN]; + + /* the integer value of the sequence number of the association request frame + */ + /* + The 802.11 sequence number may be an ambiguous indication of the most + recent association. But, this information may be useful to an + algorithm making a determination of the location of the most recent + association of a STA. + */ + UINT16 Sequence; + +} RT_IAPP_ADD_NOTIFY; + +/* MOVE requset frame */ +typedef struct PACKED _RT_IAPP_MOVE_NOTIFY { + + RT_IAPP_HEADER IappHeader; + + /* the number of octets in the MAC Address */ + UCHAR AddressLen; + + /* should be sent with a value of zero */ + UCHAR Rsvd; + + /* the MAC address of the STA that has associated */ + UCHAR MacAddr[ETH_ALEN]; + + /* the integer value of the sequence number of the association request frame + */ + UINT16 Sequence; + + /* indicates the number of octets in the Context Block field, always 0 */ + UINT16 LenOfContextBlock; + +} RT_IAPP_MOVE_NOTIFY; + +/* MOVE response frame */ +typedef struct PACKED _RT_IAPP_MOVE_RSP { + + RT_IAPP_HEADER IappHeader; + + /* the number of octets in the MAC Address */ + UCHAR AddressLen; + +#define IAPP_MOVE_RSP_STATUS_SUCCESS 0 +#define IAPP_MOVE_RSP_STATUS_DENY 1 +#define IAPP_MOVE_RSP_STATUS_STALE 2 + /* 0 Successful, 1 Move denied, 2 Stale move */ + /* + FAIL indicates that a RADIUS Access-Reject was received in response + to the RADIUS Access-Request sent to the RADUS server to look up the + IP address of the Old AP. (not use the IP in the MOVE-notify frame) + */ + UCHAR Status; + + /* the MAC address of the STA that has associated */ + UCHAR MacAddr[ETH_ALEN]; + + /* the integer value of the sequence number of the association request frame + */ + UINT16 Sequence; + + /* indicates the number of octets in the Context Block field, always 0 */ + UINT16 LenOfContextBlock; + +} RT_IAPP_MOVE_RSP; + +/* SEND-SECURITY-BLOCK frame */ +typedef struct PACKED _RT_IAPP_SEND_SECURITY_BLOCK { + + RT_IAPP_HEADER IappHeader; + + /* first 8 bytes of the ACK nonce */ +#define IAPP_SB_INIT_VEC_SIZE 8 + UCHAR InitVec[8]; + + /* indicates the number of octets in the Security Block field */ + UINT16 Length; + + /* + Contains the security information being forwarded from the + RADIUS Server through the new AP to the old AP. + */ + UCHAR SB[0]; + +} RT_IAPP_SEND_SECURITY_BLOCK; + +/* no use */ +typedef struct PACKED _RT_IAPP_ACK_SECURITY_BLOCK { + + RT_IAPP_HEADER IappHeader; + + /* copied from the Date/Time stamp */ + UCHAR InitVec[8]; + + /* + Content of the New-AP-ACK-Authenticator information element that + the old AP received in the Security Block. + */ + UCHAR NewApAckAuth[48]; + +} RT_IAPP_ACK_SECURITY_BLOCK; + +/* private frame */ +typedef struct PACKED _RT_IAPP_INFORMATION { + +#define IAPP_INFO_TYPE_BC 0 +#define IAPP_INFO_TYPE_REQ 1 +#define IAPP_INFO_TYPE_RSP 2 +#define IAPP_INFO_TYPE_MAX_NUM 3 + + RT_IAPP_HEADER IappHeader; + + /* indicates the number of octets in the Information Block field */ + UINT16 Length; + + /* contains the AP information being forwarded */ + UCHAR IB[0]; + +} RT_IAPP_INFORMATION; + +typedef struct PACKED _RT_IAPP_SECURITY_MONITOR { + + RT_IAPP_HEADER IappHeader; + RT_802_11_EVENT_TABLE EvtTab; +} RT_IAPP_SECURITY_MONITOR, *PRT_IAPP_SECURITY_MONITOR; + +/* Event structure between daemon and driver */ +#define FT_KDP_EVT_HEADER_SIZE sizeof(FT_KDP_EVT_HEADER) + +typedef struct _OID_REQ { + + INT32 OID; + INT32 Len; + CHAR Buf[0]; +} OID_REQ, *POID_REQ; + +typedef struct _MSG_BUF { + + INT32 MsgType; + INT32 MsgSubType; + CHAR Buf[1024]; +} MSG_BUF, *PMSG_BUF; + +/* Layer 2 Update frame to switch/bridge */ +typedef struct PACKED _FT_ETH_HEADER { + + UCHAR DA[ETH_ALEN]; + UCHAR SA[ETH_ALEN]; + UINT16 Len; + +} FT_ETH_HEADER; + +/* For any Layer2 devices, e.g., bridges, switches and other APs, the frame + can update their forwarding tables with the correct port to reach the new + location of the STA */ +typedef struct PACKED _RT_IAPP_L2_UPDATE_FRAME { + + FT_ETH_HEADER ETH; + UCHAR DSAP; /* must be NULL */ + UCHAR SSAP; /* must be NULL */ + UCHAR Control; /* reference to IEEE Std 802.2 */ + UCHAR XIDInfo[3]; /* reference to IEEE Std 802.2 */ +} RT_IAPP_L2_UPDATE_FRAME, *PRT_IAPP_L2_UPDATE_FRAME; + +/* RRB protocol */ +typedef struct PACKED _FT_RRB_FRAME { + /* ethernet header */ + FT_ETH_HEADER ETH; + + /* shall be set to 1 */ +#define FT_RRB_FRAME_TYPE 1 + UCHAR RemoteFrameType; + + /* 0 for Remote Request, and to 1 for Remote Response */ + UCHAR FTPacketType; + + /* the length in octets of the FT Action Frame field */ + UINT16 FTActionLength; + + /* the BSSID of the current AP */ + UCHAR ApAddress[ETH_ALEN]; + + /* + The contents of the FT Action frame, from the Category field to the + end of the Action Frame body. + */ +#define FT_RRB_HEADER_SIZE (sizeof(FT_RRB_FRAME)) + UCHAR FTActionFrame[0]; +} FT_RRB_FRAME; + +typedef struct _FT_CLIENT_INFO { + struct _FT_CLIENT_INFO *next; + INT if_idx; + UCHAR sta_mac[ETH_ALEN]; + UCHAR ap_mac[ETH_ALEN]; + UCHAR used; + UCHAR hash_idx; +} FT_CLIENT_INFO; + +typedef struct _FT_CLIENT_TABLE { + FT_CLIENT_INFO *hash[HASH_TABLE_SIZE]; + FT_CLIENT_INFO ft_sta_info[MAX_NUM_OF_CLIENT]; + INT32 ft_sta_table_size; +} FT_CLIENT_TABLE; + +/* IAPP control block */ +#define IAPP_ENCRYPT_KEY_MAX_SIZE 64 +#define MAX_WIFI_COUNT 2 +typedef struct _RTMP_IAPP { + + CHAR IfNameEth[IFNAMSIZ]; /* ethernet interface name */ + CHAR IfNameWlan[IFNAMSIZ]; /* wireless interface name */ + CHAR IfNameWlanIoctl[MAX_WIFI_COUNT][IFNAMSIZ]; /* wireless interface name */ + UCHAR IfNameWlanMAC[MAX_WIFI_COUNT][ETH_ALEN]; /* wireless interface name */ + INT32 IfNameWlanCount; + + BOOLEAN FlgIsTerminated; /* if terminate IAPP daemon */ + + struct in_addr AddrOwn; /* IP address of ethernet interface */ + struct in_addr AddrNetmask; /* netmask of ethernet interface */ + struct in_addr AddrBroadcast; /* broadcast address of ethernet interface */ + + BOOLEAN FlgIsRcvRunning; /* if rcv handler is running */ + + INT32 SocketUdpSend; /* used to send/rcv IAPP multicast frame */ + INT32 SocketTcpRcv; /* used to rcv unicast frame from a peer */ + INT32 SocketRawBr; /* used to send bridge L2 frame */ + INT32 SocketIoctl; /* used to ioctl() to WLAN driver */ + INT32 SocketRawRRB; /* used in RRB RAW protocol */ + +#ifdef FT_KDP_FUNC_SOCK_COMM + INT32 SocketRawDrv; /* used to receive message from driver */ +#endif // FT_KDP_FUNC_SOCK_COMM // + +#ifndef FT_KDP_FUNC_SOCK_COMM +#ifdef IAPP_OS_LINUX +#define FT_KDP_PIPE_ID_READ 0 +#define FT_KDP_PIPE_ID_WRITE 1 + INT32 PipeRawDrv[2]; /* used to receive message from driver */ +#endif // IAPP_OS_LINUX // +#endif // FT_KDP_FUNC_SOCK_COMM // + +#ifdef IAPP_OS_VXWORKS + VOID *pBcCookie[FT_KDP_BR_ETH_IF_NUM]; /* for bridge L2 frame */ + VOID *pDrvCookieTo; /* for ioctl to WLAN driver */ + VOID *pDrvCookieFrom; /* for ioctl from WLAN driver */ + VOID *pRrbCookieTo[FT_KDP_BR_ETH_IF_NUM]; /* used in RRB protocol */ + VOID *pRrbCookieFrom; /* for ioctl from WLAN driver */ + +#define IAPP_KDP_PIPE_DRV "/pipe/IAPP_Drv" +#define IAPP_KDP_PIPE_ETH "/pipe/IAPP_Eth" +#endif // IAPP_OS_VXWORKS // + +#ifdef IAPP_EVENT_LOG + INT32 MsgId; + BOOLEAN FlgIsMsgReady; +#endif // IAPP_EVENT_LOG // + + pid_t PID; /* IAPP task PID */ + UINT16 PacketIdentifier; /* used in IAPP frame identifier */ + +#ifdef FT_KDP_FUNC_PKT_ENCRYPT + /* common key, ASCII, the last byte must be 0x00 */ + CHAR CommonKey[IAPP_ENCRYPT_KEY_MAX_SIZE + 1]; +#endif // FT_KDP_FUNC_PKT_ENCRYPT // + + FT_CLIENT_TABLE SelfFtStaTable; +} RTMP_IAPP, *PRTMP_IAPP; + +/* key information */ +#define FT_IP_ADDRESS_SIZE 4 +#define FT_NONCE_SIZE 8 + +#define FT_KDP_WPA_NAME_MAX_SIZE 16 +#define FT_KDP_R0KHID_MAX_SIZE 48 +#define FT_KDP_R1KHID_MAX_SIZE 6 +#define FT_KDP_S1KHID_MAX_SIZE 6 +#define FT_KDP_PMKR1_MAX_SIZE 32 /* 256-bit key */ + +#define FT_R1KH_ENTRY_TABLE_SIZE 64 +#define FT_R1KH_ENTRY_HASH_TABLE_SIZE FT_R1KH_ENTRY_TABLE_SIZE + +typedef struct PACKED _FT_KDP_PMK_KEY_INFO { + + UCHAR R0KHID[FT_KDP_R0KHID_MAX_SIZE]; + UCHAR R0KHIDLen; + UCHAR PMKR0Name[FT_KDP_WPA_NAME_MAX_SIZE]; /* an ID that names the PMK-R0 */ + + UCHAR R1KHID[FT_KDP_R1KHID_MAX_SIZE]; + UCHAR S1KHID[FT_KDP_S1KHID_MAX_SIZE]; + + /* reserved field */ + UCHAR RSV[4]; + +} FT_KDP_PMK_KEY_INFO; + +typedef struct PACKED _FT_KDP_EVT_KEY_ELM { + /* must be 65535, Proprietary Information */ +#define FT_KDP_ELM_ID_PRI 65535 + UINT16 ElmId; + +#define FT_KDP_ELM_PRI_LEN (sizeof(FT_KDP_EVT_KEY_ELM) - 4) + UINT16 ElmLen; + + /* must be 0x00 0x0E 0x2E, RALINK */ +#define FT_KDP_ELM_PRI_OUI_0 0x00 +#define FT_KDP_ELM_PRI_OUI_1 0x0E +#define FT_KDP_ELM_PRI_OUI_2 0x2E +#define FT_KDP_ELM_PRI_OUI_SIZE 3 + UCHAR OUI[3]; + + /* station MAC */ + UCHAR MacAddr[ETH_ALEN]; + UCHAR RSV[3]; + + /* used in request */ + FT_KDP_PMK_KEY_INFO KeyInfo; + + /* used in response */ + UCHAR PMKR1Name[FT_KDP_WPA_NAME_MAX_SIZE]; /* an ID that names the PMK-R1 */ + UCHAR PMKR1[FT_KDP_PMKR1_MAX_SIZE]; /* PMK R1 Key */ + UCHAR R0KH_MAC[ETH_ALEN]; /* MAC of R0KH */ + + /* + During a Fast BSS Transition a non-AP STA shall negotiate the same + pairwise cipher suite with Target APs as was negotiated in the FT + Initial Mobility Domain association. The target AP shall verify + that the same pairwise cipher suite selector is used, using the + pairwise cipher suite selector value in the PMK-R1 SA received from + the R0KH. + */ + UCHAR PairwisChipher[4]; + UCHAR AkmSuite[4]; + + UINT32 KeyLifeTime; + UINT32 ReassocDeadline; +} FT_KDP_EVT_KEY_ELM; + +/* ---------------------------- API Definition ------------------------ */ + +VOID IAPP_HexDump(CHAR *pPromptStr, CHAR *pSrcBufVA, UINT32 SrcBufLen); + +BOOLEAN IAPP_IoctlToWLAN(RTMP_IAPP *pCtrlBK, INT32 Param, CHAR *pData, + INT32 *pDataLen, UCHAR ApIdx, INT32 Flags); + +BOOLEAN mt_iapp_get_wifi_iface_mac(RTMP_IAPP *pCtrlBK); + +INT32 mt_iapp_find_ifidx_by_mac(RTMP_IAPP *pCtrlBK, UCHAR *WifiMAC); + +VOID mt_iapp_set_daemon_information(RTMP_IAPP *pCtrlBK, pid_t *pPidAuth); + +VOID mt_iapp_ft_client_table_init(RTMP_IAPP *pCtrlBK); + +FT_CLIENT_INFO *mt_iapp_ft_client_look_up(FT_CLIENT_TABLE *pFtTable, + UCHAR *pAddr); + +FT_CLIENT_INFO *mt_iapp_ft_client_insert(FT_CLIENT_TABLE *pFtTable, + UCHAR *pStaAddr, UCHAR *pApAddr, + INT32 ApIfIdx); + +VOID mt_iapp_ft_client_delete(FT_CLIENT_TABLE *pFtTable, UCHAR *pStaAddr); + +INT32 mt_iapp_find_ifidx_by_sta_mac(FT_CLIENT_TABLE *pFtTable, UCHAR *pStaMAC); + +#endif /* __RTMP_IAPP_H__ */ + +/* End of rtmp_iapp.h */