/* ****************************************************************************** * SOURCE FILE * * Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipwlan_cmd_wlan.c,v $ $Revision: 1.16.16.4 $ * $Source: /home/interpeak/CVSRoot/ipwlan/src/ipwlan_cmd_wlan.c,v $ * $Author: svc-cmnet $ $Date: 2014-06-10 23:33:34 $ * $State: Exp $ $Locker: $ * * INTERPEAK_COPYRIGHT_STRING * Design and implementation by Firstname Lastname ****************************************************************************** */ /* **************************************************************************** * 2 CONFIGURATION **************************************************************************** */ #include "ipcom_config.h" /* **************************************************************************** * 3 INCLUDE FILES. **************************************************************************** */ #define IPCOM_USE_CLIB_PROTO #include #include "ipcom_clib.h" #include "ipcom_cstyle.h" #include "ipcom_getopt.h" #include "ipcom_os.h" #include "ipcom_sock.h" #include "ipcom_sock2.h" #include "ipcom_time.h" #include "ipcom_type.h" #include "ipwlan_wlan.h" /* **************************************************************************** * 4 DEFINES **************************************************************************** */ #define MIN(a, b) (((a)<(b))?(a):(b)) #define WLAN_FREQUENCY_BAND 2412000 #define WLAN_MAX_TEXT_LEN 100 #define IS_A_NEXT_IWE(iwe, iw_end) (((char *)iwe + IP_IW_EV_LCP_LEN) < (char *)iw_end) #define NEXT_IWE(iwe) ((iw_event *)((char *)iwe + iwe->len)) #define MAX_SCAN_WAITING_TIME (25) /* **************************************************************************** * 5 TYPES **************************************************************************** */ enum { wlan_mode_client_infra = 0, wlan_mode_client_adhoc, wlan_mode_client_auto, wlan_mode_ap, wlan_mode_unknown }; typedef Ipcom_iw_event iw_event; /* **************************************************************************** * 6 EXTERNAL FUNCTIONS **************************************************************************** */ IP_EXTERN int ipcom_vprintf(const char *format, va_list ap); IP_EXTERN int vsnprintf(char *, int, const char *, va_list); #ifdef IP_PORT_VXWORKS IP_EXTERN void * muxTkCookieGet(char *,int); IP_EXTERN int muxIoctl(void *,int,char *); #endif /* IP_PORT_VXWORKS */ /* **************************************************************************** * 6 LOCAL PROTOTYPES **************************************************************************** */ IP_PUBLIC int ipwlan_cmd_wlan(int argc, char **argv); Ip_u8 convertDecimalToKeycode(Ip_u8 dec); /* **************************************************************************** * 7 DATA **************************************************************************** */ /* *=========================================================================== * STATIC DATA *=========================================================================== */ IP_STATIC IP_CONST char *wlan_mode_text[] = {"client infra", "client adhoc", "client auto", "access point", "adhoc", "unknown"}; IP_CONST int ipwlan_encr_policy[] = { IP_IW_CIPHPOL_NONE, IP_IW_CIPHPOL_WEP40, IP_IW_CIPHPOL_WEP104, IP_IW_CIPHPOL_WEP40+IP_IW_CIPHPOL_WEP104, IP_IW_CIPHPOL_TKIP, IP_IW_CIPHPOL_CCMP, IP_IW_CIPHPOL_TKIP+IP_IW_CIPHPOL_CCMP, IP_IW_CIPHPOL_CCMP+IP_IW_CIPHPOL_WEP40, IP_IW_CIPHPOL_CCMP+IP_IW_CIPHPOL_WEP104, IP_IW_CIPHPOL_CCMP+IP_IW_CIPHPOL_WEP40+IP_IW_CIPHPOL_WEP104, IP_IW_CIPHPOL_TKIP+IP_IW_CIPHPOL_WEP40, IP_IW_CIPHPOL_TKIP+IP_IW_CIPHPOL_WEP104, IP_IW_CIPHPOL_TKIP+IP_IW_CIPHPOL_WEP40+IP_IW_CIPHPOL_WEP104, IP_IW_CIPHPOL_TKIP+IP_IW_CIPHPOL_CCMP+IP_IW_CIPHPOL_WEP40, IP_IW_CIPHPOL_TKIP+IP_IW_CIPHPOL_CCMP+IP_IW_CIPHPOL_WEP104, IP_IW_CIPHPOL_TKIP+IP_IW_CIPHPOL_CCMP+IP_IW_CIPHPOL_WEP40+IP_IW_CIPHPOL_WEP104 }; IP_STATIC IP_CONST char *wlan_encr_text[] = { "none", "WEP40", "WEP104", "WEP40 WEP104", "TKIP", "AES_CCMP", "TKIP, AES_CCMP", "AES_CCMP, WEP40", "AES_CCMP, WEP104", "AES_CCMP, WEP40, WEP104", "TKIP, WEP40", "TKIP, WEP104", "TKIP, WEP40, WEP104", "TKIP, AES_CCMP, WEP40", "TKIP, AES_CCMP, WEP104", "TKIP, AES_CCMP, WEP40, WEP104" }; /* **************************************************************************** * WME Standard Queue **************************************************************************** */ IP_STATIC IP_CONST char IP_IW_WMM_AC_CATEGORY[IP_IW_AC_COUNT][6] = {"AC_BE", "AC_BK", "AC_VI", "AC_VO"}; /* **************************************************************************** * 8 LOCAL FUNCTIONS **************************************************************************** */ /* *=========================================================================== * ipwlan_printf *=========================================================================== * Description: Prints to console * Parameters: 'enabled' == 0 => printout is suppressed * Returns: 0 */ IP_STATIC int ipwlan_printf(int enabled, const char *format, ...) { va_list ptr; char text[WLAN_MAX_TEXT_LEN]; va_start(ptr, format); if (enabled) { vsnprintf(text, WLAN_MAX_TEXT_LEN - 1, format, ptr); ipcom_printf("%s", text); } va_end(ptr); return 0; } /* *=========================================================================== * ipwlan_print_usage *=========================================================================== * Description: Lists shell commands available * Parameters: 'en' == 0 => No printout to console * Returns: */ IP_STATIC void ipwlan_print_usage(int en) { ipwlan_printf(en, "Usage:"IP_LF); ipwlan_printf(en, " wifi acl Get Access control list"IP_LF); ipwlan_printf(en, " acl mode [allow|deny] Set/Get Access control list mode"IP_LF); ipwlan_printf(en, " acl add|del Add/Delete station to/from acl"IP_LF); ipwlan_printf(en, " auth [open|shared-key] Set/Get authentication policy"IP_LF); ipwlan_printf(en, " auth [wpa|wpa-psk] Set/Get authentication policy"IP_LF); ipwlan_printf(en, " auth [wpa2|wpa2-psk] Set/Get authentication policy"IP_LF); ipwlan_printf(en, " bi [] Set/Get beacon interval (us)"IP_LF); ipwlan_printf(en, " bss add|del [] Add/Delete bss"IP_LF); ipwlan_printf(en, " bss [] Set/Get current bss index"IP_LF); ipwlan_printf(en, " channel [] Set/Get channel"IP_LF); ipwlan_printf(en, " channel supp Get supported channels"IP_LF); ipwlan_printf(en, " country [] Set/Get country code"IP_LF); ipwlan_printf(en, " debug [] | -h Set/Get debug level(s)"IP_LF); ipwlan_printf(en, " encr [none|tkip|ccmp] Set/Get encryption type"IP_LF); ipwlan_printf(en, " encr wep 1|2|3|4 [|] Set/Get WEP group key"IP_LF); ipwlan_printf(en, " encr wep [|] Set/Get WEP pairwise key"IP_LF); ipwlan_printf(en, " encr wpa [|] Set/Get WPA encryption"IP_LF); ipwlan_printf(en, " encr wpa2 [|] Set/Get WPA2 encryption"IP_LF); ipwlan_printf(en, " mcast_encr Get multicast encryption type"IP_LF); ipwlan_printf(en, " fragthresh [] Set/Get fragmentation threshold"IP_LF); ipwlan_printf(en, " lrl [] Set/Get long retry limit"IP_LF); ipwlan_printf(en, " mbss [on|off] Set/Get multiple bss mode"IP_LF); ipwlan_printf(en, " mode Get current mode"IP_LF); ipwlan_printf(en, " mode ap Configure as access point"IP_LF); ipwlan_printf(en, " mode client adhoc|infra Configure as client"IP_LF); ipwlan_printf(en, " pm [on|off] Set/Get power management mode"IP_LF); ipwlan_printf(en, " ps [] Set/Get tx power scale (%%)"IP_LF); ipwlan_printf(en, " quality Get link status"IP_LF); ipwlan_printf(en, " radiomode [auto|a|b|g] Set/Get radio mode"IP_LF); ipwlan_printf(en, " radiomode n bw [] Set/Get MIMO bandwidth"IP_LF); ipwlan_printf(en, " radiomode n legacy Set/Get 802.11n legacy rate"IP_LF); ipwlan_printf(en, " radiomode n on|off Enable/Disable 802.11n mode"IP_LF); ipwlan_printf(en, " rate [] Set/Get rate"IP_LF); ipwlan_printf(en, " rate supp [] Set/Get supported rates"IP_LF); ipwlan_printf(en, " regulatory [on|off] Set/Get 802.11d regulatory mode"IP_LF); ipwlan_printf(en, " rtsthresh [] Set/Get rts/cts threshold"IP_LF); ipwlan_printf(en, " scan <1-%ds> [] Scan for , display result"IP_LF, MAX_SCAN_WAITING_TIME); ipwlan_printf(en, " scan mode [active|passive] Set/Get scan mode"IP_LF); ipwlan_printf(en, " srl [] Set/Get short retry limit"IP_LF); ipwlan_printf(en, " ssid [] Set/Get SSID"IP_LF); ipwlan_printf(en, " ssid broadcast [on|off] Set/Get SSID broadcast mode"IP_LF); ipwlan_printf(en, " statistics Get system statistics"IP_LF); ipwlan_printf(en, " status Get system status"IP_LF); ipwlan_printf(en, " vlan [] Set/Get current vlan"IP_LF); ipwlan_printf(en, " wme [on|off] Enable/Disable wme"IP_LF); ipwlan_printf(en, " wme_ac [ap|sta] Get wme edcf parameters"IP_LF); } /* *=========================================================================== * ipwlan_print_usage_acl *=========================================================================== * Description: Prints acl shell command usage * Parameters: 'en' == 0 => No printout to console * Returns: */ IP_STATIC void ipwlan_print_usage_acl(int en) { ipwlan_printf(en, "Usage:"IP_LF); ipwlan_printf(en, " wifi acl mode [allow|deny] Set/Get Access control list mode"IP_LF); ipwlan_printf(en, " acl add|del Add/Delete station to/from acl"IP_LF); } /* *=========================================================================== * ipwlan_print_usage_auth *=========================================================================== * Description: Prints auth shell command usage * Parameters: 'en' == 0 => No printout to console * Returns: */ IP_STATIC void ipwlan_print_usage_auth(int en) { ipwlan_printf(en, "Usage:"IP_LF); ipwlan_printf(en, " wifi auth [open|shared-key] Set/Get authentication policy"IP_LF); ipwlan_printf(en, " auth [wpa|wpa-psk] Set/Get authentication policy"IP_LF); ipwlan_printf(en, " auth [wpa2|wpa2-psk] Set/Get authentication policy"IP_LF); } /* *=========================================================================== * ipwlan_print_usage_bi *=========================================================================== * Description: Prints bi shell command usage * Parameters: 'en' == 0 => No printout to console * Returns: */ IP_STATIC void ipwlan_print_usage_bi(int en) { ipwlan_printf(en, "Usage:"IP_LF); ipwlan_printf(en, " wifi bi [] Set/Get beacon interval (us)"IP_LF); } /* *=========================================================================== * ipwlan_print_usage_bss *=========================================================================== * Description: Prints bss shell command usage * Parameters: 'en' == 0 => No printout to console * Returns: */ IP_STATIC void ipwlan_print_usage_bss(int en) { ipwlan_printf(en, "Usage:"IP_LF); ipwlan_printf(en, " wifi bss add|del [] Add/Delete bss"IP_LF); ipwlan_printf(en, " bss [] Set/Get current bss index"IP_LF); } /* *=========================================================================== * ipwlan_print_usage_channel *=========================================================================== * Description: Prints channel shell command usage * Parameters: 'en' == 0 => No printout to console * Returns: */ IP_STATIC void ipwlan_print_usage_channel(int en) { ipwlan_printf(en, "Usage:"IP_LF); ipwlan_printf(en, " wifi channel [] Set/Get channel"IP_LF); ipwlan_printf(en, " channel supp Get supported channels"IP_LF); } /* *=========================================================================== * ipwlan_print_usage_country *=========================================================================== * Description: Prints country shell command usage * Parameters: 'en' == 0 => No printout to console * Returns: */ IP_STATIC void ipwlan_print_usage_country(int en) { ipwlan_printf(en, "Usage:"IP_LF); ipwlan_printf(en, " wifi country [] Set/Get country code"IP_LF); } /* *=========================================================================== * ipwlan_print_usage_debug *=========================================================================== * Description: Prints debug shell command usage * Parameters: 'en' == 0 => No printout to console * Returns: */ IP_GLOBAL void ipwlan_print_usage_debug(int en) { ipwlan_printf(en, "Usage:"IP_LF); ipwlan_printf(en, " wifi debug [] | -h Set/Get debug level(s)"IP_LF); } /* *=========================================================================== * ipwlan_print_usage_encr *=========================================================================== * Description: Prints encr shell command usage * Parameters: 'en' == 0 => No printout to console * Returns: */ IP_STATIC void ipwlan_print_usage_encr(int en) { ipwlan_printf(en, "Usage:"IP_LF); ipwlan_printf(en, " wifi encr [none|tkip|ccmp] Set/Get encryption type"IP_LF); ipwlan_printf(en, " encr wep 1|2|3|4 [|] Set/Get WEP group key"IP_LF); ipwlan_printf(en, " encr wep [|] Set/Get WEP pairwise key"IP_LF); ipwlan_printf(en, " encr wpa [|] Set/Get WPA encryption"IP_LF); ipwlan_printf(en, " encr wpa2 [|] Set/Get WPA2 encryption"IP_LF); } /* *=========================================================================== * ipwlan_print_usage_fragthresh *=========================================================================== * Description: Prints fragthresh shell command usage * Parameters: 'en' == 0 => No printout to console * Returns: */ IP_STATIC void ipwlan_print_usage_fragthresh(int en) { ipwlan_printf(en, "Usage:"IP_LF); ipwlan_printf(en, " wifi fragthresh [] Set/Get fragmentation threshold"IP_LF); } /* *=========================================================================== * ipwlan_print_usage_lrl *=========================================================================== * Description: Prints lrl shell command usage * Parameters: 'en' == 0 => No printout to console * Returns: */ IP_STATIC void ipwlan_print_usage_lrl(int en) { ipwlan_printf(en, "Usage:"IP_LF); ipwlan_printf(en, " wifi lrl [] Set/Get long retry limit"IP_LF); } /* *=========================================================================== * ipwlan_print_usage_mbss *=========================================================================== * Description: Prints mbss shell command usage * Parameters: 'en' == 0 => No printout to console * Returns: */ IP_STATIC void ipwlan_print_usage_mbss(int en) { ipwlan_printf(en, "Usage:"IP_LF); ipwlan_printf(en, " wifi mbss [on|off] Set/Get multiple bss mode"IP_LF); } /* *=========================================================================== * ipwlan_print_usage_wme *=========================================================================== * Description: Prints wme shell command usage * Parameters: 'en' == 0 => No printout to console * Returns: */ IP_STATIC void ipwlan_print_usage_wme(int en) { ipwlan_printf(en, "Usage:"IP_LF); ipwlan_printf(en, " wifi wme [on|off] Turn on/off wme"IP_LF); } /* *=========================================================================== * ipwlan_print_usage_wmeac *=========================================================================== */ IP_STATIC void ipwlan_print_usage_wmeac(int en) { ipwlan_printf(en, "Usage:"IP_LF); ipwlan_printf(en, " wifi wme_ac [ap|sta] Get wme edcf parameter"IP_LF); } /* *=========================================================================== * ipwlan_print_usage_mode *=========================================================================== * Description: Prints channel shell command usage * Parameters: 'en' == 0 => No printout to console * Returns: */ IP_STATIC void ipwlan_print_usage_mode(int en) { ipwlan_printf(en, "Usage:"IP_LF); ipwlan_printf(en, " wifi mode Get current mode"IP_LF); ipwlan_printf(en, " mode ap Configure as access point"IP_LF); ipwlan_printf(en, " mode client adhoc|infra Configure as client in adhoc or"IP_LF); ipwlan_printf(en, " infra mode"IP_LF); } /* *=========================================================================== * ipwlan_print_usage_pm *=========================================================================== * Description: Prints pm shell command usage * Parameters: 'en' == 0 => No printout to console * Returns: */ IP_STATIC void ipwlan_print_usage_pm(int en) { ipwlan_printf(en, "Usage:"IP_LF); ipwlan_printf(en, " wifi pm [on|off] Set/Get power management mode"IP_LF); } /* *=========================================================================== * ipwlan_print_usage_ps *=========================================================================== * Description: Prints ps shell command usage * Parameters: 'en' == 0 => No printout to console * Returns: */ IP_STATIC void ipwlan_print_usage_ps(int en) { ipwlan_printf(en, "Usage:"IP_LF); ipwlan_printf(en, " wifi ps [] Set/Get tx power scale (%%)"IP_LF); } /* *=========================================================================== * ipwlan_print_usage_quality *=========================================================================== * Description: Prints quality shell command usage * Parameters: 'en' == 0 => No printout to console * Returns: */ IP_STATIC void ipwlan_print_usage_quality(int en) { ipwlan_printf(en, "Usage:"IP_LF); ipwlan_printf(en, " wifi quality Get link status"IP_LF); } /* *=========================================================================== * ipwlan_print_usage_radiomode *=========================================================================== * Description: Prints radiomode shell command usage * Parameters: 'en' == 0 => No printout to console * Returns: */ IP_STATIC void ipwlan_print_usage_radiomode(int en) { ipwlan_printf(en, "Usage:"IP_LF); ipwlan_printf(en, " wifi radiomode [auto|a|b|g] Set/Get radio mode"IP_LF); ipwlan_printf(en, " radiomode n bw [] Set/Get MIMO bandwidth"IP_LF); ipwlan_printf(en, " radiomode n legacy Set/Get 802.11n legacy rate"IP_LF); ipwlan_printf(en, " radiomode n on|off Enable/Disable 802.11n mode"IP_LF); } /* *=========================================================================== * ipwlan_print_usage_rate *=========================================================================== * Description: Prints rate shell command usage * Parameters: 'en' == 0 => No printout to console * Returns: */ IP_STATIC void ipwlan_print_usage_rate(int en) { ipwlan_printf(en, "Usage:"IP_LF); ipwlan_printf(en, " wifi rate [] Set/Get rate"IP_LF); ipwlan_printf(en, " rate supp [] Set/Get supported rates"IP_LF); } /* *=========================================================================== * ipwlan_print_usage_regulatory *=========================================================================== * Description: Prints rtsthresh shell command usage * Parameters: 'en' == 0 => No printout to console * Returns: */ IP_STATIC void ipwlan_print_usage_regulatory(int en) { ipwlan_printf(en, "Usage:"IP_LF); ipwlan_printf(en, " wifi regulatory [on|off] Set/Get 802.11d regulatory mode"IP_LF); } /* *=========================================================================== * ipwlan_print_usage_rtsthresh *=========================================================================== * Description: Prints rtsthresh shell command usage * Parameters: 'en' == 0 => No printout to console * Returns: */ IP_STATIC void ipwlan_print_usage_rtsthresh(int en) { ipwlan_printf(en, "Usage:"IP_LF); ipwlan_printf(en, " wifi rtsthresh [] Set/Get rts/cts threshold"IP_LF); } /* *=========================================================================== * ipwlan_print_usage_scan *=========================================================================== * Description: Prints scan shell command usage * Parameters: 'en' == 0 => No printout to console * Returns: */ IP_STATIC void ipwlan_print_usage_scan(int en) { ipwlan_printf(en, "Usage:"IP_LF); ipwlan_printf(en, " wifi scan <1-%ds> [] Scan for , display result"IP_LF, MAX_SCAN_WAITING_TIME); ipwlan_printf(en, " scan mode [active|passive] Set/Get scan mode"IP_LF); } /* *=========================================================================== * ipwlan_print_usage_srl *=========================================================================== * Description: Prints srl shell command usage * Parameters: 'en' == 0 => No printout to console * Returns: */ IP_STATIC void ipwlan_print_usage_srl(int en) { ipwlan_printf(en, "Usage:"IP_LF); ipwlan_printf(en, " wifi srl [] Set/Get short retry limit"IP_LF); } /* *=========================================================================== * ipwlan_print_usage_ssid *=========================================================================== * Description: Prints ssid shell command usage * Parameters: 'en' == 0 => No printout to console * Returns: */ IP_STATIC void ipwlan_print_usage_ssid(int en) { ipwlan_printf(en, "Usage:"IP_LF); ipwlan_printf(en, " wifi ssid [] Set/Get SSID"IP_LF); ipwlan_printf(en, " ssid broadcast [on|off] Set/Get SSID broadcast mode"IP_LF); } /* *=========================================================================== * ipwlan_print_usage_statistics *=========================================================================== * Description: Prints channel shell command usage * Parameters: 'en' == 0 => No printout to console * Returns: */ IP_STATIC void ipwlan_print_usage_statistics(int en) { ipwlan_printf(en, "Usage:"IP_LF); ipwlan_printf(en, " wifi statistics Get system statistics"IP_LF); } /* *=========================================================================== * ipwlan_print_usage_status *=========================================================================== * Description: Prints status shell command usage * Parameters: 'en' == 0 => No printout to console * Returns: */ IP_STATIC void ipwlan_print_usage_status(int en) { ipwlan_printf(en, "Usage:"IP_LF); ipwlan_printf(en, " wifi status Get system status"IP_LF); } /* *=========================================================================== * ipwlan_print_usage_vlan *=========================================================================== * Description: Prints vlan shell command usage * Parameters: 'en' == 0 => No printout to console * Returns: */ IP_STATIC void ipwlan_print_usage_vlan(int en) { ipwlan_printf(en, "Usage:"IP_LF); ipwlan_printf(en, " wifi vlan [] Set/Get current vlan"IP_LF); } /* *=========================================================================== * ipwlan_get_next_iwap *=========================================================================== * Description: Get next AP entry in iw_event list * Parameters: 'iwap' : current AP entry, 'iwap_end' : end of AP list * Returns: next AP entry, or IP_NULL */ IP_STATIC void * ipwlan_get_next_iwap(iw_event *iwap, iw_event *iwap_end) { iw_event *iw; for (iw = NEXT_IWE(iwap); iw < iwap_end; iw = NEXT_IWE(iw)) { if (iw->cmd == SIOCGIWAP) { return iw; } } return IP_NULL; } /* *=========================================================================== * ipwlan_get_next_iwe *=========================================================================== * Description: Get next AP item * Parameters: iwe' : current AP item, 'iwap_end' : end of AP list * Returns: next item, or IP_NULL */ IP_STATIC void * ipwlan_get_next_iwe(iw_event *iwe, iw_event *iwap_end) { iw_event *iw; if (!IS_A_NEXT_IWE(iwe, iwap_end)) { return IP_NULL; } iw = NEXT_IWE(iwe); if (iw < iwap_end && iw->cmd != SIOCGIWAP) { return iw; } return IP_NULL; } /* *=========================================================================== * ipwlan_parse_ether_addr *=========================================================================== * Description: Parse ethernet address from command line * Parameters: 'ea_num' : destination, 'ea_string' : source * Returns: IPCOM_SUCCESS or IPCOM_ERR_FAILED */ IP_STATIC Ip_err ipwlan_parse_ether_addr(char *ea_num, char *ea_string) { int i,j; char *startp; char *endp; i = 0; startp = ipcom_strtok( ea_string, ":" ); while( startp != IP_NULL && i < IP_IW_ADDR_LEN) { j = ipcom_strtol(startp, &endp, 16); ea_num[i] = j; startp = ipcom_strtok( IP_NULL, ":" ); i ++; } if (*endp != '\0' || i < IP_IW_ADDR_LEN) { return IPCOM_ERR_FAILED; } return IPCOM_SUCCESS; } /* *=========================================================================== * ipwlan_parse_key *=========================================================================== * Description: Parse key from command line * Parameters: 'key_iw' : destination, 'key_string' : source * Returns: IPCOM_SUCCESS or IPCOM_ERR_FAILED */ IP_STATIC Ip_err ipwlan_parse_key(Ipcom_iw_key *key_iw, char *key_string) { int j; int k; if (ipcom_strspn(key_string + 2, "0123456789ABCDEFabcdef") != ipcom_strlen(key_string + 2) || ipcom_strlen(key_string + 2) > IP_IW_KEY_TKIP_LEN * 2) { return IPCOM_ERR_FAILED; } for (j = 0; ipcom_sscanf(key_string + 2 + 2 * j, "%2x", &k); j++) { key_iw->key[j] = (unsigned char)k; } key_iw->len = ipcom_strlen(key_string + 2)/2; return IPCOM_SUCCESS; } /* *=========================================================================== * ipwlan_ioctl *=========================================================================== * Description: Call ioctl * Returns: success or failure of ioctl call */ IP_GLOBAL int ipwlan_ioctl(Ip_fd sock, unsigned long request, Ipcom_iwreq *iwreq) { int status; #ifdef IP_PORT_VXWORKS void * pCookie; char * end_name; int end_instance; char if_name[IP_IFNAMSIZ]; #endif #ifdef IP_PORT_VXWORKS end_instance = atoi(iwreq->if_name+strlen(iwreq->if_name)-1); strncpy(if_name, iwreq->if_name, IP_IFNAMSIZ); end_name = ipcom_strtok(if_name,"0123456789"); if (end_name == IP_NULL || strlen(end_name) > IP_IFNAMSIZ) { return IPCOM_ERR_FAILED; } if ((pCookie = muxTkCookieGet(end_name, end_instance)) == IP_NULL) { return IPCOM_ERR_FAILED; } status = muxIoctl(pCookie, (int)request, (char*)iwreq); #else status = ipcom_socketioctl(sock, request, iwreq); #endif return status; } /* **************************************************************************** * 9 PUBLIC FUNCTIONS **************************************************************************** */ /* *=========================================================================== * ipwlan_cmd_wlan_en *=========================================================================== * Description: Parses and executes wlan shell commands. * Parameters: 'en' == 0 => Do not print to console, * Returns: 0 on success */ IP_STATIC int ipwlan_cmd_wlan_en(int en, int argc, char **argv) { int i = 0; int j = 0; int val; int basic; Ip_u8 r; Ip_fd fd; char *endp; char *data; char *startp; char ssid[32+1]; Ipcom_iwreq *iwl; Ipcom_iwreq iwreq; Ipcom_iw_event *iwe; Ipcom_iw_event *iwap, *iwap_end; Ipcom_iw_event iwe_res; Ipcom_iw_debug_level *dbg_lvl; Ipcom_iw_statistic *stat; Ip_u8 auth_known=0; Ipcom_iw_scan_result scanned; unsigned char oid_data[10]; Ip_err ret = IPCOM_SUCCESS; char *status_argv[4]; if (argc < 3) { /* To few arguments */ ipwlan_print_usage(en); return ret; } #ifdef IPCOM_USE_INET fd = ipcom_socket(IP_AF_INET, IP_SOCK_DGRAM, 0); #else fd = ipcom_socket(IP_AF_INET6, IP_SOCK_DGRAM, 0); #endif if (fd == IP_SOCKERR) { ipwlan_printf(en, "Error: unable to create command socket"IP_LF); return IPCOM_ERR_FAILED; } ipcom_memset(&iwreq, 0, sizeof(iwreq)); ipcom_sprintf(iwreq.if_name, "%.*s", IP_IFNAMSIZ - 1, argv[1]); #ifndef IP_PORT_VXWORKS /* Verify interface existance */ if(ipcom_if_nametoindex(iwreq.if_name) < 1) { ipwlan_printf(en, "Error: Interface '%s' does not exist"IP_LF, iwreq.if_name); goto error; } #endif /* Reset WLAN device */ if (!ipcom_strcmp(argv[2], "reset")) { (void)ipwlan_ioctl(fd, IP_SIOCSIWRESET, &iwreq); goto done; } /* Set/Get mode */ if (!ipcom_strcmp(argv[2], "mode")) { if (argc < 4) { if(ipwlan_ioctl(fd, IP_SIOCGIWMODE, &iwreq) < 0) { goto error; } if(iwreq.u.mode == IP_IW_MODE_INFRA) { i = wlan_mode_client_infra; } else if(iwreq.u.mode == IP_IW_MODE_AUTO) { i = wlan_mode_client_auto; } else if(iwreq.u.mode == IP_IW_MODE_ADHOC) { i = wlan_mode_client_adhoc; } else if(iwreq.u.mode == IP_IW_MODE_MASTER) { i = wlan_mode_ap; } else { i = wlan_mode_unknown; } ipwlan_printf(en, "%s"IP_LF, wlan_mode_text[i]); } else { /* Set mode */ if (!strcmp(argv[3], "client")) { if(argc < 5 || (ipcom_strcmp(argv[4], "adhoc") && ipcom_strcmp(argv[4], "auto") && ipcom_strcmp(argv[4], "infra"))) { ipwlan_print_usage_mode(en); goto done; } iwreq.u.mode = !strcmp(argv[4], "auto") ? IP_IW_MODE_AUTO : (!strcmp(argv[4], "infra") ? IP_IW_MODE_INFRA : IP_IW_MODE_ADHOC); } else if (!strcmp(argv[3], "ap")) { iwreq.u.mode = IP_IW_MODE_MASTER; } else { ipwlan_print_usage_mode(en); goto done; } if (ipwlan_ioctl(fd, IP_SIOCSIWMODE, &iwreq) < 0) { goto error; } /* initialize the auth wpa or auth supp based on mode */ if (ipwlan_ioctl(fd, IP_SIOCGIWAUTHTYPE, &iwreq) < 0) { goto error; } if (iwreq.u.auth_type & (IP_IW_AUTHPOL_WPA2|IP_IW_AUTHPOL_WPA|IP_IW_AUTHPOL_WPA_PSK|IP_IW_AUTHPOL_WPA2_PSK) ) { if (!strcmp(argv[3], "ap")) { iwreq.u.wpa_type=1; if (ipwlan_ioctl(fd,IP_SIOCSIWAUTHWPA, &iwreq) < 0) { goto error; } iwreq.u.wpa_type = 0; #ifdef BCM43XXX_SUPWPA_ENABLED if (ipwlan_ioctl(fd,IP_SIOCSIWSUPWPA, &iwreq) < 0) { goto error; } #endif } else { iwreq.u.wpa_type=1; if (ipwlan_ioctl(fd,IP_SIOCSIWSUPWPA, &iwreq) < 0) { goto error; } iwreq.u.wpa_type = 0; if (ipwlan_ioctl(fd,IP_SIOCSIWAUTHWPA, &iwreq) < 0) { goto error; } } } } goto done; } /* Get/Set SSID */ if (!ipcom_strcmp(argv[2], "ssid")) { iwreq.u.essid.pointer = ssid; if (argc > 5) { ipwlan_print_usage_ssid(en); goto done; } if (argc < 4) { /* Get SSID */ iwreq.u.essid.length = sizeof(ssid); ipcom_memset(&ssid, 0, sizeof(ssid)); if (ipwlan_ioctl(fd, IP_SIOCGIWESSID, &iwreq) == 0) { if(ssid[0]) { ipwlan_printf(en, "%s"IP_LF, ssid); } else { ipwlan_printf(en, "SSID not set or client not associated"IP_LF); } goto done; } } else { if (!ipcom_strcmp(argv[3], "broadcast")) { if (argc < 5) { /* Get broadcast ssid capability */ if (ipwlan_ioctl(fd, IP_SIOCGIWHIDESSID, &iwreq) < 0) { goto error; } if (iwreq.u.hidessid == IP_IW_SSID_SHOW) { ipwlan_printf(en, "on"IP_LF); } else if (iwreq.u.hidessid == IP_IW_SSID_HIDE) { ipwlan_printf(en, "off"IP_LF); } else { goto error; } } else { /* Set broadcast SSID capability */ if (!strcmp(argv[4], "off")) { iwreq.u.hidessid = IP_IW_SSID_HIDE; } else if (!strcmp(argv[4], "on")) { iwreq.u.hidessid = IP_IW_SSID_SHOW; } else { ipwlan_print_usage_ssid(en); goto done; } if (ipwlan_ioctl(fd, IP_SIOCSIWHIDESSID, &iwreq) < 0) { goto error; } } goto done; } else if (!ipcom_strcmp(argv[3], "-h")) { ipwlan_print_usage_ssid(en); goto done; } /* Set SSID */ startp = argv[3]; if (!ipcom_strncmp(argv[3], "--",2)) { startp = argv[3] + 2; } iwreq.u.essid.length = ipcom_sprintf(ssid, "%.*s", sizeof(ssid) , startp); if (ipwlan_ioctl(fd, IP_SIOCSIWESSID, &iwreq) == 0) { goto done; } } goto error; } /* Get/Set frequency */ if (!ipcom_strcmp(argv[2], "freq")) { if(argc < 4) { /* Get frequency */ if (ipwlan_ioctl(fd, IP_SIOCGIWFREQ, &iwreq) < 0) { goto error; } ipwlan_printf(en, "%d kHz"IP_LF, iwreq.u.freq.m); } else { /* Set frequency */ if (!strcmp(argv[3], "auto")) { iwreq.u.freq.flags = IP_IW_FREQ_AUTO; iwreq.u.freq.m = WLAN_FREQUENCY_BAND; iwreq.u.freq.e = 0; } else { i = ipcom_strtol(argv[3], &endp, 10); if (*endp != '\0') { ipwlan_printf(en, "Error: invalid frequency value, '%s'"IP_LF, argv[3]); goto done; } iwreq.u.freq.flags = IP_IW_FREQ_FIXED; iwreq.u.freq.m = i; iwreq.u.freq.e = 0; if (ipwlan_ioctl(fd, IP_SIOCSIWFREQ, &iwreq) < 0) { goto error; } } } goto done; } /* Get/Set authentication */ if (!ipcom_strcmp(argv[2], "auth")) { if (argc > 4) { ipwlan_print_usage_auth(en); goto done; } if (argc < 4) { /* Get auth type */ if (ipwlan_ioctl(fd, IP_SIOCGIWAUTHTYPE, &iwreq) < 0) { goto error; } if (iwreq.u.auth_type & IP_IW_AUTHPOL_WPA2_PSK) { auth_known=1; ipwlan_printf(en, "wpa2-psk "); } if (iwreq.u.auth_type & IP_IW_AUTHPOL_WPA2) { auth_known=1; ipwlan_printf(en, "wpa2 "); } if (iwreq.u.auth_type & IP_IW_AUTHPOL_WPA_PSK) { auth_known=1; ipwlan_printf(en, "wpa-psk "); } if (iwreq.u.auth_type & IP_IW_AUTHPOL_WPA) { auth_known=1; ipwlan_printf(en, "wpa "); } if (iwreq.u.auth_type & IP_IW_AUTHPOL_SHARED_KEY) { auth_known=1; ipwlan_printf(en, "shared-key "); } if (iwreq.u.auth_type == IP_IW_AUTHPOL_OPEN) { auth_known=1; ipwlan_printf(en, "open "IP_LF); } ipwlan_printf(en, " "IP_LF); if(!auth_known) { ipwlan_printf(en, "unknown (%d)"IP_LF, iwreq.u.auth_type); goto done; } } else { /* Set authentication policy */ if(ipcom_strcmp(argv[3], "open") == 0) iwreq.u.auth_type = IP_IW_AUTHPOL_OPEN; else if(ipcom_strcmp(argv[3], "shared-key") == 0) iwreq.u.auth_type = IP_IW_AUTHPOL_SHARED_KEY; else if (ipcom_strcmp(argv[3], "wpa2-psk") == 0) iwreq.u.auth_type = IP_IW_AUTHPOL_WPA2_PSK; else if (ipcom_strcmp(argv[3], "wpa2") == 0) iwreq.u.auth_type = IP_IW_AUTHPOL_WPA2; else if (ipcom_strcmp(argv[3], "wpa-psk") == 0) iwreq.u.auth_type = IP_IW_AUTHPOL_WPA_PSK; else if (ipcom_strcmp(argv[3], "wpa") == 0) iwreq.u.auth_type = IP_IW_AUTHPOL_WPA; else { ipwlan_print_usage_auth(en); goto done; } if (ipwlan_ioctl(fd, IP_SIOCSIWAUTHTYPE, &iwreq) < 0) { goto error; } if(ipwlan_ioctl(fd, IP_SIOCGIWMODE, &iwreq) < 0) { ipwlan_printf(en,"Error: could not determine the mode"IP_LF); } if(iwreq.u.mode == IP_IW_MODE_MASTER) { i=0; iwreq.u.wpa_type = 1; if (ipwlan_ioctl(fd,IP_SIOCSIWAUTHWPA, &iwreq) < 0) { goto error; } iwreq.u.wpa_type = 0; if (ipwlan_ioctl(fd,IP_SIOCSIWSUPWPA, &iwreq) < 0) { goto error; } } else { iwreq.u.wpa_type = 1; if (ipwlan_ioctl(fd,IP_SIOCSIWSUPWPA, &iwreq) < 0) { goto error; } iwreq.u.wpa_type = 0; if (ipwlan_ioctl(fd,IP_SIOCSIWAUTHWPA, &iwreq) < 0) { goto error; } } } goto done; } /* Get Multicast encryption */ if (!ipcom_strcmp(argv[2], "mcast_encr")) { if (argc != 3) { ipwlan_print_usage_encr(en); goto done; } if (ipwlan_ioctl(fd, IP_SIOCGIWMCASTENCRTYPE, &iwreq) < 0) { goto error; } for(i = 0; i < (int) (sizeof(ipwlan_encr_policy)/sizeof(ipwlan_encr_policy[0])); i++) { if (ipwlan_encr_policy[i] == iwreq.u.encr_type) { break; } } if (i >= (int) (sizeof(wlan_encr_text)/sizeof(wlan_encr_text[0]))) ipwlan_printf(en, "%s (0x%x)"IP_LF, "unknown", iwreq.u.encr_type); else ipwlan_printf(en, "%s"IP_LF, wlan_encr_text[i]); goto done; } /* Get/Set encryption */ if (!ipcom_strcmp(argv[2], "encr")) { if (argc > 6) { ipwlan_print_usage_encr(en); goto done; } if (argc < 4) { if (ipwlan_ioctl(fd, IP_SIOCGIWENCRTYPE, &iwreq) < 0) { goto error; } for(i = 0; i < (int) (sizeof(ipwlan_encr_policy)/sizeof(ipwlan_encr_policy[0])); i++) { if (ipwlan_encr_policy[i] == iwreq.u.encr_type) { break; } } if (i >= (int) (sizeof(wlan_encr_text)/sizeof(wlan_encr_text[0]))) ipwlan_printf(en, "%s (0x%x)"IP_LF, "unknown", iwreq.u.encr_type); else ipwlan_printf(en, "%s"IP_LF, wlan_encr_text[i]); } else { /* Set encryption parameters */ if (!strcmp(argv[3], "wep")) { if (argc < 5 || argc > 6) { ipwlan_print_usage_encr(en); goto done; } iwreq.u.key.flags = 0; iwreq.u.key.len = 0; i = ipwlan_parse_ether_addr((char *)iwreq.u.key.addr,argv[4]); if (i == IPCOM_ERR_FAILED) { i = ipcom_strtol(argv[4], &endp, 10); if (*endp != '\0' || i < 1 || i > 4) { ipwlan_printf(en, "Error: Invalid index value allowed are 1 to 4" IP_LF); goto done; } iwreq.u.key.flags |= IP_IW_KEY_FLAG_GROUP; iwreq.u.key.index = i - 1; /* Index 1 - 4 */ } else { iwreq.u.key.flags |= IP_IW_KEY_FLAG_PAIR; } if(argc == 6) { if (argv[5][0] == '0' && argv[5][1] == 'x') { ipwlan_parse_key(&iwreq.u.key, argv[5]); } else { /* key is a text string */ iwreq.u.key.len = ipcom_sprintf((char *)iwreq.u.key.key, "%.*s", MIN(sizeof(iwreq.u.key.key) - 1, ipcom_strlen(argv[5])), argv[5]); } } else { iwreq.u.key.flags |= IP_IW_KEY_FLAG_NOKEY; } if (iwreq.u.key.len == IP_IW_KEY_WEP40_LEN) { iwreq.u.key.type = IP_IW_KEY_WEP40_TYPE; } else if (iwreq.u.key.len == IP_IW_KEY_WEP104_LEN) { iwreq.u.key.type = IP_IW_KEY_WEP104_TYPE; } else if (iwreq.u.key.len == IP_IW_KEY_TKIP_LEN) { iwreq.u.key.type = IP_IW_KEY_TKIP_TYPE; } else if (iwreq.u.key.len == IP_IW_KEY_AES_LEN) { iwreq.u.key.type = IP_IW_KEY_AES_TYPE; } if (ipwlan_ioctl(fd, IP_SIOCSIWENCRKEY, &iwreq) < 0) { goto error; } if (iwreq.u.key.len == IP_IW_KEY_WEP40_LEN) { iwreq.u.encr_type = IP_IW_CIPHPOL_WEP40; } else if (iwreq.u.key.len == IP_IW_KEY_WEP104_LEN) { iwreq.u.encr_type = IP_IW_CIPHPOL_WEP104; } if (ipwlan_ioctl(fd, IP_SIOCSIWENCRTYPE, &iwreq) < 0) { goto error; } goto done; } else if (!strcmp(argv[3], "wpa")) { if ( argc != 5 ) { ipwlan_print_usage_encr(en); goto done; } if(argc == 5) { if ((argv[4][0] == '0' && argv[4][1] == 'x') || (argv[4][0] == '0' && argv[4][1] == 'X')) { if((ipcom_strlen(argv[4] + 2) == IP_IW_KEY_WPA_LEN)&&(ipcom_strspn((argv[4]+2), "0123456789ABCDEFabcdef")== IP_IW_KEY_WPA_LEN)) { iwreq.u.key.len = ipcom_sprintf((char *)iwreq.u.key.key, "%.*s", MIN(sizeof(iwreq.u.key.key), ipcom_strlen(argv[4]+2)), argv[4]+2); iwreq.u.key.flags = 0; } else if ((ipcom_strlen(argv[4]) >= 8) && (ipcom_strlen(argv[4]) < IP_IW_KEY_WPA_LEN )) { /*handle 0 x as a passphrase string*/ iwreq.u.key.len = ipcom_sprintf((char *)iwreq.u.key.key, "%.*s", MIN(sizeof(iwreq.u.key.key), ipcom_strlen(argv[4])), argv[4]); iwreq.u.key.flags = IP_IW_KEY_FLAG_PASS; } else { ipwlan_printf(en, "Error: hex string should be 64 characters. (%d)\r\n", ipcom_strlen(argv[4] + 2)); ipwlan_printf(en, "Error: passphrase should be 8-64 characters. (%d)\r\n", ipcom_strlen(argv[4])); goto error; } } else if ((ipcom_strlen(argv[4]) >= 8) && (ipcom_strlen(argv[4]) < IP_IW_KEY_WPA_LEN )) { iwreq.u.key.len = ipcom_sprintf((char *)iwreq.u.key.key, "%.*s", MIN(sizeof(iwreq.u.key.key), ipcom_strlen(argv[4])), argv[4]); iwreq.u.key.flags = IP_IW_KEY_FLAG_PASS; } else { ipwlan_printf(en, "Error: passphrase should be 8-64 characters. (%d)\r\n", ipcom_strlen(argv[4])); goto error; } } #if 0 /* dead code (coverity) */ else { iwreq.u.key.flags = IP_IW_KEY_FLAG_NOKEY; } #endif iwreq.u.key.type = IP_IW_KEY_WPA_TYPE; iwreq.u.key.index = 1; if(iwreq.u.auth_type & (IP_IW_AUTHPOL_WPA_PSK|IP_IW_AUTHPOL_WPA2_PSK) ) { if (ipwlan_ioctl(fd, IP_SIOCSIWPMKKEY, &iwreq) < 0) { goto error; } goto done; } if (ipwlan_ioctl(fd, IP_SIOCSIWPMKKEY, &iwreq) < 0) { goto error; } goto done; } else if (!strcmp(argv[3], "wpa2")) { if (argc != 5) { ipwlan_print_usage_encr(en); goto done; } if(argc == 5) { if ((argv[4][0] == '0' && argv[4][1] == 'x') || (argv[4][0] == '0' && argv[4][1] == 'X')) { if((ipcom_strlen(argv[4] + 2) == IP_IW_KEY_WPA2_LEN)&&(ipcom_strspn((argv[4]+2), "0123456789ABCDEFabcdef")== IP_IW_KEY_WPA2_LEN)) { iwreq.u.key.len = ipcom_sprintf((char *)iwreq.u.key.key, "%.*s", MIN(sizeof(iwreq.u.key.key), ipcom_strlen(argv[4]+2)), argv[4]+2); iwreq.u.key.flags = 0; } else if ((ipcom_strlen(argv[4]) >= 8) && (ipcom_strlen(argv[4]) < IP_IW_KEY_WPA2_LEN )) { /*handle 0 x as a passphrase string*/ iwreq.u.key.len = ipcom_sprintf((char *)iwreq.u.key.key, "%.*s", MIN(sizeof(iwreq.u.key.key), ipcom_strlen(argv[4])), argv[4]); iwreq.u.key.flags = IP_IW_KEY_FLAG_PASS; } else { ipwlan_printf(en, "Error: hex string should be 64 characters. (%d)\r\n", ipcom_strlen(argv[4] + 2)); ipwlan_printf(en, "Error: passphrase should be 8-64 characters. (%d)\r\n", ipcom_strlen(argv[4])); goto error; } } else if ((ipcom_strlen(argv[4]) >= 8) && (ipcom_strlen(argv[4]) < IP_IW_KEY_WPA2_LEN )) { iwreq.u.key.len = ipcom_sprintf((char *)iwreq.u.key.key, "%.*s", MIN(sizeof(iwreq.u.key.key), ipcom_strlen(argv[4])), argv[4]); iwreq.u.key.flags = IP_IW_KEY_FLAG_PASS; } else { ipwlan_printf(en, "Error: passphrase should be 8-64 characters. (%d)\r\n", ipcom_strlen(argv[4])); goto error; } } iwreq.u.key.type = IP_IW_KEY_WPA2_TYPE; iwreq.u.key.index = 1; if (ipwlan_ioctl(fd, IP_SIOCSIWPMKKEY, &iwreq) < 0) { goto error; } else goto done; } else if (!strcmp(argv[3], "none")) { iwreq.u.encr_type = IP_IW_CIPHPOL_NONE; if (ipwlan_ioctl(fd, IP_SIOCSIWENCRTYPE, &iwreq) < 0) { goto error; } } else if (!strcmp(argv[3], "tkip")) { iwreq.u.encr_type = IP_IW_CIPHPOL_TKIP; if (ipwlan_ioctl(fd, IP_SIOCSIWENCRTYPE, &iwreq) < 0) { goto error; } } else if (!strcmp(argv[3], "ccmp")) { iwreq.u.encr_type = IP_IW_CIPHPOL_CCMP; if (ipwlan_ioctl(fd, IP_SIOCSIWENCRTYPE, &iwreq) < 0) { goto error; } } else if (!strcmp(argv[3], "-h")) { ipwlan_print_usage_encr(en); goto done; } else { goto error; } } goto done; } /* Commit changes */ if (!ipcom_strcmp(argv[2], "commit")) { if (ipwlan_ioctl(fd, IP_SIOCSIWCOMMIT, &iwreq) < 0) { goto error; } goto done; } /* Get link quality */ if (!ipcom_strcmp(argv[2], "quality")) { if (argc > 3) { ipwlan_print_usage_quality(en); goto done; } (void)ipwlan_ioctl(fd, IP_SIOCGIWAP, &iwreq); ipcom_memcpy(oid_data, iwreq.u.addr.sa_data, 6); ipcom_memcpy(iwreq.u.quality.bssid, oid_data, 6); if (ipwlan_ioctl(fd, IP_SIOCGIWQUALITY, &iwreq) < 0) { goto error; } ipwlan_printf(en, "\r\nLink quality\r\n============\r\n"); ipwlan_printf(en, "RSSI: % 3d dBm\r\n", (int)iwreq.u.quality.level); ipwlan_printf(en, "Rate: % 3d Mbps\r\n", (unsigned int)iwreq.u.quality.qual); goto done; } if (!ipcom_strcmp(argv[2], "scan")) { if (argc > 5) { ipwlan_print_usage_scan(en); goto error; } if (argc >= 4) { if (!ipcom_strcmp(argv[3], "-h")) { ipwlan_print_usage_scan(en); goto done; } else if (!ipcom_strcmp(argv[3], "mode")) { if (argc < 5) { /* Get scan mode */ if (ipwlan_ioctl(fd, IP_SIOCGIWSCANMODE, &iwreq) < 0) { goto error; } if (iwreq.u.scanmode & IP_IW_SCANMODE_PASSIVE) { ipwlan_printf(en, "passive"); } if (iwreq.u.scanmode & IP_IW_SCANMODE_ACTIVE) { ipwlan_printf(en, "active"); } ipwlan_printf(en, IP_LF); } else { if (!ipcom_strcmp(argv[4], "passive")) { iwreq.u.scanmode = IP_IW_SCANMODE_PASSIVE; } else if (!ipcom_strcmp(argv[4], "active")) { iwreq.u.scanmode = IP_IW_SCANMODE_ACTIVE; } else { ipwlan_printf(en, "Error: Invalid scan mode. (%s)\r\n", argv[4]); goto error; } /* Set scan mode */ if (ipwlan_ioctl(fd, IP_SIOCSIWSCANMODE, &iwreq) < 0) { goto error; } } goto done; } else { val = ipcom_strtol(argv[3], &endp, 10); if (*endp != '\0') { ipwlan_printf(en, "Error: Invalid waiting time. (%s)\r\n", argv[3]); goto error; } if (val > MAX_SCAN_WAITING_TIME || val < 1) { ipwlan_printf(en, "Error: Illegal waiting time. Allowed are 1 - %d)\r\n", val, MAX_SCAN_WAITING_TIME); goto error; } /* Start a scan */ iwreq.u.essid.pointer = ssid; if (argc < 5) { iwreq.u.essid.length = 0; } else { startp = argv[4]; iwreq.u.essid.length = ipcom_sprintf(ssid, "%.*s", sizeof(ssid) - 1, startp); } if (ipwlan_ioctl(fd, IP_SIOCSIWSCAN, &iwreq) < 0) { goto error; } } } else { val = IP_IW_DEFAULT_SCAN_TIME; } /* Allow scan time */ ipcom_millisleep(val * 1000); /* Report scan results */ iwl = ipcom_malloc(sizeof(Ipcom_iwreq) + MAX_IWREQ_LARGE_DATA); if(iwl == IP_NULL) { goto error; } ipcom_memcpy(iwl, &iwreq, sizeof(iwreq)); iwl->u.data.length = MAX_IWREQ_LARGE_DATA; ipcom_memset(&iwe_res, 0, sizeof(Ipcom_iw_event)); if (ipwlan_ioctl(fd, IP_SIOCGIWSCAN, iwl) == 0 && iwl->u.data.length) { iwap = iwl->u.data.pointer; iwap_end = (iw_event *)((char *)iwap + iwl->u.data.length); ipwlan_printf(en, " no bssid type ch rssi noise ssid\r\n"); ipwlan_printf(en, " --|-----------------|-----|---|----|-----|--------------------------------\r\n"); for (i = 0; iwap; iwap = ipwlan_get_next_iwap(iwap, iwap_end), i++) { ipcom_memset(&scanned, 0, sizeof(scanned)); for(iwe = iwap; iwe; iwe = ipwlan_get_next_iwe(iwe, iwap_end)) { if (iwe->cmd == SIOCGIWAP) { scanned.bssid = (unsigned char *)&iwe->u.addr.sa_data; } else if (iwe->cmd == SIOCGIWESSID) { ipcom_memcpy(&iwe_res, iwe, IP_IW_EV_POINT_LEN); scanned.ssid = iwe_res.u.essid.pointer; } else if (iwe->cmd == SIOCGIWMODE) { ipcom_memcpy(&iwe_res, iwe, IP_IW_EV_UINT_LEN); scanned.mode = iwe_res.u.mode; } else if (iwe->cmd == SIOCGIWFREQ) { ipcom_memcpy(&iwe_res, iwe, IP_IW_EV_FREQ_LEN); scanned.channel = iwe_res.u.freq.m; } else if (iwe->cmd == SIOCGIWSPY) { ipcom_memcpy(&iwe_res, iwe, IP_IW_EV_QUAL_LEN); scanned.level = iwe_res.u.quality.level; scanned.noise = iwe_res.u.quality.noise; } } ipwlan_printf(en, " %2d", i); ipwlan_printf(en, " %02x:%02x:%02x:%02x:%02x:%02x", scanned.bssid[0], scanned.bssid[1], scanned.bssid[2], scanned.bssid[3], scanned.bssid[4], scanned.bssid[5]); ipwlan_printf(en, " %s", (scanned.mode == IP_IW_MODE_INFRA) ? "infra" : ((scanned.mode == IP_IW_MODE_ADHOC) ? "adhoc" : " ? ")); ipwlan_printf(en, " %3d", scanned.channel); ipwlan_printf(en, " %3d", scanned.level); ipwlan_printf(en, " %3d", (scanned.noise > 127) ? (128 - scanned.noise): scanned.noise); ipwlan_printf(en, " %.*s\r\n", 32, scanned.ssid); } } ipcom_free(iwl); goto done; } /* Set/Get power management mode */ if (!ipcom_strcmp(argv[2], "pm")) { if (argc > 4) { ipwlan_print_usage_pm(en); goto done; } if(argc < 4) { /* Get power management mode */ if (ipwlan_ioctl(fd, IP_SIOCGIWPOWERMAN, &iwreq) < 0) { goto error; } if (iwreq.u.pm >= 1) { ipwlan_printf(en, "on"IP_LF); } else { ipwlan_printf(en, "off"IP_LF); } } else { /* Set power management mode */ if (!strcmp(argv[3], "on")) { iwreq.u.pm = 1; } else if (!strcmp(argv[3], "off")) { iwreq.u.pm = 0; } else if (!strcmp(argv[3], "-h")) { ipwlan_print_usage_pm(en); goto done; } else { ipwlan_printf(en, "Error: Invalid power management mode. (%s)\r\n", argv[3]); goto error; } if (ipwlan_ioctl(fd, IP_SIOCSIWPOWERMAN, &iwreq) < 0) { goto error; } } goto done; } /* Set/Get channel */ if (!ipcom_strcmp(argv[2], "channel")) { if (argc > 4) { ipwlan_print_usage_channel(en); goto done; } if(argc < 4) { /* Get channel */ if (ipwlan_ioctl(fd, IP_SIOCGIWCHANNEL, &iwreq) < 0) { goto error; } ipwlan_printf(en, "%d"IP_LF,iwreq.u.channel); } else { if (!ipcom_strcmp(argv[3], "-h")) { ipwlan_print_usage_channel(en); goto done; } else if (!ipcom_strcmp(argv[3], "supp")) { if (argc < 5) { /* Get supported channels */ ret = ipwlan_ioctl(fd, IP_SIOCGIWSUPPCHAN, &iwreq); if (ret < 0) { goto error; } ipwlan_printf(en, "["); for (j = 0; j < iwreq.u.suppchan.count; j ++) { ipwlan_printf(en, " %d",iwreq.u.suppchan.chan[j]); } ipwlan_printf(en, " ]"IP_LF); goto done; } } else { /* Set channel */ i = ipcom_strtoul(argv[3], &endp, 10); if (*endp != '\0') { ipwlan_printf(en, "Error: invalid channel value, '%s'"IP_LF, argv[3]); goto error; } iwreq.u.channel = i; if (ipwlan_ioctl(fd, IP_SIOCSIWCHANNEL, &iwreq) < 0) { goto error; } } } goto done; } /* Set/Get long retry limit */ if (!ipcom_strcmp(argv[2], "lrl")) { if (argc > 4) { ipwlan_print_usage_lrl(en); goto done; } if(argc < 4) { /* Get long retry limit */ if (ipwlan_ioctl(fd, IP_SIOCGIWLRL, &iwreq) < 0) { goto error; } ipwlan_printf(en, "%d"IP_LF,iwreq.u.lrl); } else { /* Set long retry limit */ if (!ipcom_strcmp(argv[3], "-h")) { ipwlan_print_usage_lrl(en); goto done; } i = ipcom_strtoul(argv[3], &endp, 10); if (*endp != '\0') { ipwlan_printf(en, "Error: invalid long retry limit value, '%s'"IP_LF, argv[3]); goto error; } iwreq.u.lrl = i; if (ipwlan_ioctl(fd, IP_SIOCSIWLRL, &iwreq) < 0) { goto error; } } goto done; } /* Set/Get short retry limit */ if (!ipcom_strcmp(argv[2], "srl")) { if (argc > 4) { ipwlan_print_usage_srl(en); goto done; } if(argc < 4) { /* Get short retry limit */ if (ipwlan_ioctl(fd, IP_SIOCGIWSRL, &iwreq) < 0) { goto error; } ipwlan_printf(en, "%d"IP_LF,iwreq.u.srl); } else { /* Set short retry limit */ if (!ipcom_strcmp(argv[3], "-h")) { ipwlan_print_usage_srl(en); goto done; } i = ipcom_strtoul(argv[3], &endp, 10); if (*endp != '\0') { ipwlan_printf(en, "Error: invalid short retry limit value, '%s'"IP_LF, argv[3]); goto error; } iwreq.u.srl = i; if (ipwlan_ioctl(fd, IP_SIOCSIWSRL, &iwreq) < 0) { goto error; } } goto done; } /* Set/Get beacon interval */ if (!ipcom_strcmp(argv[2], "bi")) { if (argc > 4) { ipwlan_print_usage_bi(en); goto done; } if(argc < 4) { /* Get beacon interval */ if (ipwlan_ioctl(fd, IP_SIOCGIWBEACONINT, &iwreq) < 0) { goto error; } ipwlan_printf(en, "%d (us)"IP_LF,iwreq.u.bi); } else { /* Set beacon interval */ if (!ipcom_strcmp(argv[3], "-h")) { ipwlan_print_usage_bi(en); goto done; } i = ipcom_strtoul(argv[3], &endp, 10); if (*endp != '\0') { ipwlan_printf(en, "Error: invalid beacon interval, '%s'"IP_LF, argv[3]); goto error; } iwreq.u.bi = i; if (ipwlan_ioctl(fd, IP_SIOCSIWBEACONINT, &iwreq) < 0) { goto error; } } goto done; } /* Set/Get current/supported rates */ if (!ipcom_strcmp(argv[2], "rate")) { if (argc > 5) { ipwlan_print_usage_rate(en); goto done; } if(argc < 4) { /* Get current rate */ if (ipwlan_ioctl(fd, IP_SIOCGIWRATE, &iwreq) < 0) { goto error; } ipwlan_printf(en, "%d Mbps"IP_LF,iwreq.u.rate/2); } else { if (!ipcom_strcmp(argv[3], "supp")) { if (argc < 5) { /* Get supported rates */ if (ipwlan_ioctl(fd, IP_SIOCGIWSUPPRATES, &iwreq) < 0) { goto error; } ipwlan_printf(en, "["); for (j = 0; j < iwreq.u.supprates.count; j ++) { if ((i = iwreq.u.supprates.rates[j] & 0x7f) == 0) { break; } ipwlan_printf(en, " %d",i/2); if (i%2) { ipwlan_printf(en, ".5"); } if (iwreq.u.supprates.rates[j] & 0x80) { ipwlan_printf(en, "(b)"); } } ipwlan_printf(en, " ]"IP_LF); goto done; } else { /* Set supported rates */ basic = 0; iwreq.u.supprates.count = 0; for (j = 4; j < IP_IW_MAX_RATES+4; j ++) { if (argv[j] == IP_NULL) { break; } /* convert the rate number to a 500kbps rate by multiplying by 2 */ r = (ipcom_strtoul(argv[j], &endp, 10) & 0x7f) * 2; if (endp == argv[j]) { ipwlan_printf(en, "Error: invalid rate, '%s'"IP_LF, argv[j]); goto error; } if (!ipcom_strcmp(endp, ".5")) { r += 1; } /* check for a basic rate specifier */ if (!ipcom_strcmp(endp, "b")) { basic = 1; r |= 0x80; } iwreq.u.supprates.rates[j-4] = r; iwreq.u.supprates.count ++; } if (basic == 0) { ipwlan_printf(en, "Error: no rates marked as basic (b)\n"); goto error; } else { if (ipwlan_ioctl(fd, IP_SIOCSIWSUPPRATES, &iwreq) < 0) { goto error; } goto done; } } /*goto done;*/ } else if (!ipcom_strcmp(argv[3], "-h")) { ipwlan_print_usage_rate(en); goto done; } /* Set current rate */ i = ipcom_strtoul(argv[3], &endp, 10); if (*endp != '\0') { ipwlan_printf(en, "Error: invalid rate, '%s'"IP_LF, argv[3]); goto error; } iwreq.u.rate = i; if (ipwlan_ioctl(fd, IP_SIOCSIWRATE, &iwreq) < 0) { goto error; } } goto done; } /* Set/Get fragmentation threshold */ if (!ipcom_strcmp(argv[2], "fragthresh")) { if (argc > 4) { ipwlan_print_usage_fragthresh(en); goto done; } if(argc < 4) { /* Get fragmentation threshold */ if (ipwlan_ioctl(fd, IP_SIOCGIWFRAGTHRESH, &iwreq) < 0) { goto error; } ipwlan_printf(en, "%d"IP_LF,iwreq.u.fragthresh); } else { /* Set fragmentation threshold */ if (!ipcom_strcmp(argv[3], "-h")) { ipwlan_print_usage_fragthresh(en); goto done; } i = ipcom_strtoul(argv[3], &endp, 10); if (*endp != '\0') { ipwlan_printf(en, "Error: invalid fragmentation threshold, '%s'"IP_LF, argv[3]); goto error; } iwreq.u.fragthresh = i; if (ipwlan_ioctl(fd, IP_SIOCSIWFRAGTHRESH, &iwreq) < 0) { goto error; } } goto done; } /* Set/Get rts/cts threshold */ if (!ipcom_strcmp(argv[2], "rtsthresh")) { if (argc > 4) { ipwlan_print_usage_rtsthresh(en); goto done; } if(argc < 4) { /* Get rts/cts threshold */ if (ipwlan_ioctl(fd, IP_SIOCGIWRTSTHRESH, &iwreq) < 0) { goto error; } ipwlan_printf(en, "%d"IP_LF,iwreq.u.rtsthresh); } else { /* Set rts/cts threshold */ if (!ipcom_strcmp(argv[3], "-h")) { ipwlan_print_usage_rtsthresh(en); goto done; } i = ipcom_strtoul(argv[3], &endp, 10); if (*endp != '\0') { ipwlan_printf(en, "Error: invalid RTS/CTS threshold, '%s'"IP_LF, argv[3]); goto error; } iwreq.u.rtsthresh = i; if (ipwlan_ioctl(fd, IP_SIOCSIWRTSTHRESH, &iwreq) < 0) { goto error; } } goto done; } /* Set/Get 802.11 radio mode */ if (!ipcom_strcmp(argv[2], "radiomode")) { if (argc > 6) { ipwlan_print_usage_radiomode(en); goto done; } if(argc < 4) { /* Get radio mode */ if (ipwlan_ioctl(fd, IP_SIOCGIWRADIOMODE, &iwreq) < 0) { goto error; } i = iwreq.u.radiomode; if ( (i & IP_IW_RADIOMODE_11B) && (i & IP_IW_RADIOMODE_11G)) { ipwlan_printf(en, "Auto "); } else { if (i & IP_IW_RADIOMODE_11A) { ipwlan_printf(en, "a "); } if (i & IP_IW_RADIOMODE_11B) { ipwlan_printf(en, "b "); } if (i & IP_IW_RADIOMODE_11G) { ipwlan_printf(en, "g "); } } /* Get existing 802.11n rate settings */ iwreq.u.nmode.status = 0; (void)ipwlan_ioctl(fd, IP_SIOCGIWRADIONSTAT, &iwreq); if (iwreq.u.nmode.status == 1) { ipwlan_printf(en, ", n "); } else { ret = 0; } ipwlan_printf(en, IP_LF); goto done; } else { /* Set radio mode */ i = 0; if (!ipcom_strcmp(argv[3], "-h")) { ipwlan_print_usage_radiomode(en); goto done; } else if (!ipcom_strcmp(argv[3], "auto")) { i |= IP_IW_RADIOMODE_11G | IP_IW_RADIOMODE_11B | IP_IW_RADIOMODE_11A | IP_IW_RADIOMODE_11N; } else if (!ipcom_strcmp(argv[3], "a")) { i |= IP_IW_RADIOMODE_11A; } else if (!ipcom_strcmp(argv[3], "b")) { i |= IP_IW_RADIOMODE_11B; } else if (!ipcom_strcmp(argv[3], "g")) { i |= IP_IW_RADIOMODE_11G; } else if (!ipcom_strcmp(argv[3], "n")) { i |= IP_IW_RADIOMODE_11N; if (argc < 5) { /* Get existing 802.11n rate settings */ if (ipwlan_ioctl(fd, IP_SIOCGIWRADIONRATE, &iwreq) < 0) { goto error; } if (iwreq.u.nmode.legacymode == IP_FALSE) { ipwlan_printf(en, " Modulation Control Scheme index: %d"IP_LF,iwreq.u.nmode.mcs); ipwlan_printf(en, " Legacy rate: N/A"IP_LF); } else { ipwlan_printf(en, " Modulation Control Scheme index: N/A"IP_LF); ipwlan_printf(en, " Legacy rate: %d"IP_LF,iwreq.u.nmode.legacyrate); } ipwlan_printf(en, " Spacial Diversity method: "); if (iwreq.u.nmode.std == IP_IW_MIMO_STD_SISO) { ipwlan_printf(en, "SISO (Single Input Single Output)"IP_LF); } else if (iwreq.u.nmode.std == IP_IW_MIMO_STD_CDD) { ipwlan_printf(en, "CDD (Cyclic Delay Diversity)"IP_LF); } else if (iwreq.u.nmode.std == IP_IW_MIMO_STD_STBC) { ipwlan_printf(en, "STBC (Space-Time Block Codes)"IP_LF); } else if (iwreq.u.nmode.std == IP_IW_MIMO_STD_SDM) { ipwlan_printf(en, "SDM (Space Division Multiplexing)"IP_LF); } /* Get existing 802.11n rate settings */ if (ipwlan_ioctl(fd, IP_SIOCGIWRADIONSTAT, &iwreq) < 0) { goto error; } ipwlan_printf(en, " Status: "); if (iwreq.u.nmode.status == 1) { ipwlan_printf(en, "enabled"IP_LF); } else { ipwlan_printf(en, " disabled"IP_LF); } goto done; } else { /* Get modulation/coding and spacial diversity settings */ if (ipwlan_ioctl(fd, IP_SIOCGIWRADIONRATE, &iwreq) < 0) { goto error; } if (!ipcom_strcmp(argv[4], "mcs")) { if (argc < 6) { ipwlan_printf(en, "mcs: %d std: %d"IP_LF, iwreq.u.nmode.mcs, iwreq.u.nmode.std); goto done; } else { /* Set modulation and coding scheme */ r = ipcom_strtoul(argv[5], &endp, 10); if (*endp != '\0') { ipwlan_printf(en, "Error: invalid mcs, '%s'"IP_LF, argv[5]); goto error; } iwreq.u.nmode.mcs = r; if (argc > 6) { if (!ipcom_strcmp(argv[6], "std")) { r = ipcom_strtoul(argv[7], &endp, 10); if (*endp != '\0') { ipwlan_printf(en, "Error: invalid std, '%s'"IP_LF, argv[7]); goto error; } iwreq.u.nmode.std = r; } } iwreq.u.nmode.legacymode = IP_FALSE; if (ipwlan_ioctl(fd, IP_SIOCSIWRADIONRATE, &iwreq) < 0) { goto error; } goto done; } } else if (!ipcom_strcmp(argv[4], "std")) { if (argc < 6) { /* Get space time diversity scheme */ if (ipwlan_ioctl(fd, IP_SIOCGIWRADIONRATE, &iwreq) < 0) { goto error; } ipwlan_printf(en, "std: %d"IP_LF, iwreq.u.nmode.std); goto done; } else { /* First, get mcs */ if (ipwlan_ioctl(fd, IP_SIOCGIWRADIONRATE, &iwreq) < 0) { goto error; } /* Set space time diversity scheme */ r = ipcom_strtoul(argv[5], &endp, 10); if (*endp != '\0') { ipwlan_printf(en, "Error: invalid std, '%s'"IP_LF, argv[5]); goto error; } iwreq.u.nmode.std = r; iwreq.u.nmode.legacymode = IP_FALSE; if (ipwlan_ioctl(fd, IP_SIOCSIWRADIONRATE, &iwreq) < 0) { goto error; } goto done; } } else if (!ipcom_strcmp(argv[4], "legacy")) { if (argc < 6) { /* Get legacy rate */ if (ipwlan_ioctl(fd, IP_SIOCGIWRADIONRATE, &iwreq) < 0) { goto error; } if (iwreq.u.nmode.legacymode == IP_TRUE) { ipwlan_printf(en, "%d", iwreq.u.nmode.legacyrate); } else { ipwlan_printf(en, "disabled"IP_LF); } goto done; } else { /* Set legacy rate */ /* convert the rate number to a 500kbps rate */ /* r = ipcom_strtoul(argv[5], &endp, 10) & 0x7f * 2; */ r = ipcom_strtoul(argv[5], &endp, 10) * 2; if (endp == argv[5]) { ipwlan_printf(en, "Error: invalid rate, '%s'"IP_LF, argv[5]); goto error; } if (!ipcom_strcmp(endp, ".5")) { r += 1; } iwreq.u.nmode.legacyrate = r; iwreq.u.nmode.legacymode = IP_TRUE; if (ipwlan_ioctl(fd, IP_SIOCSIWRADIONRATE, &iwreq) < 0) { goto error; } goto done; } } else if (!ipcom_strcmp(argv[4], "on")) { /* Enable 802.11n capabilities */ iwreq.u.nmode.status = 1; if (ipwlan_ioctl(fd, IP_SIOCSIWRADIONSTAT, &iwreq) < 0) { goto error; } goto done; } else if (!ipcom_strcmp(argv[4], "off")) { /* Disable 802.11n capabilities */ iwreq.u.nmode.status = 0; if (ipwlan_ioctl(fd, IP_SIOCSIWRADIONSTAT, &iwreq) < 0) { goto error; } goto done; } else if (!ipcom_strcmp(argv[4], "bw")) { /* get/set mimo txbw (2=20Mhz(lower), 3=20Mhz upper, 4=40Mhz, 5=40Mhz dup 5) { ipwlan_print_usage_acl(en); goto done; } if (argc < 4) { /* Get Access control list */ iwl = ipcom_malloc(sizeof(Ipcom_iwreq) + MAX_IWREQ_LARGE_DATA); if(iwl == IP_NULL) { goto error; } ipcom_memcpy(iwl, &iwreq, sizeof(iwreq)); iwl->u.data.length = MAX_IWREQ_LARGE_DATA; ipcom_memset(&iwe_res, 0, sizeof(Ipcom_iw_event)); if (ipwlan_ioctl(fd, IP_SIOCGIWACL, iwl) == 0 && iwl->u.data.length) { iwap = iwl->u.data.pointer; iwap_end = (iw_event *)((char *)iwap + iwl->u.data.length); ipwlan_printf(en, " no|bssid \r\n"); ipwlan_printf(en, " --|-----------------|\r\n"); for (i = 0; iwap; iwap = ipwlan_get_next_iwap(iwap, iwap_end), i++) { ipcom_memset(&scanned, 0, sizeof(scanned)); for(iwe = iwap; iwe; iwe = ipwlan_get_next_iwe(iwe, iwap_end)) { if (iwe->cmd == SIOCGIWAP) { scanned.bssid = (unsigned char *)&iwe->u.addr.sa_data; } } ipwlan_printf(en, " %2d", i); ipwlan_printf(en, " %02x:%02x:%02x:%02x:%02x:%02x"IP_LF, scanned.bssid[0], scanned.bssid[1], scanned.bssid[2], scanned.bssid[3], scanned.bssid[4], scanned.bssid[5]); } } ipcom_free(iwl); goto done; } else { if (!ipcom_strcmp(argv[3], "mode")) { if (argc < 5) { /* Get access control mode */ if (ipwlan_ioctl(fd, IP_SIOCGIWACLMODE, &iwreq) < 0) { goto error; } if (iwreq.u.aclmode == IP_IW_ACL_NONE) { ipwlan_printf(en, "disabled"IP_LF); } else if (iwreq.u.aclmode == IP_IW_ACL_ALLOW) { ipwlan_printf(en, "allow"IP_LF); } else if (iwreq.u.aclmode == IP_IW_ACL_DENY) { ipwlan_printf(en, "deny"IP_LF); } goto done; } else { /* Set access control list mode */ if (!ipcom_strcmp(argv[4], "allow")) { iwreq.u.aclmode = IP_IW_ACL_ALLOW; } else if (!ipcom_strcmp(argv[4], "deny")) { iwreq.u.aclmode = IP_IW_ACL_DENY; } if (ipwlan_ioctl(fd, IP_SIOCSIWACLMODE, &iwreq) < 0) { goto error; } } goto done; } else if (!ipcom_strcmp(argv[3], "add")) { (void)ipwlan_parse_ether_addr(iwreq.u.addr.sa_data, argv[4]); if (ipwlan_ioctl(fd, IP_SIOCSIWACLADD, &iwreq) < 0) { goto error; } goto done; } else if (!ipcom_strcmp(argv[3], "del")) { (void)ipwlan_parse_ether_addr(iwreq.u.addr.sa_data, argv[4]); if (ipwlan_ioctl(fd, IP_SIOCSIWACLDEL, &iwreq) < 0) { goto error; } goto done; } else { ipwlan_print_usage_acl(en); goto done; } } /*goto error;*/ } /* Set/Get power scale factor */ if (!ipcom_strcmp(argv[2], "ps")) { if (argc > 4) { ipwlan_print_usage_ps(en); goto done; } if(argc < 4) { /* Get power scale factor */ if (ipwlan_ioctl(fd, IP_SIOCGIWPOWERSCALE, &iwreq) < 0) { goto error; } if (iwreq.u.ps >= 1) { ipwlan_printf(en, "%d"IP_LF, iwreq.u.ps); } else { ipwlan_printf(en, "%d"IP_LF, iwreq.u.ps); } } else { /* Set power scale factor */ if (!ipcom_strcmp(argv[3], "-h")) { ipwlan_print_usage_ps(en); goto done; } i = ipcom_strtoul(argv[3], &endp, 10); if (endp == '\0' || i < 0 || i > 100) { ipwlan_printf(en, "Error: invalid powerscale factor, '%s'"IP_LF, argv[3]); goto error; } iwreq.u.pm = i; if (ipwlan_ioctl(fd, IP_SIOCSIWPOWERSCALE, &iwreq) < 0) { goto error; } } goto done; } /* Set/Get country code */ if (!ipcom_strcmp(argv[2], "country")) { if (argc > 4) { ipwlan_print_usage_country(en); goto done; } if(argc < 4) { /* Get country code */ if (ipwlan_ioctl(fd, IP_SIOCGIWCOUNTRYCODE, &iwreq) < 0) { goto error; } ipwlan_printf(en, "%d"IP_LF, iwreq.u.countrycode); } else { /* Set country code */ if (!ipcom_strcmp(argv[3], "-h")) { ipwlan_print_usage_country(en); goto done; } i = ipcom_strtoul(argv[3], &endp, 10); if (endp == '\0' || i < 0) { ipwlan_printf(en, "Error: invalid country code, '%s'"IP_LF, argv[3]); goto error; } iwreq.u.countrycode = i; if (ipwlan_ioctl(fd, IP_SIOCSIWCOUNTRYCODE, &iwreq) < 0) { goto error; } } goto done; } /* Set/Get/Create bss */ if (!ipcom_strcmp(argv[2], "bss")) { if (argc > 5) { ipwlan_print_usage_bss(en); goto done; } if(argc < 4) { /* Get current bss index */ if (ipwlan_ioctl(fd, IP_SIOCGIWBSSINDEX, &iwreq) < 0) { goto error; } ipwlan_printf(en, "%d"IP_LF,iwreq.u.bssindex); } else { if (!ipcom_strcmp(argv[3], "add")) { /* Add BSS */ if (ipwlan_ioctl(fd, IP_SIOCSIWBSSADD, &iwreq) < 0) { goto error; } } else if (!ipcom_strcmp(argv[3], "del")) { /* Del BSS */ i = ipcom_strtoul(argv[4], &endp, 10); if (*endp != '\0') { ipwlan_printf(en, "Error: invalid bss index, '%s'"IP_LF, argv[4]); goto error; } iwreq.u.bssindex = i; if (ipwlan_ioctl(fd, IP_SIOCSIWBSSDEL, &iwreq) < 0) { goto error; } } else if (!ipcom_strcmp(argv[3], "-h")) { ipwlan_print_usage_bss(en); goto done; } else { /* Set bss index*/ i = ipcom_strtoul(argv[3], &endp, 10); if (*endp != '\0') { ipwlan_printf(en, "Error: invalid bss index, '%s'"IP_LF, argv[3]); goto error; } iwreq.u.bssindex = i; if (ipwlan_ioctl(fd, IP_SIOCSIWBSSINDEX, &iwreq) < 0) { goto error; } } } goto done; } /* Enable / Disable 802.11d regulatory mode */ if (!ipcom_strcmp(argv[2], "regulatory")) { if (argc > 4) { ipwlan_print_usage_regulatory(en); goto done; } if(argc < 4) { /* Get current regulatory mode */ if (ipwlan_ioctl(fd, IP_SIOCGIWREGMODE, &iwreq) < 0) { goto error; } if (iwreq.u.regmode == 0) { ipwlan_printf(en, "off"IP_LF); } else { ipwlan_printf(en, "on"IP_LF); } } else { /* Set regulatory mode */ if (!ipcom_strcmp(argv[3], "on")) { iwreq.u.regmode = 1; } else if (!ipcom_strcmp(argv[3], "off")) { iwreq.u.regmode = 0; } else { ipwlan_print_usage_regulatory(en); goto done; } if (ipwlan_ioctl(fd, IP_SIOCSIWREGMODE, &iwreq) < 0) { goto error; } } goto done; } /* Get overall system status */ if (!ipcom_strcmp(argv[2], "status")) { if(argc < 4) { /* Call every ioctl to retrieve system status */ /* general */ status_argv[0] = "wifi"; status_argv[1] = iwreq.if_name; /* mode */ status_argv[2] = "mode"; ipwlan_printf(en, "Mode: "); ipwlan_cmd_wlan_en(en, 3, status_argv); /* ssid */ status_argv[2] = "ssid"; ipwlan_printf(en, "SSID: "); ipwlan_cmd_wlan_en(en, 3, status_argv); /* channel */ status_argv[2] = "channel"; ipwlan_printf(en, "Channel: "); ipwlan_cmd_wlan_en(en, 3, status_argv); /* radio mode */ status_argv[2] = "radiomode"; ipwlan_printf(en, "Current Radio Mode: "); ipwlan_cmd_wlan_en(en, 3, status_argv); /* radio mode n enabled */ status_argv[2] = "radiomode"; status_argv[3] = "n"; ipwlan_printf(en, "802.11n: "IP_LF); ipwlan_cmd_wlan_en(en, 4, status_argv); /* rate */ status_argv[2] = "rate"; ipwlan_printf(en, "Rate: "); ipwlan_cmd_wlan_en(en, 3, status_argv); /* encryption type */ status_argv[2] = "encr"; ipwlan_printf(en, "Unicast Encryption type: "); ipwlan_cmd_wlan_en(en, 3, status_argv); /* encryption type */ status_argv[2] = "mcast_encr"; ipwlan_printf(en, "Multicast Encryption type: "); ipwlan_cmd_wlan_en(en, 3, status_argv); /* auth type */ status_argv[2] = "auth"; ipwlan_printf(en, "Authentication Type: "); ipwlan_cmd_wlan_en(en, 3, status_argv); /* country code */ status_argv[2] = "country"; ipwlan_printf(en, "Country Code: "); ipwlan_cmd_wlan_en(en, 3, status_argv); /* power scale */ status_argv[2] = "ps"; ipwlan_printf(en, "Power Scale Factor: "); ipwlan_cmd_wlan_en(en, 3, status_argv); /* fragthresh */ status_argv[2] = "fragthresh"; ipwlan_printf(en, "Fragmentation Threshold: "); ipwlan_cmd_wlan_en(en, 3, status_argv); /* rtsthresh */ status_argv[2] = "rtsthresh"; ipwlan_printf(en, "RTS/CTS Threshold: "); ipwlan_cmd_wlan_en(en, 3, status_argv); /* srl */ status_argv[2] = "srl"; ipwlan_printf(en, "Short Retry Limit: "); ipwlan_cmd_wlan_en(en, 3, status_argv); /* lrl */ status_argv[2] = "lrl"; ipwlan_printf(en, "Long Retry Limit: "); ipwlan_cmd_wlan_en(en, 3, status_argv); if(ipwlan_ioctl(fd, IP_SIOCGIWMODE, &iwreq) < 0) { goto error; } /* Station only features */ if(iwreq.u.mode == IP_IW_MODE_INFRA || iwreq.u.mode == IP_IW_MODE_AUTO || iwreq.u.mode == IP_IW_MODE_ADHOC) { status_argv[2] = "scan"; status_argv[3] = "mode"; ipwlan_printf(en, "Scan Mode: "); ipwlan_cmd_wlan_en(en, 4, status_argv); /* pm */ status_argv[2] = "pm"; ipwlan_printf(en, "Power Management: "); ipwlan_cmd_wlan_en(en, 3, status_argv); } /* AP / Adhoc only features */ else if(iwreq.u.mode == IP_IW_MODE_ADHOC || iwreq.u.mode == IP_IW_MODE_MASTER) { /* broadcast ssid */ status_argv[2] = "ssid"; status_argv[3] = "broadcast"; ipwlan_printf(en, "Broadcast SSID: "); ipwlan_cmd_wlan_en(en, 4, status_argv); /* beacon interval */ status_argv[2] = "bi"; ipwlan_printf(en, "Beacon Interval: "); ipwlan_cmd_wlan_en(en, 3, status_argv); /* bss index */ status_argv[2] = "bss"; ipwlan_printf(en, "Current BSS: "); ipwlan_cmd_wlan_en(en, 3, status_argv); /* acl list */ status_argv[2] = "acl"; ipwlan_printf(en, "Access Control List: "IP_LF); ipwlan_cmd_wlan_en(en, 3, status_argv); /* 802.11d enabled */ status_argv[2] = "regulatory"; ipwlan_printf(en, "802.11d Regulatory Mode: "); ipwlan_cmd_wlan_en(en, 3, status_argv); } } else { if (!ipcom_strcmp(argv[3], "-h")) { ipwlan_print_usage_status(en); goto done; } } goto done; } /* Set/Get debug level */ if (!ipcom_strcmp(argv[2], "debug")) { if(argc < 4) { /* Get current debug level */ if (ipwlan_ioctl(fd, IP_SIOCGIWDEBUGLEVEL, &iwreq) < 0) { goto error; } ipwlan_printf(en, "0x%08x"IP_LF,iwreq.u.debuglevel); } else { if (!ipcom_strcmp(argv[3], "-h")) { /* Get debug options*/ if (ipwlan_ioctl(fd, IP_SIOCGIWDEBUGOPTIONS, &iwreq) < 0) { goto error; } data = (char *)&iwreq.u.data.pointer; for (i=0; i < IP_IW_MAX_DEBUG_LEVELS; i++) { dbg_lvl = (Ipcom_iw_debug_level *)data; if (dbg_lvl->value == IP_NULL && dbg_lvl->description == IP_NULL) { break; } ipwlan_printf(en, "0x%08x: %s"IP_LF, dbg_lvl->value,dbg_lvl->description); data += sizeof(Ipcom_iw_debug_level); } } else { /* Set debug level */ if (argv[3][0] == '0' && argv[3][1] == 'x') { i = ipcom_strtol(argv[3]+2, &endp, 16); if (*endp != '\0') { ipwlan_printf(en, "Error: invalid debug level, '%s'"IP_LF, argv[3]); goto error; } } else { ipwlan_printf(en, "Error: invalid debug level, '%s'"IP_LF, argv[3]); } iwreq.u.debuglevel = i; if (ipwlan_ioctl(fd, IP_SIOCSIWDEBUGLEVEL, &iwreq) < 0) { goto error; } } } goto done; } /* Get system statistics */ if (!ipcom_strcmp(argv[2], "statistics")) { if(argc < 4) { iwl = ipcom_malloc(sizeof(Ipcom_iwreq) + MAX_IWREQ_LARGE_DATA); if(iwl == IP_NULL) { goto error; } ipcom_memcpy(iwl, &iwreq, sizeof(iwreq)); iwl->u.data.length = MAX_IWREQ_LARGE_DATA; if (ipwlan_ioctl(fd, IP_SIOCGIWSTATISTICS, iwl) < 0) { goto error; } data = iwl->u.data.pointer; for (i=0; i < IP_IW_MAX_STATISTICS; i++) { stat = (Ipcom_iw_statistic *)data; if (stat->value == IP_NULL && stat->description == IP_NULL) { break; } ipwlan_printf(en, "%s: %lld"IP_LF,stat->description,stat->value); data += sizeof(Ipcom_iw_statistic); } ipcom_free(iwl); } else { if (!ipcom_strcmp(argv[3], "-h")) { ipwlan_print_usage_statistics(en); goto done; } } goto done; } /* Set/Get/Create vlan */ if (!ipcom_strcmp(argv[2], "vlan")) { if (argc > 4) { ipwlan_print_usage_vlan(en); goto done; } if(argc < 4) { /* Get current bss index */ if (ipwlan_ioctl(fd, IP_SIOCGIWVLAN, &iwreq) < 0) { goto error; } ipwlan_printf(en, "%d"IP_LF,iwreq.u.vlan); } else { /* Set vlan */ if (!ipcom_strcmp(argv[3], "-h")) { ipwlan_print_usage_vlan(en); goto done; } i = ipcom_strtoul(argv[3], &endp, 10); if (*endp != '\0') { ipwlan_printf(en, "Error: invalid vlan, '%s'"IP_LF, argv[3]); goto error; } iwreq.u.vlan = i; if (ipwlan_ioctl(fd, IP_SIOCSIWVLAN, &iwreq) < 0) { goto error; } } goto done; } /* Turn On/Off Multiple ssid */ if (!ipcom_strcmp(argv[2], "mbss")) { if (argc > 4) { ipwlan_print_usage_mbss(en); goto done; } if(argc < 4) { /* Get current bss index */ if (ipwlan_ioctl(fd, IP_SIOCGIWMBSS, &iwreq) < 0) { goto error; } if (iwreq.u.mbss == 0) { ipwlan_printf(en, "off"IP_LF); } else { ipwlan_printf(en, "on"IP_LF); } } else { if (!strcmp(argv[3], "on")) { /* Turn on mssid */ iwreq.u.mbss = 1; if (ipwlan_ioctl(fd, IP_SIOCSIWMBSS, &iwreq) < 0) { goto error; } } else if (!strcmp(argv[3], "off")) { /* Turn off mssid */ iwreq.u.mbss = 0; if (ipwlan_ioctl(fd, IP_SIOCSIWMBSS, &iwreq) < 0) { goto error; } } else { ipwlan_print_usage_mbss(en); goto done; } } goto done; } /* wmm: wme on/off */ if (!ipcom_strcmp(argv[2], "wme")) { if (argc > 4) { ipwlan_print_usage_wme(en); goto done; } if(argc < 4) { /* Get current wme status */ if (ipwlan_ioctl(fd, IP_SIOCGIWMM, &iwreq) < 0) { goto error; } if (iwreq.u.wme == 0) { ipwlan_printf(en, "off"IP_LF); } else if((int)iwreq.u.wme == -1) { ipwlan_printf(en, "auto"IP_LF); } else if(iwreq.u.wme == 1 ) { ipwlan_printf(en, "on"IP_LF); } else { ipwlan_printf(en, "unknown"IP_LF); } } else { if (!ipcom_strcmp(argv[3], "on")) { /* Turn on mssid */ iwreq.u.wme = 1; if (ipwlan_ioctl(fd,IP_SIOCSIWMM, &iwreq) < 0) { goto error; } } else if (!ipcom_strcmp(argv[3], "off")) { /* Turn off mssid */ iwreq.u.wme = 0; if (ipwlan_ioctl(fd, IP_SIOCSIWMM, &iwreq) < 0) { goto error; } } else { ipwlan_print_usage_wme(en); goto done; } } goto done; } /* wme: access category get for ap/sta */ if (!ipcom_strcmp(argv[2], "wme_ac")) { int count =0; if (argc > 4 || argc < 4) { ipwlan_print_usage_wmeac(en); goto done; } if(argc < 5) { /* Get current ap/sta wme edcf parameter*/ if (!ipcom_strcmp(argv[3], "ap")) { iwreq.u.value32=1; /* getting parameter for ap */ } else if(!ipcom_strcmp(argv[3], "sta")) { iwreq.u.value32=0; /* getting parameter for sta*/ } else { ipwlan_print_usage_wmeac(en); goto done; } if (ipwlan_ioctl(fd,IP_SIOCGIWMMAC, &iwreq) < 0) { goto error; } ipwlan_printf(en, "\taci\tacm\taifsn\tecwmin\tecwmax\ttxop"IP_LF); for (count = 0; count < IP_IW_AC_COUNT; count++) { ipwlan_printf(en, "\t%s\t%d\t%d\t%d\t%d\t0x%x"IP_LF, IP_IW_WMM_AC_CATEGORY[count],iwreq.u.edcf[count].acm,iwreq.u.edcf[count].aifsn,iwreq.u.edcf[count].ecwmin, iwreq.u.edcf[count].ecwmax,iwreq.u.edcf[count].txop); } } goto done; } error: ipwlan_printf(en, "Error: command %s failed"IP_LF, argv[2]); ret = IPCOM_ERR_FAILED; done: (void)ipcom_socketclose(fd); return ret; } /* *=========================================================================== * ipwlan_cmd_wlan *=========================================================================== * Description: Executes shell commands. Prints output to console * Parameters: * Returns: Non-zero on failure */ IP_PUBLIC int ipwlan_cmd_wlan(int argc, char **argv) { return ipwlan_cmd_wlan_en(1, argc, argv); } /* *=========================================================================== * ipwlan_cmd_wlan_silent *=========================================================================== * Description: Executes shell commands. Printouts are disabled * Parameters: * Returns: Non-zero on failure */ IP_PUBLIC int ipwlan_cmd_wlan_silent(int argc, char **argv) { return ipwlan_cmd_wlan_en(0, argc, argv); } Ip_u8 convertDecimalToKeycode(Ip_u8 dec) { Ip_u8 decimalTokeycode[]={48,49,50,51,52,53,54,55,56,57,65,66,67,68,69,70}; dec &=0x0f; return decimalTokeycode[dec]; } /* *=========================================================================== * END OF FILE *=========================================================================== */