diff options
author | Roman Yeryomin <roman@advem.lv> | 2012-09-22 19:44:27 +0300 |
---|---|---|
committer | Roman Yeryomin <roman@advem.lv> | 2013-05-26 00:28:21 +0300 |
commit | 8f67c041fdd28dcaf3b51339084d67dd8f251261 (patch) | |
tree | be625058667a786c7846d87f18eef076e0305da9 /package/librtk-inband | |
parent | 75afc89879e308670a2680464c668159bb0f82bf (diff) |
Add hostapd-rtk and librtk-inband packages
Signed-off-by: Roman Yeryomin <roman@advem.lv>
Diffstat (limited to 'package/librtk-inband')
-rw-r--r-- | package/librtk-inband/Makefile | 54 | ||||
-rw-r--r-- | package/librtk-inband/files/librtk-inband.pc | 10 | ||||
-rw-r--r-- | package/librtk-inband/src/Makefile | 21 | ||||
-rw-r--r-- | package/librtk-inband/src/hapd_api.c | 447 | ||||
-rw-r--r-- | package/librtk-inband/src/inband_cmd.c | 465 | ||||
-rw-r--r-- | package/librtk-inband/src/inband_if.c | 443 | ||||
-rw-r--r-- | package/librtk-inband/src/inband_if.h | 30 | ||||
-rw-r--r-- | package/librtk-inband/src/include/net80211/_ieee80211.h | 246 | ||||
-rw-r--r-- | package/librtk-inband/src/include/net80211/ieee80211.h | 947 | ||||
-rw-r--r-- | package/librtk-inband/src/include/net80211/ieee80211_crypto.h | 205 | ||||
-rw-r--r-- | package/librtk-inband/src/include/net80211/ieee80211_ioctl.h | 787 | ||||
-rw-r--r-- | package/librtk-inband/src/ioh.c | 315 | ||||
-rw-r--r-- | package/librtk-inband/src/ioh.h | 64 | ||||
-rw-r--r-- | package/librtk-inband/src/wireless_copy.h | 1099 |
14 files changed, 5133 insertions, 0 deletions
diff --git a/package/librtk-inband/Makefile b/package/librtk-inband/Makefile new file mode 100644 index 000000000..1ed6c8d53 --- /dev/null +++ b/package/librtk-inband/Makefile @@ -0,0 +1,54 @@ +# +# Copyright (C) 2006-2009 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=librtk-inband +PKG_VERSION:=0.1 +PKG_RELEASE:=2 + +include $(INCLUDE_DIR)/package.mk + +define Package/librtk-inband + SECTION:=libs + CATEGORY:=Libraries + TITLE:=realtek wireless device in-band configuration library +endef + +define Package/librtk-inband/description + realtek wireless device in-band configuration library +endef + +define Build/Prepare + mkdir -p $(PKG_BUILD_DIR) + $(CP) ./src/* $(PKG_BUILD_DIR)/ +endef + +TARGET_CFLAGS += $(FPIC) + +define Build/Compile + $(MAKE) -C $(PKG_BUILD_DIR) \ + $(TARGET_CONFIGURE_OPTS) \ + CFLAGS="$(TARGET_CFLAGS)" \ + all +endef + +define Build/InstallDev + $(INSTALL_DIR) $(1)/usr/lib/pkgconfig $(1)/usr/include/ + $(INSTALL_DIR) $(1)/usr/lib/pkgconfig $(1)/usr/include/librtk-inband + $(CP) $(PKG_BUILD_DIR)/include/* $(1)/usr/include/ + $(CP) $(PKG_BUILD_DIR)/ioh.h $(1)/usr/include/librtk-inband + $(CP) $(PKG_BUILD_DIR)/librtk-inband.so $(1)/usr/lib/ + $(CP) ./files/librtk-inband.pc $(1)/usr/lib/pkgconfig +endef + +define Package/librtk-inband/install + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_BUILD_DIR)/librtk-inband.so $(1)/usr/lib/ +endef + +$(eval $(call BuildPackage,librtk-inband)) diff --git a/package/librtk-inband/files/librtk-inband.pc b/package/librtk-inband/files/librtk-inband.pc new file mode 100644 index 000000000..eb20fdb94 --- /dev/null +++ b/package/librtk-inband/files/librtk-inband.pc @@ -0,0 +1,10 @@ +prefix=/usr +exec_prefix=/usr +libdir=${exec_prefix}/lib +includedir=${prefix}/include/librtk-inband + +Name: librtk-inband +Description: library for inband configuration of realtek wireless devices +Version: 1.0 +Libs: -L${libdir} -lrtk-inband +Cflags: diff --git a/package/librtk-inband/src/Makefile b/package/librtk-inband/src/Makefile new file mode 100644 index 000000000..fa0cb9a71 --- /dev/null +++ b/package/librtk-inband/src/Makefile @@ -0,0 +1,21 @@ +INCLUDES=-Iinclude + +LIBNAME=librtk-inband.so +APPNAME=rtk-inband + +all: $(LIBNAME) $(APPNAME) + +%.o: %.c + $(CC) -c -o $@ $(INCLUDES) $(CFLAGS) $< + +OBJ=inband_if.o ioh.o + +LIB_OBJ=hapd_api.o $(OBJ) +APP_OBJ=inband_cmd.o $(OBJ) + + +$(APPNAME):$(APP_OBJ) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS) + +$(LIBNAME): $(LIB_OBJ) + $(CC) $(CFLAGS) -shared -o $@ $^ diff --git a/package/librtk-inband/src/hapd_api.c b/package/librtk-inband/src/hapd_api.c new file mode 100644 index 000000000..252a7b467 --- /dev/null +++ b/package/librtk-inband/src/hapd_api.c @@ -0,0 +1,447 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <signal.h> +#include <unistd.h> +#include <sys/ioctl.h> +#include <errno.h> + +#include <linux/if_ether.h> +#include <linux/if_packet.h> +#ifndef __IOH_H +#include "ioh.h" +#endif +#include <linux/if_arp.h> +#include "wireless_copy.h" +#include <net80211/ieee80211.h> +#include <net80211/ieee80211_crypto.h> +#include <net80211/ieee80211_ioctl.h> + +#define INBAND_INTF "wlan0" +#define INBAND_SLAVE ("001234567899") +#define INBAND_IOCTL_TYPE 0x8899 +#define INBAND_NETLINK_TYPE 0x9000 +#define INBAND_DEBUG 0 +#define RX_EXPIRE_PERIOD 3 //in secs + +#define IWREQ_LEN 32 +#define INBAND_IOCTLTYPE_LEN 4 +#define INBAND_IOCTLHDR_LEN 6 +#define INBAND_PENDING_START(data) data+INBAND_IOCTLHDR_LEN+IWREQ_LEN +#define INBAND_IOCTLRET_PTR(data) data+INBAND_IOCTLTYPE_LEN +#define IOH_HDR_LEN sizeof(struct ioh_header) + +#ifdef IEEE80211_IOCTL_SETWMMPARAMS +/* Assume this is built against realtek-ng */ +#define REALTEK_NG +#endif /* IEEE80211_IOCTL_SETWMMPARAMS */ +//#define RTL8192CD_IOCTL_DEL_STA 0x89f7 +//#define SIOCGIWIND 0x89ff +//#defein SIOCIWLASTPRIV 0x8BFF + +unsigned int get_random(int max) +{ + struct timeval tod; + + gettimeofday(&tod , NULL); + srand(tod.tv_usec); + return rand()%max; +} + +static int rx_expired(struct timeval *start) +{ + struct timeval now; + + gettimeofday(&now , NULL); + + return (now.tv_sec-start->tv_sec<RX_EXPIRE_PERIOD)?0:1; +} + +/**************************************************** + + tx_data will be formatted as following: + +--------------+------------+--------------+--------------+ + | ioctl number | req length | struct iwreq | pending data | + +--------------+------------+--------------+--------------+ + + + ****************************************************/ +int +inband_ioctl(int ioctl_op, void *req) +{ + int ret=-1, ext_len=0, sq=0, rcv_sq=0, inband_channel=-1, iw=0; + unsigned char cmd_type=0x01, buf[BUF_SIZE], *rx_buf; + struct iwreq *local_iwr; + struct timeval start; + int ioctl_op_endian; + int local_iwr_pointer; + struct ifreq *ifr_ptr; +#ifdef WPAS_INB + char* data_set_ptr; + int data_set_len = 0; + char* data_get_ptr; + int data_get_len = 0; + + int rx_retry_cnt = 0; + int tx_retry_cnt = 0; +#endif + +/*_Eric WPAS_INB ======== + +[iw] +Byte(0): 0, u.name + 1, u.data.pointer + 2, u."Others" - get + 3, u."Others" - set +Byte(1): 0, ifreq + 1, iwreq + +=====================*/ + + switch(ioctl_op) { + + case IEEE80211_IOCTL_FILTERFRAME: + case IEEE80211_IOCTL_SETPARAM: + case IEEE80211_IOCTL_DELKEY: + iw = 0x10; + break; + case IEEE80211_IOCTL_SETMLME: + case IEEE80211_IOCTL_SETKEY: + //printf("~~~%s %d\n",__FUNCTION__,__LINE__); + //hex_dump(((struct iwreq *)req)->u.data.pointer,((struct iwreq *)req)->u.data.length); +#ifdef REALTEK_NG + case IEEE80211_IOCTL_STA_STATS: +#else + case IEEE80211_IOCTL_GETSTASTATS: +#endif + case IEEE80211_IOCTL_SET_APPIEBUF: + //WPAS_INB case SIOCGIWRANGE: + //WPAS_INB case SIOCSIWESSID: + //WPAS_INB case SIOCGIWESSID: + case SIOCSIWENCODE: + case IEEE80211_IOCTL_WDSADDMAC: + case IEEE80211_IOCTL_WDSDELMAC: + case IEEE80211_IOCTL_GET_APPIEBUF: + case 0x89f7: //RTL8192CD_IOCTL_DEL_STA + case 0x89ff: //SIOCGIWIND + case 0x8bff: //SIOCIWLASTPRIV +#ifdef WPAS_INB + case IEEE80211_IOCTL_SETOPTIE://0x8bee +#endif + iw = 0x11; + break; + case SIOCGIFINDEX: + case SIOCGIFFLAGS: + case SIOCGIFHWADDR: + iw = 0x0; + break; + case SIOCSIFHWADDR: + ifr_ptr = (struct ifreq *)req; + ifr_ptr->ifr_hwaddr.sa_family = htons(ifr_ptr->ifr_hwaddr.sa_family); + iw = 0x0; + break; + case SIOCSIFFLAGS: + ifr_ptr = (struct ifreq *)req; + ifr_ptr->ifr_flags = htons(ifr_ptr->ifr_flags); + iw = 0x0; + break; + case SIOCSIFMTU: + ifr_ptr = (struct ifreq *)req; + ifr_ptr->ifr_mtu = htonl(ifr_ptr->ifr_mtu); + iw = 0x0; + break; +#ifdef WPAS_INB + case SIOCSIWSCAN: + iw = 0x10; + break; + + case SIOCGIWAP: + case SIOCGIWESSID: + case SIOCGIWSCAN: + case SIOCGIWRANGE: + case SIOCGIWMODE: + iw = 0x12; + break; + + case SIOCSIWAP: + case SIOCSIWESSID: + case SIOCSIWMODE: + iw = 0x13; + break; +#endif + default: + printf("Unknown ioctl number:%d\n",ioctl_op); + return -1; + } + + inband_channel = inband_open(INBAND_INTF, INBAND_SLAVE, INBAND_IOCTL_TYPE, INBAND_DEBUG); + if( inband_channel < 0 ) { + printf("ioctl(inband channel open) failed \n"); + goto out; + } + + ioctl_op_endian = htonl(ioctl_op);//mark_endian + memset(buf,0,BUF_SIZE); + memcpy(buf,(unsigned char *)&ioctl_op_endian,INBAND_IOCTLTYPE_LEN); +#ifdef WPAS_INB + if( (iw & 0x1) && ((iw != 0x13) && (iw != 0x12)) ) +#else + if( iw & 0x1 ) +#endif + { + local_iwr = (struct iwreq *)req; + ext_len = local_iwr->u.data.length; + local_iwr_pointer = (int)local_iwr->u.data.pointer; + local_iwr->u.data.length = htons(ext_len); + local_iwr->u.data.flags = htons(local_iwr->u.data.flags); + //memcpy(INBAND_PENDING_START(buf),local_iwr->u.data.pointer, local_iwr->u.data.length); + memcpy(INBAND_PENDING_START(buf),local_iwr->u.data.pointer, ext_len); + } + +#ifdef WPAS_INB + if( iw == 0x12 ) { + + local_iwr = (struct iwreq *)req; + + if(ioctl_op == SIOCGIWAP) + { + ; + } + else if(ioctl_op == SIOCGIWESSID) + { + local_iwr = (struct iwreq *)req; + local_iwr->u.essid.flags = htons(local_iwr->u.essid.flags); + local_iwr->u.essid.length = htons(local_iwr->u.essid.length); + } + else if(ioctl_op == SIOCGIWSCAN) + { + local_iwr = (struct iwreq *)req; + local_iwr->u.data.length = htons(local_iwr->u.data.length); + local_iwr->u.data.flags = htons(local_iwr->u.data.flags); + ext_len = 0; + } + else if(ioctl_op == SIOCGIWRANGE) + { + local_iwr = (struct iwreq *)req; + local_iwr->u.data.length = htons(local_iwr->u.data.length); + local_iwr->u.data.flags = htons(local_iwr->u.data.flags); + ext_len = 0; + } + else if(ioctl_op == SIOCGIWMODE) + { + ; + } + + } + + if( iw == 0x13 ) { + + local_iwr = (struct iwreq *)req; + data_set_len = 0; + + if(ioctl_op == SIOCSIWAP) + { + data_set_len = ETH_ALEN; + data_set_ptr = (char *)local_iwr->u.ap_addr.sa_data; + } + else if(ioctl_op == SIOCSIWESSID) + { + data_set_len = local_iwr->u.essid.length; + data_set_ptr = (char*)local_iwr->u.essid.pointer; + local_iwr->u.essid.length = htons(local_iwr->u.essid.length); + } + else if(ioctl_op == SIOCSIWMODE) + { + local_iwr->u.mode = htonl(local_iwr->u.mode); + } + + + memcpy(INBAND_PENDING_START(buf), data_set_ptr, data_set_len); + ext_len = data_set_len; + + } +#endif + + + memcpy(buf+INBAND_IOCTLHDR_LEN,(unsigned char *)req,IWREQ_LEN); + + +#ifdef WPAS_INB + if(iw >= 0x10) + buf[INBAND_IOCTLTYPE_LEN] = 0x1; + else + buf[INBAND_IOCTLTYPE_LEN] = 0x0; + + buf[INBAND_IOCTLTYPE_LEN+1] = iw&0x3; +#else + buf[INBAND_IOCTLTYPE_LEN] = iw&0x10>>4; + buf[INBAND_IOCTLTYPE_LEN+1] = iw&0x1; +#endif + + + sq = get_random(65536); + +#ifdef WPAS_INB + tx_retry_cnt = 0; + +tx_retry: + + rx_retry_cnt = 0; + tx_retry_cnt ++; + + if(tx_retry_cnt > 3) + { + printf("CAN NOT RECEIVE INBAND RESPONSE !!!! EXIT ~~~ \n"); + ret = -1; + goto out; + } +#endif + + //printf("inband ioctl %d %d >>> \n", sq, ext_len); + + + if( inband_write(inband_channel, sq, cmd_type, buf, INBAND_IOCTLHDR_LEN+IWREQ_LEN+ext_len, 0) < 0) { + printf("inband ioctl message send failed\n"); + goto out; + } + else { + gettimeofday(&start,NULL); +rx_retry: + + //_Eric timeout shall set ?? + if( inband_rcv_data_and_seq(inband_channel, &rcv_sq, &cmd_type, &rx_buf, 500000) < 0 && !rx_expired(&start) ) { + printf("inband ioctl message not receive response\n"); + +#ifdef WPAS_INB + rx_retry_cnt ++; + + if(rx_retry_cnt >= 3) + goto tx_retry; + + sleep(1); + goto rx_retry; +#else + ret = -1; + goto out; +#endif + } + //printf(" >>> inband ioctl %d \n",rcv_sq); + + +#ifdef WPAS_INB + if( sq != rcv_sq ) + goto tx_retry; +#else + if( sq != rcv_sq ) + goto rx_retry; +#endif + + + ret = *(int *)rx_buf; + +#ifdef WPAS_INB + ret = ntohl(ret); +#endif + + +#ifdef WPAS_INB + if(iw != 0x12) +#endif + memcpy((unsigned char *)req,rx_buf+INBAND_IOCTLHDR_LEN,IWREQ_LEN); + +#ifdef WPAS_INB + if( (iw & 0x1) && (iw != 0x12) && (iw != 0x13)) +#else + if( iw & 0x1 ) +#endif + { + local_iwr = (struct iwreq *)req; + memcpy((int *)local_iwr_pointer, INBAND_PENDING_START(rx_buf), ext_len); + local_iwr->u.data.length = ext_len; + local_iwr->u.data.pointer = (int *)local_iwr_pointer; + local_iwr->u.data.flags = ntohs(local_iwr->u.data.flags); + } + else if (iw == 0x0) //ifreq ; + { + switch(ioctl_op) { + case SIOCGIFINDEX: + ifr_ptr = (struct ifreq *)req; + ifr_ptr->ifr_ifindex = ntohl(ifr_ptr->ifr_ifindex); + break; + case SIOCGIFFLAGS: + ifr_ptr = (struct ifreq *)req; + ifr_ptr->ifr_flags = ntohs(ifr_ptr->ifr_flags); + break; + //case SIOCGIFHWADDR: + default: + break; + } + + } + + +#ifdef WPAS_INB + if(iw == 0x12) + { + memcpy(&data_get_len, (rx_buf + INBAND_IOCTLHDR_LEN + IWREQ_LEN + ext_len), 4); + data_get_len = ntohl(data_get_len); + data_get_ptr = (char *)(rx_buf + INBAND_IOCTLHDR_LEN + IWREQ_LEN + ext_len + 4); + + switch(ioctl_op){ + case SIOCGIWAP: + local_iwr = (struct iwreq *)req; + memcpy(local_iwr->u.ap_addr.sa_data, data_get_ptr, data_get_len); + break; + case SIOCGIWESSID: + local_iwr = (struct iwreq *)req; + local_iwr->u.essid.length = data_get_len; + memcpy(local_iwr->u.essid.pointer, data_get_ptr, data_get_len); + break; + case SIOCGIWSCAN: + local_iwr = (struct iwreq *)req; + local_iwr->u.data.length = data_get_len; + memcpy(local_iwr->u.data.pointer, data_get_ptr, data_get_len); + break; + case SIOCGIWRANGE: + local_iwr = (struct iwreq *)req; + local_iwr->u.data.length = data_get_len; + memcpy(local_iwr->u.data.pointer, data_get_ptr, data_get_len); + break; + case SIOCGIWMODE: + local_iwr = (struct iwreq *)req; + local_iwr->u.mode = ntohl(local_iwr->u.mode); + break; + default: + break; + } + } + +#endif + + } +out: + if( inband_channel >= 0 ) + inband_close(inband_channel); + + return ret; +} + + +int +inband_remote_cmd(unsigned char *cmd) +{ + unsigned char cmd_type=0x02, *buf; + unsigned int channel = -1; + + channel = inband_open(INBAND_INTF,INBAND_SLAVE,INBAND_IOCTL_TYPE,0); + if( channel < 0 || inband_write(channel, get_random(65535), cmd_type, cmd, strlen(cmd), 0) < 0) { + printf("inband sent remote command failed\n"); + } else { + if( inband_rcv_data(channel, &cmd_type, &buf, -1) < 0 ) + printf("inband try to receive respone but failed\n"); + inband_close(channel); + } +} + + + diff --git a/package/librtk-inband/src/inband_cmd.c b/package/librtk-inband/src/inband_cmd.c new file mode 100644 index 000000000..a85a04f8a --- /dev/null +++ b/package/librtk-inband/src/inband_cmd.c @@ -0,0 +1,465 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <signal.h> +#include <unistd.h> +#include <sys/ioctl.h> +#include <errno.h> + +#include <fcntl.h> +#include <sys/types.h> +#include <sys/uio.h> + +#include <sys/stat.h> //mark_file + +#include "inband_if.h" + +#define HOST_NETIF ("wlan0") +#define SLAVE_MAC ("001234567899") +#define ETH_P_RTK 0x8899 // Realtek Remote Control Protocol (RRCP) +int hcd_inband_chan=0; + +// command ID +#define id_ioctl 0x01 +#define id_systemcall 0x02 +#define id_firm_upgrade 0x03 +#define id_hostcmd_only 0xff //only for new hostcmd implement ,if the cmd is not real "inband cmd" + +// Command Table +struct inband_cmd_table_t { + char cmd_id; + const char *cmd; // Input command string + int (*func)(int index,int argc, char *argv[]); + void (*print_func)(char *para,char *data,int len); + const char *msg; // Help message +}; + +/*firmware define*/ +#define __PACK__ __attribute__ ((packed)) + +#define SIGNATURE_LEN 4 +#define FW_HEADER_WITH_ROOT ((char *)"cr6c") +#define FW_HEADER ((char *)"cs6c") +#define ROOT_HEADER ((char *)"r6cr") +#define WEB_HEADER ((char *)"w6cg") //no ap sign now //mark_issue + +typedef struct img_header { + unsigned char signature[SIGNATURE_LEN] __PACK__; + unsigned int startAddr __PACK__; + unsigned int burnAddr __PACK__; + unsigned int len __PACK__; +} IMG_HEADER_T, *IMG_HEADER_Tp; + + +unsigned int host_inband_seq=0; //use to do requset <-> response check + +int cmd_systemcall(int index,int argc, char *argv[]); +int cmd_firmware_upgrade(int index,int argc, char *argv[]); +void print_systemcall(char *para,char *data,int len); + + +struct inband_cmd_table_t inband_cmd_table[]= +{ + // + {id_systemcall,"systemcall", cmd_systemcall, print_systemcall, "inband systemcall \'cmd_string\'"}, + {id_firm_upgrade,"firm_upgrade", cmd_firmware_upgrade, NULL,"inband firm_upgrade /var/linux.bin"}, + //{id_hostcmd_only,"send_conf", cmd_sendconf, NULL,"inband send_conf /etc/xxx.conf"}, + {NULL, NULL, NULL}, +}; + + +unsigned int get_random(int max) +{ + struct timeval tod; + + gettimeofday(&tod , NULL); + srand(tod.tv_usec); + return rand()%max; +} + +void print_command_list(void) +{ + int i; + + printf("\n==========commands for debugging============\n"); + i = 0; + while (inband_cmd_table[i].cmd != NULL) { + printf("%s\n", inband_cmd_table[i].msg); + i++; + } +} + +void print_systemcall(char *para,char *data,int len) +{ + int i=0; + unsigned char *value; + + data[len] = '\0'; + printf("cmd_cfgread \n"); + printf("%s",data); +} + +static int host_inband_write(char cmd_id,char *data,int data_len) +{ + int ret; + + host_inband_seq = get_random(65536); + + ret = inband_write(hcd_inband_chan,host_inband_seq,cmd_id,data,data_len,0); //send request + return ret; +} + +static inline int CHECKSUM_OK(unsigned char *data, int len) +{ + int i; + unsigned char sum=0; + + for (i=0; i<len; i++) + sum += data[i]; + + if (sum == 0) + return 1; + else + return 0; +} + +static int fwChecksumOk(char *data, int len) +{ + unsigned short sum=0; + int i; + + for (i=0; i<len; i+=2) { +#ifdef _LITTLE_ENDIAN_ + sum += WORD_SWAP( *((unsigned short *)&data[i]) ); +#else + sum += *((unsigned short *)&data[i]); +#endif + + } + return( (sum==0) ? 1 : 0); +} +static int host_firmware_write(char *data,int len) +{ + unsigned int tx_seq,rx_seq; + int ret=0,count; + char rx_cmd_type; + char *buf_p; + + ret = host_inband_write(id_firm_upgrade,data,len); //send request + + tx_seq = host_inband_seq; + + if(ret < 0) + return -1; + + ret = inband_rcv_data_and_seq(hcd_inband_chan,&rx_seq,&rx_cmd_type,&buf_p,20000); //return data length + + if(ret < 0) + { + ret=-1; + goto out; + } + + if( (rx_cmd_type == id_firm_upgrade) && (tx_seq == rx_seq)) + printf("host_firmware_write ok!\n"); + else + { + ret=-1; + printf("host_firmware_write fail!\n"); + } + +out: + inband_free_buf(buf_p, count); + return ret; + +} + +static int rtk_firmware_update(char *upload_data, int upload_len) +{ +int head_offset=0 ; +int isIncludeRoot=0; +int len; + int numLeft; +int numWrite; +IMG_HEADER_Tp pHeader; +int fh; +int fwSizeLimit = 0x200000; +char buffer[100]; +int flag=0; + +while(head_offset < upload_len) { + + pHeader = (IMG_HEADER_Tp) &upload_data[head_offset]; + len = pHeader->len; +#ifdef _LITTLE_ENDIAN_ + len = DWORD_SWAP(len); +#endif + + numLeft = len + sizeof(IMG_HEADER_T) ; + + // check header and checksum + if (!memcmp(&upload_data[head_offset], FW_HEADER, SIGNATURE_LEN) || + !memcmp(&upload_data[head_offset], FW_HEADER_WITH_ROOT, SIGNATURE_LEN)) + flag = 1; + else if (!memcmp(&upload_data[head_offset], WEB_HEADER, SIGNATURE_LEN)) + flag = 2; + else if (!memcmp(&upload_data[head_offset], ROOT_HEADER, SIGNATURE_LEN)){ + flag = 3; + isIncludeRoot = 1; + } + else { + strcpy(buffer, "Invalid file format!"); + goto ret_upload; + } + + if(len > fwSizeLimit){ //len check by sc_yang + sprintf(buffer, "Image len exceed max size 0x%x ! len=0x%x",fwSizeLimit, len); + goto ret_upload; + } + if ( (flag == 1) || (flag == 3)) { + if ( !fwChecksumOk(&upload_data[sizeof(IMG_HEADER_T)+head_offset], len)) { + sprintf(buffer, "Image checksum mismatched! len=0x%x, checksum=0x%x", len, + *((unsigned short *)&upload_data[len-2]) ); + goto ret_upload; + } + } + else { + char *ptr = &upload_data[sizeof(IMG_HEADER_T)+head_offset]; + if ( !CHECKSUM_OK(ptr, len) ) { + sprintf(buffer, "Image checksum mismatched! len=0x%x", len); + goto ret_upload; + } + } + + //numWrite = write(fh, &(upload_data[locWrite+head_offset]), numLeft); + //inband write , and check ack + if(host_firmware_write(&(upload_data[head_offset]),numLeft) < 0 ) + { + sprintf(buffer, "host_firmware_write! numLeft=0x%x", numLeft); + goto ret_upload; + } + + head_offset += len + sizeof(IMG_HEADER_T) ; + } + + return 0; + + ret_upload: + fprintf(stderr, "%s\n", buffer); + return -1; +} //while //sc_yang + +int cmd_firmware_upgrade(int index,int argc, char *argv[]) +{ + int len,ret,count; + //char data[1480]; + char filename[50]; + char *data; + int fd,rc; + struct stat ffstat; + int flen=0; + + //sprintf(data,"%s",argv[2]); + sprintf(filename,"%s",argv[2]); + + fd = open(filename, O_RDONLY); + + if (fd < 0) { + printf("Cannot Open file %s!\n", filename); + return -1; + } + fstat(fd, &ffstat); + flen = ffstat.st_size; + printf("flen = %d \n",flen); + + if((data = (char *)malloc(flen)) == NULL) + { + printf("data buffer allocation failed!\n"); + return -1; + } + + // rc = read(fd, data, 1480); + rc = read(fd, data, flen); + + //if (rc != 1480) { + if (rc != flen) { + printf("Reading error\n"); + free(data); //need free before return!!!!! + return -1; + } + + close(fd); + + ret = rtk_firmware_update(data, flen); + + if(ret < 0) + printf("rtk_firmware_update fail \n"); + else + printf("rtk_firmware_update ok \n"); + + free(data); //need free before return!!!!! + + return ret; +} + +#if 0 +int cmd_sendconf(int index,int argc, char *argv[]) +{ + int len,ret,count; + //char data[1480]; + char cmd_id,rx_cmd_type; + char *buf_p; + unsigned int tx_seq,rx_seq; + char filename[50]; + char *data; + int fd,rc; + struct stat ffstat; + int flen=0; + + cmd_id = id_set_mib; + + //sprintf(data,"%s",argv[2]); + sprintf(filename,"%s",argv[2]); + + fd = open(filename, O_RDONLY); + + if (fd < 0) { + printf("Cannot Open file %s!\n", filename); + return -1; + } + fstat(fd, &ffstat); + flen = ffstat.st_size; + printf("flen = %d \n",flen); + + if((data = (char *)malloc(flen)) == NULL) + { + printf("data buffer allocation failed!\n"); + return -1; + } + + // rc = read(fd, data, 1480); + rc = read(fd, data, flen); + + //if (rc != 1480) { + if (rc != flen) { + printf("Reading error\n"); + free(data); //need free before return!!!!! + return -1; + } + + close(fd); + //len = 1480; + len = flen; + tx_seq = host_inband_seq; + ret = host_inband_write(cmd_id,data,len); //send request + + free(data); //need free before return!!!!! + + if(ret < 0) + return -1; + + //count = inband_rcv_data(&rx_cmd_type,&buf_p,1000); //return data length + count = inband_rcv_data_and_seq(hcd_inband_chan,&rx_seq,&rx_cmd_type,&buf_p,3000); //return data length + if(count < 0) + { + ret=-1; + goto out; + } + + if( (rx_cmd_type == cmd_id) && (tx_seq == rx_seq)) + printf("remote write ok!\n"); + else + { + ret=-1; + printf("remote write fail!\n"); + } + + out: + inband_free_buf(buf_p, count); + + return ret; +} +#endif +int cmd_systemcall(int index,int argc, char *argv[]) +{ + int len,ret,count; + char data[1480]; + char cmd_id,rx_cmd_type; + char *buf_p; + unsigned int tx_seq,rx_seq; + + cmd_id = inband_cmd_table[index].cmd_id; + + if(argc > 3) + sprintf(data,"%s %s",argv[2],argv[3]); + else + sprintf(data,"%s",argv[2]); + + len = strlen(data); + + + ret = host_inband_write(cmd_id,data,len); //send request + + tx_seq = host_inband_seq; + + if(ret < 0) + return -1; + + //count = inband_rcv_data(&rx_cmd_type,&buf_p,1000); //return data length + count = inband_rcv_data_and_seq(hcd_inband_chan,&rx_seq,&rx_cmd_type,&buf_p,1000); //return data length + + if(count < 0) + return -1; + //printf("count=%d rx_cmd_type=%x,cmd_id=%x,tx_seq=%d,rx_seq=%d",count,rx_cmd_type,cmd_id,tx_seq,rx_seq); + + if((rx_cmd_type == cmd_id) && (tx_seq == rx_seq)) + { + if(inband_cmd_table[index].print_func) + inband_cmd_table[index].print_func(data,buf_p,count); + } + else + return -1; + + return 0; + +} + +int main(int argc, char *argv[]) +{ + //int fdflags; + //unsigned int arg; + int i, ret; + int chan; + + if (argc < 2) { + print_command_list(); + return 0; + } + + //open inband + chan = inband_open(HOST_NETIF,SLAVE_MAC,ETH_P_RTK,0); + if (chan < 0) { + printf("open inband failed!\n"); + return -1; + } + hcd_inband_chan = chan; + + i = 0; + while (inband_cmd_table[i].cmd != NULL) { + if (0 == strcmp(argv[1], inband_cmd_table[i].cmd)) { + if (inband_cmd_table[i].func) { + ret = inband_cmd_table[i].func(i,argc, argv); + if (ret > 0) + printf("OK\n"); + else if (ret < 0) + printf("FAIL\n"); + } + break; + } + i++; + } + + inband_close(hcd_inband_chan); + + return 0; +} diff --git a/package/librtk-inband/src/inband_if.c b/package/librtk-inband/src/inband_if.c new file mode 100644 index 000000000..a3ce40996 --- /dev/null +++ b/package/librtk-inband/src/inband_if.c @@ -0,0 +1,443 @@ +/* + * IOH daemon + * Copyright (C)2010, Realtek Semiconductor Corp. All rights reserved + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <signal.h> +#include <unistd.h> +#include <sys/ioctl.h> + +#include <linux/if_packet.h> +#include "ioh.h" +#include "inband_if.h" + +struct inband_header { + struct ioh_header raw_header; + unsigned char rrcp_type; // should be RRCP_P_IOH + unsigned char inband_cmd; + unsigned short inband_seq; + unsigned short inband_frag; + unsigned char inband_reserved[2]; + unsigned short inband_data_len; +} __attribute__((packed)); + +struct fragment_info{ + unsigned char inband_cmd; + unsigned short inband_seq; + unsigned short inband_frag; + char *buf_ptr; + char *buf; + unsigned int data_len; +}; + +struct inband_class { + struct ioh_class ioh_obj; + struct inband_header *tx_header; + struct inband_header *rx_header; + unsigned char *tx_data; + unsigned char *rx_data; + struct fragment_info frag_info; + unsigned int in_used; +}; + +//header : 4 sign , 4 opttion , 4 offset, 4 len +#define FM_HEADER_LEN_OFFSET 12 + +#define MAX_INBAND_CHAN 1 +#define MAX_PREALLOC_INBAND_CHAN MAX_INBAND_CHAN + +int inband_rcv_timeout=0; //mark_issue, not implement now + +static struct inband_class inband_obj[MAX_INBAND_CHAN]; +static int inband_ready=0; + +static void init_inband_obj(struct inband_class *ib_obj) +{ + struct ioh_class *obj=&ib_obj->ioh_obj; + + ib_obj->tx_header = (struct inband_header *)obj->tx_header; + ib_obj->rx_header = (struct inband_header *)obj->rx_header; + + ib_obj->tx_data = (unsigned char *) obj->tx_buffer + sizeof(struct inband_header); + ib_obj->rx_data = (unsigned char *) obj->rx_buffer + sizeof(struct inband_header); + + //frag_info? +} + +static unsigned int get_free_chan() +{ + int i; + int chan=-1; + + for(i=0;i<MAX_INBAND_CHAN;i++) + { + if(inband_obj[i].in_used ==0 ) + { + inband_obj[i].in_used =1; + chan = i; + break; + } + } + return chan; +} + +static struct inband_class *get_chan_obj(unsigned int chan) +{ + return (struct inband_class *)&inband_obj[chan]; +} + +static void inband_init_all() +{ + memset(&inband_obj[0],0,sizeof(struct inband_class)*MAX_INBAND_CHAN); +} + +int inband_open(char *netif_name,char *slave_mac,unsigned short eth_type,int debug) +{ + int ret; + unsigned int chan; + struct inband_class *inband_obj_p; + struct ioh_class *ioh_obj_p; + + if(inband_ready == 0) + { + inband_init_all(); + inband_ready =1 ; + } + + chan = get_free_chan(); + if(chan < 0) + return -1; + + inband_obj_p = (struct inband_class *)get_chan_obj(chan); + + ioh_obj_p = &inband_obj_p->ioh_obj; + + ret = ioh_open(ioh_obj_p, netif_name, slave_mac,eth_type, debug); + + if(ret < 0 ) + return -1; + + init_inband_obj(inband_obj_p); + + return chan; +} + +int get_inband_socket(int chan) +{ + struct inband_class *inband_obj_p; + struct ioh_class *ioh_obj_p; + + inband_obj_p = (struct inband_class *)get_chan_obj(chan); + ioh_obj_p = &inband_obj_p->ioh_obj; + + return ioh_obj_p->sockfd; +} + +int get_inband_destMac(int chan,char *destmac) //mark_test +{ + struct inband_class *inband_obj_p; + struct ioh_class *ioh_obj_p; + + inband_obj_p = (struct inband_class *)get_chan_obj(chan); + ioh_obj_p = &inband_obj_p->ioh_obj; + + memcpy(destmac,ioh_obj_p->dest_mac,6); + + return 0; +} + +void inband_close(int chan) +{ + //clear frag_info + struct inband_class *inband_obj_p; + struct ioh_class *ioh_obj_p; + + inband_obj_p = (struct inband_class *)get_chan_obj(chan); + ioh_obj_p = &inband_obj_p->ioh_obj; + ioh_close(ioh_obj_p); + inband_obj_p->in_used =0; //free the obj +} + +static int inband_recv(struct inband_class *ib_obj,int timeout) +{ + struct ioh_class *ioh_obj_p = &ib_obj->ioh_obj; + int rx_len; + + rx_len = ioh_recv(ioh_obj_p, timeout); + if (rx_len < 0) + return ERROR_TIMOUT; + if(ib_obj->rx_header->rrcp_type != RRCP_P_IOH) + return -1; + + return rx_len; +} + +static int send_frag_ack(struct inband_class *ib_obj) +{ + struct ioh_class *ioh_obj_p = &ib_obj->ioh_obj; + + ib_obj->tx_header->rrcp_type = RRCP_P_IOH; //mark_inband + ib_obj->tx_header->inband_cmd = ib_obj->rx_header->inband_cmd; + ib_obj->tx_header->inband_seq = ib_obj->rx_header->inband_seq; + ib_obj->tx_header->inband_frag = ib_obj->rx_header->inband_frag; + ib_obj->tx_header->inband_data_len = 0; + + return ioh_send(ioh_obj_p,sizeof(struct inband_header)); //only send header for ack +} +static int check_frag_ack(struct inband_class *ib_obj) +{ + int rx_len; + + rx_len = inband_recv(ib_obj, PER_FRAME_TIMEOUT); // -1 = wait until rec + if (rx_len < 0) + { + perror("check_frag_ack fail:"); + return 0; + } + if((ib_obj->rx_header->inband_cmd == ib_obj->tx_header->inband_cmd) && + (ib_obj->rx_header->inband_seq == ib_obj->tx_header->inband_seq) && + (ib_obj->rx_header->inband_frag == ib_obj->tx_header->inband_frag) ) + return 1; //ok + + return 0; //fail +} +static char *inband_alloc_buf(struct inband_class *ib_obj) +{ + char *buf=NULL; + unsigned int buf_size=MAX_APP_DATA_SIZE; + unsigned char *image_len,header_len_offset=FM_HEADER_LEN_OFFSET; +#if 1 //it's for firmware file + if(ib_obj->rx_header->inband_cmd == id_firm_upgrade) + { + //read firmware length from it's header + image_len = (char *)ib_obj->rx_data; + buf_size =(unsigned int)( ( image_len[header_len_offset+0] <<24 ) + + ( image_len[header_len_offset+1] <<16 ) + + ( image_len[header_len_offset+2] <<8 ) + + ( image_len[header_len_offset+3] <<0 ) + 16 ) ; + + //printf("inband_alloc_buf buf_size=%x , image_len[0]= %x\n",buf_size,image_len[header_len_offset+0]); + } +#endif + buf = (char *)malloc(buf_size); + return buf; +} +//mark_issue,defragment_reset +static int init_defragment_process(struct inband_class *ib_obj) +{ + struct fragment_info *p_frag_info = &ib_obj->frag_info; + + //check if the it is first fragment id + if(ib_obj->rx_header->inband_frag != FIRST_FRAG_ID) + return ERROR_DEFRAGMENT; + + if((p_frag_info->buf = (char *)inband_alloc_buf(ib_obj)) == NULL) + { + printf("init_defragment_process : data buffer allocation failed!\n"); + return ERROR_DEFRAGMENT; + } + p_frag_info->buf_ptr = p_frag_info->buf; + p_frag_info->inband_frag = FIRST_FRAG_ID; + +#ifdef WPAS_INB + p_frag_info->inband_cmd = ntohs(ib_obj->rx_header->inband_cmd); + p_frag_info->inband_seq = ntohs(ib_obj->rx_header->inband_seq); +#else + p_frag_info->inband_cmd = ib_obj->rx_header->inband_cmd; + p_frag_info->inband_seq = ib_obj->rx_header->inband_seq; +#endif + + //copy first frame to buffer + memcpy(p_frag_info->buf,ib_obj->rx_data,ntohs(ib_obj->rx_header->inband_data_len)); + p_frag_info->buf += ntohs(ib_obj->rx_header->inband_data_len); + p_frag_info->data_len = ntohs(ib_obj->rx_header->inband_data_len); + send_frag_ack(ib_obj); + + return 0; //init ok +} + +static int do_defragment_process(struct inband_class *ib_obj) +{ + int ret=0; + struct fragment_info *p_frag_info = &ib_obj->frag_info; + + if(p_frag_info->inband_seq != ntohs(ib_obj->rx_header->inband_seq) ) + return ERROR_DEFRAGMENT; + + if( (p_frag_info->inband_frag+1) != (ntohs(ib_obj->rx_header->inband_frag) & FRAG_ID_MASK)) + return ERROR_DEFRAGMENT; + else + p_frag_info->inband_frag = ntohs(ib_obj->rx_header->inband_frag); + + memcpy(p_frag_info->buf,ib_obj->rx_data,ntohs(ib_obj->rx_header->inband_data_len)); + p_frag_info->buf += (ntohs(ib_obj->rx_header->inband_data_len)); + p_frag_info->data_len+= (ntohs(ib_obj->rx_header->inband_data_len)); + + if( (p_frag_info->inband_frag & EOF_BIT) == EOF_BIT) + ret = 1; + + return ret; // return 1 means EOF rcv , return 0 means conitiune +} + +static int get_defragment_info(struct inband_class *ib_obj,char *cmd_type,char **data) +{ + struct fragment_info *p_frag_info = &ib_obj->frag_info; + + *cmd_type = p_frag_info->inband_cmd; + *data = p_frag_info->buf_ptr; //mark_issue,hwo to free the buffer ? + return p_frag_info->data_len; +} + +static int inband_rcv_fragment(struct inband_class *ib_obj,char *cmd_type,char **data) +{ + int rx_len,ret=0; + + ret = init_defragment_process(ib_obj) ; + + if(ret < 0) + return ret; + + while( (inband_rcv_timeout!=1)) + { + rx_len = inband_recv(ib_obj, PER_FRAME_TIMEOUT); + if (rx_len < 0) + return ERROR_TIMOUT; + ret = do_defragment_process(ib_obj); + if (ret < 0) + return ret; + else if(ret == 1) //ret == 1 means defragment end , ret=0 means contiune + { + ret = get_defragment_info(ib_obj,cmd_type,data); + break; + } + send_frag_ack(ib_obj); + } + return ret; +} +void inband_free_buf(char *data_buf,int data_len) +{ + //only free allocated buffer from deframet process. + if( (data_buf != NULL) && ( data_len > MAX_INBAND_PAYLOAD_LEN ) ) + free(data_buf); +} +int inband_rcv_data(int chan,char *cmd_type,char **data,int timout_ms) //return data length +{ + int rx_len,data_len=0; + struct inband_class *inband_obj_p; + struct ioh_class *ioh_obj_p; + + inband_obj_p = (struct inband_class *)get_chan_obj(chan); + ioh_obj_p = &inband_obj_p->ioh_obj; + + + //timout_ms will be used only for the first pkt. if the pkt is fragmented then every packet will + //follow fragment_timout_ms + rx_len = inband_recv(inband_obj_p, timout_ms); // -1 = wait until rec + if (rx_len < 0) + { + perror("inband_rcv_data:"); + return -1; + } + //printf("inband_rcv_data:\n"); + //hex_dump(ioh_obj_p->rx_buffer, ntohs(inband_obj_p->rx_header->inband_data_len) + sizeof(*inband_obj_p->rx_header)); //mark_test + + //cache for tx dest mac + if( memcmp(ioh_obj_p->dest_mac,ioh_obj_p->rx_header->sa,6)) //mark_test + memcpy(ioh_obj_p->dest_mac,ioh_obj_p->rx_header->sa,6); + + //single pkt + if( inband_obj_p->rx_header->inband_frag == ntohs(SINGLE_FRAME)) //mark_endian + { + *cmd_type = inband_obj_p->rx_header->inband_cmd; + data_len = ntohs(inband_obj_p->rx_header->inband_data_len); + *data = inband_obj_p->rx_data ; //or memcpy; + } + else //fragment process + data_len = inband_rcv_fragment(inband_obj_p,cmd_type,data); + + return data_len; + +} + +//if seq is need in your application +int inband_rcv_data_and_seq(int chan,unsigned int *seq,char *cmd_type,char **data,int timout_ms) //return data length +{ + struct inband_class *inband_obj_p; + int ret=0; + + inband_obj_p = (struct inband_class *)get_chan_obj(chan); + ret = inband_rcv_data(chan,cmd_type,data, timout_ms); //return data length + if(ret < 0) + return -1; + + *seq = ntohs(inband_obj_p->rx_header->inband_seq); + return ret; +} + +static int inband_send_data(struct inband_class *ib_obj,char *data,int data_len) +{ + char *frag_ptr; + unsigned short id=0,total_frag=0; + unsigned int last_num; + struct ioh_class *ioh_obj_p = &ib_obj->ioh_obj; + + total_frag = (unsigned short)(data_len / MAX_INBAND_PAYLOAD_LEN); + + if( total_frag > MAX_FRAG_ID) + return -1; + + ib_obj->tx_header->inband_frag =0; + frag_ptr = data; + + for(id=0;id<total_frag;id++) + { + ib_obj->tx_header->inband_data_len = htons(MAX_INBAND_PAYLOAD_LEN); + ib_obj->tx_header->inband_frag = htons(id ); + memcpy(&ib_obj->tx_data[0], frag_ptr,MAX_INBAND_PAYLOAD_LEN ); + if( ioh_send(ioh_obj_p, sizeof(struct inband_header) + MAX_INBAND_PAYLOAD_LEN ) < 0) + return -1; + //if(id>= 1){ + if(check_frag_ack(ib_obj) != 1) + return -1; + //} + frag_ptr += MAX_INBAND_PAYLOAD_LEN; + } + last_num = data_len % MAX_INBAND_PAYLOAD_LEN; + //EOF fragment + ib_obj->tx_header->inband_frag = id; + ib_obj->tx_header->inband_frag |=EOF_BIT; + ib_obj->tx_header->inband_frag = htons(ib_obj->tx_header->inband_frag); + ib_obj->tx_header->inband_data_len = htons(last_num); + if(last_num >0) + memcpy(&ib_obj->tx_data[0], frag_ptr,last_num ); + + return ioh_send(ioh_obj_p,sizeof(struct inband_header)+last_num); +} + +int inband_write(int chan,unsigned int seq,char cmd,char *data,int data_len,int reply) +{ + struct inband_class *inband_obj_p; + + inband_obj_p = (struct inband_class *)get_chan_obj(chan); + + inband_obj_p->tx_header->rrcp_type = RRCP_P_IOH; //mark_inband + //fill inband header , cmd + inband_obj_p->tx_header->inband_cmd = cmd; + + //reply = 0(request) ,reply = 1(good reply),reply = 2(bad reply) + if(reply == 2) + inband_obj_p->tx_header->inband_cmd |= CMD_ERROR_REPLY_BIT; + + //fill inband header , seq + if(!reply) + inband_obj_p->tx_header->inband_seq = htons(seq); + else //seq is not used when the packet is for reply + inband_obj_p->tx_header->inband_seq = inband_obj_p->rx_header->inband_seq; + + //fill data, data_len , and send + return inband_send_data(inband_obj_p,data,data_len); +} + diff --git a/package/librtk-inband/src/inband_if.h b/package/librtk-inband/src/inband_if.h new file mode 100644 index 000000000..c37a3ca10 --- /dev/null +++ b/package/librtk-inband/src/inband_if.h @@ -0,0 +1,30 @@ +#ifndef INCLUDE_INBAND_IF_H +#define INCLUDE_INBAND_IF_H + +#define MAX_APP_DATA_SIZE 65535 +#define CMD_ERROR_REPLY_BIT 0x80 +#define MAX_INBAND_PAYLOAD_LEN 1480 +#define MAX_FRAG_ID (0x8000 -1) +#define FRAG_ID_MASK (~(0x8000)) + +#define EOF_BIT 0x8000 +#define SINGLE_FRAME 0x8000 +#define FIRST_FRAG_ID 0x0000 +#define PER_FRAME_TIMEOUT 2000 //ms + +#define ERROR_TIMOUT -1 +#define ERROR_DEFRAGMENT -2 + +#define RRCP_P_IOH 0x38 // RRCP IOH + +//mark_fm +#define id_firm_upgrade 0x03 + +int inband_open(char *netif_name,char *slave_mac,unsigned short eth_type,int debug); +void inband_close(int chan); +void inband_free_buf(char *data_buf,int data_len); +int inband_rcv_data(int chan,char *cmd_type,char **data,int timout_ms); //return data length +int inband_rcv_data_and_seq(int chan,unsigned int *seq,char *cmd_type,char **data,int timout_ms); //return data length +int inband_write(int chan,unsigned int seq,char cmd,char *data,int data_len,int reply); + +#endif diff --git a/package/librtk-inband/src/include/net80211/_ieee80211.h b/package/librtk-inband/src/include/net80211/_ieee80211.h new file mode 100644 index 000000000..f536dcb02 --- /dev/null +++ b/package/librtk-inband/src/include/net80211/_ieee80211.h @@ -0,0 +1,246 @@ +/*- + * Copyright (c) 2001 Atsushi Onoe + * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $Id: _ieee80211.h 2749 2007-10-16 08:58:14Z kelmo $ + */ +#ifndef _NET80211__IEEE80211_H_ +#define _NET80211__IEEE80211_H_ + +enum ieee80211_phytype { + IEEE80211_T_DS, /* direct sequence spread spectrum */ + IEEE80211_T_FH, /* frequency hopping */ + IEEE80211_T_OFDM, /* frequency division multiplexing */ + IEEE80211_T_TURBO, /* high rate OFDM, aka turbo mode */ +}; +#define IEEE80211_T_CCK IEEE80211_T_DS /* more common nomenclature */ + +/* XXX not really a mode; there are really multiple PHY's */ +enum ieee80211_phymode { + IEEE80211_MODE_AUTO = 0, /* autoselect */ + IEEE80211_MODE_11A = 1, /* 5GHz, OFDM */ + IEEE80211_MODE_11B = 2, /* 2GHz, CCK */ + IEEE80211_MODE_11G = 3, /* 2GHz, OFDM */ + IEEE80211_MODE_FH = 4, /* 2GHz, GFSK */ + IEEE80211_MODE_TURBO_A = 5, /* 5GHz, OFDM, 2x clock dynamic turbo */ + IEEE80211_MODE_TURBO_G = 6, /* 2GHz, OFDM, 2x clock dynamic turbo*/ +}; +#define IEEE80211_MODE_MAX (IEEE80211_MODE_TURBO_G+1) + +enum ieee80211_opmode { + IEEE80211_M_STA = 1, /* infrastructure station */ + IEEE80211_M_IBSS = 0, /* IBSS (adhoc) station */ + IEEE80211_M_AHDEMO = 3, /* Old lucent compatible adhoc demo */ + IEEE80211_M_HOSTAP = 6, /* Software Access Point */ + IEEE80211_M_MONITOR = 8, /* Monitor mode */ + IEEE80211_M_WDS = 2 /* WDS link */ +}; + +/* + * 802.11g protection mode. + */ +enum ieee80211_protmode { + IEEE80211_PROT_NONE = 0, /* no protection */ + IEEE80211_PROT_CTSONLY = 1, /* CTS to self */ + IEEE80211_PROT_RTSCTS = 2, /* RTS-CTS */ +}; + +/* + * Authentication mode. + */ +enum ieee80211_authmode { + IEEE80211_AUTH_NONE = 0, + IEEE80211_AUTH_OPEN = 1, /* open */ + IEEE80211_AUTH_SHARED = 2, /* shared-key */ + IEEE80211_AUTH_8021X = 3, /* 802.1x */ + IEEE80211_AUTH_AUTO = 4, /* auto-select/accept */ + /* NB: these are used only for ioctls */ + IEEE80211_AUTH_WPA = 5, /* WPA/RSN w/ 802.1x/PSK */ +}; + +/* + * Roaming mode is effectively who controls the operation + * of the 802.11 state machine when operating as a station. + * State transitions are controlled either by the driver + * (typically when management frames are processed by the + * hardware/firmware), the host (auto/normal operation of + * the 802.11 layer), or explicitly through ioctl requests + * when applications like wpa_supplicant want control. + */ +enum ieee80211_roamingmode { + IEEE80211_ROAMING_DEVICE= 0, /* driver/hardware control */ + IEEE80211_ROAMING_AUTO = 1, /* 802.11 layer control */ + IEEE80211_ROAMING_MANUAL= 2, /* application control */ +}; + +/* + * Scanning mode controls station scanning work; this is + * used only when roaming mode permits the host to select + * the bss to join/channel to use. + */ +enum ieee80211_scanmode { + IEEE80211_SCAN_DEVICE = 0, /* driver/hardware control */ + IEEE80211_SCAN_BEST = 1, /* 802.11 layer selects best */ + IEEE80211_SCAN_FIRST = 2, /* take first suitable candidate */ +}; + +/* + * Channels are specified by frequency and attributes. + */ +struct ieee80211_channel { + u_int16_t ic_freq; /* setting in Mhz */ + u_int16_t ic_flags; /* see below */ + u_int8_t ic_ieee; /* IEEE channel number */ + int8_t ic_maxregpower; /* maximum regulatory tx power in dBm */ + int8_t ic_maxpower; /* maximum tx power in dBm */ + int8_t ic_minpower; /* minimum tx power in dBm */ +}; + +#define IEEE80211_CHAN_MAX 255 +#define IEEE80211_CHAN_BYTES 32 /* howmany(IEEE80211_CHAN_MAX, NBBY) */ +#define IEEE80211_CHAN_ANY 0xffff /* token for ``any channel'' */ +#define IEEE80211_CHAN_ANYC ((struct ieee80211_channel *) IEEE80211_CHAN_ANY) + +#define IEEE80211_RADAR_11HCOUNT 1 +#define IEEE80211_DEFAULT_CHANCHANGE_TBTT_COUNT 3 +#define IEEE80211_RADAR_TEST_MUTE_CHAN 36 /* Move to channel 36 for mute test */ + +/* bits 0-3 are for private use by drivers */ +/* channel attributes */ +#define IEEE80211_CHAN_TURBO 0x0010 /* Turbo channel */ +#define IEEE80211_CHAN_CCK 0x0020 /* CCK channel */ +#define IEEE80211_CHAN_OFDM 0x0040 /* OFDM channel */ +#define IEEE80211_CHAN_2GHZ 0x0080 /* 2 GHz spectrum channel. */ +#define IEEE80211_CHAN_5GHZ 0x0100 /* 5 GHz spectrum channel */ +#define IEEE80211_CHAN_PASSIVE 0x0200 /* Only passive scan allowed */ +#define IEEE80211_CHAN_DYN 0x0400 /* Dynamic CCK-OFDM channel */ +#define IEEE80211_CHAN_GFSK 0x0800 /* GFSK channel (FHSS PHY) */ +#define IEEE80211_CHAN_RADAR 0x1000 /* Radar found on channel */ +#define IEEE80211_CHAN_STURBO 0x2000 /* 11a static turbo channel only */ +#define IEEE80211_CHAN_HALF 0x4000 /* Half rate channel */ +#define IEEE80211_CHAN_QUARTER 0x8000 /* Quarter rate channel */ + +/* + * Useful combinations of channel characteristics. + */ +#define IEEE80211_CHAN_FHSS \ + (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_GFSK) +#define IEEE80211_CHAN_A \ + (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM) +#define IEEE80211_CHAN_B \ + (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK) +#define IEEE80211_CHAN_PUREG \ + (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_OFDM) +#define IEEE80211_CHAN_G \ + (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN) +#define IEEE80211_CHAN_108A \ + (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM | IEEE80211_CHAN_TURBO) +#define IEEE80211_CHAN_108G \ + (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_OFDM | IEEE80211_CHAN_TURBO) +#define IEEE80211_CHAN_ST \ + (IEEE80211_CHAN_108A | IEEE80211_CHAN_STURBO) + +#define IEEE80211_CHAN_ALL \ + (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_GFSK | \ + IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM | IEEE80211_CHAN_DYN) +#define IEEE80211_CHAN_ALLTURBO \ + (IEEE80211_CHAN_ALL | IEEE80211_CHAN_TURBO | IEEE80211_CHAN_STURBO) + +#define IEEE80211_IS_CHAN_FHSS(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_FHSS) == IEEE80211_CHAN_FHSS) +#define IEEE80211_IS_CHAN_A(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_A) == IEEE80211_CHAN_A) +#define IEEE80211_IS_CHAN_B(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_B) == IEEE80211_CHAN_B) +#define IEEE80211_IS_CHAN_PUREG(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_PUREG) == IEEE80211_CHAN_PUREG) +#define IEEE80211_IS_CHAN_G(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_G) == IEEE80211_CHAN_G) +#define IEEE80211_IS_CHAN_ANYG(_c) \ + (IEEE80211_IS_CHAN_PUREG(_c) || IEEE80211_IS_CHAN_G(_c)) +#define IEEE80211_IS_CHAN_ST(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_ST) == IEEE80211_CHAN_ST) +#define IEEE80211_IS_CHAN_108A(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_108A) == IEEE80211_CHAN_108A) +#define IEEE80211_IS_CHAN_108G(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_108G) == IEEE80211_CHAN_108G) + +#define IEEE80211_IS_CHAN_2GHZ(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_2GHZ) != 0) +#define IEEE80211_IS_CHAN_5GHZ(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_5GHZ) != 0) +#define IEEE80211_IS_CHAN_OFDM(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_OFDM) != 0) +#define IEEE80211_IS_CHAN_CCK(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_CCK) != 0) +#define IEEE80211_IS_CHAN_GFSK(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_GFSK) != 0) +#define IEEE80211_IS_CHAN_TURBO(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_TURBO) != 0) +#define IEEE80211_IS_CHAN_STURBO(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_STURBO) != 0) +#define IEEE80211_IS_CHAN_DTURBO(_c) \ + (((_c)->ic_flags & \ + (IEEE80211_CHAN_TURBO | IEEE80211_CHAN_STURBO)) == IEEE80211_CHAN_TURBO) +#define IEEE80211_IS_CHAN_HALF(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_HALF) != 0) +#define IEEE80211_IS_CHAN_QUARTER(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_QUARTER) != 0) + +/* ni_chan encoding for FH phy */ +#define IEEE80211_FH_CHANMOD 80 +#define IEEE80211_FH_CHAN(set,pat) (((set) - 1) * IEEE80211_FH_CHANMOD + (pat)) +#define IEEE80211_FH_CHANSET(chan) ((chan) / IEEE80211_FH_CHANMOD + 1) +#define IEEE80211_FH_CHANPAT(chan) ((chan) % IEEE80211_FH_CHANMOD) + +/* + * 802.11 rate set. + */ +#define IEEE80211_RATE_SIZE 8 /* 802.11 standard */ +#define IEEE80211_RATE_MAXSIZE 15 /* max rates we'll handle */ +#define IEEE80211_SANITISE_RATESIZE(_rsz) \ + ((_rsz > IEEE80211_RATE_MAXSIZE) ? IEEE80211_RATE_MAXSIZE : _rsz) + +struct ieee80211_rateset { + u_int8_t rs_nrates; + u_int8_t rs_rates[IEEE80211_RATE_MAXSIZE]; +}; + +struct ieee80211_roam { + int8_t rssi11a; /* rssi thresh for 11a bss */ + int8_t rssi11b; /* for 11g sta in 11b bss */ + int8_t rssi11bOnly; /* for 11b sta */ + u_int8_t pad1; + u_int8_t rate11a; /* rate thresh for 11a bss */ + u_int8_t rate11b; /* for 11g sta in 11b bss */ + u_int8_t rate11bOnly; /* for 11b sta */ + u_int8_t pad2; +}; +#endif /* _NET80211__IEEE80211_H_ */ diff --git a/package/librtk-inband/src/include/net80211/ieee80211.h b/package/librtk-inband/src/include/net80211/ieee80211.h new file mode 100644 index 000000000..c28e83df0 --- /dev/null +++ b/package/librtk-inband/src/include/net80211/ieee80211.h @@ -0,0 +1,947 @@ +/*- + * Copyright (c) 2001 Atsushi Onoe + * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $Id: ieee80211.h 3313 2008-01-30 21:07:22Z proski $ + */ +#ifndef _NET80211_IEEE80211_H_ +#define _NET80211_IEEE80211_H_ + +#ifndef _LINUX_TYPES_H +#include <linux/types.h> +#endif + +#ifndef __packed +#define __packed __attribute__((__packed__)) +#endif + +/* + * 802.11 protocol definitions. + */ + +#define IEEE80211_ADDR_LEN 6 /* size of 802.11 address */ +/* is 802.11 address multicast/broadcast? */ +#define IEEE80211_IS_MULTICAST(_a) (*(_a) & 0x01) + +/* IEEE 802.11 PLCP header */ +struct ieee80211_plcp_hdr { + u_int16_t i_sfd; + u_int8_t i_signal; + u_int8_t i_service; + u_int16_t i_length; + u_int16_t i_crc; +} __packed; + +#define IEEE80211_PLCP_SFD 0xF3A0 +#define IEEE80211_PLCP_SERVICE 0x00 + +/* + * generic definitions for IEEE 802.11 frames + */ +struct ieee80211_frame { + u_int8_t i_fc[2]; + __le16 i_dur; + u_int8_t i_addr1[IEEE80211_ADDR_LEN]; + u_int8_t i_addr2[IEEE80211_ADDR_LEN]; + u_int8_t i_addr3[IEEE80211_ADDR_LEN]; + u_int8_t i_seq[2]; + /* possibly followed by addr4[IEEE80211_ADDR_LEN]; */ + /* see below */ +} __packed; + +struct ieee80211_qosframe { + u_int8_t i_fc[2]; + __le16 i_dur; + u_int8_t i_addr1[IEEE80211_ADDR_LEN]; + u_int8_t i_addr2[IEEE80211_ADDR_LEN]; + u_int8_t i_addr3[IEEE80211_ADDR_LEN]; + u_int8_t i_seq[2]; + u_int8_t i_qos[2]; + /* possibly followed by addr4[IEEE80211_ADDR_LEN]; */ + /* see below */ +} __packed; + +struct ieee80211_qoscntl { + u_int8_t i_qos[2]; +}; + +struct ieee80211_frame_addr4 { + u_int8_t i_fc[2]; + __le16 i_dur; + u_int8_t i_addr1[IEEE80211_ADDR_LEN]; + u_int8_t i_addr2[IEEE80211_ADDR_LEN]; + u_int8_t i_addr3[IEEE80211_ADDR_LEN]; + u_int8_t i_seq[2]; + u_int8_t i_addr4[IEEE80211_ADDR_LEN]; +} __packed; + + +struct ieee80211_qosframe_addr4 { + u_int8_t i_fc[2]; + __le16 i_dur; + u_int8_t i_addr1[IEEE80211_ADDR_LEN]; + u_int8_t i_addr2[IEEE80211_ADDR_LEN]; + u_int8_t i_addr3[IEEE80211_ADDR_LEN]; + u_int8_t i_seq[2]; + u_int8_t i_addr4[IEEE80211_ADDR_LEN]; + u_int8_t i_qos[2]; +} __packed; + +struct ieee80211_ctlframe_addr2 { + u_int8_t i_fc[2]; + __le16 i_aidordur; /* AID or duration */ + u_int8_t i_addr1[IEEE80211_ADDR_LEN]; + u_int8_t i_addr2[IEEE80211_ADDR_LEN]; +} __packed; + +#define IEEE80211_FC0_VERSION_MASK 0x03 +#define IEEE80211_FC0_VERSION_SHIFT 0 +#define IEEE80211_FC0_VERSION_0 0x00 +#define IEEE80211_FC0_TYPE_MASK 0x0c +#define IEEE80211_FC0_TYPE_SHIFT 2 +#define IEEE80211_FC0_TYPE_MGT 0x00 +#define IEEE80211_FC0_TYPE_CTL 0x04 +#define IEEE80211_FC0_TYPE_DATA 0x08 + +#define IEEE80211_FC0_SUBTYPE_MASK 0xf0 +#define IEEE80211_FC0_SUBTYPE_SHIFT 4 +/* for TYPE_MGT */ +#define IEEE80211_FC0_SUBTYPE_ASSOC_REQ 0x00 +#define IEEE80211_FC0_SUBTYPE_ASSOC_RESP 0x10 +#define IEEE80211_FC0_SUBTYPE_REASSOC_REQ 0x20 +#define IEEE80211_FC0_SUBTYPE_REASSOC_RESP 0x30 +#define IEEE80211_FC0_SUBTYPE_PROBE_REQ 0x40 +#define IEEE80211_FC0_SUBTYPE_PROBE_RESP 0x50 +#define IEEE80211_FC0_SUBTYPE_BEACON 0x80 +#define IEEE80211_FC0_SUBTYPE_ATIM 0x90 +#define IEEE80211_FC0_SUBTYPE_DISASSOC 0xa0 +#define IEEE80211_FC0_SUBTYPE_AUTH 0xb0 +#define IEEE80211_FC0_SUBTYPE_DEAUTH 0xc0 +#define IEEE80211_FC0_SUBTYPE_ACTION 0xd0 +/* for TYPE_CTL */ +#define IEEE80211_FC0_SUBTYPE_PS_POLL 0xa0 +#define IEEE80211_FC0_SUBTYPE_RTS 0xb0 +#define IEEE80211_FC0_SUBTYPE_CTS 0xc0 +#define IEEE80211_FC0_SUBTYPE_ACK 0xd0 +#define IEEE80211_FC0_SUBTYPE_CF_END 0xe0 +#define IEEE80211_FC0_SUBTYPE_CF_END_ACK 0xf0 +/* for TYPE_DATA (bit combination) */ +#define IEEE80211_FC0_SUBTYPE_DATA 0x00 +#define IEEE80211_FC0_SUBTYPE_CF_ACK 0x10 +#define IEEE80211_FC0_SUBTYPE_CF_POLL 0x20 +#define IEEE80211_FC0_SUBTYPE_CF_ACPL 0x30 +#define IEEE80211_FC0_SUBTYPE_NODATA 0x40 +#define IEEE80211_FC0_SUBTYPE_CFACK 0x50 +#define IEEE80211_FC0_SUBTYPE_CFPOLL 0x60 +#define IEEE80211_FC0_SUBTYPE_CF_ACK_CF_ACK 0x70 +#define IEEE80211_FC0_SUBTYPE_QOS 0x80 +#define IEEE80211_FC0_SUBTYPE_QOS_NULL 0xc0 + +#define IEEE80211_FC1_DIR_MASK 0x03 +#define IEEE80211_FC1_DIR_NODS 0x00 /* STA->STA */ +#define IEEE80211_FC1_DIR_TODS 0x01 /* STA->AP */ +#define IEEE80211_FC1_DIR_FROMDS 0x02 /* AP ->STA */ +#define IEEE80211_FC1_DIR_DSTODS 0x03 /* AP ->AP */ + +#define IEEE80211_FC1_MORE_FRAG 0x04 +#define IEEE80211_FC1_RETRY 0x08 +#define IEEE80211_FC1_PWR_MGT 0x10 +#define IEEE80211_FC1_MORE_DATA 0x20 +#define IEEE80211_FC1_PROT 0x40 +#define IEEE80211_FC1_ORDER 0x80 + +#define IEEE80211_SEQ_FRAG_MASK 0x000f +#define IEEE80211_SEQ_FRAG_SHIFT 0 +#define IEEE80211_SEQ_SEQ_MASK 0xfff0 +#define IEEE80211_SEQ_SEQ_SHIFT 4 + +#define IEEE80211_SEQ_LEQ(a,b) ((int)((a)-(b)) <= 0) + +#define IEEE80211_NWID_LEN 32 + +#define IEEE80211_QOS_TXOP 0x00ff +/* bit 8 is reserved */ +#define IEEE80211_QOS_ACKPOLICY 0x60 +#define IEEE80211_QOS_ACKPOLICY_S 5 +#define IEEE80211_QOS_EOSP 0x10 +#define IEEE80211_QOS_EOSP_S 4 +#define IEEE80211_QOS_TID 0x0f + +/* + * Country/Region Codes from MS WINNLS.H + * Numbering from ISO 3166 + * XXX belongs elsewhere + */ +enum CountryCode { + CTRY_ALBANIA = 8, /* Albania */ + CTRY_ALGERIA = 12, /* Algeria */ + CTRY_ARGENTINA = 32, /* Argentina */ + CTRY_ARMENIA = 51, /* Armenia */ + CTRY_AUSTRALIA = 36, /* Australia */ + CTRY_AUSTRIA = 40, /* Austria */ + CTRY_AZERBAIJAN = 31, /* Azerbaijan */ + CTRY_BAHRAIN = 48, /* Bahrain */ + CTRY_BELARUS = 112, /* Belarus */ + CTRY_BELGIUM = 56, /* Belgium */ + CTRY_BELIZE = 84, /* Belize */ + CTRY_BOLIVIA = 68, /* Bolivia */ + CTRY_BRAZIL = 76, /* Brazil */ + CTRY_BRUNEI_DARUSSALAM = 96, /* Brunei Darussalam */ + CTRY_BULGARIA = 100, /* Bulgaria */ + CTRY_CANADA = 124, /* Canada */ + CTRY_CHILE = 152, /* Chile */ + CTRY_CHINA = 156, /* People's Republic of China */ + CTRY_COLOMBIA = 170, /* Colombia */ + CTRY_COSTA_RICA = 188, /* Costa Rica */ + CTRY_CROATIA = 191, /* Croatia */ + CTRY_CYPRUS = 196, + CTRY_CZECH = 203, /* Czech Republic */ + CTRY_DENMARK = 208, /* Denmark */ + CTRY_DOMINICAN_REPUBLIC = 214, /* Dominican Republic */ + CTRY_ECUADOR = 218, /* Ecuador */ + CTRY_EGYPT = 818, /* Egypt */ + CTRY_EL_SALVADOR = 222, /* El Salvador */ + CTRY_ESTONIA = 233, /* Estonia */ + CTRY_FAEROE_ISLANDS = 234, /* Faeroe Islands */ + CTRY_FINLAND = 246, /* Finland */ + CTRY_FRANCE = 250, /* France */ + CTRY_FRANCE2 = 255, /* France2 */ + CTRY_GEORGIA = 268, /* Georgia */ + CTRY_GERMANY = 276, /* Germany */ + CTRY_GREECE = 300, /* Greece */ + CTRY_GUATEMALA = 320, /* Guatemala */ + CTRY_HONDURAS = 340, /* Honduras */ + CTRY_HONG_KONG = 344, /* Hong Kong S.A.R., P.R.C. */ + CTRY_HUNGARY = 348, /* Hungary */ + CTRY_ICELAND = 352, /* Iceland */ + CTRY_INDIA = 356, /* India */ + CTRY_INDONESIA = 360, /* Indonesia */ + CTRY_IRAN = 364, /* Iran */ + CTRY_IRAQ = 368, /* Iraq */ + CTRY_IRELAND = 372, /* Ireland */ + CTRY_ISRAEL = 376, /* Israel */ + CTRY_ITALY = 380, /* Italy */ + CTRY_JAMAICA = 388, /* Jamaica */ + CTRY_JAPAN = 392, /* Japan */ + CTRY_JAPAN1 = 393, /* Japan (JP1) */ + CTRY_JAPAN2 = 394, /* Japan (JP0) */ + CTRY_JAPAN3 = 395, /* Japan (JP1-1) */ + CTRY_JAPAN4 = 396, /* Japan (JE1) */ + CTRY_JAPAN5 = 397, /* Japan (JE2) */ + CTRY_JAPAN6 = 399, /* Japan (JP6) */ + CTRY_JAPAN7 = 900, /* Japan */ + CTRY_JAPAN8 = 901, /* Japan */ + CTRY_JAPAN9 = 902, /* Japan */ + CTRY_JAPAN10 = 903, /* Japan */ + CTRY_JAPAN11 = 904, /* Japan */ + CTRY_JAPAN12 = 905, /* Japan */ + CTRY_JAPAN13 = 906, /* Japan */ + CTRY_JAPAN14 = 907, /* Japan */ + CTRY_JAPAN15 = 908, /* Japan */ + CTRY_JAPAN16 = 909, /* Japan */ + CTRY_JAPAN17 = 910, /* Japan */ + CTRY_JAPAN18 = 911, /* Japan */ + CTRY_JAPAN19 = 912, /* Japan */ + CTRY_JAPAN20 = 913, /* Japan */ + CTRY_JAPAN21 = 914, /* Japan */ + CTRY_JAPAN22 = 915, /* Japan */ + CTRY_JAPAN23 = 916, /* Japan */ + CTRY_JAPAN24 = 917, /* Japan */ + CTRY_JAPAN25 = 918, /* Japan */ + CTRY_JAPAN26 = 919, /* Japan */ + CTRY_JAPAN27 = 920, /* Japan */ + CTRY_JAPAN28 = 921, /* Japan */ + CTRY_JAPAN29 = 922, /* Japan */ + CTRY_JAPAN30 = 923, /* Japan */ + CTRY_JAPAN31 = 924, /* Japan */ + CTRY_JAPAN32 = 925, /* Japan */ + CTRY_JAPAN33 = 926, /* Japan */ + CTRY_JAPAN34 = 927, /* Japan */ + CTRY_JAPAN35 = 928, /* Japan */ + CTRY_JAPAN36 = 929, /* Japan */ + CTRY_JAPAN37 = 930, /* Japan */ + CTRY_JAPAN38 = 931, /* Japan */ + CTRY_JAPAN39 = 932, /* Japan */ + CTRY_JAPAN40 = 933, /* Japan */ + CTRY_JAPAN41 = 934, /* Japan */ + CTRY_JAPAN42 = 935, /* Japan */ + CTRY_JAPAN43 = 936, /* Japan */ + CTRY_JAPAN44 = 937, /* Japan */ + CTRY_JAPAN45 = 938, /* Japan */ + CTRY_JAPAN46 = 939, /* Japan */ + CTRY_JAPAN47 = 940, /* Japan */ + CTRY_JAPAN48 = 941, /* Japan */ + CTRY_JORDAN = 400, /* Jordan */ + CTRY_KAZAKHSTAN = 398, /* Kazakhstan */ + CTRY_KENYA = 404, /* Kenya */ + CTRY_KOREA_NORTH = 408, /* North Korea */ + CTRY_KOREA_ROC = 410, /* South Korea */ + CTRY_KOREA_ROC2 = 411, /* South Korea */ + CTRY_KUWAIT = 414, /* Kuwait */ + CTRY_LATVIA = 428, /* Latvia */ + CTRY_LEBANON = 422, /* Lebanon */ + CTRY_LIBYA = 434, /* Libya */ + CTRY_LIECHTENSTEIN = 438, /* Liechtenstein */ + CTRY_LITHUANIA = 440, /* Lithuania */ + CTRY_LUXEMBOURG = 442, /* Luxembourg */ + CTRY_MACAU = 446, /* Macau */ + CTRY_MACEDONIA = 807, /* the Former Yugoslav Republic of Macedonia */ + CTRY_MALAYSIA = 458, /* Malaysia */ + CTRY_MEXICO = 484, /* Mexico */ + CTRY_MONACO = 492, /* Principality of Monaco */ + CTRY_MOROCCO = 504, /* Morocco */ + CTRY_NETHERLANDS = 528, /* Netherlands */ + CTRY_NEW_ZEALAND = 554, /* New Zealand */ + CTRY_NICARAGUA = 558, /* Nicaragua */ + CTRY_NORWAY = 578, /* Norway */ + CTRY_OMAN = 512, /* Oman */ + CTRY_PAKISTAN = 586, /* Islamic Republic of Pakistan */ + CTRY_PANAMA = 591, /* Panama */ + CTRY_PARAGUAY = 600, /* Paraguay */ + CTRY_PERU = 604, /* Peru */ + CTRY_PHILIPPINES = 608, /* Republic of the Philippines */ + CTRY_POLAND = 616, /* Poland */ + CTRY_PORTUGAL = 620, /* Portugal */ + CTRY_PUERTO_RICO = 630, /* Puerto Rico */ + CTRY_QATAR = 634, /* Qatar */ + CTRY_ROMANIA = 642, /* Romania */ + CTRY_RUSSIA = 643, /* Russia */ + CTRY_SAUDI_ARABIA = 682, /* Saudi Arabia */ + CTRY_SINGAPORE = 702, /* Singapore */ + CTRY_SLOVAKIA = 703, /* Slovak Republic */ + CTRY_SLOVENIA = 705, /* Slovenia */ + CTRY_SOUTH_AFRICA = 710, /* South Africa */ + CTRY_SPAIN = 724, /* Spain */ + CTRY_SWEDEN = 752, /* Sweden */ + CTRY_SWITZERLAND = 756, /* Switzerland */ + CTRY_SYRIA = 760, /* Syria */ + CTRY_TAIWAN = 158, /* Taiwan */ + CTRY_THAILAND = 764, /* Thailand */ + CTRY_TRINIDAD_Y_TOBAGO = 780, /* Trinidad y Tobago */ + CTRY_TUNISIA = 788, /* Tunisia */ + CTRY_TURKEY = 792, /* Turkey */ + CTRY_UAE = 784, /* U.A.E. */ + CTRY_UKRAINE = 804, /* Ukraine */ + CTRY_UNITED_KINGDOM = 826, /* United Kingdom */ + CTRY_UNITED_STATES = 840, /* United States */ + CTRY_UNITED_STATES_FCC49 = 842, /* United States (Public Safety)*/ + CTRY_URUGUAY = 858, /* Uruguay */ + CTRY_UZBEKISTAN = 860, /* Uzbekistan */ + CTRY_VENEZUELA = 862, /* Venezuela */ + CTRY_VIET_NAM = 704, /* Viet Nam */ + CTRY_YEMEN = 887, /* Yemen */ + CTRY_ZIMBABWE = 716 /* Zimbabwe */ +}; + +/* + * Generic information element + */ +struct ieee80211_ie { + u_int8_t id; + u_int8_t len; + u_int8_t info[0]; +} __packed; + +/* + * Country information element. + */ +#define IEEE80211_COUNTRY_MAX_TRIPLETS (83) +struct ieee80211_ie_country { + u_int8_t country_id; + u_int8_t country_len; + u_int8_t country_str[3]; + u_int8_t country_triplet[IEEE80211_COUNTRY_MAX_TRIPLETS * 3]; +} __packed; + +/* + * Channel Switch Announcement information element. + */ +struct ieee80211_ie_csa { + u_int8_t csa_id; /* IEEE80211_ELEMID_CHANSWITCHANN */ + u_int8_t csa_len; /* == 3 */ + u_int8_t csa_mode; /* Channel Switch Mode: 1 == stop transmission until CS */ + u_int8_t csa_chan; /* New Channel Number */ + u_int8_t csa_count; /* TBTTs until Channel Switch happens */ +} __packed; + +/* minimal Channel Switch Count in the initial announcement */ +#define IEEE80211_CSA_PROTECTION_PERIOD 3 + +/* maximum allowed deviance of measurement of intervals between CSA in Beacons */ +#define IEEE80211_CSA_SANITY_THRESHOLD 100 + + +/* does frame have QoS sequence control data */ +#define IEEE80211_QOS_HAS_SEQ(wh) \ + (((wh)->i_fc[0] & \ + (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_QOS)) == \ + (IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_QOS)) + +#define WME_QOSINFO_COUNT 0x0f /* Mask for Param Set Count field */ +/* + * WME/802.11e information element. + */ +struct ieee80211_ie_wme { + u_int8_t wme_id; /* IEEE80211_ELEMID_VENDOR */ + u_int8_t wme_len; /* length in bytes */ + u_int8_t wme_oui[3]; /* 0x00, 0x50, 0xf2 */ + u_int8_t wme_type; /* OUI type */ + u_int8_t wme_subtype; /* OUI subtype */ + u_int8_t wme_version; /* spec revision */ + u_int8_t wme_info; /* QoS info */ +} __packed; + +/* + * WME/802.11e Tspec Element + */ +struct ieee80211_wme_tspec { + u_int8_t ts_id; + u_int8_t ts_len; + u_int8_t ts_oui[3]; + u_int8_t ts_oui_type; + u_int8_t ts_oui_subtype; + u_int8_t ts_version; + u_int8_t ts_tsinfo[3]; + u_int8_t ts_nom_msdu[2]; + u_int8_t ts_max_msdu[2]; + u_int8_t ts_min_svc[4]; + u_int8_t ts_max_svc[4]; + u_int8_t ts_inactv_intv[4]; + u_int8_t ts_susp_intv[4]; + u_int8_t ts_start_svc[4]; + u_int8_t ts_min_rate[4]; + u_int8_t ts_mean_rate[4]; + u_int8_t ts_max_burst[4]; + u_int8_t ts_min_phy[4]; + u_int8_t ts_peak_rate[4]; + u_int8_t ts_delay[4]; + u_int8_t ts_surplus[2]; + u_int8_t ts_medium_time[2]; +} __packed; + +/* + * WME AC parameter field + */ + +struct ieee80211_wme_acparams { + u_int8_t acp_aci_aifsn; + u_int8_t acp_logcwminmax; + u_int16_t acp_txop; +} __packed; + +#define IEEE80211_WME_PARAM_LEN 24 +#define WME_NUM_AC 4 /* 4 AC categories */ + +#define WME_PARAM_ACI 0x60 /* Mask for ACI field */ +#define WME_PARAM_ACI_S 5 /* Shift for ACI field */ +#define WME_PARAM_ACM 0x10 /* Mask for ACM bit */ +#define WME_PARAM_ACM_S 4 /* Shift for ACM bit */ +#define WME_PARAM_AIFSN 0x0f /* Mask for aifsn field */ +#define WME_PARAM_AIFSN_S 0 /* Shift for aifsn field */ +#define WME_PARAM_LOGCWMIN 0x0f /* Mask for CwMin field (in log) */ +#define WME_PARAM_LOGCWMIN_S 0 /* Shift for CwMin field */ +#define WME_PARAM_LOGCWMAX 0xf0 /* Mask for CwMax field (in log) */ +#define WME_PARAM_LOGCWMAX_S 4 /* Shift for CwMax field */ + +#define WME_AC_TO_TID(_ac) ( \ + ((_ac) == WME_AC_VO) ? 6 : \ + ((_ac) == WME_AC_VI) ? 5 : \ + ((_ac) == WME_AC_BK) ? 1 : \ + 0) + +#define TID_TO_WME_AC(_tid) ( \ + ((_tid) < 1) ? WME_AC_BE : \ + ((_tid) < 3) ? WME_AC_BK : \ + ((_tid) < 6) ? WME_AC_VI : \ + WME_AC_VO) + +/* + * WME Parameter Element + */ + +struct ieee80211_wme_param { + u_int8_t param_id; + u_int8_t param_len; + u_int8_t param_oui[3]; + u_int8_t param_oui_type; + u_int8_t param_oui_sybtype; + u_int8_t param_version; + u_int8_t param_qosInfo; + u_int8_t param_reserved; + struct ieee80211_wme_acparams params_acParams[WME_NUM_AC]; +} __packed; + +/* + * WME U-APSD qos info field defines + */ +#define WME_CAPINFO_UAPSD_EN 0x00000080 +#define WME_CAPINFO_UAPSD_VO 0x00000001 +#define WME_CAPINFO_UAPSD_VI 0x00000002 +#define WME_CAPINFO_UAPSD_BK 0x00000004 +#define WME_CAPINFO_UAPSD_BE 0x00000008 +#define WME_CAPINFO_UAPSD_ACFLAGS_SHIFT 0 +#define WME_CAPINFO_UAPSD_ACFLAGS_MASK 0xF +#define WME_CAPINFO_UAPSD_MAXSP_SHIFT 5 +#define WME_CAPINFO_UAPSD_MAXSP_MASK 0x3 +#define WME_CAPINFO_IE_OFFSET 8 +#define WME_UAPSD_MAXSP(_qosinfo) (((_qosinfo) >> WME_CAPINFO_UAPSD_MAXSP_SHIFT) & WME_CAPINFO_UAPSD_MAXSP_MASK) +#define WME_UAPSD_AC_ENABLED(_ac, _qosinfo) ( (1<<(3 - (_ac))) & \ + (((_qosinfo) >> WME_CAPINFO_UAPSD_ACFLAGS_SHIFT) & WME_CAPINFO_UAPSD_ACFLAGS_MASK) ) + +/* + * Atheros Advanced Capability information element. + */ +struct ieee80211_ie_athAdvCap { + u_int8_t athAdvCap_id; /* IEEE80211_ELEMID_VENDOR */ + u_int8_t athAdvCap_len; /* length in bytes */ + u_int8_t athAdvCap_oui[3]; /* 0x00, 0x03, 0x7f */ + u_int8_t athAdvCap_type; /* OUI type */ + u_int8_t athAdvCap_subtype; /* OUI subtype */ + u_int8_t athAdvCap_version; /* spec revision */ + u_int8_t athAdvCap_capability; /* Capability info */ + u_int16_t athAdvCap_defKeyIndex; +} __packed; + +/* + * Atheros XR information element. + */ +struct ieee80211_xr_param { + u_int8_t param_id; + u_int8_t param_len; + u_int8_t param_oui[3]; + u_int8_t param_oui_type; + u_int8_t param_oui_sybtype; + u_int8_t param_version; + u_int8_t param_Info; + u_int8_t param_base_bssid[IEEE80211_ADDR_LEN]; + u_int8_t param_xr_bssid[IEEE80211_ADDR_LEN]; + u_int16_t param_xr_beacon_interval; + u_int8_t param_base_ath_capability; + u_int8_t param_xr_ath_capability; +} __packed; + +/* Atheros capabilities */ +#define IEEE80211_ATHC_TURBOP 0x0001 /* Turbo Prime */ +#define IEEE80211_ATHC_COMP 0x0002 /* Compression */ +#define IEEE80211_ATHC_FF 0x0004 /* Fast Frames */ +#define IEEE80211_ATHC_XR 0x0008 /* Xtended Range support */ +#define IEEE80211_ATHC_AR 0x0010 /* Advanced Radar support */ +#define IEEE80211_ATHC_BURST 0x0020 /* Bursting - not negotiated */ +#define IEEE80211_ATHC_WME 0x0040 /* CWMin tuning */ +#define IEEE80211_ATHC_BOOST 0x0080 /* Boost */ + +/* + * Management Notification Frame + */ +struct ieee80211_mnf { + u_int8_t mnf_category; + u_int8_t mnf_action; + u_int8_t mnf_dialog; + u_int8_t mnf_status; +} __packed; +#define MNF_SETUP_REQ 0 +#define MNF_SETUP_RESP 1 +#define MNF_TEARDOWN 2 + +/* + * Control frames. + */ +struct ieee80211_frame_min { + u_int8_t i_fc[2]; + __le16 i_dur; + u_int8_t i_addr1[IEEE80211_ADDR_LEN]; + u_int8_t i_addr2[IEEE80211_ADDR_LEN]; + /* FCS */ +} __packed; + +struct ieee80211_frame_rts { + u_int8_t i_fc[2]; + __le16 i_dur; + u_int8_t i_ra[IEEE80211_ADDR_LEN]; + u_int8_t i_ta[IEEE80211_ADDR_LEN]; + /* FCS */ +} __packed; + +struct ieee80211_frame_cts { + u_int8_t i_fc[2]; + __le16 i_dur; + u_int8_t i_ra[IEEE80211_ADDR_LEN]; + /* FCS */ +} __packed; + +struct ieee80211_frame_ack { + u_int8_t i_fc[2]; + __le16 i_dur; + u_int8_t i_ra[IEEE80211_ADDR_LEN]; + /* FCS */ +} __packed; + +struct ieee80211_frame_pspoll { + u_int8_t i_fc[2]; + u_int8_t i_aid[2]; + u_int8_t i_bssid[IEEE80211_ADDR_LEN]; + u_int8_t i_ta[IEEE80211_ADDR_LEN]; + /* FCS */ +} __packed; + +struct ieee80211_frame_cfend { /* NB: also CF-End+CF-Ack */ + u_int8_t i_fc[2]; + __le16 i_dur; /* should be zero */ + u_int8_t i_ra[IEEE80211_ADDR_LEN]; + u_int8_t i_bssid[IEEE80211_ADDR_LEN]; + /* FCS */ +} __packed; + +/* + * BEACON management packets + * + * octet timestamp[8] + * octet beacon interval[2] + * octet capability information[2] + * information element + * octet elemid + * octet length + * octet information[length] + */ + +typedef u_int8_t *ieee80211_mgt_beacon_t; + +#define IEEE80211_BEACON_INTERVAL(beacon) \ + ((beacon)[8] | ((beacon)[9] << 8)) +#define IEEE80211_BEACON_CAPABILITY(beacon) \ + ((beacon)[10] | ((beacon)[11] << 8)) + +#define IEEE80211_CAPINFO_ESS 0x0001 +#define IEEE80211_CAPINFO_IBSS 0x0002 +#define IEEE80211_CAPINFO_CF_POLLABLE 0x0004 +#define IEEE80211_CAPINFO_CF_POLLREQ 0x0008 +#define IEEE80211_CAPINFO_PRIVACY 0x0010 +#define IEEE80211_CAPINFO_SHORT_PREAMBLE 0x0020 +#define IEEE80211_CAPINFO_PBCC 0x0040 +#define IEEE80211_CAPINFO_CHNL_AGILITY 0x0080 +/* bits 8-9 are reserved (8 now for spectrum management) */ +#define IEEE80211_CAPINFO_SPECTRUM_MGMT 0x0100 +#define IEEE80211_CAPINFO_SHORT_SLOTTIME 0x0400 +#define IEEE80211_CAPINFO_RSN 0x0800 +/* bit 12 is reserved */ +#define IEEE80211_CAPINFO_DSSSOFDM 0x2000 +/* bits 14-15 are reserved */ + +/* + * 802.11i/WPA information element (maximally sized). + */ +struct ieee80211_ie_wpa { + u_int8_t wpa_id; /* IEEE80211_ELEMID_VENDOR */ + u_int8_t wpa_len; /* length in bytes */ + u_int8_t wpa_oui[3]; /* 0x00, 0x50, 0xf2 */ + u_int8_t wpa_type; /* OUI type */ + u_int16_t wpa_version; /* spec revision */ + u_int32_t wpa_mcipher[1]; /* multicast/group key cipher */ + u_int16_t wpa_uciphercnt; /* # pairwise key ciphers */ + u_int32_t wpa_uciphers[8]; /* ciphers */ + u_int16_t wpa_authselcnt; /* authentication selector cnt*/ + u_int32_t wpa_authsels[8]; /* selectors */ + u_int16_t wpa_caps; /* 802.11i capabilities */ + u_int16_t wpa_pmkidcnt; /* 802.11i pmkid count */ + u_int16_t wpa_pmkids[8]; /* 802.11i pmkids */ +} __packed; + +/* + * Management information element payloads. + */ + +enum { + IEEE80211_ELEMID_SSID = 0, + IEEE80211_ELEMID_RATES = 1, + IEEE80211_ELEMID_FHPARMS = 2, + IEEE80211_ELEMID_DSPARMS = 3, + IEEE80211_ELEMID_CFPARMS = 4, + IEEE80211_ELEMID_TIM = 5, + IEEE80211_ELEMID_IBSSPARMS = 6, + IEEE80211_ELEMID_COUNTRY = 7, + IEEE80211_ELEMID_REQINFO = 10, + IEEE80211_ELEMID_CHALLENGE = 16, + /* 17-31 reserved for challenge text extension */ + IEEE80211_ELEMID_PWRCNSTR = 32, + IEEE80211_ELEMID_PWRCAP = 33, + IEEE80211_ELEMID_TPCREQ = 34, + IEEE80211_ELEMID_TPCREP = 35, + IEEE80211_ELEMID_SUPPCHAN = 36, + IEEE80211_ELEMID_CHANSWITCHANN = 37, + IEEE80211_ELEMID_MEASREQ = 38, + IEEE80211_ELEMID_MEASREP = 39, + IEEE80211_ELEMID_QUIET = 40, + IEEE80211_ELEMID_IBSSDFS = 41, + IEEE80211_ELEMID_ERP = 42, + IEEE80211_ELEMID_RSN = 48, + IEEE80211_ELEMID_XRATES = 50, + /* 128-129 proprietary elements used by Agere chipsets */ + IEEE80211_ELEMID_AGERE1 = 128, + IEEE80211_ELEMID_AGERE2 = 129, + IEEE80211_ELEMID_TPC = 150, + IEEE80211_ELEMID_CCKM = 156, + IEEE80211_ELEMID_VENDOR = 221, /* vendor private */ +}; + +#define IEEE80211_CHANSWITCHANN_BYTES 5 + +struct ieee80211_tim_ie { + u_int8_t tim_ie; /* IEEE80211_ELEMID_TIM */ + u_int8_t tim_len; + u_int8_t tim_count; /* DTIM count */ + u_int8_t tim_period; /* DTIM period */ + u_int8_t tim_bitctl; /* bitmap control */ + u_int8_t tim_bitmap[1]; /* variable-length bitmap */ +} __packed; + +struct ieee80211_country_ie { + u_int8_t ie; /* IEEE80211_ELEMID_COUNTRY */ + u_int8_t len; + u_int8_t cc[3]; /* ISO CC+(I)ndoor/(O)utdoor */ + struct { + u_int8_t schan; /* starting channel */ + u_int8_t nchan; /* number channels */ + u_int8_t maxtxpwr; /* tx power cap */ + } __packed band[4]; /* up to 4 sub bands */ +} __packed; + +#define IEEE80211_CHALLENGE_LEN 128 + +#define IEEE80211_SUPPCHAN_LEN 26 + +#define IEEE80211_RATE_BASIC 0x80 +#define IEEE80211_RATE_VAL 0x7f + +/* EPR information element flags */ +#define IEEE80211_ERP_NON_ERP_PRESENT 0x01 +#define IEEE80211_ERP_USE_PROTECTION 0x02 +#define IEEE80211_ERP_LONG_PREAMBLE 0x04 + +/* Atheros private advanced capabilities info */ +#define ATHEROS_CAP_TURBO_PRIME 0x01 +#define ATHEROS_CAP_COMPRESSION 0x02 +#define ATHEROS_CAP_FAST_FRAME 0x04 +/* bits 3-6 reserved */ +#define ATHEROS_CAP_BOOST 0x80 + +#define ATH_OUI 0x7f0300 /* Atheros OUI */ +#define ATH_OUI_TYPE 0x01 +#define ATH_OUI_SUBTYPE 0x01 +#define ATH_OUI_VERSION 0x00 +#define ATH_OUI_TYPE_XR 0x03 +#define ATH_OUI_VER_XR 0x01 + +#define WPA_OUI 0xf25000 +#define WPA_OUI_TYPE 0x01 +#define WPA_VERSION 1 /* current supported version */ + +#define WPA_CSE_NULL 0x00 +#define WPA_CSE_WEP40 0x01 +#define WPA_CSE_TKIP 0x02 +#define WPA_CSE_CCMP 0x04 +#define WPA_CSE_WEP104 0x05 + +#define WPA_ASE_NONE 0x00 +#define WPA_ASE_8021X_UNSPEC 0x01 +#define WPA_ASE_8021X_PSK 0x02 + +#define RSN_OUI 0xac0f00 +#define RSN_VERSION 1 /* current supported version */ + +#define RSN_CSE_NULL 0x00 +#define RSN_CSE_WEP40 0x01 +#define RSN_CSE_TKIP 0x02 +#define RSN_CSE_WRAP 0x03 +#define RSN_CSE_CCMP 0x04 +#define RSN_CSE_WEP104 0x05 + +#define RSN_ASE_NONE 0x00 +#define RSN_ASE_8021X_UNSPEC 0x01 +#define RSN_ASE_8021X_PSK 0x02 + +#define RSN_CAP_PREAUTH 0x01 + +#define WME_OUI 0xf25000 +#define WME_OUI_TYPE 0x02 +#define WME_INFO_OUI_SUBTYPE 0x00 +#define WME_PARAM_OUI_SUBTYPE 0x01 +#define WME_VERSION 1 + +/* WME stream classes */ +#define WME_AC_BE 0 /* best effort */ +#define WME_AC_BK 1 /* background */ +#define WME_AC_VI 2 /* video */ +#define WME_AC_VO 3 /* voice */ + +/* + * AUTH management packets + * + * octet algo[2] + * octet seq[2] + * octet status[2] + * octet chal.id + * octet chal.length + * octet chal.text[253] + */ + +typedef u_int8_t *ieee80211_mgt_auth_t; + +#define IEEE80211_AUTH_ALGORITHM(auth) \ + ((auth)[0] | ((auth)[1] << 8)) +#define IEEE80211_AUTH_TRANSACTION(auth) \ + ((auth)[2] | ((auth)[3] << 8)) +#define IEEE80211_AUTH_STATUS(auth) \ + ((auth)[4] | ((auth)[5] << 8)) + +#define IEEE80211_AUTH_ALG_OPEN 0x0000 +#define IEEE80211_AUTH_ALG_SHARED 0x0001 +#define IEEE80211_AUTH_ALG_LEAP 0x0080 + +enum { + IEEE80211_AUTH_OPEN_REQUEST = 1, + IEEE80211_AUTH_OPEN_RESPONSE = 2, +}; + +enum { + IEEE80211_AUTH_SHARED_REQUEST = 1, + IEEE80211_AUTH_SHARED_CHALLENGE = 2, + IEEE80211_AUTH_SHARED_RESPONSE = 3, + IEEE80211_AUTH_SHARED_PASS = 4, +}; + +/* + * Reason codes + * + * Unlisted codes are reserved + */ + +enum { + IEEE80211_REASON_UNSPECIFIED = 1, + IEEE80211_REASON_AUTH_EXPIRE = 2, + IEEE80211_REASON_AUTH_LEAVE = 3, + IEEE80211_REASON_ASSOC_EXPIRE = 4, + IEEE80211_REASON_ASSOC_TOOMANY = 5, + IEEE80211_REASON_NOT_AUTHED = 6, + IEEE80211_REASON_NOT_ASSOCED = 7, + IEEE80211_REASON_ASSOC_LEAVE = 8, + IEEE80211_REASON_ASSOC_NOT_AUTHED = 9, + + IEEE80211_REASON_RSN_REQUIRED = 11, + IEEE80211_REASON_RSN_INCONSISTENT = 12, + IEEE80211_REASON_IE_INVALID = 13, + IEEE80211_REASON_MIC_FAILURE = 14, + + IEEE80211_STATUS_SUCCESS = 0, + IEEE80211_STATUS_UNSPECIFIED = 1, + IEEE80211_STATUS_CAPINFO = 10, + IEEE80211_STATUS_NOT_ASSOCED = 11, + IEEE80211_STATUS_OTHER = 12, + IEEE80211_STATUS_ALG = 13, + IEEE80211_STATUS_SEQUENCE = 14, + IEEE80211_STATUS_CHALLENGE = 15, + IEEE80211_STATUS_TIMEOUT = 16, + IEEE80211_STATUS_TOOMANY = 17, + IEEE80211_STATUS_BASIC_RATE = 18, + IEEE80211_STATUS_SP_REQUIRED = 19, + IEEE80211_STATUS_PBCC_REQUIRED = 20, + IEEE80211_STATUS_CA_REQUIRED = 21, + IEEE80211_STATUS_TOO_MANY_STATIONS = 22, + IEEE80211_STATUS_RATES = 23, + IEEE80211_STATUS_SHORTSLOT_REQUIRED = 25, + IEEE80211_STATUS_DSSSOFDM_REQUIRED = 26, +}; + +#define IEEE80211_WEP_KEYLEN 5 /* 40bit */ +#define IEEE80211_WEP_IVLEN 3 /* 24bit */ +#define IEEE80211_WEP_KIDLEN 1 /* 1 octet */ +#define IEEE80211_WEP_CRCLEN 4 /* CRC-32 */ +#define IEEE80211_WEP_NKID 4 /* number of key ids */ + +/* + * 802.11i defines an extended IV for use with non-WEP ciphers. + * When the EXTIV bit is set in the key id byte an additional + * 4 bytes immediately follow the IV for TKIP. For CCMP the + * EXTIV bit is likewise set but the 8 bytes represent the + * CCMP header rather than IV+extended-IV. + */ +#define IEEE80211_WEP_EXTIV 0x20 +#define IEEE80211_WEP_EXTIVLEN 4 /* extended IV length */ +#define IEEE80211_WEP_MICLEN 8 /* trailing MIC */ + +#define IEEE80211_CRC_LEN 4 + +/* + * Maximum acceptable MTU is: + * IEEE80211_MAX_LEN - WEP overhead - CRC - + * QoS overhead - RSN/WPA overhead + * Min is arbitrarily chosen > IEEE80211_MIN_LEN. The default + * mtu is Ethernet-compatible; it's set by ether_ifattach. + */ +#define IEEE80211_MTU_MAX 2290 +#define IEEE80211_MTU_MIN 32 + +#define IEEE80211_MAX_LEN (2300 + IEEE80211_CRC_LEN + \ + (IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN + IEEE80211_WEP_CRCLEN)) +#define IEEE80211_ACK_LEN \ + (sizeof(struct ieee80211_frame_ack) + IEEE80211_CRC_LEN) +#define IEEE80211_MIN_LEN \ + (sizeof(struct ieee80211_frame_min) + IEEE80211_CRC_LEN) + +/* + * The 802.11 spec says at most 2007 stations may be + * associated at once. For most AP's this is way more + * than is feasible so we use a default of 128. This + * number may be overridden by the driver and/or by + * user configuration. + */ +#define IEEE80211_AID_MAX 2007 +#define IEEE80211_AID_DEF 128 + +#define IEEE80211_AID(b) ((b) &~ 0xc000) + +/* + * RTS frame length parameters. The default is specified in + * the 802.11 spec. The max may be wrong for jumbo frames. + */ +#define IEEE80211_RTS_DEFAULT 512 +#define IEEE80211_RTS_MIN 1 +#define IEEE80211_RTS_MAX 2346 + +/* + * Regulatory extension identifier for country IE. + */ +#define IEEE80211_REG_EXT_ID 201 + +/* + * IEEE 802.11 timer synchronization function (TSF) timestamp length + */ +#define IEEE80211_TSF_LEN 8 + +#endif /* _NET80211_IEEE80211_H_ */ diff --git a/package/librtk-inband/src/include/net80211/ieee80211_crypto.h b/package/librtk-inband/src/include/net80211/ieee80211_crypto.h new file mode 100644 index 000000000..23d4c052a --- /dev/null +++ b/package/librtk-inband/src/include/net80211/ieee80211_crypto.h @@ -0,0 +1,205 @@ +/*- + * Copyright (c) 2001 Atsushi Onoe + * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $Id: ieee80211_crypto.h 1441 2006-02-06 16:03:21Z mrenzmann $ + */ +#ifndef _NET80211_IEEE80211_CRYPTO_H_ +#define _NET80211_IEEE80211_CRYPTO_H_ + +/* + * 802.11 protocol crypto-related definitions. + */ +#define IEEE80211_KEYBUF_SIZE 16 +#define IEEE80211_MICBUF_SIZE (8 + 8) /* space for both tx+rx keys */ +#define IEEE80211_TID_SIZE 17 /* total number of TIDs */ + +/* + * Old WEP-style key. Deprecated. + */ +struct ieee80211_wepkey { + u_int wk_len; /* key length in bytes */ + u_int8_t wk_key[IEEE80211_KEYBUF_SIZE]; +}; + +struct ieee80211_cipher; + +/* + * Crypto key state. There is sufficient room for all supported + * ciphers (see below). The underlying ciphers are handled + * separately through loadable cipher modules that register with + * the generic crypto support. A key has a reference to an instance + * of the cipher; any per-key state is hung off wk_private by the + * cipher when it is attached. Ciphers are automatically called + * to detach and cleanup any such state when the key is deleted. + * + * The generic crypto support handles encap/decap of cipher-related + * frame contents for both hardware- and software-based implementations. + * A key requiring software crypto support is automatically flagged and + * the cipher is expected to honor this and do the necessary work. + * Ciphers such as TKIP may also support mixed hardware/software + * encrypt/decrypt and MIC processing. + */ +/* XXX need key index typedef */ +/* XXX pack better? */ +/* XXX 48-bit rsc/tsc */ +struct ieee80211_key { + u_int8_t wk_keylen; /* key length in bytes */ + u_int8_t wk_flags; +#define IEEE80211_KEY_XMIT 0x01 /* key used for xmit */ +#define IEEE80211_KEY_RECV 0x02 /* key used for recv */ +#define IEEE80211_KEY_GROUP 0x04 /* key used for WPA group operation */ +#define IEEE80211_KEY_SWCRYPT 0x10 /* host-based encrypt/decrypt */ +#define IEEE80211_KEY_SWMIC 0x20 /* host-based enmic/demic */ + u_int16_t wk_keyix; /* key index */ + u_int8_t wk_key[IEEE80211_KEYBUF_SIZE+IEEE80211_MICBUF_SIZE]; +#define wk_txmic wk_key+IEEE80211_KEYBUF_SIZE+0 /* XXX can't () right */ +#define wk_rxmic wk_key+IEEE80211_KEYBUF_SIZE+8 /* XXX can't () right */ + u_int64_t wk_keyrsc[IEEE80211_TID_SIZE]; /* key receive sequence counter */ + u_int64_t wk_keytsc; /* key transmit sequence counter */ + const struct ieee80211_cipher *wk_cipher; + void *wk_private; /* private cipher state */ +}; +#define IEEE80211_KEY_COMMON /* common flags passed in by apps */\ + (IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV | IEEE80211_KEY_GROUP) + +/* + * NB: these values are ordered carefully; there are lots of + * of implications in any reordering. In particular beware + * that 4 is not used to avoid conflicting with IEEE80211_F_PRIVACY. + */ +#define IEEE80211_CIPHER_WEP 0 +#define IEEE80211_CIPHER_TKIP 1 +#define IEEE80211_CIPHER_AES_OCB 2 +#define IEEE80211_CIPHER_AES_CCM 3 +#define IEEE80211_CIPHER_CKIP 5 +#define IEEE80211_CIPHER_NONE 6 /* pseudo value */ + +#define IEEE80211_CIPHER_MAX (IEEE80211_CIPHER_NONE+1) + +#define IEEE80211_KEYIX_NONE ((u_int16_t) - 1) + +#if defined(__KERNEL__) || defined(_KERNEL) + +struct ieee80211com; +struct ieee80211vap; +struct ieee80211_node; +struct sk_buff; + +void ieee80211_crypto_attach(struct ieee80211com *); +void ieee80211_crypto_detach(struct ieee80211com *); +void ieee80211_crypto_vattach(struct ieee80211vap *); +void ieee80211_crypto_vdetach(struct ieee80211vap *); +int ieee80211_crypto_newkey(struct ieee80211vap *, int, int, + struct ieee80211_key *); +int ieee80211_crypto_delkey(struct ieee80211vap *, struct ieee80211_key *, + struct ieee80211_node *); +int ieee80211_crypto_setkey(struct ieee80211vap *, struct ieee80211_key *, + const u_int8_t macaddr[IEEE80211_ADDR_LEN], struct ieee80211_node *); +void ieee80211_crypto_delglobalkeys(struct ieee80211vap *); + +/* + * Template for a supported cipher. Ciphers register with the + * crypto code and are typically loaded as separate modules + * (the null cipher is always present). + * XXX may need refcnts + */ +struct ieee80211_cipher { + const char *ic_name; /* printable name */ + u_int ic_cipher; /* IEEE80211_CIPHER_* */ + u_int ic_header; /* size of privacy header (bytes) */ + u_int ic_trailer; /* size of privacy trailer (bytes) */ + u_int ic_miclen; /* size of mic trailer (bytes) */ + void *(*ic_attach)(struct ieee80211vap *, struct ieee80211_key *); + void (*ic_detach)(struct ieee80211_key *); + int (*ic_setkey)(struct ieee80211_key *); + int (*ic_encap)(struct ieee80211_key *, struct sk_buff *, u_int8_t); + int (*ic_decap)(struct ieee80211_key *, struct sk_buff *, int); + int (*ic_enmic)(struct ieee80211_key *, struct sk_buff *, int); + int (*ic_demic)(struct ieee80211_key *, struct sk_buff *, int); +}; +extern const struct ieee80211_cipher ieee80211_cipher_none; + +void ieee80211_crypto_register(const struct ieee80211_cipher *); +void ieee80211_crypto_unregister(const struct ieee80211_cipher *); +int ieee80211_crypto_available(u_int); + +struct ieee80211_key *ieee80211_crypto_encap(struct ieee80211_node *, + struct sk_buff *); +struct ieee80211_key *ieee80211_crypto_decap(struct ieee80211_node *, + struct sk_buff *, int); + +/* + * Check and remove any MIC. + */ +static __inline int +ieee80211_crypto_demic(struct ieee80211vap *vap, struct ieee80211_key *k, + struct sk_buff *skb, int hdrlen) +{ + const struct ieee80211_cipher *cip = k->wk_cipher; + return (cip->ic_miclen > 0 ? cip->ic_demic(k, skb, hdrlen) : 1); +} + +/* + * Add any MIC. + */ +static __inline int +ieee80211_crypto_enmic(struct ieee80211vap *vap, struct ieee80211_key *k, + struct sk_buff *skb, int force) +{ + const struct ieee80211_cipher *cip = k->wk_cipher; + return (cip->ic_miclen > 0 ? cip->ic_enmic(k, skb, force) : 1); +} + +/* + * Reset key state to an unused state. The crypto + * key allocation mechanism ensures other state (e.g. + * key data) is properly setup before a key is used. + */ +static __inline void +ieee80211_crypto_resetkey(struct ieee80211vap *vap, struct ieee80211_key *k, + u_int16_t ix) +{ + k->wk_cipher = &ieee80211_cipher_none;; + k->wk_private = k->wk_cipher->ic_attach(vap, k); + k->wk_keyix = ix; + k->wk_flags = IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV; +} + +/* + * Crypto-related notification methods. + */ +void ieee80211_notify_replay_failure(struct ieee80211vap *, + const struct ieee80211_frame *, const struct ieee80211_key *, + u_int64_t rsc); +void ieee80211_notify_michael_failure(struct ieee80211vap *, + const struct ieee80211_frame *, u_int keyix); +#endif /* defined(__KERNEL__) || defined(_KERNEL) */ +#endif /* _NET80211_IEEE80211_CRYPTO_H_ */ diff --git a/package/librtk-inband/src/include/net80211/ieee80211_ioctl.h b/package/librtk-inband/src/include/net80211/ieee80211_ioctl.h new file mode 100644 index 000000000..51ad90a37 --- /dev/null +++ b/package/librtk-inband/src/include/net80211/ieee80211_ioctl.h @@ -0,0 +1,787 @@ +/*- + * Copyright (c) 2001 Atsushi Onoe + * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $Id: ieee80211_ioctl.h 3313 2008-01-30 21:07:22Z proski $ + */ +#ifndef _NET80211_IEEE80211_IOCTL_H_ +#define _NET80211_IEEE80211_IOCTL_H_ + +/* + * IEEE 802.11 ioctls. + */ +#include <net80211/_ieee80211.h> +#include <net80211/ieee80211.h> +#include <net80211/ieee80211_crypto.h> + +/* + * Per/node (station) statistics available when operating as an AP. + */ +struct ieee80211_nodestats { + u_int32_t ns_rx_data; /* rx data frames */ + u_int32_t ns_rx_mgmt; /* rx management frames */ + u_int32_t ns_rx_ctrl; /* rx control frames */ + u_int32_t ns_rx_ucast; /* rx unicast frames */ + u_int32_t ns_rx_mcast; /* rx multi/broadcast frames */ + u_int64_t ns_rx_bytes; /* rx data count (bytes) */ + u_int64_t ns_rx_beacons; /* rx beacon frames */ + u_int32_t ns_rx_proberesp; /* rx probe response frames */ + + u_int32_t ns_rx_dup; /* rx discard because it's a dup */ + u_int32_t ns_rx_noprivacy; /* rx w/ wep but privacy off */ + u_int32_t ns_rx_wepfail; /* rx wep processing failed */ + u_int32_t ns_rx_demicfail; /* rx demic failed */ + u_int32_t ns_rx_decap; /* rx decapsulation failed */ + u_int32_t ns_rx_defrag; /* rx defragmentation failed */ + u_int32_t ns_rx_disassoc; /* rx disassociation */ + u_int32_t ns_rx_deauth; /* rx deauthentication */ + u_int32_t ns_rx_decryptcrc; /* rx decrypt failed on crc */ + u_int32_t ns_rx_unauth; /* rx on unauthorized port */ + u_int32_t ns_rx_unencrypted; /* rx unecrypted w/ privacy */ + + u_int32_t ns_tx_data; /* tx data frames */ + u_int32_t ns_tx_mgmt; /* tx management frames */ + u_int32_t ns_tx_ucast; /* tx unicast frames */ + u_int32_t ns_tx_mcast; /* tx multi/broadcast frames */ + u_int64_t ns_tx_bytes; /* tx data count (bytes) */ + u_int32_t ns_tx_probereq; /* tx probe request frames */ + u_int32_t ns_tx_uapsd; /* tx on uapsd queue */ + + u_int32_t ns_tx_novlantag; /* tx discard due to no tag */ + u_int32_t ns_tx_vlanmismatch; /* tx discard due to of bad tag */ + + u_int32_t ns_tx_eosplost; /* uapsd EOSP retried out */ + + u_int32_t ns_ps_discard; /* ps discard due to of age */ + + u_int32_t ns_uapsd_triggers; /* uapsd triggers */ + + /* MIB-related state */ + u_int32_t ns_tx_assoc; /* [re]associations */ + u_int32_t ns_tx_assoc_fail; /* [re]association failures */ + u_int32_t ns_tx_auth; /* [re]authentications */ + u_int32_t ns_tx_auth_fail; /* [re]authentication failures*/ + u_int32_t ns_tx_deauth; /* deauthentications */ + u_int32_t ns_tx_deauth_code; /* last deauth reason */ + u_int32_t ns_tx_disassoc; /* disassociations */ + u_int32_t ns_tx_disassoc_code; /* last disassociation reason */ + u_int32_t ns_psq_drops; /* power save queue drops */ +}; + +/* + * Summary statistics. + */ +struct ieee80211_stats { + u_int32_t is_rx_badversion; /* rx frame with bad version */ + u_int32_t is_rx_tooshort; /* rx frame too short */ + u_int32_t is_rx_wrongbss; /* rx from wrong bssid */ + u_int32_t is_rx_dup; /* rx discard due to it's a dup */ + u_int32_t is_rx_wrongdir; /* rx w/ wrong direction */ + u_int32_t is_rx_mcastecho; /* rx discard due to of mcast echo */ + u_int32_t is_rx_notassoc; /* rx discard due to sta !assoc */ + u_int32_t is_rx_noprivacy; /* rx w/ wep but privacy off */ + u_int32_t is_rx_unencrypted; /* rx w/o wep and privacy on */ + u_int32_t is_rx_wepfail; /* rx wep processing failed */ + u_int32_t is_rx_decap; /* rx decapsulation failed */ + u_int32_t is_rx_mgtdiscard; /* rx discard mgt frames */ + u_int32_t is_rx_ctl; /* rx discard ctrl frames */ + u_int32_t is_rx_beacon; /* rx beacon frames */ + u_int32_t is_rx_rstoobig; /* rx rate set truncated */ + u_int32_t is_rx_elem_missing; /* rx required element missing*/ + u_int32_t is_rx_elem_toobig; /* rx element too big */ + u_int32_t is_rx_elem_toosmall; /* rx element too small */ + u_int32_t is_rx_elem_unknown; /* rx element unknown */ + u_int32_t is_rx_badchan; /* rx frame w/ invalid chan */ + u_int32_t is_rx_chanmismatch; /* rx frame chan mismatch */ + u_int32_t is_rx_nodealloc; /* rx frame dropped */ + u_int32_t is_rx_ssidmismatch; /* rx frame ssid mismatch */ + u_int32_t is_rx_auth_unsupported;/* rx w/ unsupported auth alg */ + u_int32_t is_rx_auth_fail; /* rx sta auth failure */ + u_int32_t is_rx_auth_countermeasures;/* rx auth discard due to CM */ + u_int32_t is_rx_assoc_bss; /* rx assoc from wrong bssid */ + u_int32_t is_rx_assoc_notauth; /* rx assoc w/o auth */ + u_int32_t is_rx_assoc_capmismatch;/* rx assoc w/ cap mismatch */ + u_int32_t is_rx_assoc_norate; /* rx assoc w/ no rate match */ + u_int32_t is_rx_assoc_badwpaie; /* rx assoc w/ bad WPA IE */ + u_int32_t is_rx_deauth; /* rx deauthentication */ + u_int32_t is_rx_disassoc; /* rx disassociation */ + u_int32_t is_rx_badsubtype; /* rx frame w/ unknown subtype*/ + u_int32_t is_rx_nobuf; /* rx failed for lack of buf */ + u_int32_t is_rx_decryptcrc; /* rx decrypt failed on crc */ + u_int32_t is_rx_ahdemo_mgt; /* rx discard ahdemo mgt frame*/ + u_int32_t is_rx_bad_auth; /* rx bad auth request */ + u_int32_t is_rx_unauth; /* rx on unauthorized port */ + u_int32_t is_rx_badkeyid; /* rx w/ incorrect keyid */ + u_int32_t is_rx_ccmpreplay; /* rx seq# violation (CCMP) */ + u_int32_t is_rx_ccmpformat; /* rx format bad (CCMP) */ + u_int32_t is_rx_ccmpmic; /* rx MIC check failed (CCMP) */ + u_int32_t is_rx_tkipreplay; /* rx seq# violation (TKIP) */ + u_int32_t is_rx_tkipformat; /* rx format bad (TKIP) */ + u_int32_t is_rx_tkipmic; /* rx MIC check failed (TKIP) */ + u_int32_t is_rx_tkipicv; /* rx ICV check failed (TKIP) */ + u_int32_t is_rx_badcipher; /* rx failed due to of key type */ + u_int32_t is_rx_nocipherctx; /* rx failed due to key !setup */ + u_int32_t is_rx_acl; /* rx discard due to of acl policy */ + u_int32_t is_rx_ffcnt; /* rx fast frames */ + u_int32_t is_rx_badathtnl; /* driver key alloc failed */ + u_int32_t is_tx_nobuf; /* tx failed for lack of buf */ + u_int32_t is_tx_nonode; /* tx failed for no node */ + u_int32_t is_tx_unknownmgt; /* tx of unknown mgt frame */ + u_int32_t is_tx_badcipher; /* tx failed due to of key type */ + u_int32_t is_tx_nodefkey; /* tx failed due to no defkey */ + u_int32_t is_tx_noheadroom; /* tx failed due to no space */ + u_int32_t is_tx_ffokcnt; /* tx fast frames sent success */ + u_int32_t is_tx_fferrcnt; /* tx fast frames sent success */ + u_int32_t is_scan_active; /* active scans started */ + u_int32_t is_scan_passive; /* passive scans started */ + u_int32_t is_node_timeout; /* nodes timed out inactivity */ + u_int32_t is_crypto_nomem; /* no memory for crypto ctx */ + u_int32_t is_crypto_tkip; /* tkip crypto done in s/w */ + u_int32_t is_crypto_tkipenmic; /* tkip en-MIC done in s/w */ + u_int32_t is_crypto_tkipdemic; /* tkip de-MIC done in s/w */ + u_int32_t is_crypto_tkipcm; /* tkip counter measures */ + u_int32_t is_crypto_ccmp; /* ccmp crypto done in s/w */ + u_int32_t is_crypto_wep; /* wep crypto done in s/w */ + u_int32_t is_crypto_setkey_cipher;/* cipher rejected key */ + u_int32_t is_crypto_setkey_nokey;/* no key index for setkey */ + u_int32_t is_crypto_delkey; /* driver key delete failed */ + u_int32_t is_crypto_badcipher; /* unknown cipher */ + u_int32_t is_crypto_nocipher; /* cipher not available */ + u_int32_t is_crypto_attachfail; /* cipher attach failed */ + u_int32_t is_crypto_swfallback; /* cipher fallback to s/w */ + u_int32_t is_crypto_keyfail; /* driver key alloc failed */ + u_int32_t is_crypto_enmicfail; /* en-MIC failed */ + u_int32_t is_ibss_capmismatch; /* merge failed-cap mismatch */ + u_int32_t is_ibss_norate; /* merge failed-rate mismatch */ + u_int32_t is_ps_unassoc; /* ps-poll for unassoc. sta */ + u_int32_t is_ps_badaid; /* ps-poll w/ incorrect aid */ + u_int32_t is_ps_qempty; /* ps-poll w/ nothing to send */ +}; + +/* + * Max size of optional information elements. We artificially + * constrain this; it's limited only by the max frame size (and + * the max parameter size of the wireless extensions). + */ +#define IEEE80211_MAX_OPT_IE 256 + +/* + * WPA/RSN get/set key request. Specify the key/cipher + * type and whether the key is to be used for sending and/or + * receiving. The key index should be set only when working + * with global keys (use IEEE80211_KEYIX_NONE for ``no index''). + * Otherwise a unicast/pairwise key is specified by the bssid + * (on a station) or mac address (on an ap). They key length + * must include any MIC key data; otherwise it should be no + more than IEEE80211_KEYBUF_SIZE. + */ +#pragma pack(1) + +struct ieee80211req_key { + u_int8_t ik_type; /* key/cipher type */ + u_int8_t ik_pad; + u_int16_t ik_keyix; /* key index */ + u_int8_t ik_keylen; /* key length in bytes */ + u_int8_t ik_flags; +/* NB: IEEE80211_KEY_XMIT and IEEE80211_KEY_RECV defined elsewhere */ +#define IEEE80211_KEY_DEFAULT 0x80 /* default xmit key */ + u_int8_t ik_macaddr[IEEE80211_ADDR_LEN]; + u_int64_t ik_keyrsc; /* key receive sequence counter */ //RTK_WPAS WIFI_WPAS + //u_int64_t ik_keytsc; /* key transmit sequence counter */ + u_int8_t ik_keydata[IEEE80211_KEYBUF_SIZE+IEEE80211_MICBUF_SIZE]; +}; + +#pragma pack(0) + + +/* + * Delete a key either by index or address. Set the index + * to IEEE80211_KEYIX_NONE when deleting a unicast key. + */ +struct ieee80211req_del_key { + u_int8_t idk_keyix; /* key index */ + u_int8_t idk_macaddr[IEEE80211_ADDR_LEN]; +}; + +/* + * MLME state manipulation request. IEEE80211_MLME_ASSOC + * only makes sense when operating as a station. The other + * requests can be used when operating as a station or an + * ap (to effect a station). + */ +struct ieee80211req_mlme { + u_int8_t im_op; /* operation to perform */ +#define IEEE80211_MLME_ASSOC 1 /* associate station */ +#define IEEE80211_MLME_DISASSOC 2 /* disassociate station */ +#define IEEE80211_MLME_DEAUTH 3 /* deauthenticate station */ +#define IEEE80211_MLME_AUTHORIZE 4 /* authorize station */ +#define IEEE80211_MLME_UNAUTHORIZE 5 /* unauthorize station */ +#define IEEE80211_MLME_CLEAR_STATS 6 /* clear station statistic */ + u_int8_t im_ssid_len; /* length of optional ssid */ + u_int16_t im_reason; /* 802.11 reason code */ + u_int8_t im_macaddr[IEEE80211_ADDR_LEN]; + u_int8_t im_ssid[IEEE80211_NWID_LEN]; +}; + +/* + * MAC ACL operations. + */ +enum { + IEEE80211_MACCMD_POLICY_OPEN = 0, /* set policy: no ACL's */ + IEEE80211_MACCMD_POLICY_ALLOW = 1, /* set policy: allow traffic */ + IEEE80211_MACCMD_POLICY_DENY = 2, /* set policy: deny traffic */ + IEEE80211_MACCMD_FLUSH = 3, /* flush ACL database */ + IEEE80211_MACCMD_DETACH = 4, /* detach ACL policy */ +}; + +/* + * Set the active channel list. Note this list is + * intersected with the available channel list in + * calculating the set of channels actually used in + * scanning. + */ +struct ieee80211req_chanlist { + u_int8_t ic_channels[IEEE80211_CHAN_BYTES]; +}; + +/* + * Get the active channel list info. + */ +struct ieee80211req_chaninfo { + u_int ic_nchans; + struct ieee80211_channel ic_chans[IEEE80211_CHAN_MAX]; +}; + +/* + * Retrieve the WPA/RSN information element for an associated station. + */ +struct ieee80211req_wpaie { + u_int8_t wpa_macaddr[IEEE80211_ADDR_LEN]; + u_int8_t wpa_ie[IEEE80211_MAX_OPT_IE]; + u_int8_t rsn_ie[IEEE80211_MAX_OPT_IE]; + + u_int8_t wps_ie[IEEE80211_MAX_OPT_IE]; //RTK_HAPD WIFI_HAPD + +}; + +/* + * Retrieve per-node statistics. + */ +struct ieee80211req_sta_stats { + union { + /* NB: explicitly force 64-bit alignment */ + u_int8_t macaddr[IEEE80211_ADDR_LEN]; + u_int64_t pad; + } is_u; + struct ieee80211_nodestats is_stats; +}; + +/* + * Station information block; the mac address is used + * to retrieve other data like stats, unicast key, etc. + */ +struct ieee80211req_sta_info { + u_int16_t isi_len; /* length (mult of 4) */ + u_int16_t isi_freq; /* MHz */ + u_int16_t isi_flags; /* channel flags */ + u_int16_t isi_state; /* state flags */ + u_int8_t isi_authmode; /* authentication algorithm */ + u_int8_t isi_rssi; + u_int16_t isi_capinfo; /* capabilities */ + u_int8_t isi_athflags; /* Atheros capabilities */ + u_int8_t isi_erp; /* ERP element */ + u_int8_t isi_macaddr[IEEE80211_ADDR_LEN]; + u_int8_t isi_nrates; /* negotiated rates */ + u_int8_t isi_rates[IEEE80211_RATE_MAXSIZE]; + u_int8_t isi_txrate; /* index to isi_rates[] */ + u_int16_t isi_ie_len; /* IE length */ + u_int16_t isi_associd; /* assoc response */ + u_int16_t isi_txpower; /* current tx power */ + u_int16_t isi_vlan; /* vlan tag */ + u_int16_t isi_txseqs[17]; /* seq to be transmitted */ + u_int16_t isi_rxseqs[17]; /* seq previous for qos frames*/ + u_int16_t isi_inact; /* inactivity timer */ + u_int8_t isi_uapsd; /* UAPSD queues */ + u_int8_t isi_opmode; /* sta operating mode */ + + /* XXX frag state? */ + /* variable length IE data */ +}; + +enum { + IEEE80211_STA_OPMODE_NORMAL, + IEEE80211_STA_OPMODE_XR +}; + +/* + * Retrieve per-station information; to retrieve all + * specify a mac address of ff:ff:ff:ff:ff:ff. + */ +struct ieee80211req_sta_req { + union { + /* NB: explicitly force 64-bit alignment */ + u_int8_t macaddr[IEEE80211_ADDR_LEN]; + u_int64_t pad; + } is_u; + struct ieee80211req_sta_info info[1]; /* variable length */ +}; + +/* + * Get/set per-station tx power cap. + */ +struct ieee80211req_sta_txpow { + u_int8_t it_macaddr[IEEE80211_ADDR_LEN]; + u_int8_t it_txpow; +}; + +/* + * WME parameters are set and return using i_val and i_len. + * i_val holds the value itself. i_len specifies the AC + * and, as appropriate, then high bit specifies whether the + * operation is to be applied to the BSS or ourself. + */ +#define IEEE80211_WMEPARAM_SELF 0x0000 /* parameter applies to self */ +#define IEEE80211_WMEPARAM_BSS 0x8000 /* parameter applies to BSS */ +#define IEEE80211_WMEPARAM_VAL 0x7fff /* parameter value */ + +/* + * Scan result data returned for IEEE80211_IOC_SCAN_RESULTS. + */ +struct ieee80211req_scan_result { + u_int16_t isr_len; /* length (mult of 4) */ + u_int16_t isr_freq; /* MHz */ + u_int16_t isr_flags; /* channel flags */ + u_int8_t isr_noise; + u_int8_t isr_rssi; + u_int8_t isr_intval; /* beacon interval */ + u_int16_t isr_capinfo; /* capabilities */ + u_int8_t isr_erp; /* ERP element */ + u_int8_t isr_bssid[IEEE80211_ADDR_LEN]; + u_int8_t isr_nrates; + u_int8_t isr_rates[IEEE80211_RATE_MAXSIZE]; + u_int8_t isr_ssid_len; /* SSID length */ + u_int8_t isr_ie_len; /* IE length */ + u_int8_t isr_pad[5]; + /* variable length SSID followed by IE data */ +}; + +#ifdef __FreeBSD__ +/* + * FreeBSD-style ioctls. + */ +/* the first member must be matched with struct ifreq */ +struct ieee80211req { + char i_name[IFNAMSIZ]; /* if_name, e.g. "wi0" */ + u_int16_t i_type; /* req type */ + int16_t i_val; /* Index or simple value */ + int16_t i_len; /* Index or simple value */ + void *i_data; /* Extra data */ +}; +#define SIOCS80211 _IOW('i', 234, struct ieee80211req) +#define SIOCG80211 _IOWR('i', 235, struct ieee80211req) +#define SIOCG80211STATS _IOWR('i', 236, struct ifreq) +#define SIOC80211IFCREATE _IOWR('i', 237, struct ifreq) +#define SIOC80211IFDESTROY _IOW('i', 238, struct ifreq) + +#define IEEE80211_IOC_SSID 1 +#define IEEE80211_IOC_NUMSSIDS 2 +#define IEEE80211_IOC_WEP 3 +#define IEEE80211_WEP_NOSUP -1 +#define IEEE80211_WEP_OFF 0 +#define IEEE80211_WEP_ON 1 +#define IEEE80211_WEP_MIXED 2 +#define IEEE80211_IOC_WEPKEY 4 +#define IEEE80211_IOC_NUMWEPKEYS 5 +#define IEEE80211_IOC_WEPTXKEY 6 +#define IEEE80211_IOC_AUTHMODE 7 +#define IEEE80211_IOC_STATIONNAME 8 +#define IEEE80211_IOC_CHANNEL 9 +#define IEEE80211_IOC_POWERSAVE 10 +#define IEEE80211_POWERSAVE_NOSUP -1 +#define IEEE80211_POWERSAVE_OFF 0 +#define IEEE80211_POWERSAVE_CAM 1 +#define IEEE80211_POWERSAVE_PSP 2 +#define IEEE80211_POWERSAVE_PSP_CAM 3 +#define IEEE80211_POWERSAVE_ON IEEE80211_POWERSAVE_CAM +#define IEEE80211_IOC_POWERSAVESLEEP 11 +#define IEEE80211_IOC_RTSTHRESHOLD 12 +#define IEEE80211_IOC_PROTMODE 13 +#define IEEE80211_PROTMODE_OFF 0 +#define IEEE80211_PROTMODE_CTS 1 +#define IEEE80211_PROTMODE_RTSCTS 2 +#define IEEE80211_IOC_TXPOWER 14 /* global tx power limit */ +#define IEEE80211_IOC_BSSID 15 +#define IEEE80211_IOC_ROAMING 16 /* roaming mode */ +#define IEEE80211_IOC_PRIVACY 17 /* privacy invoked */ +#define IEEE80211_IOC_DROPUNENCRYPTED 18 /* discard unencrypted frames */ +#define IEEE80211_IOC_WPAKEY 19 +#define IEEE80211_IOC_DELKEY 20 +#define IEEE80211_IOC_MLME 21 +#define IEEE80211_IOC_OPTIE 22 /* optional info. element */ +#define IEEE80211_IOC_SCAN_REQ 23 +#define IEEE80211_IOC_SCAN_RESULTS 24 +#define IEEE80211_IOC_COUNTERMEASURES 25 /* WPA/TKIP countermeasures */ +#define IEEE80211_IOC_WPA 26 /* WPA mode (0,1,2) */ +#define IEEE80211_IOC_CHANLIST 27 /* channel list */ +#define IEEE80211_IOC_WME 28 /* WME mode (on, off) */ +#define IEEE80211_IOC_HIDESSID 29 /* hide SSID mode (on, off) */ +#define IEEE80211_IOC_APBRIDGE 30 /* AP inter-sta bridging */ +#define IEEE80211_IOC_MCASTCIPHER 31 /* multicast/default cipher */ +#define IEEE80211_IOC_MCASTKEYLEN 32 /* multicast key length */ +#define IEEE80211_IOC_UCASTCIPHERS 33 /* unicast cipher suites */ +#define IEEE80211_IOC_UCASTCIPHER 34 /* unicast cipher */ +#define IEEE80211_IOC_UCASTKEYLEN 35 /* unicast key length */ +#define IEEE80211_IOC_DRIVER_CAPS 36 /* driver capabilities */ +#define IEEE80211_IOC_KEYMGTALGS 37 /* key management algorithms */ +#define IEEE80211_IOC_RSNCAPS 38 /* RSN capabilities */ +#define IEEE80211_IOC_WPAIE 39 /* WPA information element */ +#define IEEE80211_IOC_STA_STATS 40 /* per-station statistics */ +#define IEEE80211_IOC_MACCMD 41 /* MAC ACL operation */ +#define IEEE80211_IOC_TXPOWMAX 43 /* max tx power for channel */ +#define IEEE80211_IOC_STA_TXPOW 44 /* per-station tx power limit */ +#define IEEE80211_IOC_STA_INFO 45 /* station/neighbor info */ +#define IEEE80211_IOC_WME_CWMIN 46 /* WME: ECWmin */ +#define IEEE80211_IOC_WME_CWMAX 47 /* WME: ECWmax */ +#define IEEE80211_IOC_WME_AIFS 48 /* WME: AIFSN */ +#define IEEE80211_IOC_WME_TXOPLIMIT 49 /* WME: txops limit */ +#define IEEE80211_IOC_WME_ACM 50 /* WME: ACM (bss only) */ +#define IEEE80211_IOC_WME_ACKPOLICY 51 /* WME: ACK policy (!bss only)*/ +#define IEEE80211_IOC_DTIM_PERIOD 52 /* DTIM period (beacons) */ +#define IEEE80211_IOC_BEACON_INTERVAL 53 /* beacon interval (ms) */ +#define IEEE80211_IOC_ADDMAC 54 /* add sta to MAC ACL table */ +#define IEEE80211_IOC_DELMAC 55 /* del sta from MAC ACL table */ +#define IEEE80211_IOC_FF 56 /* ATH fast frames (on, off) */ +#define IEEE80211_IOC_TURBOP 57 /* ATH turbo' (on, off) */ +#define IEEE80211_IOC_APPIEBUF 58 /* IE in the management frame */ +#define IEEE80211_IOC_FILTERFRAME 59 /* management frame filter */ + +/* + * Scan result data returned for IEEE80211_IOC_SCAN_RESULTS. + */ +struct ieee80211req_scan_result { + u_int16_t isr_len; /* length (mult of 4) */ + u_int16_t isr_freq; /* MHz */ + u_int16_t isr_flags; /* channel flags */ + u_int8_t isr_noise; + u_int8_t isr_rssi; + u_int8_t isr_intval; /* beacon interval */ + u_int16_t isr_capinfo; /* capabilities */ + u_int8_t isr_erp; /* ERP element */ + u_int8_t isr_bssid[IEEE80211_ADDR_LEN]; + u_int8_t isr_nrates; + u_int8_t isr_rates[IEEE80211_RATE_MAXSIZE]; + u_int8_t isr_ssid_len; /* SSID length */ + u_int8_t isr_ie_len; /* IE length */ + u_int8_t isr_pad[5]; + /* variable length SSID followed by IE data */ +}; + +#endif /* __FreeBSD__ */ + +#ifdef __linux__ +/* + * Wireless Extensions API, private ioctl interfaces. + * + * NB: Even-numbered ioctl numbers have set semantics and are privileged! + * (regardless of the incorrect comment in wireless.h!) + */ +#ifdef __KERNEL__ +#include <linux/if.h> +#endif +#define IEEE80211_IOCTL_SETPARAM (SIOCIWFIRSTPRIV+0) +#define IEEE80211_IOCTL_GETPARAM (SIOCIWFIRSTPRIV+1) +#define IEEE80211_IOCTL_SETMODE (SIOCIWFIRSTPRIV+2) +#define IEEE80211_IOCTL_GETMODE (SIOCIWFIRSTPRIV+3) +#define IEEE80211_IOCTL_SETWMMPARAMS (SIOCIWFIRSTPRIV+4) +#define IEEE80211_IOCTL_GETWMMPARAMS (SIOCIWFIRSTPRIV+5) +#define IEEE80211_IOCTL_SETCHANLIST (SIOCIWFIRSTPRIV+6) +#define IEEE80211_IOCTL_GETCHANLIST (SIOCIWFIRSTPRIV+7) +#define IEEE80211_IOCTL_CHANSWITCH (SIOCIWFIRSTPRIV+8) +#define IEEE80211_IOCTL_GET_APPIEBUF (SIOCIWFIRSTPRIV+9) +#define IEEE80211_IOCTL_SET_APPIEBUF (SIOCIWFIRSTPRIV+10) +#define IEEE80211_IOCTL_FILTERFRAME (SIOCIWFIRSTPRIV+12) +#define IEEE80211_IOCTL_GETCHANINFO (SIOCIWFIRSTPRIV+13) +#define IEEE80211_IOCTL_SETOPTIE (SIOCIWFIRSTPRIV+14) +#define IEEE80211_IOCTL_GETOPTIE (SIOCIWFIRSTPRIV+15) +#define IEEE80211_IOCTL_SETMLME (SIOCIWFIRSTPRIV+16) +#define IEEE80211_IOCTL_SETKEY (SIOCIWFIRSTPRIV+18) +#define IEEE80211_IOCTL_DELKEY (SIOCIWFIRSTPRIV+20) +#define IEEE80211_IOCTL_ADDMAC (SIOCIWFIRSTPRIV+22) +#define IEEE80211_IOCTL_DELMAC (SIOCIWFIRSTPRIV+24) +#define IEEE80211_IOCTL_WDSADDMAC (SIOCIWFIRSTPRIV+26) +#define IEEE80211_IOCTL_WDSDELMAC (SIOCIWFIRSTPRIV+28) +#define IEEE80211_IOCTL_KICKMAC (SIOCIWFIRSTPRIV+30) + +enum { + IEEE80211_WMMPARAMS_CWMIN = 1, + IEEE80211_WMMPARAMS_CWMAX = 2, + IEEE80211_WMMPARAMS_AIFS = 3, + IEEE80211_WMMPARAMS_TXOPLIMIT = 4, + IEEE80211_WMMPARAMS_ACM = 5, + IEEE80211_WMMPARAMS_NOACKPOLICY = 6, +}; +enum { + IEEE80211_PARAM_TURBO = 1, /* turbo mode */ + IEEE80211_PARAM_MODE = 2, /* phy mode (11a, 11b, etc.) */ + IEEE80211_PARAM_AUTHMODE = 3, /* authentication mode */ + IEEE80211_PARAM_PROTMODE = 4, /* 802.11g protection */ + IEEE80211_PARAM_MCASTCIPHER = 5, /* multicast/default cipher */ + IEEE80211_PARAM_MCASTKEYLEN = 6, /* multicast key length */ + IEEE80211_PARAM_UCASTCIPHERS = 7, /* unicast cipher suites */ + IEEE80211_PARAM_UCASTCIPHER = 8, /* unicast cipher */ + IEEE80211_PARAM_UCASTKEYLEN = 9, /* unicast key length */ + IEEE80211_PARAM_WPA = 10, /* WPA mode (0,1,2) */ + IEEE80211_PARAM_ROAMING = 12, /* roaming mode */ + IEEE80211_PARAM_PRIVACY = 13, /* privacy invoked */ + IEEE80211_PARAM_COUNTERMEASURES = 14, /* WPA/TKIP countermeasures */ + IEEE80211_PARAM_DROPUNENCRYPTED = 15, /* discard unencrypted frames */ + IEEE80211_PARAM_DRIVER_CAPS = 16, /* driver capabilities */ + IEEE80211_PARAM_MACCMD = 17, /* MAC ACL operation */ + IEEE80211_PARAM_WMM = 18, /* WMM mode (on, off) */ + IEEE80211_PARAM_HIDESSID = 19, /* hide SSID mode (on, off) */ + IEEE80211_PARAM_APBRIDGE = 20, /* AP inter-sta bridging */ + IEEE80211_PARAM_KEYMGTALGS = 21, /* key management algorithms */ + IEEE80211_PARAM_RSNCAPS = 22, /* RSN capabilities */ + IEEE80211_PARAM_INACT = 23, /* station inactivity timeout */ + IEEE80211_PARAM_INACT_AUTH = 24, /* station auth inact timeout */ + IEEE80211_PARAM_INACT_INIT = 25, /* station init inact timeout */ + IEEE80211_PARAM_ABOLT = 26, /* Atheros Adv. Capabilities */ + IEEE80211_PARAM_DTIM_PERIOD = 28, /* DTIM period (beacons) */ + IEEE80211_PARAM_BEACON_INTERVAL = 29, /* beacon interval (ms) */ + IEEE80211_PARAM_DOTH = 30, /* 11.h is on/off */ + IEEE80211_PARAM_PWRTARGET = 31, /* Current Channel Pwr Constraint */ + IEEE80211_PARAM_GENREASSOC = 32, /* Generate a reassociation request */ + IEEE80211_PARAM_COMPRESSION = 33, /* compression */ + IEEE80211_PARAM_FF = 34, /* fast frames support */ + IEEE80211_PARAM_XR = 35, /* XR support */ + IEEE80211_PARAM_BURST = 36, /* burst mode */ + IEEE80211_PARAM_PUREG = 37, /* pure 11g (no 11b stations) */ + IEEE80211_PARAM_AR = 38, /* AR support */ + IEEE80211_PARAM_WDS = 39, /* Enable 4 address processing */ + IEEE80211_PARAM_BGSCAN = 40, /* bg scanning (on, off) */ + IEEE80211_PARAM_BGSCAN_IDLE = 41, /* bg scan idle threshold */ + IEEE80211_PARAM_BGSCAN_INTERVAL = 42, /* bg scan interval */ + IEEE80211_PARAM_MCAST_RATE = 43, /* Multicast Tx Rate */ + IEEE80211_PARAM_COVERAGE_CLASS = 44, /* coverage class */ + IEEE80211_PARAM_COUNTRY_IE = 45, /* enable country IE */ + IEEE80211_PARAM_SCANVALID = 46, /* scan cache valid threshold */ + IEEE80211_PARAM_ROAM_RSSI_11A = 47, /* rssi threshold in 11a */ + IEEE80211_PARAM_ROAM_RSSI_11B = 48, /* rssi threshold in 11b */ + IEEE80211_PARAM_ROAM_RSSI_11G = 49, /* rssi threshold in 11g */ + IEEE80211_PARAM_ROAM_RATE_11A = 50, /* tx rate threshold in 11a */ + IEEE80211_PARAM_ROAM_RATE_11B = 51, /* tx rate threshold in 11b */ + IEEE80211_PARAM_ROAM_RATE_11G = 52, /* tx rate threshold in 11g */ + IEEE80211_PARAM_UAPSDINFO = 53, /* value for qos info field */ + IEEE80211_PARAM_SLEEP = 54, /* force sleep/wake */ + IEEE80211_PARAM_QOSNULL = 55, /* force sleep/wake */ + IEEE80211_PARAM_PSPOLL = 56, /* force ps-poll generation (sta only) */ + IEEE80211_PARAM_EOSPDROP = 57, /* force uapsd EOSP drop (ap only) */ + IEEE80211_PARAM_MARKDFS = 58, /* mark a dfs interference channel when found */ + IEEE80211_PARAM_REGCLASS = 59, /* enable regclass ids in country IE */ + IEEE80211_PARAM_DROPUNENC_EAPOL = 60, /* drop unencrypted eapol frames */ + IEEE80211_PARAM_SHPREAMBLE = 61, /* Short Preamble */ +}; + +#define SIOCG80211STATS (SIOCDEVPRIVATE+2) +/* NB: require in+out parameters so cannot use wireless extensions, yech */ +#define IEEE80211_IOCTL_GETKEY (SIOCDEVPRIVATE+3) +#define IEEE80211_IOCTL_GETWPAIE (SIOCDEVPRIVATE+4) +#define IEEE80211_IOCTL_STA_STATS (SIOCDEVPRIVATE+5) +#define IEEE80211_IOCTL_STA_INFO (SIOCDEVPRIVATE+6) +#define SIOC80211IFCREATE (SIOCDEVPRIVATE+7) +#define SIOC80211IFDESTROY (SIOCDEVPRIVATE+8) +#define IEEE80211_IOCTL_SCAN_RESULTS (SIOCDEVPRIVATE+9) + +struct ieee80211_clone_params { + char icp_name[IFNAMSIZ]; /* device name */ + u_int16_t icp_opmode; /* operating mode */ + u_int16_t icp_flags; /* see below */ +#define IEEE80211_CLONE_BSSID 0x0001 /* allocate unique mac/bssid */ +#define IEEE80211_NO_STABEACONS 0x0002 /* Do not setup the station beacon timers */ +}; + +/* APPIEBUF related definitions */ + +/* Management frame type to which application IE is added */ +enum { + IEEE80211_APPIE_FRAME_BEACON = 0, + IEEE80211_APPIE_FRAME_PROBE_REQ = 1, + IEEE80211_APPIE_FRAME_PROBE_RESP = 2, + IEEE80211_APPIE_FRAME_ASSOC_REQ = 3, + IEEE80211_APPIE_FRAME_ASSOC_RESP = 4, + IEEE80211_APPIE_NUM_OF_FRAME = 5 +}; + +struct ieee80211req_getset_appiebuf { + u_int32_t app_frmtype; /* management frame type for which buffer is added */ + u_int32_t app_buflen; /* application-supplied buffer length */ + u_int8_t app_buf[0]; /* application-supplied IE(s) */ +}; + +/* Flags ORed by application to set filter for receiving management frames */ +enum { + IEEE80211_FILTER_TYPE_BEACON = 1<<0, + IEEE80211_FILTER_TYPE_PROBE_REQ = 1<<1, + IEEE80211_FILTER_TYPE_PROBE_RESP = 1<<2, + IEEE80211_FILTER_TYPE_ASSOC_REQ = 1<<3, + IEEE80211_FILTER_TYPE_ASSOC_RESP = 1<<4, + IEEE80211_FILTER_TYPE_AUTH = 1<<5, + IEEE80211_FILTER_TYPE_DEAUTH = 1<<6, + IEEE80211_FILTER_TYPE_DISASSOC = 1<<7, + IEEE80211_FILTER_TYPE_ALL = 0xFF /* used to check the valid filter bits */ +}; + +struct ieee80211req_set_filter { + u_int32_t app_filterype; /* management frame filter type */ +}; + + +//RTK_HAPD WIFI_HAPD + +#define MAX_2G_CHANNEL_NUM 14 + +#ifdef CONFIG_RTL8196B_TLD +#define NUM_ACL 64 +#else +#define NUM_ACL 32 +#endif + +#define MACADDRLEN 6 + +#pragma pack(1) + +struct rtk_hapd_config{ + unsigned char is_hapd; + unsigned int band; // hw_mode, ieee80211n + unsigned int channel; //channel + unsigned int bcnint; //beacon_int + unsigned int dtimperiod; //dtim_period + unsigned int stanum; //max_num_sta + unsigned int rtsthres; //rts_threshold + unsigned int fragthres; //fragm_threshold + unsigned int oprates; //supported_rates + unsigned int basicrates; //basic_rates + unsigned int preamble; //preamble + unsigned int aclmode; //macaddr_acl, accept_mac_file, deny_mac_file + unsigned int aclnum; //macaddr_acl, accept_mac_file, deny_mac_file + unsigned char acladdr[NUM_ACL][MACADDRLEN]; //macaddr_acl, accept_mac_file, deny_mac_file + unsigned int hiddenAP; //ignore_broadcast_ssid + unsigned int qos_enable; //wmm_enable + unsigned int expired_time; //ap_max_inactivity + unsigned int block_relay; //bridge_packets + unsigned int shortGI20M; // ht_capab + unsigned int shortGI40M; // ht_capab + + //Above are for Hostapd owned configurations + //===================================================== + //Below are for RTK private configurations + + unsigned char pwrlevelCCK_A[MAX_2G_CHANNEL_NUM]; + unsigned char pwrlevelCCK_B[MAX_2G_CHANNEL_NUM]; + unsigned char pwrlevelHT40_1S_A[MAX_2G_CHANNEL_NUM]; + unsigned char pwrlevelHT40_1S_B[MAX_2G_CHANNEL_NUM]; + unsigned char pwrdiffHT40_2S[MAX_2G_CHANNEL_NUM]; + unsigned char pwrdiffHT20[MAX_2G_CHANNEL_NUM]; + unsigned char pwrdiffOFDM[MAX_2G_CHANNEL_NUM]; + unsigned int phyBandSelect; + unsigned int ther; + unsigned int swcrypto; + unsigned int regdomain; + unsigned int autorate; + unsigned int fixrate; + unsigned int disable_protection; + unsigned int disable_olbc; + unsigned int deny_legacy; + unsigned int opmode; + unsigned int vap_enable; + unsigned int use40M; + unsigned int _2ndchoffset; + unsigned int ampdu; + unsigned int coexist; + unsigned int rssi_dump; + unsigned int mp_specific; + unsigned int use_ext_pa; + unsigned int guest_access; + unsigned int macPhyMode; + +}; + +#pragma pack(0) + + + +#define MAX_WDS_NUM 4 +#define HOSTAPD_MAX_SSID_LEN 32 + +struct rtk_wds_config { + int wdsEnabled; + unsigned char macAddr [MAX_WDS_NUM][6]; + int wdsNum; + char ssid[HOSTAPD_MAX_SSID_LEN + 1]; + int wdsPrivacy; + int wdsWepKeyLen; + char *wdsWepKey; + char *wdsPskPassPhrase; +}; + + +//END --- RTK_HAPD WIFI_HAPD + + +//RTK_WPAS WIFI_WPAS + +enum { + WPAS_CONFIG_MIB = 1, + WPAS_CONFIG_WEPKEY = 2, +}; + +#pragma pack(1) + +struct rtk_wpas_config { + unsigned char is_hapd; + unsigned char type; + unsigned char bandmode; // 1: selective 2: concurrent + unsigned char phymode; // 1: 2.4G 2: 5G + unsigned char wep_key[16]; + int wep_keyidx; + int wep_keylen; + +}; + +#pragma pack(0) + + +//END --- RTK_WPAS WIFI_WPAS + + + +#endif /* __linux__ */ + +#endif /* _NET80211_IEEE80211_IOCTL_H_ */ diff --git a/package/librtk-inband/src/ioh.c b/package/librtk-inband/src/ioh.c new file mode 100644 index 000000000..71989dc1b --- /dev/null +++ b/package/librtk-inband/src/ioh.c @@ -0,0 +1,315 @@ +/* + * IOH helper functions + * Copyright (C)2010, Realtek Semiconductor Corp. All rights reserved + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <signal.h> +#include <unistd.h> +#include <time.h> +#include <sys/ioctl.h> + +//#include <linux/if_packet.h> +#include "ioh.h" + +#include <linux/if_arp.h> + +int bin2hex(const unsigned char *bin, char *hex, const int len) +{ + int i, idx; + char hex_char[] = "0123456789ABCDEF"; + + for (i=0, idx=0; i<len; i++) + { + hex[idx++] = hex_char[(bin[i] & 0xf0) >> 4]; + hex[idx++] = hex_char[bin[i] & 0x0f]; + } + + hex[idx] = 0; + return 0; +} + +int hex2bin(const char *hex, unsigned char *bin, const int len) +{ + int i, idx; + unsigned char bytes[2]; + + for (i=0, idx=0; hex[i]; i++) + { + if (hex[i & 0x01] == 0) + return -1; // hex length != even + + if (hex[i] >= '0' && hex[i] <= '9') + bytes[i & 0x01] = hex[i] - '0'; + else if (hex[i] >= 'A' && hex[i] <= 'F') + bytes[i & 0x01] = hex[i] - 'A' + 10; + else if (hex[i] >= 'a' && hex[i] <= 'f') + bytes[i & 0x01] = hex[i] - 'a' + 10; + else + return -1; // not hex + + if (i & 0x01) + { + if (idx >= len) + return -1; // out of size + + bin[idx++] = (bytes[0] << 4) | bytes[1]; + } + } + + return 0; +} + +void hex_dump(void *data, int size) +{ + /* dumps size bytes of *data to stdout. Looks like: + * [0000] 75 6E 6B 6E 6F 77 6E 20 + * 30 FF 00 00 00 00 39 00 unknown 0.....9. + * (in a single line of course) + */ + + unsigned char *p = data; + unsigned char c; + int n; + char bytestr[4] = {0}; + char addrstr[10] = {0}; + char hexstr[ 16*3 + 5] = {0}; + char charstr[16*1 + 5] = {0}; + for(n=1;n<=size;n++) { + if (n%16 == 1) { + /* store address for this line */ + snprintf(addrstr, sizeof(addrstr), "%.4x", + ((unsigned int)p-(unsigned int)data) ); + } + + c = *p; + if (isalnum(c) == 0) { + c = '.'; + } + + /* store hex str (for left side) */ + snprintf(bytestr, sizeof(bytestr), "%02X ", *p); + strncat(hexstr, bytestr, sizeof(hexstr)-strlen(hexstr)-1); + + /* store char str (for right side) */ + snprintf(bytestr, sizeof(bytestr), "%c", c); + strncat(charstr, bytestr, sizeof(charstr)-strlen(charstr)-1); + + if(n%16 == 0) { + /* line completed */ + printf("[%4.4s] %-50.50s %s\n", addrstr, hexstr, charstr); + hexstr[0] = 0; + charstr[0] = 0; + } else if(n%8 == 0) { + /* half line: add whitespaces */ + strncat(hexstr, " ", sizeof(hexstr)-strlen(hexstr)-1); + strncat(charstr, " ", sizeof(charstr)-strlen(charstr)-1); + } + p++; /* next byte */ + } + + if (strlen(hexstr) > 0) { + /* print rest of buffer if not empty */ + printf("[%4.4s] %-50.50s %s\n", addrstr, hexstr, charstr); + } +} + + +int ioh_open(struct ioh_class *obj, char *dev, char *da,unsigned short eth_type, int debug) +{ + struct ifreq ifr; + int ifindex; + + strcpy(obj->dev, dev); + + if (da == NULL) + ; // da == NULL if iohd + else + hex2bin(da, obj->dest_mac, ETH_MAC_LEN); + + obj->debug = debug; + + obj->tx_header = (void *) obj->tx_buffer; + obj->rx_header = (void *) obj->rx_buffer; + obj->tx_data = (unsigned char *) obj->tx_buffer + sizeof(*obj->tx_header); + obj->rx_data = (unsigned char *) obj->rx_buffer + sizeof(*obj->rx_header); + obj->eth_type = eth_type; + // create raw socket + obj->sockfd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); + if (obj->sockfd == -1) + { + perror("socket():"); + return -1; + } + + if (obj->debug) + printf("Successfully opened socket: %i\n", obj->sockfd); + + // retrieve ethernet interface index + bzero(&ifr, sizeof(ifr)); + strncpy(ifr.ifr_name, obj->dev, IFNAMSIZ); + if (ioctl(obj->sockfd, SIOCGIFINDEX, &ifr) == -1) + { + perror("SIOCGIFINDEX"); + return -1; + } + ifindex = ifr.ifr_ifindex; + if (obj->debug) + printf("Successfully got interface index: %i\n", ifindex); + + // retrieve corresponding MAC + if (ioctl(obj->sockfd, SIOCGIFHWADDR, &ifr) == -1) + { + perror("SIOCGIFHWADDR"); + return -1; + } + + memcpy(obj->src_mac, ifr.ifr_hwaddr.sa_data, sizeof(obj->src_mac)); + if (obj->debug) + { + printf("Successfully got our MAC address: %02X:%02X:%02X:%02X:%02X:%02X\n", + obj->src_mac[0], obj->src_mac[1], obj->src_mac[2], + obj->src_mac[3], obj->src_mac[4], obj->src_mac[5]); + } + + // Bind our raw socket to this interface + bzero(&obj->socket_address, sizeof(obj->socket_address)); + obj->socket_address.sll_family = PF_PACKET; + obj->socket_address.sll_protocol = htons(obj->eth_type); + obj->socket_address.sll_ifindex = ifindex; + if((bind(obj->sockfd, (struct sockaddr *) &obj->socket_address, + sizeof(obj->socket_address)))== -1) + { + perror("Error binding socket to interface\n"); + return -1; + } + + return 0; +} + +int ioh_close(struct ioh_class *obj) +{ + close(obj->sockfd); + return 0; +} + +int ioh_send(struct ioh_class *obj , unsigned int send_len) +{ + int sent; // length of sent packet + + //fill pkt header + memcpy(obj->tx_header->da, obj->dest_mac, ETH_MAC_LEN); + memcpy(obj->tx_header->sa, obj->src_mac, ETH_MAC_LEN); + obj->tx_header->eth_type = htons(obj->eth_type); + + obj->socket_address.sll_hatype = ARPHRD_ETHER; + obj->socket_address.sll_pkttype = PACKET_OTHERHOST; + obj->socket_address.sll_halen = ETH_ALEN; + obj->socket_address.sll_addr[0] = obj->dest_mac[0]; + obj->socket_address.sll_addr[1] = obj->dest_mac[1]; + obj->socket_address.sll_addr[2] = obj->dest_mac[2]; + obj->socket_address.sll_addr[3] = obj->dest_mac[3]; + obj->socket_address.sll_addr[4] = obj->dest_mac[4]; + obj->socket_address.sll_addr[5] = obj->dest_mac[5]; + obj->socket_address.sll_addr[6] = 0x00; + obj->socket_address.sll_addr[7] = 0x00; + + if (obj->debug) + { + printf("%s: tx len = %d\n", __FUNCTION__, send_len); + hex_dump(obj->tx_buffer, send_len); + } + + sent = sendto(obj->sockfd, obj->tx_buffer, + send_len, 0, + (struct sockaddr*) &obj->socket_address, sizeof(obj->socket_address)); + + if (sent < 0) + { + perror("sendto():"); + return -1; + } + + return sent; +} + +static int check_rcv_header(struct ioh_class *obj,int rx_len) +{ + if (rx_len < 0) + { + perror("check_rcv_header:"); + return -1; + } + + /* obj->rx_header->rrcp_type != RRCP_P_IOH) //mark_inband + return -1;*/ + + if (obj->rx_header->eth_type != ntohs(obj->eth_type) ) + return -1; +#if 0 //mark_inband + if (rx_len != ntohs(obj->rx_header->ioh_data_len) + sizeof(*obj->rx_header)) + { + if (ntohs(obj->rx_header->ioh_data_len) + sizeof(*obj->rx_header) < + ETH_MIN_FRAME_LEN && rx_len == ETH_MIN_FRAME_LEN) + { + // its ok for min ethernet packet padding + } + else + { + printf("%s: rx len (%d) != %d\n", __FUNCTION__, + rx_len, ntohs(obj->rx_header->ioh_data_len) + sizeof(*obj->rx_header)); + return -1; + } + } +#endif + + return rx_len; + +} + +int ioh_recv(struct ioh_class *obj, int timeout_ms) +{ + fd_set rfds; + struct timeval timeout; + int retval; + int rx_len; + + FD_ZERO(&rfds); + FD_SET(obj->sockfd, &rfds); + + if (timeout_ms < 0) + { + retval = select(obj->sockfd + 1, &rfds, NULL, NULL, NULL); + } + else + { + timeout.tv_sec = 0; + timeout.tv_usec = timeout_ms * 1000; + retval = select(obj->sockfd + 1, &rfds, NULL, NULL, &timeout); + } + + if (retval && FD_ISSET(obj->sockfd, &rfds)) + { + rx_len = recvfrom(obj->sockfd, obj->rx_buffer, + sizeof(obj->rx_buffer), 0, NULL, NULL); + + return check_rcv_header(obj,rx_len); + } + else if (retval == 0) + { + if (obj->debug) + printf("Timeout!!!\n"); + + return -1; + } + else + { + perror("select():"); + return -1; + } + + return -2; +} + diff --git a/package/librtk-inband/src/ioh.h b/package/librtk-inband/src/ioh.h new file mode 100644 index 000000000..d017eab17 --- /dev/null +++ b/package/librtk-inband/src/ioh.h @@ -0,0 +1,64 @@ +/* + * IOH header + * Copyright (C)2010, Realtek Semiconductor Corp. All rights reserved + */ + + +#ifndef __IOH_H +#define __IOH_H + +#include <netinet/in.h> +#include <linux/if_ether.h> +#ifndef __LINUX_IF_PACKET_H +#include <linux/if_packet.h> +#endif + +#define ETH_MAC_LEN ETH_ALEN /* Octets in one ethernet addr */ +#define ETH_HEADER_LEN ETH_HLEN /* Total octets in header. */ +#define ETH_MIN_FRAME_LEN ETH_ZLEN /* Min. octets in frame sans FCS */ +#define ETH_USER_DATA_LEN ETH_DATA_LEN /* Max. octets in payload */ +#define ETH_MAX_FRAME_LEN ETH_FRAME_LEN /* Max. octets in frame sans FCS */ + +#define ETH_FRAME_TOTALLEN 1518 /*Header: 14 + User Data: 1500 FCS: 4*/ + +#ifndef WPAS_INB +#define WPAS_INB +#endif + +struct ioh_header { + unsigned char da[ETH_ALEN]; + unsigned char sa[ETH_ALEN]; + unsigned short eth_type; +}; + +#define BUF_SIZE ETH_FRAME_TOTALLEN + +struct ioh_class { + int sockfd; + char dev[64]; + unsigned char src_mac[ETH_MAC_LEN]; + unsigned char dest_mac[ETH_MAC_LEN]; + unsigned short eth_type; + struct sockaddr_ll socket_address; + char tx_buffer[BUF_SIZE]; + char rx_buffer[BUF_SIZE]; + struct ioh_header *tx_header; + struct ioh_header *rx_header; + unsigned char *tx_data; + unsigned char *rx_data; + int debug; +}; + +int ioh_open(struct ioh_class *obj, char *dev, char *da,unsigned short eth_type, int debug); +int ioh_close(struct ioh_class *obj); +int ioh_send(struct ioh_class *obj,unsigned int send_len); +int ioh_recv(struct ioh_class *obj, int timeout_ms); + +#define mac2str(mac, str) bin2hex((mac), (str), 6) +#define str2mac(str, mac) hex2bin((str), (mac), 6) + +int bin2hex(const unsigned char *bin, char *hex, const int len); +int hex2bin(const char *hex, unsigned char *bin, const int len); +void hex_dump(void *data, int size); + +#endif diff --git a/package/librtk-inband/src/wireless_copy.h b/package/librtk-inband/src/wireless_copy.h new file mode 100644 index 000000000..d93e0daf5 --- /dev/null +++ b/package/librtk-inband/src/wireless_copy.h @@ -0,0 +1,1099 @@ +/* This is based on Linux Wireless Extensions header file from WIRELESS_EXT 18. + * I have just removed kernel related headers and added some typedefs etc. to + * make this easier to include into user space programs. + * Jouni Malinen, 2005-03-12. + */ + + +/* + * This file define a set of standard wireless extensions + * + * Version : 19 18.3.05 + * + * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com> + * Copyright (c) 1997-2005 Jean Tourrilhes, All Rights Reserved. + */ + +#ifndef _LINUX_WIRELESS_H +#define _LINUX_WIRELESS_H + +/************************** DOCUMENTATION **************************/ +/* + * Initial APIs (1996 -> onward) : + * ----------------------------- + * Basically, the wireless extensions are for now a set of standard ioctl + * call + /proc/net/wireless + * + * The entry /proc/net/wireless give statistics and information on the + * driver. + * This is better than having each driver having its entry because + * its centralised and we may remove the driver module safely. + * + * Ioctl are used to configure the driver and issue commands. This is + * better than command line options of insmod because we may want to + * change dynamically (while the driver is running) some parameters. + * + * The ioctl mechanimsm are copied from standard devices ioctl. + * We have the list of command plus a structure descibing the + * data exchanged... + * Note that to add these ioctl, I was obliged to modify : + * # net/core/dev.c (two place + add include) + * # net/ipv4/af_inet.c (one place + add include) + * + * /proc/net/wireless is a copy of /proc/net/dev. + * We have a structure for data passed from the driver to /proc/net/wireless + * Too add this, I've modified : + * # net/core/dev.c (two other places) + * # include/linux/netdevice.h (one place) + * # include/linux/proc_fs.h (one place) + * + * New driver API (2002 -> onward) : + * ------------------------------- + * This file is only concerned with the user space API and common definitions. + * The new driver API is defined and documented in : + * # include/net/iw_handler.h + * + * Note as well that /proc/net/wireless implementation has now moved in : + * # net/core/wireless.c + * + * Wireless Events (2002 -> onward) : + * -------------------------------- + * Events are defined at the end of this file, and implemented in : + * # net/core/wireless.c + * + * Other comments : + * -------------- + * Do not add here things that are redundant with other mechanisms + * (drivers init, ifconfig, /proc/net/dev, ...) and with are not + * wireless specific. + * + * These wireless extensions are not magic : each driver has to provide + * support for them... + * + * IMPORTANT NOTE : As everything in the kernel, this is very much a + * work in progress. Contact me if you have ideas of improvements... + */ + +/***************************** INCLUDES *****************************/ + + /* jkm - replaced linux headers with C library headers, added typedefs */ +#if 0 +/* To minimise problems in user space, I might remove those headers + * at some point. Jean II */ +#include <linux/types.h> /* for "caddr_t" et al */ +#include <linux/socket.h> /* for "struct sockaddr" et al */ +#include <linux/if.h> /* for IFNAMSIZ and co... */ +#else +#include <sys/types.h> +//#include <net/if.h> +typedef __uint32_t __u32; +typedef __int32_t __s32; +typedef __uint16_t __u16; +typedef __int16_t __s16; +typedef __uint8_t __u8; +#ifndef __user +#define __user +#endif /* __user */ +#endif + +/***************************** VERSION *****************************/ +/* + * This constant is used to know the availability of the wireless + * extensions and to know which version of wireless extensions it is + * (there is some stuff that will be added in the future...) + * I just plan to increment with each new version. + */ +#define WIRELESS_EXT 19 + +/* + * Changes : + * + * V2 to V3 + * -------- + * Alan Cox start some incompatibles changes. I've integrated a bit more. + * - Encryption renamed to Encode to avoid US regulation problems + * - Frequency changed from float to struct to avoid problems on old 386 + * + * V3 to V4 + * -------- + * - Add sensitivity + * + * V4 to V5 + * -------- + * - Missing encoding definitions in range + * - Access points stuff + * + * V5 to V6 + * -------- + * - 802.11 support (ESSID ioctls) + * + * V6 to V7 + * -------- + * - define IW_ESSID_MAX_SIZE and IW_MAX_AP + * + * V7 to V8 + * -------- + * - Changed my e-mail address + * - More 802.11 support (nickname, rate, rts, frag) + * - List index in frequencies + * + * V8 to V9 + * -------- + * - Support for 'mode of operation' (ad-hoc, managed...) + * - Support for unicast and multicast power saving + * - Change encoding to support larger tokens (>64 bits) + * - Updated iw_params (disable, flags) and use it for NWID + * - Extracted iw_point from iwreq for clarity + * + * V9 to V10 + * --------- + * - Add PM capability to range structure + * - Add PM modifier : MAX/MIN/RELATIVE + * - Add encoding option : IW_ENCODE_NOKEY + * - Add TxPower ioctls (work like TxRate) + * + * V10 to V11 + * ---------- + * - Add WE version in range (help backward/forward compatibility) + * - Add retry ioctls (work like PM) + * + * V11 to V12 + * ---------- + * - Add SIOCSIWSTATS to get /proc/net/wireless programatically + * - Add DEV PRIVATE IOCTL to avoid collisions in SIOCDEVPRIVATE space + * - Add new statistics (frag, retry, beacon) + * - Add average quality (for user space calibration) + * + * V12 to V13 + * ---------- + * - Document creation of new driver API. + * - Extract union iwreq_data from struct iwreq (for new driver API). + * - Rename SIOCSIWNAME as SIOCSIWCOMMIT + * + * V13 to V14 + * ---------- + * - Wireless Events support : define struct iw_event + * - Define additional specific event numbers + * - Add "addr" and "param" fields in union iwreq_data + * - AP scanning stuff (SIOCSIWSCAN and friends) + * + * V14 to V15 + * ---------- + * - Add IW_PRIV_TYPE_ADDR for struct sockaddr private arg + * - Make struct iw_freq signed (both m & e), add explicit padding + * - Add IWEVCUSTOM for driver specific event/scanning token + * - Add IW_MAX_GET_SPY for driver returning a lot of addresses + * - Add IW_TXPOW_RANGE for range of Tx Powers + * - Add IWEVREGISTERED & IWEVEXPIRED events for Access Points + * - Add IW_MODE_MONITOR for passive monitor + * + * V15 to V16 + * ---------- + * - Increase the number of bitrates in iw_range to 32 (for 802.11g) + * - Increase the number of frequencies in iw_range to 32 (for 802.11b+a) + * - Reshuffle struct iw_range for increases, add filler + * - Increase IW_MAX_AP to 64 for driver returning a lot of addresses + * - Remove IW_MAX_GET_SPY because conflict with enhanced spy support + * - Add SIOCSIWTHRSPY/SIOCGIWTHRSPY and "struct iw_thrspy" + * - Add IW_ENCODE_TEMP and iw_range->encoding_login_index + * + * V16 to V17 + * ---------- + * - Add flags to frequency -> auto/fixed + * - Document (struct iw_quality *)->updated, add new flags (INVALID) + * - Wireless Event capability in struct iw_range + * - Add support for relative TxPower (yick !) + * + * V17 to V18 (From Jouni Malinen <j@w1.fi>) + * ---------- + * - Add support for WPA/WPA2 + * - Add extended encoding configuration (SIOCSIWENCODEEXT and + * SIOCGIWENCODEEXT) + * - Add SIOCSIWGENIE/SIOCGIWGENIE + * - Add SIOCSIWMLME + * - Add SIOCSIWPMKSA + * - Add struct iw_range bit field for supported encoding capabilities + * - Add optional scan request parameters for SIOCSIWSCAN + * - Add SIOCSIWAUTH/SIOCGIWAUTH for setting authentication and WPA + * related parameters (extensible up to 4096 parameter values) + * - Add wireless events: IWEVGENIE, IWEVMICHAELMICFAILURE, + * IWEVASSOCREQIE, IWEVASSOCRESPIE, IWEVPMKIDCAND + * + * V18 to V19 + * ---------- + * - Remove (struct iw_point *)->pointer from events and streams + * - Remove header includes to help user space + * - Increase IW_ENCODING_TOKEN_MAX from 32 to 64 + * - Add IW_QUAL_ALL_UPDATED and IW_QUAL_ALL_INVALID macros + * - Add explicit flag to tell stats are in dBm : IW_QUAL_DBM + * - Add IW_IOCTL_IDX() and IW_EVENT_IDX() macros + */ + +/**************************** CONSTANTS ****************************/ + +/* -------------------------- IOCTL LIST -------------------------- */ + +/* Wireless Identification */ +#define SIOCSIWCOMMIT 0x8B00 /* Commit pending changes to driver */ +#define SIOCGIWNAME 0x8B01 /* get name == wireless protocol */ +/* SIOCGIWNAME is used to verify the presence of Wireless Extensions. + * Common values : "IEEE 802.11-DS", "IEEE 802.11-FH", "IEEE 802.11b"... + * Don't put the name of your driver there, it's useless. */ + +/* Basic operations */ +#define SIOCSIWNWID 0x8B02 /* set network id (pre-802.11) */ +#define SIOCGIWNWID 0x8B03 /* get network id (the cell) */ +#define SIOCSIWFREQ 0x8B04 /* set channel/frequency (Hz) */ +#define SIOCGIWFREQ 0x8B05 /* get channel/frequency (Hz) */ +#define SIOCSIWMODE 0x8B06 /* set operation mode */ +#define SIOCGIWMODE 0x8B07 /* get operation mode */ +#define SIOCSIWSENS 0x8B08 /* set sensitivity (dBm) */ +#define SIOCGIWSENS 0x8B09 /* get sensitivity (dBm) */ + +/* Informative stuff */ +#define SIOCSIWRANGE 0x8B0A /* Unused */ +#define SIOCGIWRANGE 0x8B0B /* Get range of parameters */ +#define SIOCSIWPRIV 0x8B0C /* Unused */ +#define SIOCGIWPRIV 0x8B0D /* get private ioctl interface info */ +#define SIOCSIWSTATS 0x8B0E /* Unused */ +#define SIOCGIWSTATS 0x8B0F /* Get /proc/net/wireless stats */ +/* SIOCGIWSTATS is strictly used between user space and the kernel, and + * is never passed to the driver (i.e. the driver will never see it). */ + +/* Spy support (statistics per MAC address - used for Mobile IP support) */ +#define SIOCSIWSPY 0x8B10 /* set spy addresses */ +#define SIOCGIWSPY 0x8B11 /* get spy info (quality of link) */ +#define SIOCSIWTHRSPY 0x8B12 /* set spy threshold (spy event) */ +#define SIOCGIWTHRSPY 0x8B13 /* get spy threshold */ + +/* Access Point manipulation */ +#define SIOCSIWAP 0x8B14 /* set access point MAC addresses */ +#define SIOCGIWAP 0x8B15 /* get access point MAC addresses */ +#define SIOCGIWAPLIST 0x8B17 /* Deprecated in favor of scanning */ +#define SIOCSIWSCAN 0x8B18 /* trigger scanning (list cells) */ +#define SIOCGIWSCAN 0x8B19 /* get scanning results */ + +/* 802.11 specific support */ +#define SIOCSIWESSID 0x8B1A /* set ESSID (network name) */ +#define SIOCGIWESSID 0x8B1B /* get ESSID */ +#define SIOCSIWNICKN 0x8B1C /* set node name/nickname */ +#define SIOCGIWNICKN 0x8B1D /* get node name/nickname */ +/* As the ESSID and NICKN are strings up to 32 bytes long, it doesn't fit + * within the 'iwreq' structure, so we need to use the 'data' member to + * point to a string in user space, like it is done for RANGE... */ + +/* Other parameters useful in 802.11 and some other devices */ +#define SIOCSIWRATE 0x8B20 /* set default bit rate (bps) */ +#define SIOCGIWRATE 0x8B21 /* get default bit rate (bps) */ +#define SIOCSIWRTS 0x8B22 /* set RTS/CTS threshold (bytes) */ +#define SIOCGIWRTS 0x8B23 /* get RTS/CTS threshold (bytes) */ +#define SIOCSIWFRAG 0x8B24 /* set fragmentation thr (bytes) */ +#define SIOCGIWFRAG 0x8B25 /* get fragmentation thr (bytes) */ +#define SIOCSIWTXPOW 0x8B26 /* set transmit power (dBm) */ +#define SIOCGIWTXPOW 0x8B27 /* get transmit power (dBm) */ +#define SIOCSIWRETRY 0x8B28 /* set retry limits and lifetime */ +#define SIOCGIWRETRY 0x8B29 /* get retry limits and lifetime */ + +/* Encoding stuff (scrambling, hardware security, WEP...) */ +#define SIOCSIWENCODE 0x8B2A /* set encoding token & mode */ +#define SIOCGIWENCODE 0x8B2B /* get encoding token & mode */ +/* Power saving stuff (power management, unicast and multicast) */ +#define SIOCSIWPOWER 0x8B2C /* set Power Management settings */ +#define SIOCGIWPOWER 0x8B2D /* get Power Management settings */ + +/* WPA : Generic IEEE 802.11 informatiom element (e.g., for WPA/RSN/WMM). + * This ioctl uses struct iw_point and data buffer that includes IE id and len + * fields. More than one IE may be included in the request. Setting the generic + * IE to empty buffer (len=0) removes the generic IE from the driver. Drivers + * are allowed to generate their own WPA/RSN IEs, but in these cases, drivers + * are required to report the used IE as a wireless event, e.g., when + * associating with an AP. */ +#define SIOCSIWGENIE 0x8B30 /* set generic IE */ +#define SIOCGIWGENIE 0x8B31 /* get generic IE */ + +/* WPA : IEEE 802.11 MLME requests */ +#define SIOCSIWMLME 0x8B16 /* request MLME operation; uses + * struct iw_mlme */ +/* WPA : Authentication mode parameters */ +#define SIOCSIWAUTH 0x8B32 /* set authentication mode params */ +#define SIOCGIWAUTH 0x8B33 /* get authentication mode params */ + +/* WPA : Extended version of encoding configuration */ +#define SIOCSIWENCODEEXT 0x8B34 /* set encoding token & mode */ +#define SIOCGIWENCODEEXT 0x8B35 /* get encoding token & mode */ + +/* WPA2 : PMKSA cache management */ +#define SIOCSIWPMKSA 0x8B36 /* PMKSA cache operation */ + +/* -------------------- DEV PRIVATE IOCTL LIST -------------------- */ + +/* These 32 ioctl are wireless device private, for 16 commands. + * Each driver is free to use them for whatever purpose it chooses, + * however the driver *must* export the description of those ioctls + * with SIOCGIWPRIV and *must* use arguments as defined below. + * If you don't follow those rules, DaveM is going to hate you (reason : + * it make mixed 32/64bit operation impossible). + */ +#define SIOCIWFIRSTPRIV 0x8BE0 +#define SIOCIWLASTPRIV 0x8BFF +/* Previously, we were using SIOCDEVPRIVATE, but we now have our + * separate range because of collisions with other tools such as + * 'mii-tool'. + * We now have 32 commands, so a bit more space ;-). + * Also, all 'odd' commands are only usable by root and don't return the + * content of ifr/iwr to user (but you are not obliged to use the set/get + * convention, just use every other two command). More details in iwpriv.c. + * And I repeat : you are not forced to use them with iwpriv, but you + * must be compliant with it. + */ + +/* ------------------------- IOCTL STUFF ------------------------- */ + +/* The first and the last (range) */ +#define SIOCIWFIRST 0x8B00 +#define SIOCIWLAST SIOCIWLASTPRIV /* 0x8BFF */ +#define IW_IOCTL_IDX(cmd) ((cmd) - SIOCIWFIRST) + +/* Even : get (world access), odd : set (root access) */ +#define IW_IS_SET(cmd) (!((cmd) & 0x1)) +#define IW_IS_GET(cmd) ((cmd) & 0x1) + +/* ----------------------- WIRELESS EVENTS ----------------------- */ +/* Those are *NOT* ioctls, do not issue request on them !!! */ +/* Most events use the same identifier as ioctl requests */ + +#define IWEVTXDROP 0x8C00 /* Packet dropped to excessive retry */ +#define IWEVQUAL 0x8C01 /* Quality part of statistics (scan) */ +#define IWEVCUSTOM 0x8C02 /* Driver specific ascii string */ +#define IWEVREGISTERED 0x8C03 /* Discovered a new node (AP mode) */ +#define IWEVEXPIRED 0x8C04 /* Expired a node (AP mode) */ +#define IWEVGENIE 0x8C05 /* Generic IE (WPA, RSN, WMM, ..) + * (scan results); This includes id and + * length fields. One IWEVGENIE may + * contain more than one IE. Scan + * results may contain one or more + * IWEVGENIE events. */ +#define IWEVMICHAELMICFAILURE 0x8C06 /* Michael MIC failure + * (struct iw_michaelmicfailure) + */ +#define IWEVASSOCREQIE 0x8C07 /* IEs used in (Re)Association Request. + * The data includes id and length + * fields and may contain more than one + * IE. This event is required in + * Managed mode if the driver + * generates its own WPA/RSN IE. This + * should be sent just before + * IWEVREGISTERED event for the + * association. */ +#define IWEVASSOCRESPIE 0x8C08 /* IEs used in (Re)Association + * Response. The data includes id and + * length fields and may contain more + * than one IE. This may be sent + * between IWEVASSOCREQIE and + * IWEVREGISTERED events for the + * association. */ +#define IWEVPMKIDCAND 0x8C09 /* PMKID candidate for RSN + * pre-authentication + * (struct iw_pmkid_cand) */ + +#define IWEVFIRST 0x8C00 +#define IW_EVENT_IDX(cmd) ((cmd) - IWEVFIRST) + +/* ------------------------- PRIVATE INFO ------------------------- */ +/* + * The following is used with SIOCGIWPRIV. It allow a driver to define + * the interface (name, type of data) for its private ioctl. + * Privates ioctl are SIOCIWFIRSTPRIV -> SIOCIWLASTPRIV + */ + +#define IW_PRIV_TYPE_MASK 0x7000 /* Type of arguments */ +#define IW_PRIV_TYPE_NONE 0x0000 +#define IW_PRIV_TYPE_BYTE 0x1000 /* Char as number */ +#define IW_PRIV_TYPE_CHAR 0x2000 /* Char as character */ +#define IW_PRIV_TYPE_INT 0x4000 /* 32 bits int */ +#define IW_PRIV_TYPE_FLOAT 0x5000 /* struct iw_freq */ +#define IW_PRIV_TYPE_ADDR 0x6000 /* struct sockaddr */ + +#define IW_PRIV_SIZE_FIXED 0x0800 /* Variable or fixed number of args */ + +#define IW_PRIV_SIZE_MASK 0x07FF /* Max number of those args */ + +/* + * Note : if the number of args is fixed and the size < 16 octets, + * instead of passing a pointer we will put args in the iwreq struct... + */ + +/* ----------------------- OTHER CONSTANTS ----------------------- */ + +/* Maximum frequencies in the range struct */ +#define IW_MAX_FREQUENCIES 32 +/* Note : if you have something like 80 frequencies, + * don't increase this constant and don't fill the frequency list. + * The user will be able to set by channel anyway... */ + +/* Maximum bit rates in the range struct */ +#define IW_MAX_BITRATES 32 + +/* Maximum tx powers in the range struct */ +#define IW_MAX_TXPOWER 8 +/* Note : if you more than 8 TXPowers, just set the max and min or + * a few of them in the struct iw_range. */ + +/* Maximum of address that you may set with SPY */ +#define IW_MAX_SPY 8 + +/* Maximum of address that you may get in the + list of access points in range */ +#define IW_MAX_AP 64 + +/* Maximum size of the ESSID and NICKN strings */ +#define IW_ESSID_MAX_SIZE 32 + +/* Modes of operation */ +#define IW_MODE_AUTO 0 /* Let the driver decides */ +#define IW_MODE_ADHOC 1 /* Single cell network */ +#define IW_MODE_INFRA 2 /* Multi cell network, roaming, ... */ +#define IW_MODE_MASTER 3 /* Synchronisation master or Access Point */ +#define IW_MODE_REPEAT 4 /* Wireless Repeater (forwarder) */ +#define IW_MODE_SECOND 5 /* Secondary master/repeater (backup) */ +#define IW_MODE_MONITOR 6 /* Passive monitor (listen only) */ + +/* Statistics flags (bitmask in updated) */ +#define IW_QUAL_QUAL_UPDATED 0x01 /* Value was updated since last read */ +#define IW_QUAL_LEVEL_UPDATED 0x02 +#define IW_QUAL_NOISE_UPDATED 0x04 +#define IW_QUAL_ALL_UPDATED 0x07 +#define IW_QUAL_DBM 0x08 /* Level + Noise are dBm */ +#define IW_QUAL_QUAL_INVALID 0x10 /* Driver doesn't provide value */ +#define IW_QUAL_LEVEL_INVALID 0x20 +#define IW_QUAL_NOISE_INVALID 0x40 +#define IW_QUAL_ALL_INVALID 0x70 + +/* Frequency flags */ +#define IW_FREQ_AUTO 0x00 /* Let the driver decides */ +#define IW_FREQ_FIXED 0x01 /* Force a specific value */ + +/* Maximum number of size of encoding token available + * they are listed in the range structure */ +#define IW_MAX_ENCODING_SIZES 8 + +/* Maximum size of the encoding token in bytes */ +#define IW_ENCODING_TOKEN_MAX 64 /* 512 bits (for now) */ + +/* Flags for encoding (along with the token) */ +#define IW_ENCODE_INDEX 0x00FF /* Token index (if needed) */ +#define IW_ENCODE_FLAGS 0xFF00 /* Flags defined below */ +#define IW_ENCODE_MODE 0xF000 /* Modes defined below */ +#define IW_ENCODE_DISABLED 0x8000 /* Encoding disabled */ +#define IW_ENCODE_ENABLED 0x0000 /* Encoding enabled */ +#define IW_ENCODE_RESTRICTED 0x4000 /* Refuse non-encoded packets */ +#define IW_ENCODE_OPEN 0x2000 /* Accept non-encoded packets */ +#define IW_ENCODE_NOKEY 0x0800 /* Key is write only, so not present */ +#define IW_ENCODE_TEMP 0x0400 /* Temporary key */ + +/* Power management flags available (along with the value, if any) */ +#define IW_POWER_ON 0x0000 /* No details... */ +#define IW_POWER_TYPE 0xF000 /* Type of parameter */ +#define IW_POWER_PERIOD 0x1000 /* Value is a period/duration of */ +#define IW_POWER_TIMEOUT 0x2000 /* Value is a timeout (to go asleep) */ +#define IW_POWER_MODE 0x0F00 /* Power Management mode */ +#define IW_POWER_UNICAST_R 0x0100 /* Receive only unicast messages */ +#define IW_POWER_MULTICAST_R 0x0200 /* Receive only multicast messages */ +#define IW_POWER_ALL_R 0x0300 /* Receive all messages though PM */ +#define IW_POWER_FORCE_S 0x0400 /* Force PM procedure for sending unicast */ +#define IW_POWER_REPEATER 0x0800 /* Repeat broadcast messages in PM period */ +#define IW_POWER_MODIFIER 0x000F /* Modify a parameter */ +#define IW_POWER_MIN 0x0001 /* Value is a minimum */ +#define IW_POWER_MAX 0x0002 /* Value is a maximum */ +#define IW_POWER_RELATIVE 0x0004 /* Value is not in seconds/ms/us */ + +/* Transmit Power flags available */ +#define IW_TXPOW_TYPE 0x00FF /* Type of value */ +#define IW_TXPOW_DBM 0x0000 /* Value is in dBm */ +#define IW_TXPOW_MWATT 0x0001 /* Value is in mW */ +#define IW_TXPOW_RELATIVE 0x0002 /* Value is in arbitrary units */ +#define IW_TXPOW_RANGE 0x1000 /* Range of value between min/max */ + +/* Retry limits and lifetime flags available */ +#define IW_RETRY_ON 0x0000 /* No details... */ +#define IW_RETRY_TYPE 0xF000 /* Type of parameter */ +#define IW_RETRY_LIMIT 0x1000 /* Maximum number of retries*/ +#define IW_RETRY_LIFETIME 0x2000 /* Maximum duration of retries in us */ +#define IW_RETRY_MODIFIER 0x000F /* Modify a parameter */ +#define IW_RETRY_MIN 0x0001 /* Value is a minimum */ +#define IW_RETRY_MAX 0x0002 /* Value is a maximum */ +#define IW_RETRY_RELATIVE 0x0004 /* Value is not in seconds/ms/us */ + +/* Scanning request flags */ +#define IW_SCAN_DEFAULT 0x0000 /* Default scan of the driver */ +#define IW_SCAN_ALL_ESSID 0x0001 /* Scan all ESSIDs */ +#define IW_SCAN_THIS_ESSID 0x0002 /* Scan only this ESSID */ +#define IW_SCAN_ALL_FREQ 0x0004 /* Scan all Frequencies */ +#define IW_SCAN_THIS_FREQ 0x0008 /* Scan only this Frequency */ +#define IW_SCAN_ALL_MODE 0x0010 /* Scan all Modes */ +#define IW_SCAN_THIS_MODE 0x0020 /* Scan only this Mode */ +#define IW_SCAN_ALL_RATE 0x0040 /* Scan all Bit-Rates */ +#define IW_SCAN_THIS_RATE 0x0080 /* Scan only this Bit-Rate */ +/* struct iw_scan_req scan_type */ +#define IW_SCAN_TYPE_ACTIVE 0 +#define IW_SCAN_TYPE_PASSIVE 1 +/* Maximum size of returned data */ +#define IW_SCAN_MAX_DATA 4096 /* In bytes */ + +/* Max number of char in custom event - use multiple of them if needed */ +#define IW_CUSTOM_MAX 256 /* In bytes */ + +/* Generic information element */ +#define IW_GENERIC_IE_MAX 1024 + +/* MLME requests (SIOCSIWMLME / struct iw_mlme) */ +#define IW_MLME_DEAUTH 0 +#define IW_MLME_DISASSOC 1 + +/* SIOCSIWAUTH/SIOCGIWAUTH struct iw_param flags */ +#define IW_AUTH_INDEX 0x0FFF +#define IW_AUTH_FLAGS 0xF000 +/* SIOCSIWAUTH/SIOCGIWAUTH parameters (0 .. 4095) + * (IW_AUTH_INDEX mask in struct iw_param flags; this is the index of the + * parameter that is being set/get to; value will be read/written to + * struct iw_param value field) */ +#define IW_AUTH_WPA_VERSION 0 +#define IW_AUTH_CIPHER_PAIRWISE 1 +#define IW_AUTH_CIPHER_GROUP 2 +#define IW_AUTH_KEY_MGMT 3 +#define IW_AUTH_TKIP_COUNTERMEASURES 4 +#define IW_AUTH_DROP_UNENCRYPTED 5 +#define IW_AUTH_80211_AUTH_ALG 6 +#define IW_AUTH_WPA_ENABLED 7 +#define IW_AUTH_RX_UNENCRYPTED_EAPOL 8 +#define IW_AUTH_ROAMING_CONTROL 9 +#define IW_AUTH_PRIVACY_INVOKED 10 +#define IW_AUTH_CIPHER_GROUP_MGMT 11 +#define IW_AUTH_MFP 12 + +/* IW_AUTH_WPA_VERSION values (bit field) */ +#define IW_AUTH_WPA_VERSION_DISABLED 0x00000001 +#define IW_AUTH_WPA_VERSION_WPA 0x00000002 +#define IW_AUTH_WPA_VERSION_WPA2 0x00000004 + +/* IW_AUTH_PAIRWISE_CIPHER and IW_AUTH_GROUP_CIPHER values (bit field) */ +#define IW_AUTH_CIPHER_NONE 0x00000001 +#define IW_AUTH_CIPHER_WEP40 0x00000002 +#define IW_AUTH_CIPHER_TKIP 0x00000004 +#define IW_AUTH_CIPHER_CCMP 0x00000008 +#define IW_AUTH_CIPHER_WEP104 0x00000010 + +/* IW_AUTH_KEY_MGMT values (bit field) */ +#define IW_AUTH_KEY_MGMT_802_1X 1 +#define IW_AUTH_KEY_MGMT_PSK 2 + +/* IW_AUTH_80211_AUTH_ALG values (bit field) */ +#define IW_AUTH_ALG_OPEN_SYSTEM 0x00000001 +#define IW_AUTH_ALG_SHARED_KEY 0x00000002 +#define IW_AUTH_ALG_LEAP 0x00000004 + +/* IW_AUTH_ROAMING_CONTROL values */ +#define IW_AUTH_ROAMING_ENABLE 0 /* driver/firmware based roaming */ +#define IW_AUTH_ROAMING_DISABLE 1 /* user space program used for roaming + * control */ + +/* IW_AUTH_MFP (management frame protection) values */ +#define IW_AUTH_MFP_DISABLED 0 /* MFP disabled */ +#define IW_AUTH_MFP_OPTIONAL 1 /* MFP optional */ +#define IW_AUTH_MFP_REQUIRED 2 /* MFP required */ + +/* SIOCSIWENCODEEXT definitions */ +#define IW_ENCODE_SEQ_MAX_SIZE 8 +/* struct iw_encode_ext ->alg */ +#define IW_ENCODE_ALG_NONE 0 +#define IW_ENCODE_ALG_WEP 1 +#define IW_ENCODE_ALG_TKIP 2 +#define IW_ENCODE_ALG_CCMP 3 +#define IW_ENCODE_ALG_PMK 4 +#define IW_ENCODE_ALG_AES_CMAC 5 +/* struct iw_encode_ext ->ext_flags */ +#define IW_ENCODE_EXT_TX_SEQ_VALID 0x00000001 +#define IW_ENCODE_EXT_RX_SEQ_VALID 0x00000002 +#define IW_ENCODE_EXT_GROUP_KEY 0x00000004 +#define IW_ENCODE_EXT_SET_TX_KEY 0x00000008 + +/* IWEVMICHAELMICFAILURE : struct iw_michaelmicfailure ->flags */ +#define IW_MICFAILURE_KEY_ID 0x00000003 /* Key ID 0..3 */ +#define IW_MICFAILURE_GROUP 0x00000004 +#define IW_MICFAILURE_PAIRWISE 0x00000008 +#define IW_MICFAILURE_STAKEY 0x00000010 +#define IW_MICFAILURE_COUNT 0x00000060 /* 1 or 2 (0 = count not supported) + */ + +/* Bit field values for enc_capa in struct iw_range */ +#define IW_ENC_CAPA_WPA 0x00000001 +#define IW_ENC_CAPA_WPA2 0x00000002 +#define IW_ENC_CAPA_CIPHER_TKIP 0x00000004 +#define IW_ENC_CAPA_CIPHER_CCMP 0x00000008 +#define IW_ENC_CAPA_4WAY_HANDSHAKE 0x00000010 + +/* Event capability macros - in (struct iw_range *)->event_capa + * Because we have more than 32 possible events, we use an array of + * 32 bit bitmasks. Note : 32 bits = 0x20 = 2^5. */ +#define IW_EVENT_CAPA_BASE(cmd) ((cmd >= SIOCIWFIRSTPRIV) ? \ + (cmd - SIOCIWFIRSTPRIV + 0x60) : \ + (cmd - SIOCSIWCOMMIT)) +#define IW_EVENT_CAPA_INDEX(cmd) (IW_EVENT_CAPA_BASE(cmd) >> 5) +#define IW_EVENT_CAPA_MASK(cmd) (1 << (IW_EVENT_CAPA_BASE(cmd) & 0x1F)) +/* Event capability constants - event autogenerated by the kernel + * This list is valid for most 802.11 devices, customise as needed... */ +#define IW_EVENT_CAPA_K_0 (IW_EVENT_CAPA_MASK(0x8B04) | \ + IW_EVENT_CAPA_MASK(0x8B06) | \ + IW_EVENT_CAPA_MASK(0x8B1A)) +#define IW_EVENT_CAPA_K_1 (IW_EVENT_CAPA_MASK(0x8B2A)) +/* "Easy" macro to set events in iw_range (less efficient) */ +#define IW_EVENT_CAPA_SET(event_capa, cmd) (event_capa[IW_EVENT_CAPA_INDEX(cmd)] |= IW_EVENT_CAPA_MASK(cmd)) +#define IW_EVENT_CAPA_SET_KERNEL(event_capa) {event_capa[0] |= IW_EVENT_CAPA_K_0; event_capa[1] |= IW_EVENT_CAPA_K_1; } + + +/****************************** TYPES ******************************/ + +/* --------------------------- SUBTYPES --------------------------- */ +/* + * Generic format for most parameters that fit in an int + */ +struct iw_param +{ + __s32 value; /* The value of the parameter itself */ + __u8 fixed; /* Hardware should not use auto select */ + __u8 disabled; /* Disable the feature */ + __u16 flags; /* Various specifc flags (if any) */ +}; + +/* + * For all data larger than 16 octets, we need to use a + * pointer to memory allocated in user space. + */ +struct iw_point +{ + void __user *pointer; /* Pointer to the data (in user space) */ + __u16 length; /* number of fields or size in bytes */ + __u16 flags; /* Optional params */ +}; + +/* + * A frequency + * For numbers lower than 10^9, we encode the number in 'm' and + * set 'e' to 0 + * For number greater than 10^9, we divide it by the lowest power + * of 10 to get 'm' lower than 10^9, with 'm'= f / (10^'e')... + * The power of 10 is in 'e', the result of the division is in 'm'. + */ +struct iw_freq +{ + __s32 m; /* Mantissa */ + __s16 e; /* Exponent */ + __u8 i; /* List index (when in range struct) */ + __u8 flags; /* Flags (fixed/auto) */ +}; + +/* + * Quality of the link + */ +struct iw_quality +{ + __u8 qual; /* link quality (%retries, SNR, + %missed beacons or better...) */ + __u8 level; /* signal level (dBm) */ + __u8 noise; /* noise level (dBm) */ + __u8 updated; /* Flags to know if updated */ +}; + +/* + * Packet discarded in the wireless adapter due to + * "wireless" specific problems... + * Note : the list of counter and statistics in net_device_stats + * is already pretty exhaustive, and you should use that first. + * This is only additional stats... + */ +struct iw_discarded +{ + __u32 nwid; /* Rx : Wrong nwid/essid */ + __u32 code; /* Rx : Unable to code/decode (WEP) */ + __u32 fragment; /* Rx : Can't perform MAC reassembly */ + __u32 retries; /* Tx : Max MAC retries num reached */ + __u32 misc; /* Others cases */ +}; + +/* + * Packet/Time period missed in the wireless adapter due to + * "wireless" specific problems... + */ +struct iw_missed +{ + __u32 beacon; /* Missed beacons/superframe */ +}; + +/* + * Quality range (for spy threshold) + */ +struct iw_thrspy +{ + struct sockaddr addr; /* Source address (hw/mac) */ + struct iw_quality qual; /* Quality of the link */ + struct iw_quality low; /* Low threshold */ + struct iw_quality high; /* High threshold */ +}; + +/* + * Optional data for scan request + * + * Note: these optional parameters are controlling parameters for the + * scanning behavior, these do not apply to getting scan results + * (SIOCGIWSCAN). Drivers are expected to keep a local BSS table and + * provide a merged results with all BSSes even if the previous scan + * request limited scanning to a subset, e.g., by specifying an SSID. + * Especially, scan results are required to include an entry for the + * current BSS if the driver is in Managed mode and associated with an AP. + */ +struct iw_scan_req +{ + __u8 scan_type; /* IW_SCAN_TYPE_{ACTIVE,PASSIVE} */ + __u8 essid_len; + __u8 num_channels; /* num entries in channel_list; + * 0 = scan all allowed channels */ + __u8 flags; /* reserved as padding; use zero, this may + * be used in the future for adding flags + * to request different scan behavior */ + struct sockaddr bssid; /* ff:ff:ff:ff:ff:ff for broadcast BSSID or + * individual address of a specific BSS */ + + /* + * Use this ESSID if IW_SCAN_THIS_ESSID flag is used instead of using + * the current ESSID. This allows scan requests for specific ESSID + * without having to change the current ESSID and potentially breaking + * the current association. + */ + __u8 essid[IW_ESSID_MAX_SIZE]; + + /* + * Optional parameters for changing the default scanning behavior. + * These are based on the MLME-SCAN.request from IEEE Std 802.11. + * TU is 1.024 ms. If these are set to 0, driver is expected to use + * reasonable default values. min_channel_time defines the time that + * will be used to wait for the first reply on each channel. If no + * replies are received, next channel will be scanned after this. If + * replies are received, total time waited on the channel is defined by + * max_channel_time. + */ + __u32 min_channel_time; /* in TU */ + __u32 max_channel_time; /* in TU */ + + struct iw_freq channel_list[IW_MAX_FREQUENCIES]; +}; + +/* ------------------------- WPA SUPPORT ------------------------- */ + +/* + * Extended data structure for get/set encoding (this is used with + * SIOCSIWENCODEEXT/SIOCGIWENCODEEXT. struct iw_point and IW_ENCODE_* + * flags are used in the same way as with SIOCSIWENCODE/SIOCGIWENCODE and + * only the data contents changes (key data -> this structure, including + * key data). + * + * If the new key is the first group key, it will be set as the default + * TX key. Otherwise, default TX key index is only changed if + * IW_ENCODE_EXT_SET_TX_KEY flag is set. + * + * Key will be changed with SIOCSIWENCODEEXT in all cases except for + * special "change TX key index" operation which is indicated by setting + * key_len = 0 and ext_flags |= IW_ENCODE_EXT_SET_TX_KEY. + * + * tx_seq/rx_seq are only used when respective + * IW_ENCODE_EXT_{TX,RX}_SEQ_VALID flag is set in ext_flags. Normal + * TKIP/CCMP operation is to set RX seq with SIOCSIWENCODEEXT and start + * TX seq from zero whenever key is changed. SIOCGIWENCODEEXT is normally + * used only by an Authenticator (AP or an IBSS station) to get the + * current TX sequence number. Using TX_SEQ_VALID for SIOCSIWENCODEEXT and + * RX_SEQ_VALID for SIOCGIWENCODEEXT are optional, but can be useful for + * debugging/testing. + */ +struct iw_encode_ext +{ + __u32 ext_flags; /* IW_ENCODE_EXT_* */ + __u8 tx_seq[IW_ENCODE_SEQ_MAX_SIZE]; /* LSB first */ + __u8 rx_seq[IW_ENCODE_SEQ_MAX_SIZE]; /* LSB first */ + struct sockaddr addr; /* ff:ff:ff:ff:ff:ff for broadcast/multicast + * (group) keys or unicast address for + * individual keys */ + __u16 alg; /* IW_ENCODE_ALG_* */ + __u16 key_len; + __u8 key[0]; +}; + +/* SIOCSIWMLME data */ +struct iw_mlme +{ + __u16 cmd; /* IW_MLME_* */ + __u16 reason_code; + struct sockaddr addr; +}; + +/* SIOCSIWPMKSA data */ +#define IW_PMKSA_ADD 1 +#define IW_PMKSA_REMOVE 2 +#define IW_PMKSA_FLUSH 3 + +#define IW_PMKID_LEN 16 + +struct iw_pmksa +{ + __u32 cmd; /* IW_PMKSA_* */ + struct sockaddr bssid; + __u8 pmkid[IW_PMKID_LEN]; +}; + +/* IWEVMICHAELMICFAILURE data */ +struct iw_michaelmicfailure +{ + __u32 flags; + struct sockaddr src_addr; + __u8 tsc[IW_ENCODE_SEQ_MAX_SIZE]; /* LSB first */ +}; + +/* IWEVPMKIDCAND data */ +#define IW_PMKID_CAND_PREAUTH 0x00000001 /* RNS pre-authentication enabled */ +struct iw_pmkid_cand +{ + __u32 flags; /* IW_PMKID_CAND_* */ + __u32 index; /* the smaller the index, the higher the + * priority */ + struct sockaddr bssid; +}; + +/* ------------------------ WIRELESS STATS ------------------------ */ +/* + * Wireless statistics (used for /proc/net/wireless) + */ +struct iw_statistics +{ + __u16 status; /* Status + * - device dependent for now */ + + struct iw_quality qual; /* Quality of the link + * (instant/mean/max) */ + struct iw_discarded discard; /* Packet discarded counts */ + struct iw_missed miss; /* Packet missed counts */ +}; + +/* ------------------------ IOCTL REQUEST ------------------------ */ +/* + * This structure defines the payload of an ioctl, and is used + * below. + * + * Note that this structure should fit on the memory footprint + * of iwreq (which is the same as ifreq), which mean a max size of + * 16 octets = 128 bits. Warning, pointers might be 64 bits wide... + * You should check this when increasing the structures defined + * above in this file... + */ +union iwreq_data +{ + /* Config - generic */ + char name[IFNAMSIZ]; + /* Name : used to verify the presence of wireless extensions. + * Name of the protocol/provider... */ + + struct iw_point essid; /* Extended network name */ + struct iw_param nwid; /* network id (or domain - the cell) */ + struct iw_freq freq; /* frequency or channel : + * 0-1000 = channel + * > 1000 = frequency in Hz */ + + struct iw_param sens; /* signal level threshold */ + struct iw_param bitrate; /* default bit rate */ + struct iw_param txpower; /* default transmit power */ + struct iw_param rts; /* RTS threshold threshold */ + struct iw_param frag; /* Fragmentation threshold */ + __u32 mode; /* Operation mode */ + struct iw_param retry; /* Retry limits & lifetime */ + + struct iw_point encoding; /* Encoding stuff : tokens */ + struct iw_param power; /* PM duration/timeout */ + struct iw_quality qual; /* Quality part of statistics */ + + struct sockaddr ap_addr; /* Access point address */ + struct sockaddr addr; /* Destination address (hw/mac) */ + + struct iw_param param; /* Other small parameters */ + struct iw_point data; /* Other large parameters */ +}; + +/* + * The structure to exchange data for ioctl. + * This structure is the same as 'struct ifreq', but (re)defined for + * convenience... + * Do I need to remind you about structure size (32 octets) ? + */ +struct iwreq +{ + union + { + char ifrn_name[IFNAMSIZ]; /* if name, e.g. "eth0" */ + } ifr_ifrn; + + /* Data part (defined just above) */ + union iwreq_data u; +}; + +/* -------------------------- IOCTL DATA -------------------------- */ +/* + * For those ioctl which want to exchange mode data that what could + * fit in the above structure... + */ + +/* + * Range of parameters + */ + +struct iw_range +{ + /* Informative stuff (to choose between different interface) */ + __u32 throughput; /* To give an idea... */ + /* In theory this value should be the maximum benchmarked + * TCP/IP throughput, because with most of these devices the + * bit rate is meaningless (overhead an co) to estimate how + * fast the connection will go and pick the fastest one. + * I suggest people to play with Netperf or any benchmark... + */ + + /* NWID (or domain id) */ + __u32 min_nwid; /* Minimal NWID we are able to set */ + __u32 max_nwid; /* Maximal NWID we are able to set */ + + /* Old Frequency (backward compat - moved lower ) */ + __u16 old_num_channels; + __u8 old_num_frequency; + + /* Wireless event capability bitmasks */ + __u32 event_capa[6]; + + /* signal level threshold range */ + __s32 sensitivity; + + /* Quality of link & SNR stuff */ + /* Quality range (link, level, noise) + * If the quality is absolute, it will be in the range [0 ; max_qual], + * if the quality is dBm, it will be in the range [max_qual ; 0]. + * Don't forget that we use 8 bit arithmetics... */ + struct iw_quality max_qual; /* Quality of the link */ + /* This should contain the average/typical values of the quality + * indicator. This should be the threshold between a "good" and + * a "bad" link (example : monitor going from green to orange). + * Currently, user space apps like quality monitors don't have any + * way to calibrate the measurement. With this, they can split + * the range between 0 and max_qual in different quality level + * (using a geometric subdivision centered on the average). + * I expect that people doing the user space apps will feedback + * us on which value we need to put in each driver... */ + struct iw_quality avg_qual; /* Quality of the link */ + + /* Rates */ + __u8 num_bitrates; /* Number of entries in the list */ + __s32 bitrate[IW_MAX_BITRATES]; /* list, in bps */ + + /* RTS threshold */ + __s32 min_rts; /* Minimal RTS threshold */ + __s32 max_rts; /* Maximal RTS threshold */ + + /* Frag threshold */ + __s32 min_frag; /* Minimal frag threshold */ + __s32 max_frag; /* Maximal frag threshold */ + + /* Power Management duration & timeout */ + __s32 min_pmp; /* Minimal PM period */ + __s32 max_pmp; /* Maximal PM period */ + __s32 min_pmt; /* Minimal PM timeout */ + __s32 max_pmt; /* Maximal PM timeout */ + __u16 pmp_flags; /* How to decode max/min PM period */ + __u16 pmt_flags; /* How to decode max/min PM timeout */ + __u16 pm_capa; /* What PM options are supported */ + + /* Encoder stuff */ + __u16 encoding_size[IW_MAX_ENCODING_SIZES]; /* Different token sizes */ + __u8 num_encoding_sizes; /* Number of entry in the list */ + __u8 max_encoding_tokens; /* Max number of tokens */ + /* For drivers that need a "login/passwd" form */ + __u8 encoding_login_index; /* token index for login token */ + + /* Transmit power */ + __u16 txpower_capa; /* What options are supported */ + __u8 num_txpower; /* Number of entries in the list */ + __s32 txpower[IW_MAX_TXPOWER]; /* list, in bps */ + + /* Wireless Extension version info */ + __u8 we_version_compiled; /* Must be WIRELESS_EXT */ + __u8 we_version_source; /* Last update of source */ + + /* Retry limits and lifetime */ + __u16 retry_capa; /* What retry options are supported */ + __u16 retry_flags; /* How to decode max/min retry limit */ + __u16 r_time_flags; /* How to decode max/min retry life */ + __s32 min_retry; /* Minimal number of retries */ + __s32 max_retry; /* Maximal number of retries */ + __s32 min_r_time; /* Minimal retry lifetime */ + __s32 max_r_time; /* Maximal retry lifetime */ + + /* Frequency */ + __u16 num_channels; /* Number of channels [0; num - 1] */ + __u8 num_frequency; /* Number of entry in the list */ + struct iw_freq freq[IW_MAX_FREQUENCIES]; /* list */ + /* Note : this frequency list doesn't need to fit channel numbers, + * because each entry contain its channel index */ + + __u32 enc_capa; /* IW_ENC_CAPA_* bit field */ +}; + +/* + * Private ioctl interface information + */ + +struct iw_priv_args +{ + __u32 cmd; /* Number of the ioctl to issue */ + __u16 set_args; /* Type and number of args */ + __u16 get_args; /* Type and number of args */ + char name[IFNAMSIZ]; /* Name of the extension */ +}; + +/* ----------------------- WIRELESS EVENTS ----------------------- */ +/* + * Wireless events are carried through the rtnetlink socket to user + * space. They are encapsulated in the IFLA_WIRELESS field of + * a RTM_NEWLINK message. + */ + +/* + * A Wireless Event. Contains basically the same data as the ioctl... + */ +struct iw_event +{ + __u16 len; /* Real lenght of this stuff */ + __u16 cmd; /* Wireless IOCTL */ + union iwreq_data u; /* IOCTL fixed payload */ +}; + +/* Size of the Event prefix (including padding and alignement junk) */ +#define IW_EV_LCP_LEN (sizeof(struct iw_event) - sizeof(union iwreq_data)) +/* Size of the various events */ +#define IW_EV_CHAR_LEN (IW_EV_LCP_LEN + IFNAMSIZ) +#define IW_EV_UINT_LEN (IW_EV_LCP_LEN + sizeof(__u32)) +#define IW_EV_FREQ_LEN (IW_EV_LCP_LEN + sizeof(struct iw_freq)) +#define IW_EV_PARAM_LEN (IW_EV_LCP_LEN + sizeof(struct iw_param)) +#define IW_EV_ADDR_LEN (IW_EV_LCP_LEN + sizeof(struct sockaddr)) +#define IW_EV_QUAL_LEN (IW_EV_LCP_LEN + sizeof(struct iw_quality)) + +/* iw_point events are special. First, the payload (extra data) come at + * the end of the event, so they are bigger than IW_EV_POINT_LEN. Second, + * we omit the pointer, so start at an offset. */ +#define IW_EV_POINT_OFF (((char *) &(((struct iw_point *) NULL)->length)) - \ + (char *) NULL) +#define IW_EV_POINT_LEN (IW_EV_LCP_LEN + sizeof(struct iw_point) - \ + IW_EV_POINT_OFF) + +#endif /* _LINUX_WIRELESS_H */ |