hostap-utils-0.4.7/0000755000175000001440000000000010340222766012505 5ustar jmusershostap-utils-0.4.7/.cvsignore0000644000175000001440000000010507742036541014507 0ustar jmusershostap_crypt_conf hostap_diag prism2_srec hostap_io_debug hostap_rid hostap-utils-0.4.7/ChangeLog0000644000175000001440000000306610340220272014252 0ustar jmusersChangeLog for Host AP utils 2005-11-20 - v0.4.7 (beginning of 0.4.x stable releases) 2005-04-25 - v0.4.0 (beginning of 0.4.x development releases) * no changes since 0.3.2 2005-02-12 - v0.3.7 (beginning of 0.3.x stable releases) 2004-12-19 - v0.3.2 * split_combined_hex: updated to use head/tail -n argument (tail +N did not work anymore) 2004-12-05 - v0.3.0 (beginning of 0.3.x development releases) * no changes since 0.2.4 2004-07-17 - v0.2.4 (beginning of 0.2.x stable releases) * no changes since 0.2.1 2004-05-06 - v0.2.1 * hostap_rid: fixed handling of failed RID reads 2004-02-15 - v0.2.0 * fixed prism2_srec not to allow combination of volatile and non-volatile firmware images (they will corrupt the card flash) * added support for loading PRI firmware for cards without PRI in flash (new prism2_srec command line option, -s, for skipping PDA read since PDA is not available without PRI firmware) * added example script, hostap_fw_load, to demonstrate how firmware images can be loaded automatically based on what images are available in card flash; this script includes commands needed to initialize cards without PRI image in flash (like D-Link DWL-650 rev. P1 and D-Link DWL-520 rev. E1 * fixed volatile download of combined primary and secondary firmware to start running the secondary firmware * added support for dumping PDA in text format and overriding PDA with text and binary files (prism2_srec options -D, -P, and -O) Note: Older changes up to and including v0.1.0 are included in the ChangeLog of the Host AP driver. hostap-utils-0.4.7/Makefile0000644000175000001440000000134610165443153014151 0ustar jmusersifndef CFLAGS CFLAGS = -O2 -Wall endif # Include directory for CVS version CFLAGS += -I../driver/modules all: prism2_srec hostap_crypt_conf hostap_diag hostap_io_debug hostap_rid prism2_srec: prism2_srec.o util.o prism2_srec.o: prism2_srec.c util.h hostap_crypt_conf: hostap_crypt_conf.c hostap_diag: hostap_diag.o util.o $(CC) -o hostap_diag $(CFLAGS) hostap_diag.o util.o hostap_diag.o: hostap_diag.c util.h util.o: util.c util.h hostap_io_debug: hostap_io_debug.c $(CC) -o hostap_io_debug $(CFLAGS) hostap_io_debug.c hostap_rid: hostap_rid.o util.o $(CC) -o hostap_rid $(CFLAGS) hostap_rid.o util.o hostap_rid.o: hostap_rid.c util.h clean: rm -f prism2_srec hostap_crypt_conf hostap_diag hostap_rid \ hostap_io_debug *.o hostap-utils-0.4.7/README0000644000175000001440000001643010013472771013371 0ustar jmusersUtility programs for Host AP driver for Intersil Prism2/2.5/3 ============================================================= Copyright (c) 2002-2004, Jouni Malinen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. See COPYING for more details. hostap_crypt_conf ================= hostap_crypt_conf is a tool for configuring encryption keys to the Host AP driver. It extends the features of iwconfig by supporting individual per STA keys and support more than one encryption algorithm. hostap_crypt_conf takes following options: Usage: hostap_crypt_conf [-1]..[-9] [-t] [-p] [key] Options: -1 .. -9 key index (for WEP); only one index per command -t set TX key index (given with -1 .. -9) -p permanent station configuration (do not expire data) device wlan# addr station hwaddr or ff:ff:ff:ff:ff:ff for default/broadcast key alg crypt algorithm (WEP, NULL, none) key key data (in hex, e.g. '0011223344', or s:string) Algorithms: WEP 40 or 104 bit WEP TKIP Temporal Key Integrity Protocol (TKIP), WEP with per-packet temporal keys and Michael MIC CCMP AES-CCM (Counter with CBC-MAC) NULL NULL encryption (i.e., do not encrypt/decrypt); used to configure no encryption for given station when using default encryption none disable encryption IEEE 802.11 (Chap. 8.3.2) specifies that dot11WEPKeyMappings uses only one key per station address (whereas dot11WEDefaultKeys has four), but Host AP uses a more general implementation that allows four keys even with individual keys. However, to remain compliant with the standard, it is recommended to use only the first key with station-specific key mapping. In addition, it might be useful to configure default TX key to be something else than the first key to allow individual keys to be used even with stations that not explicitly support WEP key mapping. Examples: AP configuration ---------------- # use station specific key also with broadcast RX frames to support # different keys with stations that do not use WEP key mapping; # if the stations allow configuration of separate key for broadcast/multicast # bcrx_sta_key should be left to 0 (default) prism2_param wlan0 bcrx_sta_key 1 # set key2 as the default key (used with broadcast/multicast frames # and with stations for which there is no individual key mapping) hostap_crypt_conf -2t wlan0 ff:ff:ff:ff:ff:ff WEP s:abcde # or with iwconfig: iwconfig wlan0 key s:abcde [2] iwconfig wlan0 key [2] # set a permanent key mapping for STA2 (hwaddr=00:11:22:33:44:55) hostap_crypt_conf -p wlan0 00:11:22:33:44:55 WEP s:qwert STA1 configuration ------------------ # use only the default key (i.e., no key mapping) iwconfig wlan0 key s:abcde [2] iwconfig wlan0 key [2] STA2 configuration (hwaddr=00:11:22:33:44:55) ------------------ # configure default key (idx 2) so that the station knows how to # decrypt broadcast/multicast frames iwconfig wlan0 key s:abcde [2] # configure individual key (idx 1) that will be used to decrypt unicast # frames from the AP and to encrypt all frames to the AP iwconfig wlan0 key s:qwert [1] iwconfig wlan0 key [1] hostap_diag =========== Diagnostics tools for showing details of Prism2/2.5/3 configuration. Usage: hostap_diag [-abhpru] Options: -h show this usage info -a show all info -b show baseband processor control registers -p show production data area (PDA) -r show known RIDs -u show unknown RIDs hostap_io_debug =============== Debugging tool for generating human readable debug log from Host AP driver io_debug file. hostap_rid ========== Debugging tool for reading and writing Prism2/2.5/3 RID values. Usage: hostap_rid [data] Examples: hostap_rid wlan0 get fc00 hostap_rid wlan0 set fc00 06 00 hostap_rid wlan0 set fc0e 06 00 66 6f 6f 62 61 72 Note: - Prism2/2.5/3 uses little-endian byte order - The most common word size is 16 bits - Set command needs the raw RID contents, i.e., it will be written as is to the device prism2_param ============ prism2_param is a shell script wrapper for 'iwpriv wlan0 prism2_param ' command. The wrapper translates parameter names from text format into a integer value used in the real iwpriv command. Usage: prism2_param [value] Wrapper for setting hostap_{cs,plx,pci}.o parameters using iwpriv and prism2_param ioctl. This wrapper converts the given text parameter (see list below) to corresponding prism2_param ioctl() value and uses iwpriv to set the given value. If value argument is not given, the current value is shown (if available). interface: interface name for the wireless LAN device to be used (e.g., wlan0) parameter: see README in Host AP driver package for full list of prism2_param parameters prism2_srec =========== Firmware image downloaded for Host AP driver Usage: prism2_srec [-vvrgfdpisD] [-P ] [-O ] \ [srec file name] Options: -v verbose (add another for more verbosity -r download SREC file into RAM (volatile) -g download SREC file into RAM (volatile in Genesis mode) -f download SREC file into flash (non-volatile) -d dump SREC image into prism2_srec.dump -p persistent mode for volatile download -i ignore incompatible interfaces errors Warning! This can result in failed upgrade! -s Skip PDA reading and use defaults from the firmware image -D Dump PDA in text format (this can be used without srec file) -P Override card PDA (with a PDA file in text format) Warning! This can result in failed upgrade! -O Override procfs path for binary PDA Warning! This can result in failed upgrade! Options -r, -g, and -f cannot be used together. If -r, -g, or -f is not specified, image summary is shown and compatibility with WLAN card is verified without downloading anything. Two images, PRI and STA firmware, can be combined by giving file names for both images on the command line. See hostap_fw_load script for an example that loads firmware images for cards without firmware in a flash chip (e.g., D-Link DWL-650 rev. P1 and D-Link DWL-520 rev. E1). PDA data can be dumped in text format (PDRs in hex format using 16-bit words) with -D option. This format matches with the one used in Intersil's PDA files and it can be used to modify PDA contents for a download by using -P option. This does not overwrite PDA in the flash, so the modified PDA text file must be specified with all download commands. Similarily, -O option can be used to override PDA with a binary file (e.g., copy of /proc/net/hostap/wlan0/pda). Note: Modifying PDA data can result in failed download and/or invalid operation of the card after the download. This command should not be used unless you are absolutely sure you know what you are doing. split_combined_hex ================== Tool for splitting combined S3 image files into seprate hex files. This can be used to convert combined firmware image files, e.g., extracted from some Windows drivers, into separate image files that can then be downloaded using prism2_srec. hostap-utils-0.4.7/hostap_crypt_conf.c0000644000175000001440000002042607713615014016403 0ustar jmusers/* * Host AP crypto configuration tool for Host AP kernel driver * Copyright (c) 2002, Jouni Malinen * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. See README and COPYING for * more details. */ #include #include #include #include #include #include #include #include #include #include #include "util.h" #include "wireless_copy.h" #define DEFAULT_KEYS "ff:ff:ff:ff:ff:ff" static inline int hex2int(char c) { if (c >= '0' && c <= '9') return (c - '0'); if (c >= 'a' && c <= 'f') return (c - 'a' + 10); if (c >= 'A' && c <= 'F') return (c - 'A' + 10); return -1; } static int macstr2addr(const char *macstr, u8 *addr) { int i, val, val2; const char *pos = macstr; for (i = 0; i < 6; i++) { val = hex2int(*pos++); if (val < 0) return -1; val2 = hex2int(*pos++); if (val2 < 0) return -1; addr[i] = (val * 16 + val2) & 0xff; if (i < 5 && *pos++ != ':') return -1; } if (*pos != '\0') return -1; return 0; } static void usage(void) { printf("Usage: hostap_crypt_conf [-123456789tpl] [addr] " "[alg] [key]\n" "Options:\n" " -1 .. -9 key index (for WEP); only one index per command\n" " -t set TX key index (given with -1 .. -9)\n" " -p permanent station configuration (do not expire " "data)\n" " -l list configured keys (do not use addr or alg)\n" " device wlan#\n" " addr station hwaddr or " DEFAULT_KEYS " for default/" "broadcast key\n" " alg crypt algorithm (WEP, NULL, none)\n" " key key data (in hex, e.g. '0011223344', or s:string)" "\n\n" "Algorithms:\n" " WEP 40 or 104 bit WEP\n" " NULL NULL encryption (i.e., do not encrypt/decrypt);\n" " used to configure no encryption for given\n" " station when using default encryption\n" " none disable encryption\n"); exit(1); } static void parse_key_string(struct prism2_hostapd_param *param, const char *key) { param->u.crypt.key_len = strlen(key); if (param->u.crypt.key_len > 1024 - sizeof(*param)) { fprintf(stderr, "Too long key.\n"); exit(1); } memcpy(param->u.crypt.key, key, param->u.crypt.key_len); } static void parse_key_hex(struct prism2_hostapd_param *param, const char *key) { int len = strlen(key); const char *ipos; char *opos; if (len & 1) { fprintf(stderr, "Invalid hex string '%s' (odd length)\n", key); exit(1); } param->u.crypt.key_len = len / 2; if (param->u.crypt.key_len > 1024 - sizeof(*param)) { fprintf(stderr, "Too long key.\n"); exit(1); } ipos = key; opos = param->u.crypt.key; while (len > 0) { int val1, val2; val1 = hex2int(*ipos++); val2 = hex2int(*ipos++); if (val1 < 0 || val2 < 0) { fprintf(stderr, "Invalid hex string '%s' (could not " "parse '%c%c')\n", key, *(ipos - 2), *(ipos - 1)); exit(1); } *opos++ = (val1 << 4) + val2; len -= 2; } } static void show_error(struct prism2_hostapd_param *param) { switch (param->u.crypt.err) { case HOSTAP_CRYPT_ERR_UNKNOWN_ALG: printf("Unknown algorithm '%s'.\n" "You may need to load kernel module to register that " "algorithm.\n" "E.g., 'modprobe hostap_crypt_wep' for WEP.\n", param->u.crypt.alg); break; case HOSTAP_CRYPT_ERR_UNKNOWN_ADDR: printf("Unknown address " MACSTR ".\n", MAC2STR(param->sta_addr)); if (!(param->u.crypt.flags & HOSTAP_CRYPT_FLAG_PERMANENT)) printf("You can use -p flag to add permanent entry " "for not yet associated station.\n"); break; case HOSTAP_CRYPT_ERR_CRYPT_INIT_FAILED: printf("Crypt algorithm initialization failed.\n"); break; case HOSTAP_CRYPT_ERR_KEY_SET_FAILED: printf("Key setting failed.\n"); break; case HOSTAP_CRYPT_ERR_TX_KEY_SET_FAILED: printf("TX key index setting failed.\n"); break; case HOSTAP_CRYPT_ERR_CARD_CONF_FAILED: printf("Card configuration failed.\n"); break; } } static int do_ioctl(const char *dev, struct prism2_hostapd_param *param, int show_err) { int s; struct iwreq iwr; s = socket(PF_INET, SOCK_DGRAM, 0); if (s < 0) { perror("socket"); return -1; } memset(&iwr, 0, sizeof(iwr)); strncpy(iwr.ifr_name, dev, IFNAMSIZ); iwr.u.data.pointer = (caddr_t) param; iwr.u.data.length = (int) ((char *) param->u.crypt.key - (char *) param) + param->u.crypt.key_len; if (ioctl(s, PRISM2_IOCTL_HOSTAPD, &iwr) < 0) { if (show_err) { perror("ioctl[PRISM2_IOCTL_HOSTAPD]"); show_error(param); } return -1; } return 0; } static int show_key(const char *dev, char *addr, int forced_show) { char buf[1024]; struct prism2_hostapd_param *param; int idx, i, max_key_len; max_key_len = sizeof(buf) - (int) ((char *) param->u.crypt.key - (char *) param); memset(buf, 0, sizeof(buf)); param = (struct prism2_hostapd_param *) buf; param->cmd = PRISM2_GET_ENCRYPTION; if (macstr2addr(addr, param->sta_addr)) return -1; param->u.crypt.idx = 0xff; param->u.crypt.key_len = max_key_len; if (do_ioctl(dev, param, forced_show)) return -1; if (!forced_show && strcmp(param->u.crypt.alg, "none") == 0) return 0; if (strcmp(addr, DEFAULT_KEYS) == 0) printf("Default keys\n"); else printf("\nKeys for %s\n", addr); printf(" algorithm: %s\n", param->u.crypt.alg); if (strcmp(param->u.crypt.alg, "none") == 0) return 0; if (param->u.crypt.idx != 0xff) printf(" TX key idx: %d\n", param->u.crypt.idx + 1); for (idx = 0; idx < 4; idx++) { param->u.crypt.idx = idx; param->u.crypt.key_len = max_key_len; if (do_ioctl(dev, param, forced_show) == 0) { printf(" key %d:", idx + 1); if (param->u.crypt.key_len > max_key_len) printf(" invalid key_len %d", param->u.crypt.key_len); else for (i = 0; i < param->u.crypt.key_len; i++) printf(" %02x", param->u.crypt.key[i]); printf("\n"); } } return 0; } static int show_key_list(const char *dev) { char dirname[128]; DIR *procdir; struct dirent *entry; if (show_key(dev, DEFAULT_KEYS, 1)) return -1; snprintf(dirname, sizeof(dirname), "/proc/net/hostap/%s", dev); procdir = opendir(dirname); if (!procdir) { printf("Could not open directory '%s'\n", dirname); perror("opendir"); return -1; } while ((entry = readdir(procdir)) != NULL) { if (strlen(entry->d_name) == 17 && entry->d_name[2] == ':') show_key(dev, entry->d_name, 0); } if (closedir(procdir)) perror("closedir"); return 0; } int main(int argc, char *argv[]) { int opt, idx = 0, list_keys = 0; char buf[1024]; const char *arg_dev = NULL, *arg_addr = NULL, *arg_alg = NULL, *arg_key = NULL; struct prism2_hostapd_param *param; memset(buf, 0, sizeof(buf)); param = (struct prism2_hostapd_param *) buf; param->cmd = PRISM2_SET_ENCRYPTION; for (;;) { opt = getopt(argc, argv, "123456789tphl"); if (opt < 0) break; if (opt == 't') param->u.crypt.flags |= HOSTAP_CRYPT_FLAG_SET_TX_KEY; else if (opt == 'p') param->u.crypt.flags |= HOSTAP_CRYPT_FLAG_PERMANENT; else if (opt == 'l') list_keys++; else if (opt >= '1' && opt <= '9') { if (idx != 0) usage(); idx = opt - '0'; } else { /* -h or invalid options */ usage(); } } param->u.crypt.idx = idx > 0 ? idx - 1 : 0; if (argc > optind) arg_dev = argv[optind++]; if (argc > optind) arg_addr = argv[optind++]; if (argc > optind) arg_alg = argv[optind++]; if (argc > optind) arg_key = argv[optind++]; if (list_keys) { if (!arg_dev) usage(); return show_key_list(arg_dev); } if (!arg_addr) usage(); if (macstr2addr(arg_addr, param->sta_addr) < 0) { fprintf(stderr, "Invalid hwaddr '%s'.\n", arg_addr); usage(); } if (!arg_alg) usage(); if (strlen(arg_alg) > HOSTAP_CRYPT_ALG_NAME_LEN) { fprintf(stderr, "Too long algorithm name '%s'.\n", arg_alg); exit(1); } strncpy(param->u.crypt.alg, arg_alg, HOSTAP_CRYPT_ALG_NAME_LEN); if (arg_key) { if (arg_key[0] == 's' && arg_key[1] == ':') parse_key_string(param, arg_key + 2); else parse_key_hex(param, arg_key); } return do_ioctl(arg_dev, param, 1); } hostap-utils-0.4.7/hostap_diag.c0000644000175000001440000006557410013452346015150 0ustar jmusers/* * Wireless LAN card diagnostics tool for Host AP kernel driver * Copyright (c) 2002-2004, Jouni Malinen * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. See README and COPYING for * more details. */ #include #include #include #include #include #include #include #include "util.h" static int diag_show_summary(const char *dev) { char buf[PRISM2_HOSTAPD_MAX_BUF_SIZE]; struct prism2_hostapd_param *param; int res; printf("Host AP driver diagnostics information for '%s'\n\n", dev); param = (struct prism2_hostapd_param *) buf; res = hostapd_get_rid(dev, param, HFA384X_RID_NICID, 1); if (res == EPERM) { printf("hostap_diag requires root privileges\n"); return -1; } if (res == ENODATA) { printf("NICID read did not return any data.\n"); } else if (res) { printf("Could not communicate with the kernel driver.\n"); return -1; } if (res == 0) hostap_show_nicid(param->u.rid.data, param->u.rid.len); if (!hostapd_get_rid(dev, param, HFA384X_RID_PRIID, 1)) hostap_show_priid(param->u.rid.data, param->u.rid.len); if (!hostapd_get_rid(dev, param, HFA384X_RID_STAID, 1)) hostap_show_staid(param->u.rid.data, param->u.rid.len); return 0; } #define RID(n,t) { HFA384X_RID_##n, #n, t } enum { RID_HEXDUMP, RID_WORD, RID_HWADDR, RID_STRING, RID_COMPID, RID_SUPRANGE, RID_HEXSTRING, RID_CIS }; static struct { u16 rid; char *name; int type; } rid_table[] = { RID(CNFPORTTYPE, RID_WORD), RID(CNFOWNMACADDR, RID_HWADDR), RID(CNFDESIREDSSID, RID_STRING), RID(CNFOWNCHANNEL, RID_WORD), RID(CNFOWNSSID, RID_STRING), RID(CNFOWNATIMWINDOW, RID_WORD), RID(CNFSYSTEMSCALE, RID_WORD), RID(CNFMAXDATALEN, RID_WORD), RID(CNFWDSADDRESS, RID_HWADDR), RID(CNFPMENABLED, RID_WORD), RID(CNFPMEPS, RID_WORD), RID(CNFMULTICASTRECEIVE, RID_WORD), RID(CNFMAXSLEEPDURATION, RID_WORD), RID(CNFPMHOLDOVERDURATION, RID_WORD), RID(CNFOWNNAME, RID_STRING), RID(CNFOWNDTIMPERIOD, RID_WORD), RID(CNFWDSADDRESS1, RID_HWADDR), RID(CNFWDSADDRESS2, RID_HWADDR), RID(CNFWDSADDRESS3, RID_HWADDR), RID(CNFWDSADDRESS4, RID_HWADDR), RID(CNFWDSADDRESS5, RID_HWADDR), RID(CNFWDSADDRESS6, RID_HWADDR), RID(CNFMULTICASTPMBUFFERING, RID_WORD), RID(UNKNOWN1, RID_WORD), RID(UNKNOWN2, RID_WORD), RID(CNFWEPDEFAULTKEYID, RID_WORD), RID(CNFDEFAULTKEY0, RID_HEXDUMP), RID(CNFDEFAULTKEY1, RID_HEXDUMP), RID(CNFDEFAULTKEY2, RID_HEXDUMP), RID(CNFDEFAULTKEY3, RID_HEXDUMP), RID(CNFWEPFLAGS, RID_HEXDUMP), RID(CNFWEPKEYMAPPINGTABLE, RID_HEXDUMP), RID(CNFAUTHENTICATION, RID_WORD), RID(CNFMAXASSOCSTA, RID_WORD), RID(CNFTXCONTROL, RID_WORD), RID(CNFROAMINGMODE, RID_WORD), RID(CNFHOSTAUTHENTICATION, RID_WORD), RID(CNFRCVCRCERROR, RID_WORD), RID(CNFMMLIFE, RID_WORD), RID(CNFALTRETRYCOUNT, RID_WORD), RID(CNFBEACONINT, RID_WORD), RID(CNFAPPCFINFO, RID_HEXDUMP), RID(CNFSTAPCFINFO, RID_HEXDUMP), RID(CNFPRIORITYQUSAGE, RID_HEXDUMP), RID(CNFTIMCTRL, RID_WORD), RID(UNKNOWN3, RID_HEXDUMP), RID(CNFTHIRTY2TALLY, RID_WORD), RID(CNFENHSECURITY, RID_WORD), RID(CNFDBMADJUST, RID_WORD), RID(GENERICELEMENT, RID_HEXDUMP), RID(PROPAGATIONDELAY, RID_WORD), RID(GROUPADDRESSES, RID_HEXDUMP), RID(CREATEIBSS, RID_WORD), RID(FRAGMENTATIONTHRESHOLD, RID_WORD), RID(RTSTHRESHOLD, RID_WORD), RID(TXRATECONTROL, RID_WORD), RID(PROMISCUOUSMODE, RID_WORD), RID(FRAGMENTATIONTHRESHOLD0, RID_WORD), RID(FRAGMENTATIONTHRESHOLD1, RID_WORD), RID(FRAGMENTATIONTHRESHOLD2, RID_WORD), RID(FRAGMENTATIONTHRESHOLD3, RID_WORD), RID(FRAGMENTATIONTHRESHOLD4, RID_WORD), RID(FRAGMENTATIONTHRESHOLD5, RID_WORD), RID(FRAGMENTATIONTHRESHOLD6, RID_WORD), RID(RTSTHRESHOLD0, RID_WORD), RID(RTSTHRESHOLD1, RID_WORD), RID(RTSTHRESHOLD2, RID_WORD), RID(RTSTHRESHOLD3, RID_WORD), RID(RTSTHRESHOLD4, RID_WORD), RID(RTSTHRESHOLD5, RID_WORD), RID(RTSTHRESHOLD6, RID_WORD), RID(TXRATECONTROL0, RID_WORD), RID(TXRATECONTROL1, RID_WORD), RID(TXRATECONTROL2, RID_WORD), RID(TXRATECONTROL3, RID_WORD), RID(TXRATECONTROL4, RID_WORD), RID(TXRATECONTROL5, RID_WORD), RID(TXRATECONTROL6, RID_WORD), RID(CNFSHORTPREAMBLE, RID_WORD), RID(CNFEXCLUDELONGPREAMBLE, RID_WORD), RID(CNFAUTHENTICATIONRSPTO, RID_WORD), RID(CNFBASICRATES, RID_HEXDUMP), RID(CNFSUPPORTEDRATES, RID_HEXDUMP), RID(CNFFALLBACKCTRL, RID_WORD), RID(WEPKEYDISABLE, RID_WORD), RID(WEPKEYMAPINDEX, RID_HEXDUMP), RID(BROADCASTKEYID, RID_HEXDUMP), RID(ENTSECFLAGEYID, RID_HEXDUMP), RID(CNFPASSIVESCANCTRL, RID_WORD), RID(SSNHANDLINGMODE, RID_WORD), RID(MDCCONTROL, RID_WORD), RID(MDCCOUNTRY, RID_HEXDUMP), RID(TXPOWERMAX, RID_WORD), RID(CNFLFOENABLED, RID_WORD), RID(CAPINFO, RID_WORD), RID(LISTENINTERVAL, RID_WORD), RID(SW_ANT_DIV, RID_HEXDUMP), RID(LED_CTRL, RID_HEXDUMP), RID(HFODELAY, RID_WORD), RID(DISALLOWEDBSSID, RID_HEXDUMP), RID(TICKTIME, RID_WORD), RID(SCANREQUEST, RID_HEXDUMP), RID(JOINREQUEST, RID_HEXDUMP), RID(AUTHENTICATESTATION, RID_HEXDUMP), RID(CHANNELINFOREQUEST, RID_HEXDUMP), RID(HOSTSCAN, RID_HEXDUMP), RID(MAXLOADTIME, RID_WORD), RID(DOWNLOADBUFFER, RID_HEXDUMP), RID(PRIID, RID_COMPID), RID(PRISUPRANGE, RID_SUPRANGE), RID(CFIACTRANGES, RID_SUPRANGE), RID(NICSERNUM, RID_STRING), RID(NICID, RID_COMPID), RID(MFISUPRANGE, RID_SUPRANGE), RID(CFISUPRANGE, RID_SUPRANGE), RID(CHANNELLIST, RID_HEXDUMP), RID(REGULATORYDOMAINS, RID_STRING), RID(TEMPTYPE, RID_WORD), RID(CIS, RID_CIS), RID(STAID, RID_COMPID), RID(STASUPRANGE, RID_SUPRANGE), RID(MFIACTRANGES, RID_SUPRANGE), RID(CFIACTRANGES2, RID_SUPRANGE), RID(PRODUCTNAME, RID_STRING), RID(PORTSTATUS, RID_WORD), RID(CURRENTSSID, RID_STRING), RID(CURRENTBSSID, RID_HWADDR), RID(COMMSQUALITY, RID_HEXDUMP), RID(CURRENTTXRATE, RID_WORD), RID(CURRENTBEACONINTERVAL, RID_WORD), RID(CURRENTSCALETHRESHOLDS, RID_HEXDUMP), RID(PROTOCOLRSPTIME, RID_WORD), RID(SHORTRETRYLIMIT, RID_WORD), RID(LONGRETRYLIMIT, RID_WORD), RID(MAXTRANSMITLIFETIME, RID_WORD), RID(MAXRECEIVELIFETIME, RID_WORD), RID(CFPOLLABLE, RID_WORD), RID(AUTHENTICATIONALGORITHMS, RID_HEXDUMP), RID(PRIVACYOPTIONIMPLEMENTED, RID_WORD), RID(DBMCOMMSQUALITY, RID_HEXDUMP), RID(CURRENTTXRATE1, RID_WORD), RID(CURRENTTXRATE2, RID_WORD), RID(CURRENTTXRATE3, RID_WORD), RID(CURRENTTXRATE4, RID_WORD), RID(CURRENTTXRATE5, RID_WORD), RID(CURRENTTXRATE6, RID_WORD), RID(OWNMACADDR, RID_HWADDR), RID(SCANRESULTSTABLE, RID_HEXDUMP), RID(HOSTSCANRESULTS, RID_HEXDUMP), RID(AUTHENTICATIONUSED, RID_HEXDUMP), RID(CNFFAASWITCHCTRL, RID_WORD), RID(ASSOCIATIONFAILURE, RID_HEXDUMP), RID(PHYTYPE, RID_WORD), RID(CURRENTCHANNEL, RID_WORD), RID(CURRENTPOWERSTATE, RID_WORD), RID(CCAMODE, RID_WORD), RID(SUPPORTEDDATARATES, RID_HEXSTRING), RID(LFO_VOLT_REG_TEST_RES, RID_HEXDUMP), RID(BUILDSEQ, RID_HEXDUMP), RID(FWID, RID_STRING) }; static void diag_show_known_rids(const char *dev) { char buf[PRISM2_HOSTAPD_MAX_BUF_SIZE]; u8 *rid; struct prism2_hostapd_param *param; int res, i, j, k, len, slen; struct hfa384x_comp_ident *compid; struct hfa384x_sup_range *range; printf("\nKnown RIDs (Resource IDentifiers)\n\n"); param = (struct prism2_hostapd_param *) buf; for (i = 0; i < sizeof(rid_table) / sizeof(rid_table[0]); i++) { res = hostapd_get_rid(dev, param, rid_table[i].rid, 0); if (res == ENODATA) continue; if (res) { printf("Could not read RID %04X (res=%d)\n", rid_table[i].rid, res); break; } printf("%04X=%s=", rid_table[i].rid, rid_table[i].name); rid = param->u.rid.data; len = param->u.rid.len; switch (rid_table[i].type) { case RID_HEXDUMP: for (j = 0; j < len; j++) printf("<%02x>", rid[j]); printf("\n"); break; case RID_WORD: if (len != 2) { printf("\n", len); } else { u16 val = le_to_host16(*(u16 *)rid); printf("%d\n", val); } break; case RID_HWADDR: if (len != 6) { printf("\n", len); } else { printf(MACSTR "\n", MAC2STR(rid)); } break; case RID_STRING: slen = le_to_host16(*(u16 *)rid); if (slen > len) slen = len; for (j = 2; j < slen + 2; j++) { if (rid[j] >= 32 && rid[j] < 127) printf("%c", rid[j]); else printf("<%02x>", rid[j]); } printf("\n"); break; case RID_COMPID: if (len != sizeof(*compid)) { printf("\n", len); break; } compid = (struct hfa384x_comp_ident *) rid; printf("0x%02x v%d.%d.%d\n", le_to_host16(compid->id), le_to_host16(compid->major), le_to_host16(compid->minor), le_to_host16(compid->variant)); break; case RID_SUPRANGE: if (len != sizeof(*range)) { printf("\n", len); break; } range = (struct hfa384x_sup_range *) rid; printf("%d 0x%02x %d %d-%d\n", le_to_host16(range->role), le_to_host16(range->id), le_to_host16(range->variant), le_to_host16(range->bottom), le_to_host16(range->top)); break; case RID_HEXSTRING: slen = le_to_host16(*(u16 *)rid); if (slen > len) slen = len; for (j = 2; j < slen + 2; j++) printf("<%02x>", rid[j]); printf("\n"); break; case RID_CIS: k = len; while (k > 0 && rid[k - 1] == 0xff) k--; for (j = 0; j < k; j++) printf("<%02x>", rid[j]); if (k != len) printf(" + %d*", len - k); printf("\n"); break; default: printf("\n", rid_table[i].type); break; } } } static void diag_show_unknown_rids(const char *dev) { char buf[PRISM2_HOSTAPD_MAX_BUF_SIZE]; struct prism2_hostapd_param *param; int res, j; u16 rid; int pos, rid_entries; printf("\nUnknown RIDs (Resource IDentifiers)\n\n"); param = (struct prism2_hostapd_param *) buf; pos = 0; rid_entries = sizeof(rid_table) / sizeof(rid_table[0]); for (rid = 0xfc00; rid <= 0xfdff; rid++) { if (pos < rid_entries) { if (rid_table[pos].rid == rid) { pos++; continue; } while (pos < rid_entries && rid_table[pos].rid < rid) pos++; } res = hostapd_get_rid(dev, param, rid, 0); if (res == ENODATA) continue; if (res) { printf("Could not read RID %04X (res=%d)\n", rid_table[pos].rid, res); break; } printf("%04X=", rid); for (j = 0; j < param->u.rid.len; j++) printf("<%02x>", param->u.rid.data[j]); printf("\n"); } } static inline void show_bbp_cr(const char *dev, int cr, const char *desc, const char *extra) { int res; res = hostap_ioctl_readmif(dev, cr); if (res >= 0) printf("CR%d (%s): %d%s\n", cr, desc, res, extra); } static inline void show_bbp_cr_signed(const char *dev, int cr, const char *desc, const char *extra) { int res; res = hostap_ioctl_readmif(dev, cr); if (res >= 0) printf("CR%d (%s): %d%s\n", cr, desc, (signed char) res, extra); } static inline void show_a_values(const char *dev) { printf(" CR50..CR63: 'a' value\n"); show_bbp_cr(dev, 50, "Test Bus Read", ""); show_bbp_cr(dev, 51, "Noise floorAntA", ""); show_bbp_cr(dev, 52, "Noise floorAntB", ""); show_bbp_cr(dev, 53, "AGC error / I DC Offset", ""); show_bbp_cr(dev, 54, "Unassigned / Q DC Offset", ""); show_bbp_cr(dev, 55, "Unassigned Multipath Metric", ""); show_bbp_cr(dev, 56, "Unassigned / Multipath Count", ""); show_bbp_cr(dev, 57, "Unassigned / Packet Signal Quality", ""); show_bbp_cr_signed(dev, 58, "TX Power Measurement", ""); show_bbp_cr(dev, 59, "RX Mean Power / Header Signal Quality", ""); } static inline void show_b_values(const char *dev) { printf(" CR50..CR63: 'b' value\n"); show_bbp_cr(dev, 50, "Test Bus Read", ""); show_bbp_cr(dev, 51, "Signal Quality Measure Based on Carrier Tracking", ""); show_bbp_cr(dev, 52, "Received Signal Field", ""); show_bbp_cr(dev, 53, "Received Service Field", ""); show_bbp_cr(dev, 54, "Received Length Field, Low", ""); show_bbp_cr(dev, 55, "Received Length Field, High", ""); show_bbp_cr(dev, 56, "Calculated CRC on Received Header, Low", ""); show_bbp_cr(dev, 57, "Calculated CRC on Received Header, High", ""); show_bbp_cr_signed(dev, 58, "TX Power Measurement", ""); show_bbp_cr(dev, 59, "RX Mean Power", ""); } static void diag_show_bbp(const char *dev) { int res, res2; /* This info is based on Intersil FN4816 (HFA3861B Data Sheet) */ printf("\nBaseband proccessor (BBP) Configuration Registers\n\n"); res = hostap_ioctl_readmif(dev, 0); if (res >= 0) { int part, version; part = res / 16; version = res % 16; printf("CR0 (Part/Version Code): %d - Part=%d ", res, part); switch (part) { case 1: printf("(HFA3861B series)"); break; case 3: printf("(HFA3863 series)"); break; case 7: printf("(HFA3871 series?)"); break; default: printf("(unknown)"); break; } printf(" Version=%d ", version); switch (version) { case 0: printf("(3863 Version)"); break; case 3: printf("(3861B Version)"); break; case 4: printf("(3871 Version?)"); break; default: printf("(unknown)"); break; } printf("\n"); } res = hostap_ioctl_readmif(dev, 1); if (res >= 0) { printf("CR1 (I/O Polarity): %d (normal setting 0)\n", res); printf(" Phase of RX carrier rotation sense: %s\n", res & BIT(7) ? "Inverted rotation (CW), Invert Q in" : "normal rotation (CCW)"); printf(" Phase of TX carrier rotation sense: %s\n", res & BIT(6) ? "Inverted rotation (CW), Invert Q out" : "normal rotation (CCW)"); printf(" Phase of TX output clock (TXCLK) pin: %s\n", res & BIT(5) ? "Inverted TXCLK" : "NON-Inverted TXCLK"); printf(" Active level of the Transmit Ready output: %s\n", res & BIT(4) ? "TX_RDY Active 0" : "TX_RDY Active 1"); printf(" Active level of the transmit enable input: %s\n", res & BIT(3) ? "TX_PE Active 0" : "TX_PE Active 1"); printf(" Active level of the Clear Channel Assessment " "output: %s\n", res & BIT(2) ? "CCA Active 1" : "CCA Active 0"); printf(" Active level of the MD_RDY output: %s\n", res & BIT(1) ? "MD_RDY Active 0" : "MD_RDY Active 1"); printf(" Phase of the RX_CLK output: %s\n", res & BIT(0) ? "Invert Clk" : "Non-Inverted Clk"); } show_bbp_cr(dev, 2, "I Cover Code", " (nominally 72)"); show_bbp_cr(dev, 3, "Q Cover Code", " (nominally 72)"); show_bbp_cr(dev, 4, "TX Preamble Length", " (IEEE 802.11: 128)"); res = hostap_ioctl_readmif(dev, 5); if (res >= 0) { printf("CR5 (TX Signal Field): %d\n" " Preamble mode: %s\n" " TX data rate: ", res, res & BIT(3) ? "Short preamble and header mode" : "Normal"); switch (res & (BIT(1) | BIT(0))) { case 0: printf("00 = DBPSK - 11 chip sequence (1Mbps)\n"); break; case 1: printf("01 = DQPSK - 11 chip sequence (2Mbps)\n"); break; case 2: printf("10 = CCK - 8 chip sequence (5.5Mbps)\n"); break; case 3: printf("11 = CCK - 8 chip sequence (11Mbps)\n"); break; } } show_bbp_cr(dev, 6, "TX Service Field", ""); show_bbp_cr(dev, 7, "TX Length Field, High", ""); show_bbp_cr(dev, 8, "TX Length Field, Low", ""); res = hostap_ioctl_readmif(dev, 7); res2 = hostap_ioctl_readmif(dev, 8); if (res >= 0 && res2 >= 0) printf(" TX Length Field: %d usec\n", (res << 8) | res2); res = hostap_ioctl_readmif(dev, 9); if (res >= 0) { printf("CR9 (TX Configure): %d\n", res); printf(" CCA sample mode time: %s usec\n", res & BIT(7) ? "15.8" : "19.9"); printf(" CCA mode: CCA is based "); switch ((res & (BIT(6) | BIT(5))) >> 5) { case 0: printf("only on ED\n"); break; case 1: printf("on (CS1 OR SQ1/CS2)\n"); break; case 2: printf("on (ED AND (CS1 OR SQ1/CS2))\n"); break; case 3: printf("on (ED OR (CS1 OR SQ1/CS2))\n"); break; } printf(" TX test modes: %s\n", res & BIT(4) ? "all chips set to 1 for CW carrier" : "Alternating bits for carrier suppression test"); printf(" Enable TX test modes: %s\n", res & BIT(3) ? "Invoke tests described above" : "normal operation"); printf(" Antenna choice for TX: Set AntSel %s\n", res & BIT(2) ? "high" : "low"); printf(" TX Antenna Mode: set AntSel pin to %s\n", res & BIT(1) ? "antenna for which last valid header CRC" " occurred" : "value in choice above"); } res = hostap_ioctl_readmif(dev, 10); if (res >= 0) { printf("CR10 (RX Configure): %d\n", res); printf(" Initial CS2 estimate: Use %s\n", res & BIT(7) ? "SQ1 from Barker correlator peaks" : "dot product result"); printf(" CIR estimate/Dot product clock control: %s\n", res & BIT(6) ? "only on after detect" : "on during acquisition"); printf(" SFD Time-out values: "); switch ((res & (BIT(5) | BIT(4))) > 4) { case 0: printf("56 usec\n"); break; case 1: printf("64 usec\n"); break; case 2: printf("128 usec\n"); break; case 3: printf("144 usec\n"); break; } printf(" MD_RDY control: After %s\n", res & BIT(3) ? "SFD" : "CRC16"); printf(" Force Frequency Offset Estimating in all antenna " "diversity timelines: %s\n", res & BIT(2) ? "enabled" : "disabled"); printf(" Antenna choice for RX when single antenna " "acquisition is selected: AntSel pin %s\n", res & BIT(1) ? "high" : "low"); printf(" Antenna acquire: %s\n", res & BIT(0) ? "single antenna" : "dual antenna for diversity acquisition"); } res = hostap_ioctl_readmif(dev, 11); if (res >= 0) { printf("CR11 (RX/TX Configure): %d\n", res); printf(" Continuous internal RX 22 and 44 MHZ clocks: %d\n", res & BIT(7) ? 1 : 0); printf(" A/D input coupling: %s\n", res & BIT(6) ? "AC (external bias network required)" : "DC"); printf(" TX filter / CMF weight select: %s\n", res & BIT(5) ? "Japan" : "US"); printf(" Ping Pong Differential Encode: %s\n", res & BIT(4) ? "normal" : "disabled"); printf(" CCA mode: %s\n", res & BIT(3) ? "Sampled CCA; CCA will update once per " "slot (20 usec)" : "normal CCA; CCA will immediately " "respond to changes in ED, CS1, and SQ1"); printf(" Precursor value in CIR estimate: %d\n", res & (BIT(2) | BIT(1) | BIT(0))); } res = hostap_ioctl_readmif(dev, 12); if (res >= 0) { printf("CR12 (A/D Test Modes 1): %d\n", res); printf(" All DAC and A/D clock source control: %s\n", res & BIT(7) ? "clock via SDI pin" : "normal internal clocks"); printf(" TX DAC clock: %s\n", res & BIT(6) ? "disable" : "enable"); printf(" RX DAC clock: %s\n", res & BIT(5) ? "disable" : "enable"); printf(" I DAC clock: %s\n", res & BIT(4) ? "disable" : "enable"); printf(" Q DAC clock: %s\n", res & BIT(3) ? "disable" : "enable"); printf(" RF A/D clock: %s\n", res & BIT(2) ? "disable" : "enable"); printf(" I A/D clock: %s\n", res & BIT(1) ? "disable" : "enable"); printf(" Q A/D clock: %s\n", res & BIT(0) ? "disable" : "enable"); } res = hostap_ioctl_readmif(dev, 13); if (res >= 0) { printf("CR13 (A/D Test Modes 2): %d\n", res); printf(" Standby: %s\n", res & BIT(7) ? "enable" : "disable"); printf(" SLEEP TX: %s\n", res & BIT(6) ? "enable" : "disable"); printf(" SLEEP RX: %s\n", res & BIT(5) ? "enable" : "disable"); printf(" SLEEP IQ: %s\n", res & BIT(4) ? "enable" : "disable"); printf(" Analog TX Shut_down: %s\n", res & BIT(3) ? "enable" : "disable"); printf(" Analog RX Shut_down: %s\n", res & BIT(2) ? "enable" : "disable"); printf(" Analog Standby: %s\n", res & BIT(1) ? "enable" : "disable"); printf(" Manual control of mixed signal power down " "signals (other CR13 bits): %s\n", res & BIT(0) ? "enable" : "disable"); } res = hostap_ioctl_readmif(dev, 14); if (res >= 0) { printf("CR14 (A/D Test Modes 3): %d\n", res); printf(" DFS - select straight binary output of I/Q and " "RF A/D converters: %d\n", res & BIT(7) ? 1 : 0); printf(" I/Q DAC input control: "); switch ((res & (BIT(6) | BIT(5) | BIT(4))) >> 4) { case 0: printf("normal (TX filter)\n"); break; case 1: printf("down converter\n"); break; case 2: printf("E/L integrator - upper 6 bits (Q) and AGC " "error (I)\n"); break; case 3: printf("I/Q A/D's\n"); break; case 4: printf("Bigger picker output - upper 6 bits of FWT_I " "winner and FWT_Q winner\n"); break; case 5: printf("CMF weights - upper 6 bits of all 16 CMF " "weights circularly shifted with full scale " "negative sync pulse interleaved between " "them\n"); break; case 6: printf("Test Bus pins (5:0) when configured as " "inputs\n"); break; case 7: printf("Barker Correlator/low rate samples\n"); break; } printf(" Enable test bus into RX and TX DAC: %s\n", res & BIT(3) ? "enable" : "disable"); printf(" Enable RF A/D into RX DAC: %s\n", res & BIT(2) ? "enable" : "disable"); printf(" VRbit1: %d\n", res & BIT(1) ? 1 : 0); printf(" VRbit0: %d\n", res & BIT(0) ? 1 : 0); } show_bbp_cr(dev, 15, "AGC GainClip", ""); res = hostap_ioctl_readmif(dev, 16); if (res >= 0) { printf("CR16 (AGC Sat Cpints): %d\n", res); printf(" AGC mid Sat counts: %d\n", (res & (BIT(7) | BIT(6) | BIT(5) | BIT(4))) >> 4); printf(" AGC low Sat counts: %d\n", res & (BIT(3) | BIT(2) | BIT(1) | BIT(0))); } res = hostap_ioctl_readmif(dev, 17); if (res >= 0) { printf("CR17 (AGC Update Control): %d\n", res); printf(" AGC update during CIR injest: %s\n", res & BIT(7) ? "enable" : "disable"); printf(" AGC timer count: %d (must be >31)\n", res & (BIT(5) | BIT(4) | BIT(3) | BIT(2) | BIT(1) | BIT(0))); } show_bbp_cr(dev, 18, "AGC HiSat", ""); show_bbp_cr(dev, 19, "AGC LockinLevel/CW detect threshold", ""); show_bbp_cr(dev, 20, "AGC LockWindow, pos side", ""); show_bbp_cr(dev, 21, "AGC Threshold", ""); show_bbp_cr(dev, 22, "AGC Lookup Table Addr and Control", ""); show_bbp_cr(dev, 23, "AGC Lookup Table Data", ""); show_bbp_cr(dev, 24, "AGC LoopGain", ""); show_bbp_cr(dev, 25, "AGC RX_IF", ""); show_bbp_cr(dev, 26, "AGC Test Modes", ""); show_bbp_cr(dev, 27, "AGC RX_RF Threshold", ""); show_bbp_cr(dev, 28, "AGC Low SatAtten", ""); show_bbp_cr(dev, 29, "AGC LockWindow, negative side", ""); show_bbp_cr(dev, 30, "Carrier Sense 2", ""); show_bbp_cr(dev, 31, "Manual TX Power Control", ""); show_bbp_cr(dev, 32, "Test Modes 1", ""); show_bbp_cr(dev, 33, "Test Modes 2", ""); show_bbp_cr(dev, 34, "Test Bus Address", ""); show_bbp_cr(dev, 35, "CMF Coefficient Control", ""); show_bbp_cr(dev, 36, "Scrambler Seed, Long Preamble Option", ""); show_bbp_cr(dev, 37, "Scrambler Seed, Short Preamble Option", ""); show_bbp_cr(dev, 38, "ED Threshold", ""); show_bbp_cr(dev, 39, "CMF Gain Threshold", ""); show_bbp_cr(dev, 40, "Threshold for antenna decision", ""); show_bbp_cr(dev, 41, "Preamble tracking loop lead coefficient", ""); show_bbp_cr(dev, 42, "Preamble tracking loop lag coefficient", ""); show_bbp_cr(dev, 43, "Header tracking loop lead coefficient", ""); show_bbp_cr(dev, 44, "Header tracking loop lag coefficient", ""); show_bbp_cr(dev, 45, "Data tracking loop lead coefficient", ""); show_bbp_cr(dev, 46, "Data tracking loop lag coefficient", ""); show_bbp_cr(dev, 47, "RF attenuator value", ""); show_bbp_cr(dev, 48, "ED and SQ1 control and SQ1 scale factor", ""); res = hostap_ioctl_readmif(dev, 49); if (res >= 0) { printf("CR49 (Read only register mux control for registers 50 " "to 63): %d\n", res); printf(" CW RSSI threshold: %d\n", res & 127); if (res & 128) show_a_values(dev); else show_b_values(dev); } show_bbp_cr(dev, 60, "RX_IF AGC", ""); res = hostap_ioctl_readmif(dev, 61); if (res >= 0) { printf("CR61 (RX Status Reg): %d\n", res); if (res & BIT(4)) printf(" ED, energy detect past threshold\n"); if (res & BIT(3)) printf(" TX PWR det Register semaphore (CR58 " "updated since last read)\n"); if (res & BIT(2)) printf(" AGC_lock (AGC is within limits of lock " "window CR20)\n"); if (res & BIT(1)) printf(" hwStopBHit (rails hit, AGC updates " "stopped)\n"); if (res & BIT(0)) printf(" RX_RF_AGC - status of AGC output to RF " "chip\n"); } show_bbp_cr(dev, 62, "RSSI", ""); res = hostap_ioctl_readmif(dev, 63); if (res >= 0) { int val; printf("CR63 (RX Status Reg): %d\n", res); val = (res & (BIT(7) | BIT(6))) >> 6; printf(" Signal field value: "); switch (val) { case 0: printf("1 M\n"); break; case 1: printf("2 M\n"); break; case 2: printf("5.5 M\n"); break; case 3: printf("11 M\n"); break; } if (res & BIT(5)) printf(" SFD found\n"); if (res & BIT(4)) printf(" Short preamble detected\n"); if (res & BIT(3)) printf(" Valid signal field found\n"); if (res & BIT(2)) printf(" Valid CRC 16\n"); if (res & BIT(1)) printf(" Antenna selected by received when last " "valid header CRC occurred\n"); if (res & BIT(0)) printf(" not used\n"); } } static void diag_show_pda(const char *dev) { char fname[256]; struct prism2_pda pda; int i, j; printf("\nProduction Data Area (PDA)\n\n"); snprintf(fname, sizeof(fname), "/proc/net/hostap/%s/pda", dev); if (read_wlan_pda(fname, &pda)) { printf("Could not read wlan PDA. This requires " "PRISM2_DOWNLOAD_SUPPORT definition for the kernel " "driver.\n"); return; } for (i = 0; i < pda.pdr_count; i++) { printf("PDR 0x%04x len=%i %s\n ", pda.pdrs[i].pdr, pda.pdrs[i].len, prism2_pdr_name(pda.pdrs[i].pdr)); for (j = 0; j < pda.pdrs[i].len; j++) printf(" %02x", pda.pdrs[i].data[j]); printf("\n"); } free(pda.pdrs); } static void usage(void) { printf("Usage: hostap_diag [-abhpru] \n" "Options:\n" " -h show this usage info\n" " -a show all info\n" " -b show baseband processor control registers\n" " -p show production data area (PDA)\n" " -r show known RIDs\n" " -u show unknown RIDs\n"); exit(1); } int main(int argc, char *argv[]) { int c; int show_known_rids = 0; int show_unknown_rids = 0; int show_bbp = 0; int show_pda = 0; char *dev; for (;;) { c = getopt(argc, argv, "abhpru"); if (c < 0) break; if (c == 'a') { show_known_rids = 1; show_unknown_rids = 1; show_bbp = 1; show_pda = 1; } else if (c == 'b') show_bbp = 1; else if (c == 'h') usage(); else if (c == 'r') show_known_rids = 1; else if (c == 'u') show_unknown_rids = 1; else if (c == 'p') show_pda = 1; else usage(); } if (argc != optind + 1) usage(); dev = argv[optind]; if (diag_show_summary(dev)) exit(1); if (show_known_rids) diag_show_known_rids(dev); if (show_unknown_rids) diag_show_unknown_rids(dev); if (show_bbp) diag_show_bbp(dev); if (show_pda) diag_show_pda(dev); return 0; } hostap-utils-0.4.7/hostap_fw_load0000755000175000001440000000176010004642675015432 0ustar jmusers#!/bin/sh # Example script for automatically loading firmware images when needed. This # can be run, e.g., from /etc/pcmcia/wireless. # Firmware images for the card # TODO: could try to select correct firmware type automatically PRI=/etc/pcmcia/PM010102.HEX STA=/etc/pcmcia/RF010802.HEX PRISM2_SREC=/usr/local/bin/prism2_srec set -e if [ -z "$1" ]; then echo "usage: $0 " exit 1 fi IFNAME=$1 DIR=/proc/net/hostap/$IFNAME if [ ! -d $DIR ]; then echo "Host AP driver data for device $IFNAME not found in procfs." exit 1 fi if grep -q no_pri=1 $DIR/debug; then # no primary image - load primary in two steps, first without PDA and then # with full PDA plugging echo "Downloading primary firmware $PRI" $PRISM2_SREC -gs $IFNAME $PRI $PRISM2_SREC -gp $IFNAME $PRI fi if grep -q pri_only=1 $DIR/debug; then echo "Downloading secondary (station) firmware $STA" $PRISM2_SREC -rp $IFNAME $STA fi echo "Card is ready with both PRI and STA firmware images" hostap-utils-0.4.7/hostap_io_debug.c0000644000175000001440000001455007653623505016022 0ustar jmusers/* * Wireless LAN card I/O debugging tool for Host AP kernel driver * Copyright (c) 2003, Jouni Malinen * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. See README and COPYING for * more details. */ #include #include #include #include #define PRISM2_IO_DEBUG_CMD_INB 0 #define PRISM2_IO_DEBUG_CMD_INW 1 #define PRISM2_IO_DEBUG_CMD_INSW 2 #define PRISM2_IO_DEBUG_CMD_OUTB 3 #define PRISM2_IO_DEBUG_CMD_OUTW 4 #define PRISM2_IO_DEBUG_CMD_OUTSW 5 #define PRISM2_IO_DEBUG_CMD_ERROR 6 #define PRISM2_IO_DEBUG_CMD_INTERRUPT 7 /* PC Card / PLX registers */ #define PCCARD_CMD_OFF 0x00 #define PCCARD_PARAM0_OFF 0x02 #define PCCARD_PARAM1_OFF 0x04 #define PCCARD_PARAM2_OFF 0x06 #define PCCARD_STATUS_OFF 0x08 #define PCCARD_RESP0_OFF 0x0A #define PCCARD_RESP1_OFF 0x0C #define PCCARD_RESP2_OFF 0x0E #define PCCARD_INFOFID_OFF 0x10 #define PCCARD_CONTROL_OFF 0x14 #define PCCARD_SELECT0_OFF 0x18 #define PCCARD_SELECT1_OFF 0x1A #define PCCARD_OFFSET0_OFF 0x1C #define PCCARD_OFFSET1_OFF 0x1E #define PCCARD_RXFID_OFF 0x20 #define PCCARD_ALLOCFID_OFF 0x22 #define PCCARD_TXCOMPLFID_OFF 0x24 #define PCCARD_SWSUPPORT0_OFF 0x28 #define PCCARD_SWSUPPORT1_OFF 0x2A #define PCCARD_SWSUPPORT2_OFF 0x2C #define PCCARD_EVSTAT_OFF 0x30 #define PCCARD_INTEN_OFF 0x32 #define PCCARD_EVACK_OFF 0x34 #define PCCARD_DATA0_OFF 0x36 #define PCCARD_DATA1_OFF 0x38 #define PCCARD_AUXPAGE_OFF 0x3A #define PCCARD_AUXOFFSET_OFF 0x3C #define PCCARD_AUXDATA_OFF 0x3E /* PCI registers */ #define PCI_CMD_OFF 0x00 #define PCI_PARAM0_OFF 0x04 #define PCI_PARAM1_OFF 0x08 #define PCI_PARAM2_OFF 0x0C #define PCI_STATUS_OFF 0x10 #define PCI_RESP0_OFF 0x14 #define PCI_RESP1_OFF 0x18 #define PCI_RESP2_OFF 0x1C #define PCI_INFOFID_OFF 0x20 #define PCI_CONTROL_OFF 0x28 #define PCI_SELECT0_OFF 0x30 #define PCI_SELECT1_OFF 0x34 #define PCI_OFFSET0_OFF 0x38 #define PCI_OFFSET1_OFF 0x3C #define PCI_RXFID_OFF 0x40 #define PCI_ALLOCFID_OFF 0x44 #define PCI_TXCOMPLFID_OFF 0x48 #define PCI_PCICOR_OFF 0x4C #define PCI_SWSUPPORT0_OFF 0x50 #define PCI_SWSUPPORT1_OFF 0x54 #define PCI_SWSUPPORT2_OFF 0x58 #define PCI_PCIHCR_OFF 0x5C #define PCI_EVSTAT_OFF 0x60 #define PCI_INTEN_OFF 0x64 #define PCI_EVACK_OFF 0x68 #define PCI_DATA0_OFF 0x6C #define PCI_DATA1_OFF 0x70 #define PCI_AUXPAGE_OFF 0x74 #define PCI_AUXOFFSET_OFF 0x78 #define PCI_AUXDATA_OFF 0x7C #define PCI_PCI_M0_ADDRH_OFF 0x80 #define PCI_PCI_M0_ADDRL_OFF 0x84 #define PCI_PCI_M0_LEN_OFF 0x88 #define PCI_PCI_M0_CTL_OFF 0x8C #define PCI_PCI_STATUS_OFF 0x98 #define PCI_PCI_M1_ADDRH_OFF 0xA0 #define PCI_PCI_M1_ADDRL_OFF 0xA4 #define PCI_PCI_M1_LEN_OFF 0xA8 #define PCI_PCI_M1_CTL_OFF 0xAC struct reg_info { int reg; char *name; }; static struct reg_info prism2_pccard_regs[] = { { PCCARD_CMD_OFF, "CMD" }, { PCCARD_PARAM0_OFF, "PARAM0" }, { PCCARD_PARAM1_OFF, "PARAM1" }, { PCCARD_PARAM2_OFF, "PARAM2" }, { PCCARD_STATUS_OFF, "STATUS" }, { PCCARD_RESP0_OFF, "RESP0" }, { PCCARD_RESP1_OFF, "RESP1" }, { PCCARD_RESP2_OFF, "RESP2" }, { PCCARD_INFOFID_OFF, "INFOFID" }, { PCCARD_CONTROL_OFF, "CONTROL" }, { PCCARD_SELECT0_OFF, "SELECT0" }, { PCCARD_SELECT1_OFF, "SELECT1" }, { PCCARD_OFFSET0_OFF, "OFFSET0" }, { PCCARD_OFFSET1_OFF, "OFFSET1" }, { PCCARD_RXFID_OFF, "RXFID" }, { PCCARD_ALLOCFID_OFF, "ALLOCFID" }, { PCCARD_TXCOMPLFID_OFF, "TXCOMPLFID" }, { PCCARD_SWSUPPORT0_OFF, "SWSUPPORT0" }, { PCCARD_SWSUPPORT1_OFF, "SWSUPPORT1" }, { PCCARD_SWSUPPORT2_OFF, "SWSUPPORT2" }, { PCCARD_EVSTAT_OFF, "EVSTAT" }, { PCCARD_INTEN_OFF, "INTEN" }, { PCCARD_EVACK_OFF, "EVACK" }, { PCCARD_DATA0_OFF, "DATA0" }, { PCCARD_DATA1_OFF, "DATA1" }, { PCCARD_AUXPAGE_OFF, "AUXPAGE" }, { PCCARD_AUXOFFSET_OFF, "AUXOFFSET" }, { PCCARD_AUXDATA_OFF, "AUXDATA" }, { 0, NULL } }; static struct reg_info prism2_pci_regs[] = { { PCI_CMD_OFF, "CMD" }, { PCI_PARAM0_OFF, "PARAM0" }, { PCI_PARAM1_OFF, "PARAM1" }, { PCI_PARAM2_OFF, "PARAM2" }, { PCI_STATUS_OFF, "STATUS" }, { PCI_RESP0_OFF, "RESP0" }, { PCI_RESP1_OFF, "RESP1" }, { PCI_RESP2_OFF, "RESP2" }, { PCI_INFOFID_OFF, "INFOFID" }, { PCI_CONTROL_OFF, "CONTROL" }, { PCI_SELECT0_OFF, "SELECT0" }, { PCI_SELECT1_OFF, "SELECT1" }, { PCI_OFFSET0_OFF, "OFFSET0" }, { PCI_OFFSET1_OFF, "OFFSET1" }, { PCI_RXFID_OFF, "RXFID" }, { PCI_ALLOCFID_OFF, "ALLOCFID" }, { PCI_TXCOMPLFID_OFF, "TXCOMPLFID" }, { PCI_SWSUPPORT0_OFF, "SWSUPPORT0" }, { PCI_SWSUPPORT1_OFF, "SWSUPPORT1" }, { PCI_SWSUPPORT2_OFF, "SWSUPPORT2" }, { PCI_EVSTAT_OFF, "EVSTAT" }, { PCI_INTEN_OFF, "INTEN" }, { PCI_EVACK_OFF, "EVACK" }, { PCI_DATA0_OFF, "DATA0" }, { PCI_DATA1_OFF, "DATA1" }, { PCI_AUXPAGE_OFF, "AUXPAGE" }, { PCI_AUXOFFSET_OFF, "AUXOFFSET" }, { PCI_AUXDATA_OFF, "AUXDATA" }, { 0, NULL } }; static struct reg_info *prism2_regs = prism2_pccard_regs; static const char * cmd_str(int cmd) { switch (cmd) { case PRISM2_IO_DEBUG_CMD_INB: return "INB"; case PRISM2_IO_DEBUG_CMD_INW: return "INW"; case PRISM2_IO_DEBUG_CMD_INSW: return "INSW"; case PRISM2_IO_DEBUG_CMD_OUTB: return "OUTB"; case PRISM2_IO_DEBUG_CMD_OUTW: return "OUTW"; case PRISM2_IO_DEBUG_CMD_OUTSW: return "OUTSW"; case PRISM2_IO_DEBUG_CMD_ERROR: return "ERROR"; case PRISM2_IO_DEBUG_CMD_INTERRUPT: return "INTERRUPT"; default: return "??"; }; } static const char * addr_str(int cmd, int addr) { static char buf[32]; struct reg_info *reg = prism2_regs; if (cmd == PRISM2_IO_DEBUG_CMD_ERROR) return ""; while (reg->name) { if (reg->reg == addr) return reg->name; reg++; } snprintf(buf, sizeof(buf), "%d", addr); return buf; } int main(int argc, char *argv[]) { FILE *f; uint32_t buf[65536]; size_t len; int i; if (argc < 2) { fprintf(stderr, "hostap_io_debug [-p] \n\n" "example: " "hostap_io_debug /proc/net/hostap/wlan0/io_debug\n"); exit(1); } i = 1; if (strcmp(argv[i], "-p") == 0) { i++; printf("PCI\n"); prism2_regs = prism2_pci_regs; } f = fopen(argv[i], "r"); if (f == NULL) { fprintf(stderr, "File '%s' not found.\n", argv[1]); exit(1); } len = fread(buf, 1, sizeof(buf), f); for (i = 0; i < len / 4; i += 2) { uint32_t cmd, addr, val; cmd = buf[i + 1] >> 24; addr = (buf[i + 1] >> 16) & 0xff; val = buf[i + 1] & 0xffff; printf("%09d %s %s 0x%04x\n", buf[i], cmd_str(cmd), addr_str(cmd, addr), val); } fclose(f); return 0; } hostap-utils-0.4.7/hostap_rid.c0000644000175000001440000000532510034044506015004 0ustar jmusers/* * Prism2/2.5/3 RID get/set tool for Host AP kernel driver * Copyright (c) 2003, Jouni Malinen * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. See README and COPYING for * more details. */ #include #include #include #include #include #include #include #include "util.h" static void usage(void) { printf("Usage: hostap_rid [data]\n" "\n" "Examples:\n" " hostap_rid wlan0 get fc00\n" " hostap_rid wlan0 set fc00 06 00\n" " hostap_rid wlan0 set fc0e 06 00 66 6f 6f 62 61 72\n" "\n" "Note:\n" "- Prism2/2.5/3 uses little-endian byte order\n" "- The most common word size is 16 bits\n" "- Set command needs the raw RID contents, i.e., it will be " "written as is to the device\n"); } static int get_rid(const char *dev, u16 rid) { char buf[PRISM2_HOSTAPD_MAX_BUF_SIZE]; struct prism2_hostapd_param *param; int res, i; param = (struct prism2_hostapd_param *) buf; res = hostapd_get_rid(dev, param, rid, 1); if (res == EPERM) { printf("hostap_rid requires root privileges\n"); return -1; } if (res == ENODATA) { printf("Get RID did not return any data.\n"); return -1; } else if (res) { printf("Could not communicate with the kernel driver.\n"); return -1; } for (i = 0; i < param->u.rid.len; i++) printf("%02x ", param->u.rid.data[i]); printf("\n"); return 0; } static int set_rid(const char *dev, u16 rid, int argc, char *argv[]) { u8 *data; int res, i; long int val; data = (u8 *) malloc(argc); if (data == NULL) return -1; for (i = 0; i < argc; i++) { val = strtol(argv[i], NULL, 16); if (val < 0 || val > 255) { usage(); printf("\nInvalid data value '%s'\n", argv[i]); return -1; } data[i] = val; } res = hostapd_set_rid(dev, rid, data, argc, 1); if (res == EPERM) { printf("hostap_rid requires root privileges\n"); return -1; } if (res) { printf("Could not communicate with the kernel driver.\n"); return -1; } return 0; } int main(int argc, char *argv[]) { char *dev; int set; long int rid; if (argc < 4) { usage(); return -1; } dev = argv[1]; if (strcmp(argv[2], "set") == 0) set = 1; else if (strcmp(argv[2], "get") == 0) set = 0; else { usage(); return -1; } rid = strtol(argv[3], NULL, 16); if (rid < 0 || rid > 65535) { usage(); printf("\nInvalid rid 0x%lx\n", rid); return -1; } if (set) return set_rid(dev, rid, argc - 4, &argv[4]); else return get_rid(dev, rid); } hostap-utils-0.4.7/prism2_param0000755000175000001440000001577207745650221015051 0ustar jmusers#!/bin/sh IWPRIV=iwpriv usage() { cat < [value] Wrapper for setting prism2.o parameters using iwpriv and prism2_param ioctl. This wrapper converts the given text parameter (see list below) to corresponding prism2_param ioctl() value and uses iwpriv to set the given value. If value argument is not given, the current value is shown (if available). interface: interface name for the wireless LAN device to be used (e.g., wlan0) parameter: txratectrl: 0 = use host driver based TX rate control (default), 1 = use f/w based TX rate control beacon_int: beacon interval (1 = 1024 usec) dtim_period: DTIM period, i.e., number of beacon intervals between successive delivery traffic identification maps (DTIMs), used for power saving and multicast/broadcast delivery pseudo_ibss: 0 = use IEEE 802.11 IBSS mode (default), 1 = use pseudo adhoc mode (no management frames) other_ap_policy: 0 = skip all beacons 1 = accept beacons with our SSID 2 = accept beacons from all APs 3 = accept all beacons (even from IBSS) dump: set RX/TX/TXEXC debug dump header bitfield 0 = do not dump frame headers 1 = dump RX frame headers 2 = dump TX frame headers 4 = dump TX error frame headers (these values can be bitwise ORed; e.g. 3 = both RX and TX) ap_max_inactivity: Time (in seconds) after which inactive stations can be removed from AP's station list ap_bridge_packets: 0 = do not bridge packets between associated stations, i.e., just pass them to upper layers for handling 1 = bridge packets directly between associated stations, i.e., upper layers do not even see these packets ap_nullfunc_ack: 0 = let station firmware take care of data::nullfunc ACKs 1 = send "extra" ACKs for data::nullfunc frames to workaround problems with stations using PS mode (default 1 if STA f/w version is 0.8.0, otherwise 0) max_wds: maximum number of allowed WDS connections (default 16) autom_ap_wds: 0 = add WDS connections manually 1 = add WDS connections automatically to all recorded APs (based on other_ap_policy) ap_auth_algs: allowed authentication algorithms 0 = none (no authentication will succeed) 1 = only open 2 = only shared key 3 = open or shared key (default) monitor_allow_fcserr: 0 = drop frames with FCS errors in monitor mode 1 = pass also frames with FCS errors host_encrypt: 0 = do not use host encryption unless in Host AP mode 1 = use host encryption in all modes host_decrypt: 0 = use WLAN card firmware to decrypt frames 1 = use host driver to decrypt frames bus_master_threshold_rx: packet length threshold for using PCI bus master on RX (only used with hostap_pci.o and if PRISM2_BUS_MASTER is set) bus_master_threshold_tx: packet length threshold for using PCI bus master on TX (only used with hostap_pci.o and if PRISM2_BUS_MASTER is set) host_roaming: 0 = use station firmware for roaming decision (default) 1 = use host driver roaming decision (automatic scan) 2 = manual scan and roaming bcrx_sta_key: 0 = use station specific key (WEP key mapping) to override default keys only for RX frames sent to unicast address ("individual RA") (default) 1 = use station specific key also with broadcast RX frames (this is against IEEE 802.11, but makes it easier to use different keys with stations that do not support WEP key mapping) ieee_802_1x: 0 = do not use IEEE 802.1X specific functionality (default) 1 = use IEEE 802.1X: require 802.1X auth, filter EAPOL packets antsel_tx: 0 = do not touch TX AntSel, i.e., use card default (default) 1 = use antenna diversity 2 = force TX AntSel pin low 3 = force TX AntSel pin high antsel_rx: 0 = do not touch RX AntSel, i.e., use card default (default) 1 = use antenna diversity 2 = force RX AntSel pin low 3 = force RX AntSel pin high monitor_type: 0 = IEEE 802.11 headers (ARPHRD_IEEE80211) 1 = Prism2 + IEEE 802.11 headers (ARPHRD_IEEE80211_PRISM) 2 = AVS monitor header + IEEE 802.11 headers (ARPHRD_IEEE80211_PRISM) wds_type: WDS type bitfield 0 = options disabled (default) 1 = use broadcast RA (WDS frame destination) for broadcast and multicast frames 2 = use AP client mode in 'Managed mode' 4 = use standard compliant WDS (4 addr) frame also in Host AP mode (Note! This requires STA f/w ver 1.5.x or newer) hostscan: perform non-destructive AP scanning (i.e., maintain current association state); this requires STA f/w ver 1.3.1 or newer 1 = send Probe Request at 1 Mbps 2 = send Probe Request at 2 Mbps 3 = send Probe Request at 5.5 Mbps 4 = send Probe Request at 11 Mbps ap_scan: interval (in seconds) between passive AP scans on different channels, 0 = disabled (default) enh_sec: "enhanced security" bitfield 0 = options disabled (default) 1 = hide SSID in beacon frames 2 = ignore clients configured with "ANY" (broadcast) SSID (3 = both options) Note! This requires STA f/w ver 1.6.3 or newer basic_rates: basic transmit rate bitmap bit 0: 1 M, bit 1: 2 M, bit 2: 5.5 M, bit 3: 11 M (default 3: 1 and 2 Mbps) oper_rates: operational transmit rate bitmap bit 0: 1 M, bit 1: 2 M, bit 2: 5.5 M, bit 3: 11 M (default 15: 1, 2, 5.5, and 11 Mbps) Note! This changes the same value as iwconfig rate command, but as a bitfield. hostapd: hostapd mode configuration 0 = use kernel driver for IEEE 802.11 management 1 = use user space daemon, hostapd, for IEEE 802.11 management hostapd_sta: hostapd mode configuration 0 = no extra STA interface 1 = use hostapd to control extra STA interface (wlan#sta) Following parameters are for debug use only; do not use unless you are sure what you are doing! alc: 0=disabled ALC, 1=enable ALC (automatic level control) EOF exit 1; } if [ $# != 3 -a $# != 2 ]; then usage fi if ! $IWPRIV $1 | grep -q prism2_param; then echo "Interface '$1' does not seem to support prism2_param command." echo "Run '$0' without any arguments for usage information." exit 2 fi case $2 in txratectrl) param=2 ;; beacon_int) param=3 ;; pseudo_ibss) param=4 ;; alc) param=5 ;; dump) param=7 ;; other_ap_policy) param=8 ;; ap_max_inactivity) param=9 ;; ap_bridge_packets) param=10 ;; dtim_period) param=11 ;; ap_nullfunc_ack) param=12 ;; max_wds) param=13 ;; autom_ap_wds) param=14 ;; ap_auth_algs) param=15 ;; monitor_allow_fcserr) param=16 ;; host_encrypt) param=17 ;; host_decrypt) param=18 ;; bus_master_threshold_rx) param=19 ;; bus_master_threshold_tx) param=20 ;; host_roaming) param=21 ;; bcrx_sta_key) param=22 ;; ieee_802_1x) param=23 ;; antsel_tx) param=24 ;; antsel_rx) param=25 ;; monitor_type) param=26 ;; wds_type) param=27 ;; hostscan) param=28 ;; ap_scan) param=29 ;; enh_sec) param=30 ;; io_debug) param=31 ;; basic_rates) param=32 ;; oper_rates) param=33 ;; hostapd) param=34 ;; hostapd_sta) param=35 ;; *) echo "Unknown parameter '$2'." echo "Run '$0' without any arguments for usage information." exit 3 esac if [ $# = 3 ]; then $IWPRIV $1 prism2_param $param $3 else $IWPRIV $1 getprism2_param $param fi hostap-utils-0.4.7/prism2_srec.c0000644000175000001440000013612210252206750015103 0ustar jmusers/* * Firmware image downloader for Host AP driver * (for Intersil Prism2/2.5/3 cards) * * Copyright (c) 2002-2004, Jouni Malinen * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. See README and COPYING for * more details. */ #include #include #include #include #include #include #include #include #include "wireless_copy.h" #include "util.h" static int verbose = 0; static int ignore_incompatible_interface = 0; static int skip_pda_read = 0; enum { MODE_NO_DOWNLOAD, MODE_VOLATILE, MODE_NON_VOLATILE, MODE_GENESIS }; #define verbose_printf(a...) do { if (verbose) printf(a); } while (0) #define vverbose_printf(a...) do { if (verbose > 1) printf(a); } while (0) struct s3_record { unsigned int addr; int len; unsigned char *data; }; struct s3_info_platform { unsigned int platform, variant, major, minor; }; struct s3_info_component { unsigned int component, variant, major, minor; }; struct s3_info_compatibility { unsigned int role, iface_id, variant, bottom, top; }; struct s3_crc16 { unsigned int start, len, prog; }; struct s3_plug_record { unsigned int pdr, plug_addr, plug_len; }; #define S3_SPECIAL_MASK 0xff000000 #define S3_PLUG_ADDR 0xff000000 #define S3_CRC16_ADDR 0xff100000 #define S3_FW_INFO_ADDR_MASK 0xffff0000 #define S3_FW_INFO_ADDR 0xff200000 #define S3_PRI_INFO_ADDR 0xff010000 #define S3_ENG_ADDR 0xffff0000 struct srec_data { char *name; char *name_rec; struct s3_info_component component; int component_set; int start_addr_set; unsigned int start_addr; struct s3_record *s3_records; int s3_used, s3_entries; struct s3_info_platform *platforms; int platform_count; struct s3_info_compatibility *compatibilities; int compatibility_count; struct s3_crc16 *crc16; int crc16_count; struct s3_plug_record *plugs; int plug_count; unsigned int s3_fw_info_addr; /* expected next S3 f/w info address */ size_t s3_fw_info_buf_len; char *s3_fw_info_buf; }; struct wlan_info { struct s3_info_platform nicid, priid, staid; struct s3_info_compatibility mfi_pri_sup, cfi_pri_sup, pri_sup, sta_sup, mfi_sta_act, cfi_pri_act, cfi_sta_act; struct prism2_pda pda; const char *ifname; }; static int s3_comp(const void *a, const void *b) { const struct s3_record *aa = a, *bb = b; return aa->addr - bb->addr; } static int hex2int(char c) { if (c >= '0' && c <= '9') return (c - '0'); if (c >= 'a' && c <= 'f') return (c - 'a' + 10); if (c >= 'A' && c <= 'F') return (c - 'A' + 10); printf("{hex2int failure '%c'}", c); return -1; } int get_hex8(char *txt) { int val, val2; val = hex2int(txt[0]); val2 = hex2int(txt[1]); if (val < 0 || val2 < 0) return -1; return (val * 16 + val2) & 0xff; } unsigned int get_hex16_le(char *txt) { unsigned int val = 0; int i; for (i = 1; i >= 0; i--) val = (val << 8) | get_hex8(&txt[i * 2]); return val; } unsigned int get_hex32(char *txt) { unsigned int val = 0; int i; for (i = 0; i < 4; i++) val = (val << 8) | get_hex8(&txt[i * 2]); return val; } unsigned int get_hex32_le(char *txt) { unsigned int val = 0; int i; for (i = 3; i >= 0; i--) val = (val << 8) | get_hex8(&txt[i * 2]); return val; } int verify_checksum(char *data, int len) { int i; unsigned char c, c2; c = 0; for (i = 0; i < len; i++) c += get_hex8(&data[i * 2]); c = 0xff - c; c2 = get_hex8(&data[len * 2]); if (c != c2) return 1; return 0; } void enlarge_s3_buf(struct srec_data *srec) { srec->s3_records = (struct s3_record *) realloc(srec->s3_records, 2 * srec->s3_entries * sizeof(struct s3_record)); if (srec->s3_records == NULL) { printf("Could not allocate memory for S3 records.\n"); exit(1); } memset(&srec->s3_records[srec->s3_entries], 0, srec->s3_entries * sizeof(struct s3_record)); srec->s3_entries *= 2; } int s3_combine(struct srec_data *srec) { int from, to, removed; from = to = removed = 0; while (from < srec->s3_used) { struct s3_record *_to, *_to_1, *_from; _to = &srec->s3_records[to]; _to_1 = to > 0 ? &srec->s3_records[to - 1] : NULL; _from = &srec->s3_records[from]; if (_from->len == 0) { removed++; from++; continue; } if (to != 0 && _to_1->addr + _to_1->len == _from->addr) { _to_1->data = (unsigned char *) realloc(_to_1->data, _to_1->len + _from->len); if (_to_1->data == NULL) { printf("realloc() failed\n"); return 1; } memcpy(_to_1->data + _to_1->len, _from->data, _from->len); free(_from->data); _from->data = NULL; _to_1->len += _from->len; removed++; } else { if (from != to) memcpy(_to, _from, sizeof(struct s3_record)); to++; } from++; } srec->s3_used -= removed; if (srec->s3_entries > srec->s3_used) { srec->s3_entries = srec->s3_used; srec->s3_records = (struct s3_record *) realloc(srec->s3_records, srec->s3_entries * sizeof(struct s3_record)); if (srec->s3_records == NULL) { printf("realloc() failed\n"); return 1; } } return 0; } void show_s3_data_areas(struct srec_data *srec) { int i, total_len; printf("S3 area count: %i\n", srec->s3_used); total_len = 0; for (i = 0; i < srec->s3_used; i++) { printf(" addr=0x%08X..0x%08X (len=%i)\n", srec->s3_records[i].addr, srec->s3_records[i].addr + srec->s3_records[i].len - 1, srec->s3_records[i].len); total_len += srec->s3_records[i].len; } printf("Total data length: %i\n", total_len); } int verify_s3_data(struct srec_data *srec) { int i; struct s3_record *p, *e; for (i = 1; i < srec->s3_used; i++) { p = &srec->s3_records[i - 1]; e = &srec->s3_records[i]; if (p->addr + p->len > e->addr) { printf("Overlapping S3 data records (%08x..%08x and " "%08x..%08x)\n", p->addr, p->addr + p->len, e->addr, e->addr + e->len); return 1; } /* TODO: could verify that addresses look correct for volatile/ * non-volatile download */ } return 0; } void overlap_crc16_signatures(struct srec_data *srec, struct srec_data *srec2) { int i, j; /* CRC-16 signatures in STA f/w overlap with PRI f/w area; allow this * as an exception to no overlapping rule. */ for (i = 0; i < srec2->crc16_count; i++) { struct s3_crc16 *c = &srec2->crc16[i]; if (!c->prog) continue; for (j = 0; j < srec->s3_used; j++) { struct s3_record *s = &srec->s3_records[j]; if (c->start == s->addr + s->len && s->len >= 2) { printf("Allowing S3 overlap due to CRC-16 " "signature at 0x%08x (was: %02x%02x)\n", c->start - 2, s->data[s->len - 2], s->data[s->len - 1]); s->len -= 2; break; } } } } /* Merge S3 data areas from srec2 into srec. srec2 will be left with empty * S3 data. */ int merge_s3_data(struct srec_data *srec, struct srec_data *srec2) { int total, i, ret; overlap_crc16_signatures(srec, srec2); total = srec->s3_used + srec2->s3_used; if (srec->s3_entries < total) { struct s3_record *tmp; tmp = (struct s3_record *) realloc(srec->s3_records, total * sizeof(struct s3_record)); if (!tmp) return 1; srec->s3_entries = total; srec->s3_records = tmp; } for (i = 0; i < srec2->s3_used; i++) { memcpy(&srec->s3_records[srec->s3_used], &srec2->s3_records[i], sizeof(struct s3_record)); srec->s3_used++; } srec2->s3_used = 0; qsort(srec->s3_records, srec->s3_used, sizeof(struct s3_record), s3_comp); ret = s3_combine(srec) || verify_s3_data(srec); if (verbose) { printf("After srec file merge\n"); show_s3_data_areas(srec); } return ret; } int process_s3_plug(struct srec_data *srec, char *data, int len, unsigned int addr) { struct s3_plug_record *p; if (len != 3 * 4) { printf("Unknown S3 plug record length %d\n", len); return 1; } srec->plugs = (struct s3_plug_record *) realloc(srec->plugs, (srec->plug_count + 1) * sizeof(struct s3_plug_record)); assert(srec->plugs != NULL); p = &srec->plugs[srec->plug_count]; srec->plug_count++; p->pdr = get_hex32_le(data); p->plug_addr = get_hex32_le(data + 8); p->plug_len = get_hex32_le(data + 16); vverbose_printf("S3 plug record: PDR=0x%04x plug: addr=0x%08X " "len=%i\n", p->pdr, p->plug_addr, p->plug_len); return 0; } int process_s3_crc16(struct srec_data *srec, char *data, int len, unsigned int addr) { struct s3_crc16 *c; if (len != 3 * 4) { printf("Unknown S3 CRC-16 generation record length %d\n", len); return 1; } srec->crc16 = (struct s3_crc16 *) realloc(srec->crc16, (srec->crc16_count + 1) * sizeof(struct s3_crc16)); assert(srec->crc16 != NULL); c = &srec->crc16[srec->crc16_count]; srec->crc16_count++; c->start = get_hex32_le(data); c->len = get_hex32_le(data + 8); c->prog = get_hex32_le(data + 16); verbose_printf("S3 CRC-16 generation record: start=0x%08X " "len=%d prog=%d\n", c->start, c->len, c->prog); return 0; } static int process_s3_fw_info_name(struct srec_data *srec, char *data, int len, unsigned short words) { int i; srec->name_rec = (char *) malloc(len + 1); assert(srec->name_rec != NULL); memset(srec->name_rec, 0, len + 1); for (i = 0; i < len; i++) { int c; c = get_hex8(data + 2 * i); if (c == 0) break; if (c >= 32 && c < 127) srec->name_rec[i] = c; else srec->name_rec[i] = '_'; } verbose_printf("Special S3 firmware info record - name '%s'\n", srec->name_rec); return 0; } static int process_s3_fw_info_ver(struct srec_data *srec, char *data, int words) { if (words != 4) { printf("Invalid S3 f/w info: version info (words=%i)\n", words); return 1; } if (srec->component_set) { printf("More than one S3 f/w info component?\n"); return 1; } srec->component_set++; srec->component.component = get_hex16_le(data); srec->component.variant = get_hex16_le(data + 4); srec->component.major = get_hex16_le(data + 8); srec->component.minor = get_hex16_le(data + 12); vverbose_printf("S3 f/w info: version: component=0x%04x %i.%i.%i\n", srec->component.component, srec->component.major, srec->component.minor, srec->component.variant); return 0; } static int process_s3_fw_info_comp(struct srec_data *srec, char *data, int words) { struct s3_info_compatibility *r; int role, iface_id; if (words < 5 || (words - 2) % 3) { printf("Invalid S3 firmware info: compatibility info " "(words=%i)\n", words); return 1; } role = get_hex16_le(data); iface_id = get_hex16_le(data + 4); data += 2 * 4; words -= 2; while (words >= 3) { srec->compatibilities = (struct s3_info_compatibility *) realloc(srec->compatibilities, (srec->compatibility_count + 1) * sizeof(struct s3_info_compatibility)); assert(srec->compatibilities != NULL); r = &srec->compatibilities[srec->compatibility_count]; srec->compatibility_count++; r->role = role; r->iface_id = iface_id; r->variant = get_hex16_le(data); r->bottom = get_hex16_le(data + 4); r->top = get_hex16_le(data + 8); data += 3 * 4; words -= 3; vverbose_printf("S3 f/w info: compatibility: role=0x%04x " "iface_id=0x%04x variant=%i range=%i-%i\n", r->role, r->iface_id, r->variant, r->bottom, r->top); } return 0; } static int process_s3_fw_info_seq(struct srec_data *srec, char *data, int words) { unsigned short seq; if (words != 1) { printf("Invalid S3 firmware info: " "build sequence words: %i\n", words); return 1; } seq = get_hex16_le(data); vverbose_printf("S3 f/w info: build seq#: %i\n", seq); return 0; } static int process_s3_fw_info_platform(struct srec_data *srec, char *data, int words) { struct s3_info_platform *p; if (words != 4) { printf("Invalid S3 firmware info: " "platform info words: %i\n", words); return 1; } srec->platforms = (struct s3_info_platform *) realloc(srec->platforms, (srec->platform_count + 1) * sizeof(struct s3_info_platform)); assert(srec->platforms != NULL); p = &srec->platforms[srec->platform_count]; srec->platform_count++; p->platform = get_hex16_le(data); p->variant = get_hex16_le(data + 4); p->major = get_hex16_le(data + 8); p->minor = get_hex16_le(data + 12); vverbose_printf("S3 f/w info: platform: id=0x%04x %u.%u.%u\n", p->platform, p->major, p->minor, p->variant); return 0; } int process_s3_fw_info(struct srec_data *srec, char *data, int len, unsigned int addr) { unsigned short words, type; int ret = 0; if (addr != srec->s3_fw_info_addr) { printf("Invalid S3 firmware info start addr 0x%x (expected " "0x%x)\n", addr, srec->s3_fw_info_addr); srec->s3_fw_info_addr = S3_FW_INFO_ADDR; return 1; } if (addr == S3_FW_INFO_ADDR) { if (srec->s3_fw_info_buf) { printf("Unfinished S3 firmware info\n"); return 1; } if (len < 4) { printf("Too short S3 firmware info (len %i)\n", len); printf("S3 line: %s\n", data); return 1; } words = get_hex16_le(data); type = get_hex16_le(data + 4); } else { if (srec->s3_fw_info_buf == NULL) { printf("Did not see first fragment of S3 firmware " "info record\n"); return -1; } words = get_hex16_le(srec->s3_fw_info_buf); type = get_hex16_le(srec->s3_fw_info_buf + 4); } if (addr != S3_FW_INFO_ADDR || len + srec->s3_fw_info_buf_len < words * 2) { /* S3 f/w info record spanning multiple S3 records */ char *newbuf; newbuf = realloc(srec->s3_fw_info_buf, (srec->s3_fw_info_buf_len + len) * 2); if (newbuf == NULL) { printf("Failed to allocate memory for S3 f/w info " "record\n"); return 1; } memcpy(newbuf + srec->s3_fw_info_buf_len * 2, data, len * 2); srec->s3_fw_info_buf = newbuf; srec->s3_fw_info_buf_len += len; srec->s3_fw_info_addr = addr + len; if (srec->s3_fw_info_buf_len < words * 2) return 0; /* continued in the next S3 record */ /* Full S3 f/w info record has now been reassembled */ data = srec->s3_fw_info_buf; len = srec->s3_fw_info_buf_len; } /* remove words and type fields */ data += 8; len -= 4; /* silly, but this special record has different logic in words field */ if (type != 0x8001) words--; if (words * 2 != len) { printf("Invalid S3 firmware info len: len=%i words=%i " "type=0x%x\n", len, words, type); printf("S3 line: %s\n", data); return 1; } /* Reset next S3 f/w info address into default value */ srec->s3_fw_info_addr = S3_FW_INFO_ADDR; switch (type) { case 1: ret = process_s3_fw_info_ver(srec, data, words); break; case 2: ret = process_s3_fw_info_comp(srec, data, words); break; case 3: ret = process_s3_fw_info_seq(srec, data, words); break; case 4: ret = process_s3_fw_info_platform(srec, data, words); break; case 0x8001: ret = process_s3_fw_info_name(srec, data, len, words); break; default: printf("Unknown S3 firmware info type %i\n", type); ret = 1; break; } free(srec->s3_fw_info_buf); srec->s3_fw_info_buf = NULL; srec->s3_fw_info_buf_len = 0; return ret; } #define MAX_S3_LEN 128 int process_s3_data(struct srec_data *srec, char *data, int len, unsigned int addr) { unsigned char buf[MAX_S3_LEN]; int i; for (i = 0; i < len; i++) buf[i] = get_hex8(data + i * 2); if (srec->s3_used > 0 && srec->s3_records[srec->s3_used - 1].addr + srec->s3_records[srec->s3_used - 1].len == addr) { /* combine with previous S3 record */ srec->s3_records[srec->s3_used - 1].data = (unsigned char *) realloc(srec->s3_records[srec->s3_used - 1].data, srec->s3_records[srec->s3_used - 1].len + len); if (srec->s3_records[srec->s3_used - 1].data == NULL) { printf("realloc() failed\n"); return 1; } memcpy(srec->s3_records[srec->s3_used - 1].data + srec->s3_records[srec->s3_used - 1].len, buf, len); srec->s3_records[srec->s3_used - 1].len += len; } else { if (srec->s3_used + 1 == srec->s3_entries) enlarge_s3_buf(srec); srec->s3_records[srec->s3_used].addr = addr; srec->s3_records[srec->s3_used].len = len; srec->s3_records[srec->s3_used].data = (unsigned char *) malloc(len); if (srec->s3_records[srec->s3_used].data == NULL) { printf("malloc() failed\n"); return 1; } memcpy(srec->s3_records[srec->s3_used].data, buf, len); srec->s3_used++; } return 0; } int process_s3(struct srec_data *srec, char *data, int len) { unsigned int addr; if (len < 4) { printf("Too short S3 len=%i\n", len); return 1; } if (len - 4 > MAX_S3_LEN) { printf("Too long S3 len=%i\n", len); return 1; } addr = get_hex32(data); len -= 4; data += 8; if (addr & S3_SPECIAL_MASK) { /* special S3 records */ if (addr == S3_PLUG_ADDR) { if (process_s3_plug(srec, data, len, addr)) return 1; } else if (addr == S3_CRC16_ADDR) { if (process_s3_crc16(srec, data, len, addr)) return 1; } else if ((addr & S3_FW_INFO_ADDR_MASK) == S3_FW_INFO_ADDR) { if (process_s3_fw_info(srec, data, len, addr)) return 1; } else { printf("Unknown special S3 record: '%s'\n", data); return 1; } } else { /* normal S3 record */ if (process_s3_data(srec, data, len, addr)) return 1; } return 0; } int process_s7(struct srec_data *srec, char *data, int len) { int i; if (len != 4) { printf("Invalid S7 length %i (expected 4)\n", len); return 1; } srec->start_addr = 0; for (i = 0; i < 4; i++) { srec->start_addr = (srec->start_addr << 8) | (hex2int(data[i * 2]) << 4) | hex2int(data[1 + i * 2]); } srec->start_addr_set = 1; verbose_printf("Start address 0x%08x\n", srec->start_addr); return 0; } void free_srec(struct srec_data *srec) { int i; if (srec == NULL) return; if (srec->s3_records != NULL) { for (i = 0; i < srec->s3_used; i++) free(srec->s3_records[i].data); free(srec->s3_records); } free(srec->platforms); free(srec->compatibilities); free(srec->crc16); free(srec->plugs); free(srec->name); free(srec->name_rec); free(srec->s3_fw_info_buf); free(srec); } struct srec_data * read_srec(const char *fname) { FILE *f; char buf[1024]; const char *pos; int i, len, slen; int errors = 0, line = 0; struct srec_data *srec; f = fopen(fname, "r"); if (f == NULL) { printf("'%s' not readable: %s.\n", fname, strerror(errno)); return NULL; } srec = (struct srec_data *) malloc(sizeof(struct srec_data)); if (srec == NULL) { fclose(f); return NULL; } memset(srec, 0, sizeof(struct srec_data)); srec->s3_fw_info_addr = S3_FW_INFO_ADDR; pos = strrchr(fname, '/'); if (pos == NULL) pos = fname; else pos++; srec->name = strdup(pos); srec->s3_used = 0; srec->s3_entries = 1024; srec->s3_records = (struct s3_record *) malloc(srec->s3_entries * sizeof(struct s3_record)); if (srec->s3_records == NULL) { printf("Could not allocate memory for S3 records.\n"); fclose(f); free(srec); return NULL; } memset(srec->s3_records, 0, srec->s3_entries * sizeof(struct s3_record)); while (fgets(buf, sizeof(buf), f) != NULL) { line++; buf[sizeof(buf) - 1] = '\0'; for (i = 0; i < sizeof(buf); i++) { if (buf[i] == '\r' || buf[i] == '\n') { buf[i] = '\0'; } if (buf[i] == '\0') break; } if (buf[0] == '\0') continue; if (buf[0] != 'S' || buf[1] == '\0') { fprintf(stderr, "Skipped unrecognized line %i: '%s'\n", line, buf); errors++; continue; } len = get_hex8(buf + 2); slen = strlen(buf + 2); if (len < 1 || slen & 1 || len + 1 != slen / 2) { printf("Invalid line %i length (len=%d slen=%d) " "'%s'\n", line, len, slen, buf); } if (verify_checksum(buf + 2, len)) { printf("line %i: checksum failure\n", line); errors++; continue; } buf[slen] = '\0'; switch (buf[1]) { case '3': if (process_s3(srec, buf + 4, len - 1)) { printf("S3 parse error; line=%d\n", line); errors++; } break; case '7': if (process_s7(srec, buf + 4, len - 1)) { printf("S7 parse error; line=%d\n", line); errors++; } break; default: fprintf(stderr, "Skipped unrecognized S-line %i: " "'%s'\n", line, buf); errors++; break; } } fclose(f); if (srec->s3_fw_info_buf) { fprintf(stderr, "Unfinished S3 firmware info\n"); errors++; } if (verbose > 1) { printf("Before S3 sort\n"); show_s3_data_areas(srec); } qsort(srec->s3_records, srec->s3_used, sizeof(struct s3_record), s3_comp); if (s3_combine(srec) || verify_s3_data(srec)) errors++; if (verbose > 1) { printf("\nAfter S3 sort\n"); show_s3_data_areas(srec); } if (errors > 0) { printf("Errors found - file cannot be used\n"); free_srec(srec); return NULL; } return srec; } enum { ROLE_SUPPLIER = 0, ROLE_ACTOR = 1 }; enum { IFACE_MF = 1, IFACE_CF = 2, IFACE_PRI = 3, IFACE_STA = 4 }; void show_compatibility(struct s3_info_compatibility *r, const char *prefix) { const char *iface_id_str; switch (r->iface_id) { case IFACE_MF: iface_id_str = "Modem-Firmware"; break; case IFACE_CF: iface_id_str = "Controller-Firmware"; break; case IFACE_PRI: iface_id_str = "Primary Firmware-Driver"; break; case IFACE_STA: iface_id_str = "Station Firmware-Driver"; break; default: iface_id_str = "??"; break; } printf(" %srole=%s variant=%d range=%d-%d iface=%s (%d)\n", prefix, r->role == ROLE_SUPPLIER ? "Supplier" : "Actor ", r->variant, r->bottom, r->top, iface_id_str, r->iface_id); } void show_srec(struct srec_data *srec) { int i; printf("srec summary for %s\n", srec->name); if (srec->name_rec) printf("Included file name: %s\n", srec->name_rec); printf("Component: 0x%04x %i.%i.%i", srec->component.component, srec->component.major, srec->component.minor, srec->component.variant); switch (srec->component.component) { case HFA384X_COMP_ID_PRI: printf(" (primary firmware)"); break; case HFA384X_COMP_ID_STA: printf(" (station firmware)"); break; case HFA384X_COMP_ID_FW_AP: printf(" (tertiary firmware)"); break; } printf("\n"); if (verbose) { printf("Supported platforms:\n"); for (i = 0; i < srec->platform_count; i++) { struct s3_info_platform *p = &srec->platforms[i]; printf(" 0x%04x %u.%u.%u", p->platform, p->major, p->minor, p->variant); if (i == srec->platform_count - 1 || i % 5 == 4) printf("\n"); else printf(","); } printf("Interface compatibility information:\n"); for (i = 0; i < srec->compatibility_count; i++) show_compatibility(&srec->compatibilities[i], ""); printf("Separate S3 data areas:\n"); show_s3_data_areas(srec); if (srec->start_addr_set) printf("Start address 0x%08x\n", srec->start_addr); } } static int get_compid(const char *dev, u16 rid, struct s3_info_platform *p) { char buf[PRISM2_HOSTAPD_MAX_BUF_SIZE]; struct prism2_hostapd_param *param; struct hfa384x_comp_ident *comp; param = (struct prism2_hostapd_param *) buf; comp = (struct hfa384x_comp_ident *) param->u.rid.data; if (hostapd_get_rid(dev, param, rid, 1) || param->u.rid.len != sizeof(*comp)) return -1; p->platform = le_to_host16(comp->id); p->major = le_to_host16(comp->major); p->minor = le_to_host16(comp->minor); p->variant = le_to_host16(comp->variant); return 0; } static int get_range(const char *dev, u16 rid, struct s3_info_compatibility *r) { char buf[PRISM2_HOSTAPD_MAX_BUF_SIZE]; struct prism2_hostapd_param *param; struct hfa384x_sup_range *range; param = (struct prism2_hostapd_param *) buf; range = (struct hfa384x_sup_range *) param->u.rid.data; if (hostapd_get_rid(dev, param, rid, 1) || param->u.rid.len != sizeof(*range)) return -1; r->role = le_to_host16(range->role); r->iface_id = le_to_host16(range->id); r->variant = le_to_host16(range->variant); r->bottom = le_to_host16(range->bottom); r->top = le_to_host16(range->top); return 0; } int read_wlan_rids(const char *dev, struct wlan_info *wlan) { if (get_compid(dev, HFA384X_RID_NICID, &wlan->nicid) || get_compid(dev, HFA384X_RID_PRIID, &wlan->priid)) { printf("Missing wlan component info\n"); return 1; } if (get_compid(dev, HFA384X_RID_STAID, &wlan->staid)) printf("STAID not available (maybe running PRI-only)\n"); get_range(dev, HFA384X_RID_PRISUPRANGE, &wlan->pri_sup); get_range(dev, HFA384X_RID_CFIACTRANGES, &wlan->cfi_pri_act); get_range(dev, HFA384X_RID_MFISUPRANGE, &wlan->mfi_pri_sup); get_range(dev, HFA384X_RID_CFISUPRANGE, &wlan->cfi_pri_sup); get_range(dev, HFA384X_RID_STASUPRANGE, &wlan->sta_sup); get_range(dev, HFA384X_RID_MFIACTRANGES, &wlan->mfi_sta_act); get_range(dev, HFA384X_RID_CFIACTRANGES, &wlan->cfi_sta_act); return 0; } void show_wlan(struct wlan_info *wlan) { if (verbose) { printf("Wireless LAN card information:\n"); printf("Components:\n"); printf(" NICID: 0x%04x v%u.%u.%u\n", wlan->nicid.platform, wlan->nicid.major, wlan->nicid.minor, wlan->nicid.variant); printf(" PRIID: 0x%04x v%u.%u.%u\n", wlan->priid.platform, wlan->priid.major, wlan->priid.minor, wlan->priid.variant); printf(" STAID: 0x%04x v%u.%u.%u\n", wlan->staid.platform, wlan->staid.major, wlan->staid.minor, wlan->staid.variant); printf("Interface compatibility information:\n"); show_compatibility(&wlan->mfi_pri_sup, "PRI "); show_compatibility(&wlan->cfi_pri_sup, "PRI "); show_compatibility(&wlan->pri_sup, "PRI "); show_compatibility(&wlan->sta_sup, "STA "); show_compatibility(&wlan->cfi_pri_act, "PRI "); show_compatibility(&wlan->cfi_sta_act, "STA "); show_compatibility(&wlan->mfi_sta_act, "STA "); } if (verbose > 1) { int i, j; for (i = 0; i < wlan->pda.pdr_count; i++) { printf("PDR 0x%04x len=%i:", wlan->pda.pdrs[i].pdr, wlan->pda.pdrs[i].len); for (j = 0; j < wlan->pda.pdrs[i].len; j++) printf(" %02x", wlan->pda.pdrs[i].data[j]); printf("\n"); } } } void free_wlan(struct wlan_info *wlan) { if (wlan->pda.pdrs) free(wlan->pda.pdrs); } unsigned char *get_s3_data_pos(struct srec_data *srec, unsigned int addr, unsigned int len) { int i; for (i = 0; i < srec->s3_used; i++) { struct s3_record *s = &srec->s3_records[i]; if (s->addr <= addr && s->addr + s->len > addr) { if (s->len - (addr - s->addr) < len) { printf("Plug record (addr=0x%08x, len=%u) not " "within data area\n", addr, len); return NULL; } return s->data + (addr - s->addr); } } return NULL; } static int supported_platform(struct s3_info_platform *nicid, struct srec_data *srec, int dl_mode) { int i; if (dl_mode == MODE_GENESIS && (skip_pda_read || (ignore_incompatible_interface && srec->component.component == HFA384X_COMP_ID_PRI))) { /* No PRI f/w - NIC/PRI/STA versions were not read */ return 1; } for (i = 0; i < srec->platform_count; i++) { struct s3_info_platform *p = &srec->platforms[i]; if (p->platform == nicid->platform && p->major == nicid->major && p->minor == nicid->minor && p->variant == nicid->variant) return 1; } /* NICID was not found - reported compatability, if it is known to work * and non-volatile download is not used */ if (dl_mode == MODE_NON_VOLATILE) return 0; for (i = 0; i < srec->platform_count; i++) { struct s3_info_platform *p = &srec->platforms[i]; /* Known to work: * NICID 0x8008 v1.0.1 (D-Link DWL-650) with supported platform * 0x8008 v1.0.0 */ if (nicid->platform == 0x8008 && nicid->major == 1 && nicid->minor == 0 && nicid->variant == 1 && p->platform == 0x8008 && p->major == 1 && p->minor == 0 && p->variant == 0) { printf("Exact NICID was not found from the list of " "supported platforms, but an\nalternative that " "has been reported to work was found.\n"); return 1; } } return 0; } int verify_compatibility(struct wlan_info *wlan, struct srec_data *srec, struct s3_info_compatibility *pri_sup, int image2, int dl_mode) { int i; if (dl_mode == MODE_GENESIS && skip_pda_read) { /* No PRI f/w - RIDs were not read */ return 0; } for (i = 0; i < srec->compatibility_count; i++) { struct s3_info_compatibility *sr, *wr; sr = &srec->compatibilities[i]; if (sr->role == ROLE_SUPPLIER) continue; if (sr->role != ROLE_ACTOR) { printf("Unknown interface compatibility role %d\n", sr->role); return 1; } switch (sr->iface_id) { case IFACE_MF: wr = &wlan->mfi_pri_sup; break; case IFACE_CF: wr = &wlan->cfi_pri_sup; break; case IFACE_PRI: wr = pri_sup; break; case IFACE_STA: wr = &wlan->sta_sup; break; default: printf("Unknown interface compatibility id %d\n", sr->iface_id); return 1; } /* Ignore differences in variant when both PRI and STA * firmwares are being combined. */ if (((!image2 || sr->iface_id != IFACE_PRI) && sr->variant != wr->variant) || sr->top < wr->bottom || sr->bottom > wr->top) { printf("Incompatible interfaces:\n"); show_compatibility(sr, "SREC: "); show_compatibility(wr, "card: "); if (ignore_incompatible_interface) printf("Ignoring incompatibility\n"); else return 1; } } return 0; } static int plug_pdr_0400(const char *ifname, u8 *pdr) { int ram16 = -1, pci = -1, len; char fname[256], buf[1024], *pos, *pos2, *end; FILE *f; snprintf(fname, sizeof(fname), "/proc/net/hostap/%s/debug", ifname); f = fopen(fname, "r"); if (f == NULL) { printf("Failed to open '%s' for reading.\n", fname); return -1; } len = fread(buf, 1, sizeof(buf) - 1, f); if (len < 0) { printf("Failed to read '%s' for reading.\n", fname); return -1; } buf[len] = '\0'; pos = buf; end = buf + len; while (pos < end) { pos2 = strchr(pos, '\n'); if (pos2) *pos2 = '\0'; if (strncmp(pos, "pci=", 4) == 0) { pci = atoi(pos + 4); } else if (strncmp(pos, "sram_type=", 10) == 0) { ram16 = atoi(pos + 10) == 0 ? 0 : 1; } if (pos2 == NULL) break; pos = pos2 + 1; } if (pci == -1 || ram16 == -1) { printf("Failed to parse 'pci' or 'sram_type' from %s.\n", fname); return -1; } pdr[0] = (pci ? BIT(2) : 0) | (ram16 ? BIT(1) : 0) | BIT(0); pdr[1] = 0x00; printf("Plugging PDR 0400 (NIC configuration): ram16=%d " "pci=%d (%02x %02x)\n", ram16, pci, pdr[0], pdr[1]); return 0; } int plug_pdr_entries(struct wlan_info *wlan, struct srec_data *srec) { int i, j, found; for (i = 0; i < srec->plug_count; i++) { struct s3_plug_record *p = &srec->plugs[i]; unsigned char *pos; verbose_printf("Plugging PDR 0x%04x at 0x%08x (len=%d)\n", p->pdr, p->plug_addr, p->plug_len); pos = get_s3_data_pos(srec, p->plug_addr, p->plug_len); if (pos == NULL) { printf("Could not find data position for plugging PDR " "0x%04x at 0x%08x (len=%d)\n", p->pdr, p->plug_addr, p->plug_len); } if (p->pdr == 0xffffffff) { /* Special PDR reserved for an ASCIIZ string * (available from RID FFFF); like file name for * upgrade packet, etc. */ int len; if (pos == NULL) return 1; memset(pos, 0, p->plug_len); len = strlen(srec->name); if (p->plug_len > 0) memcpy(pos, srec->name, len > p->plug_len - 1 ? p->plug_len - 1 : len); continue; } if (skip_pda_read && p->pdr == 0x0400 && p->plug_len == 2) { if (pos == NULL) return 1; if (plug_pdr_0400(wlan->ifname, pos)) return 1; continue; } found = 0; for (j = 0; j < wlan->pda.pdr_count; j++) { if (wlan->pda.pdrs[j].pdr == p->pdr) { if (wlan->pda.pdrs[j].len != p->plug_len) { printf("Plug record length mismatch " "(PDR=0x%04x): %i != %i\n", p->pdr, wlan->pda.pdrs[j].len, p->plug_len); if (ignore_incompatible_interface) { printf("==> use default\n"); break; } else if (p->pdr == 1 && wlan->pda.pdrs[j].len < p->plug_len) { /* PDR 0x0001 - 'manufacturing * part number' seems to be * smaller on some PDAs; just * enlarge it using default */ printf("==> extend from " "default\n"); } else return 1; } if (pos == NULL) return 1; memcpy(pos, wlan->pda.pdrs[j].data, wlan->pda.pdrs[j].len); found = 1; break; } } if (!found && pos == NULL) { printf("PDR 0x%04x is not in wlan card PDA and " "there is no default data. Ignoring plug " "record.\n", p->pdr); continue; } if (!found && verbose) { int j; printf("PDR 0x%04x not found from wlan card PDA. " "Using default data.\n len=%i:", p->pdr, p->plug_len); for (j = 0; j < p->plug_len; j++) printf(" %02x", pos[j]); printf("\n"); } } return 0; } int generate_crc16(struct srec_data *srec) { int i, j, found; for (i = 0; i < srec->crc16_count; i++) { struct s3_crc16 *c = &srec->crc16[i]; if (c->prog) { struct s3_record *s = NULL; verbose_printf("Generating CRC-16 (start=0x%08x, " "len=%d) at 0x%08x\n", c->start, c->len, c->start - 2); /* Note! CRC-16 support is not implemented, but primary * firmware expects that secondary firmware has * signature stamp 0xC0DE at the address location of * CRC-16 value (just before c->start). */ found = 0; for (j = 0; j < srec->s3_used; j++) { s = &srec->s3_records[j]; if (s->addr == c->start) { found = 1; break; } } if (!found) { printf("Could not find proper place for " "CRC-16\n"); return 1; } s->data = realloc(s->data, s->len + 2); assert(s->data != NULL); memmove(s->data + 2, s->data, s->len); s->addr -= 2; s->len += 2; s->data[0] = 0xDE; s->data[1] = 0xC0; } } return 0; } /* Verify compatibility of the image(s) to be downloaded with the current * hardware/firmware revisions. Plug PDA information. If two images are * downloaded at the same time, srec is PRI f/w and srec2 is STA f/w. */ int combine_info(struct wlan_info *wlan, struct srec_data *srec, struct srec_data *srec2, int dl_mode) { if (!supported_platform(&wlan->nicid, srec, dl_mode)) { printf("NICID was not found from the list of supported " "platforms.\n"); return 1; } if (verify_compatibility(wlan, srec, &wlan->pri_sup, 0, dl_mode) || plug_pdr_entries(wlan, srec) || generate_crc16(srec)) return 1; if (srec2) { struct s3_info_compatibility *pri_sup = &wlan->pri_sup; int i; for (i = 0; i < srec->compatibility_count; i++) { struct s3_info_compatibility *sr; sr = &srec->compatibilities[i]; if (sr->role == ROLE_SUPPLIER && sr->iface_id == IFACE_PRI) { printf("PRI: old iface %d:%d-%d new iface " "%d:%d-%d\n", pri_sup->variant, pri_sup->bottom, pri_sup->top, sr->variant, sr->bottom, sr->top); pri_sup = sr; break; } } if (!supported_platform(&wlan->nicid, srec2, dl_mode) || verify_compatibility(wlan, srec2, pri_sup, 1, dl_mode) || plug_pdr_entries(wlan, srec2) || generate_crc16(srec2)) { printf("Compatibility verification failed for the " "second image.\n"); return 1; } if (merge_s3_data(srec, srec2)) { printf("Failed to merge firmware images for " "downloading.\n"); return 1; } } if ((dl_mode == MODE_VOLATILE || dl_mode == MODE_GENESIS) && srec->start_addr == 0) { printf("\nThis image is not meant to be downloaded to " "volatile memory.\n"); return 1; } if (dl_mode == MODE_NON_VOLATILE && srec->start_addr != 0) { printf("\nThis image is not meant to be downloaded to " "non-volatile memory.\n"); return 1; } return 0; } void dump_s3_data(struct srec_data *srec, const char *fname) { FILE *f; int i; f = fopen(fname, "w"); if (f == NULL) return; printf("Writing image dump into '%s'\n", fname); for (i = 0; i < srec->s3_used; i++) { fseek(f, srec->s3_records[i].addr, SEEK_SET); fwrite(srec->s3_records[i].data, srec->s3_records[i].len, 1, f); } fclose(f); } int download_srec(const char *iface, struct srec_data *srec, int non_volatile, int genesis, int persistent) { struct prism2_download_param *param; int plen, i, ret = 0, s = -1; unsigned int total_len; struct iwreq iwr; plen = sizeof(struct prism2_download_param) + srec->s3_used * sizeof(struct prism2_download_area); param = (struct prism2_download_param *) malloc(plen); assert(param != NULL); memset(param, 0, plen); if (non_volatile) param->dl_cmd = PRISM2_DOWNLOAD_NON_VOLATILE; else if (genesis && persistent) param->dl_cmd = PRISM2_DOWNLOAD_VOLATILE_GENESIS_PERSISTENT; else if (genesis) param->dl_cmd = PRISM2_DOWNLOAD_VOLATILE_GENESIS; else if (persistent) param->dl_cmd = PRISM2_DOWNLOAD_VOLATILE_PERSISTENT; else param->dl_cmd = PRISM2_DOWNLOAD_VOLATILE; param->start_addr = srec->start_addr; param->num_areas = srec->s3_used; total_len = 0; for (i = 0; i < srec->s3_used; i++) { if (srec->s3_records[i].len > PRISM2_MAX_DOWNLOAD_AREA_LEN) { printf("Too large data area.\n"); ret = 1; goto out; } param->data[i].addr = srec->s3_records[i].addr; param->data[i].len = srec->s3_records[i].len; param->data[i].ptr = srec->s3_records[i].data; total_len += srec->s3_records[i].len; } if (total_len > PRISM2_MAX_DOWNLOAD_LEN) { printf("Too large total download length.\n"); ret = 1; goto out; } s = socket(AF_INET, SOCK_DGRAM, 0); if (s < 0) { perror("socket"); ret = 1; goto out; } memset(&iwr, 0, sizeof(iwr)); strncpy(iwr.ifr_name, iface, IFNAMSIZ); iwr.u.data.pointer = (caddr_t) param; iwr.u.data.length = plen; if (ioctl(s, PRISM2_IOCTL_DOWNLOAD, &iwr) < 0) { if (errno == EOPNOTSUPP) { /* PDA read should have already failed if * PRISM2_DOWNLOAD_SUPPORT is not defined */ printf("Odd.. Download request for the kernel driver " "failed.\n" "Are you sure you have compiled (and loaded " "the correct version of)\n" "hostap.o module with " "PRISM2_DOWNLOAD_SUPPORT definition in\n" "driver/module/hostap_config.h?\n"); if (non_volatile) { printf("In addition, non-volatile download " "requires PRISM2_NON_VOLATILE_DOWNLOAD" "\nto be defined.\n"); } } perror("ioctl[PRISM2_IOCTL_DOWNLOAD]"); ret = 1; goto out; } out: if (s >= 0) close(s); free(param); return ret; } static void pdr_compid_to_info(struct s3_info_platform *p, unsigned char *data) { struct pdr_compid *comp = (struct pdr_compid *) data; p->platform = le_to_host16(comp->id); p->major = le_to_host16(comp->major); p->minor = le_to_host16(comp->minor); p->variant = le_to_host16(comp->variant); } static void pdr_range_to_info(struct s3_info_compatibility *r, unsigned char *data) { struct pdr_supplier_range *range = (struct pdr_supplier_range *) data; r->role = le_to_host16(range->role); r->iface_id = le_to_host16(range->iface_id); r->variant = le_to_host16(range->variant); r->bottom = le_to_host16(range->bottom); r->top = le_to_host16(range->top); } static void compat_from_pda(struct wlan_info *wlan) { int i; for (i = 0; i < wlan->pda.pdr_count; i++) { switch (wlan->pda.pdrs[i].pdr) { case PDR_RF_MODE_SUPP_RANGE: if (wlan->pda.pdrs[i].len == sizeof(struct pdr_supplier_range)) pdr_range_to_info(&wlan->mfi_pri_sup, wlan->pda.pdrs[i].data); break; case PDR_MAC_CTRL_SUPP_RANGE: if (wlan->pda.pdrs[i].len == sizeof(struct pdr_supplier_range)) pdr_range_to_info(&wlan->cfi_pri_sup, wlan->pda.pdrs[i].data); break; case PDR_NIC_ID_COMP: if (wlan->pda.pdrs[i].len == sizeof(struct pdr_compid)) pdr_compid_to_info(&wlan->nicid, wlan->pda.pdrs[i].data); break; } } } static void dump_pda_data(struct prism2_pda *pda) { int i, j; for (i = 0; i < pda->pdr_count; i++) { if (pda->pdrs[i].len & 1) printf("WARNING: odd PDR 0x%04x length (%d)\n", pda->pdrs[i].pdr, pda->pdrs[i].len); printf("; PDR 0x%04x data len=%i %s\n", pda->pdrs[i].pdr, pda->pdrs[i].len, prism2_pdr_name(pda->pdrs[i].pdr)); printf("%x %04x\n", pda->pdrs[i].len / 2 + 1, pda->pdrs[i].pdr); for (j = 0; j < pda->pdrs[i].len; j += 2) printf("%s%02x%02x", j == 0 ? "" : " ", pda->pdrs[i].data[j + 1], pda->pdrs[i].data[j]); printf("\n"); } } void usage(void) { printf("Firmware image downloader for Host AP driver\n" " (for Intersil Prism2/2.5/3 cards)\n" "Copyright (c) 2002-2004, Jouni Malinen \n" "\n" "Usage:\n" " prism2_srec [-vvrgfdpisD] [-P ] [-O ] " " \\\n" " [srec file name]\n" "Options:\n" " -v verbose (add another for more verbosity\n" " -r download SREC file into RAM (volatile)\n" " -g download SREC file into RAM (volatile in Genesis mode)" "\n" " -f download SREC file into flash (non-volatile)\n" " -d dump SREC image into prism2_srec.dump\n" " -p persistent mode for volatile download\n" " -i ignore incompatible interfaces errors\n" " Warning! This can result in failed upgrade!\n" " -s Skip PDA reading and use defaults from the firmware " "image\n" " -D Dump PDA in text format (this can be used without " "srec file)\n" " -P Override card PDA (with a PDA file in text " "format)\n" " Warning! This can result in failed upgrade!\n" " -O Override procfs path for binary PDA\n" " Warning! This can result in failed upgrade!\n" "\n" "Options -r, -g, and -f cannot be used together.\n" "If -r, -g, or -f is not specified, image summary is shown and" "\n" "compatibility with WLAN card is verified without downloading\n" "anything.\n"); exit(1); } int main(int argc, char *argv[]) { struct srec_data *srec, *srec2; struct wlan_info wlan; int opt, ret; const char *iface, *srec_fname, *srec_fname2, *pda_fname = NULL, *pda_procfs_override = NULL; char fname[256]; int dump_image_data = 0; int volatile_download = 0; int volatile_download_genesis = 0; int non_volatile_download = 0; int show_after = 0; int dl_mode = MODE_NO_DOWNLOAD; int persistent = 0; int dump_pda = 0; for (;;) { opt = getopt(argc, argv, "vrgfdipsDP:O:"); if (opt < 0) break; switch (opt) { case 'v': verbose++; break; case 'r': volatile_download++; dl_mode = MODE_VOLATILE; break; case 'g': volatile_download_genesis++; dl_mode = MODE_GENESIS; break; case 'f': non_volatile_download++; dl_mode = MODE_NON_VOLATILE; break; case 'd': dump_image_data++; break; case 'i': ignore_incompatible_interface++; break; case 'p': persistent++; break; case 's': skip_pda_read++; break; case 'D': dump_pda++; break; case 'P': pda_fname = optarg; break; case 'O': pda_procfs_override = optarg; break; default: usage(); break; } } if (non_volatile_download && ignore_incompatible_interface) ignore_incompatible_interface = 0; if (volatile_download + non_volatile_download + volatile_download_genesis > 1) usage(); if ((!dump_pda || argc - optind != 1) && argc - optind != 2 && argc - optind != 3) usage(); iface = argv[optind++]; if (argc > optind) srec_fname = argv[optind++]; else srec_fname = NULL; if (argc > optind) srec_fname2 = argv[optind++]; else srec_fname2 = NULL; if (srec_fname) { srec = read_srec(srec_fname); if (srec == NULL) { printf("Parsing '%s' failed.\n", srec_fname); exit(1); } show_srec(srec); printf("\n"); } else srec = NULL; if (srec_fname2) { srec2 = read_srec(srec_fname2); if (srec2 == NULL) { printf("Parsing '%s' failed.\n", srec_fname2); exit(1); } show_srec(srec2); printf("\n"); /* Make sure that srec is PRI and srec2 STA f/w. */ if (srec->component.component == HFA384X_COMP_ID_PRI && srec2->component.component == HFA384X_COMP_ID_STA) { } else if (srec->component.component == HFA384X_COMP_ID_STA && srec2->component.component == HFA384X_COMP_ID_PRI) { struct srec_data *temp = srec; srec = srec2; srec2 = temp; } else { printf("Only PRI & STA images can be current " "combined\n"); return 1; } if (!!srec->start_addr != !!srec2->start_addr) { printf("Cannot combine volatile and non-volatile " "images.\n"); return 1; } /* Start STA f/w if both PRI and STA f/w are loaded */ srec->start_addr = srec2->start_addr; } else srec2 = NULL; memset(&wlan, 0, sizeof(wlan)); wlan.ifname = iface; if (srec && (!skip_pda_read || !volatile_download_genesis) && read_wlan_rids(iface, &wlan)) { printf("Could not read wlan RIDs\n"); exit(1); } if (skip_pda_read && non_volatile_download) { printf("Skipping PDA read not allowed for non-volatile " "download.\n"); exit(1); } if (pda_fname && read_wlan_pda_text(pda_fname, &wlan.pda)) { printf("Could not read wlan PDA from '%s'\n", pda_fname); exit(1); } snprintf(fname, sizeof(fname), "/proc/net/hostap/%s/pda", iface); if (!pda_fname && !skip_pda_read && read_wlan_pda(pda_procfs_override ? pda_procfs_override : fname, &wlan.pda)) { printf("Could not read wlan PDA. This requires " "PRISM2_DOWNLOAD_SUPPORT definition in\n" "driver/module/hostap_config.h.\n"); exit(1); } /* If loading primary firmware, trust PDA, not the old firmware */ if (!skip_pda_read && srec && (srec->component.component == HFA384X_COMP_ID_PRI)) { verbose_printf("Overriding component id and supplied range " "data using PDA.\n"); compat_from_pda(&wlan); } show_wlan(&wlan); if (srec) { printf("\nVerifying update compatibility and combining " "data:\n"); if (combine_info(&wlan, srec, srec2, dl_mode)) { printf("Incompatible update data.\n"); exit(1); } printf("OK.\n"); } ret = 0; if (srec && (volatile_download || volatile_download_genesis)) { printf("\nDownloading to volatile memory (RAM).\n"); if (download_srec(iface, srec, 0, volatile_download_genesis, persistent)) { printf("\nDownload failed!\n"); ret = 1; } else { printf("OK.\n"); if (dl_mode != MODE_GENESIS) show_after = 1; } } if (srec && non_volatile_download) { if (srec->component.component != HFA384X_COMP_ID_STA && srec->component.component != HFA384X_COMP_ID_PRI && srec2 == NULL) { printf("\nNon-volatile downloading supports only " "primary and station firmware images in this " "version.\nAborted.\n"); return -1; } printf("\nDownloading to non-volatile memory (flash).\n" "Note! This can take about 30 seconds. " "Do _not_ remove card during download.\n"); if (download_srec(iface, srec, 1, 0, 0)) { printf("\nDownload failed!\n"); ret = 1; } else { printf("OK.\n"); show_after = 1; } } if (srec && dump_image_data) dump_s3_data(srec, "prism2_srec.dump"); if (dump_pda) dump_pda_data(&wlan.pda); if (show_after) { struct s3_info_platform id; printf("Components after download:\n"); if (get_compid(iface, HFA384X_RID_NICID, &id) == 0) printf(" NICID: 0x%04x v%u.%u.%u\n", id.platform, id.major, id.minor, id.variant); if (get_compid(iface, HFA384X_RID_PRIID, &id) == 0) printf(" PRIID: 0x%04x v%u.%u.%u\n", id.platform, id.major, id.minor, id.variant); if (get_compid(iface, HFA384X_RID_STAID, &id) == 0) printf(" STAID: 0x%04x v%u.%u.%u\n", id.platform, id.major, id.minor, id.variant); } free_srec(srec); free_srec(srec2); free_wlan(&wlan); return ret; } hostap-utils-0.4.7/split_combined_hex0000755000175000001440000000200510160470200016253 0ustar jmusers#!/bin/sh # Split combined S3 image file into separate hex files" set -e TOOL="`dirname $0`/prism2_srec" if [ ! -x "$TOOL" ]; then echo "Could not find compiled prism2_srec tool using path '$TOOL'" exit 1 fi TMPDIR=`mktemp -d srec_temp.XXXXXX` || exit 1 IN=$TMPDIR/data PART=$TMPDIR/part cat > $IN num=0 while [ -s $IN ]; do num=$(($num+1)) echo "Image $num" eline=`grep -n ^S6 $IN | head -n 1 | cut -f1 -d:` if [ -n "$eline" ]; then head -n $eline $IN | grep -vE '^S6|^S4' > $PART tail -n +$(($eline+1)) $IN > $IN.tmp && mv $IN.tmp $IN else grep -vE '^S6|^S4' $IN > $PART rm $IN fi fname=`$TOOL dummydev $PART 2> /dev/null | grep "^Included file name" | head -n 1 | colrm 1 20` if [ -z "$fname" ] || echo "$fname" | grep -q /; then fname=image-$num.hex fi mv $PART $TMPDIR/$fname echo " ==> $fname" $TOOL dummydev $TMPDIR/$fname 2> /dev/null | grep -E '^Component|0x8' || true echo done rm -f $IN $PART echo "Resulting files in '$TMPDIR':" ls -l $TMPDIR hostap-utils-0.4.7/util.c0000644000175000001440000003431510013466744013637 0ustar jmusers/* * Common functions for Host AP utils * Copyright (c) 2002-2003, Jouni Malinen * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. See README and COPYING for * more details. */ #include #include #include #include #include #include #include #include #include #include #include "wireless_copy.h" #include "util.h" struct hostap_nicid_rec { u16 id; char *txt; }; static struct hostap_nicid_rec hostap_nicids[] = { { 0x8000, "EVB2 (HFA3841EVAL1) with PRISM I (3860B) Radio" }, { 0x8001, "HWB3763 Rev B" }, { 0x8002, "HWB3163-01,02,03,04 Rev A" }, { 0x8003, "HWB3163 Rev B, Samsung PC Card Rev. B" }, { 0x8004, "EVB3 (HFA3843EVAL1, Rev B1)" }, { 0x8006, "Nortel Sputnik I" }, { 0x8007, "HWB1153 PRISM I Ref" }, { 0x8008, "HWB3163, Prism II reference with SSF Flash" }, { 0x800A, "3842 Evaluation Board" }, { 0x800B, "PRISM II (2.5) PCMCIA (AMD parallel flash)" }, { 0x800C, "PRISM II (2.5) PCMCIA (SST parallel flash)" }, { 0x800D, "PRISM II (2.5) PCMCIA (AT45DB011 compatible large serial " "flash)" }, { 0x800E, "PRISM II (2.5) PCMCIA (AT24C08 compatible small serial " "flash)" }, { 0x8012, "PRISM II (2.5) Mini-PCI (AMD parallel flash)" }, { 0x8013, "PRISM II (2.5) Mini-PCI (SST parallel flash)" }, { 0x8014, "PRISM II (2.5) Mini-PCI (AT45DB011 compatible large serial " "flash)" }, { 0x8015, "PRISM II (2.5) Mini-PCI (AT24C08 compatible small serial " "flash)" }, { 0x8016, "PCI-bridge (AMD parallel flash)" }, { 0x8017, "PCI-bridge (SST parallel flash)" }, { 0x8018, "PCI-bridge (AT45DB011 compatible large serial flash)" }, { 0x8019, "PCI-bridge (AT24C08 compatible small serial flash)" }, { 0x801A, "PRISM III PCMCIA (AMD parallel flash)" }, { 0x801B, "PRISM III PCMCIA (SST parallel flash)" }, { 0x801C, "PRISM III PCMCIA (AT45DB011 compatible large serial flash)" }, { 0x801D, "PRISM III PCMCIA (AT24C08 compatible small serial flash)" }, { 0x8021, "PRISM III Mini-PCI (AMD parallel flash)" }, { 0x8022, "PRISM III Mini-PCI (SST parallel flash)" }, { 0x8023, "PRISM III Mini-PCI (AT45DB011 compatible large serial " "flash)" }, { 0x8024, "PRISM III Mini-PCI (AT24C08 compatible small serial flash)" }, }; void hostap_show_nicid(u8 *data, int len) { struct hfa384x_comp_ident *comp; int i; u16 id; char *txt = "unknown"; if (len != sizeof(*comp)) { printf("Invalid NICID length %d\n", len); return; } comp = (struct hfa384x_comp_ident *) data; id = le_to_host16(comp->id); for (i = 0; i < sizeof(hostap_nicids) / sizeof(hostap_nicids[0]); i++) { if (hostap_nicids[i].id == id) { txt = hostap_nicids[i].txt; break; } } printf("NICID: id=0x%04x v%d.%d.%d (%s)", id, le_to_host16(comp->major), le_to_host16(comp->minor), le_to_host16(comp->variant), txt); printf("\n"); } void hostap_show_priid(u8 *data, int len) { struct hfa384x_comp_ident *comp; if (len != sizeof(*comp)) { printf("Invalid PRIID length %d\n", len); return; } comp = (struct hfa384x_comp_ident *) data; printf("PRIID: id=0x%04x v%d.%d.%d\n", le_to_host16(comp->id), le_to_host16(comp->major), le_to_host16(comp->minor), le_to_host16(comp->variant)); if (le_to_host16(comp->id) != HFA384X_COMP_ID_PRI) printf(" Unknown primary firmware component id!\n"); } void hostap_show_staid(u8 *data, int len) { struct hfa384x_comp_ident *comp; u16 id, major, minor, variant; if (len != sizeof(*comp)) { printf("Invalid STAID length %d\n", len); return; } comp = (struct hfa384x_comp_ident *) data; id = le_to_host16(comp->id); major = le_to_host16(comp->major); minor = le_to_host16(comp->minor); variant = le_to_host16(comp->variant); printf("STAID: id=0x%04x v%d.%d.%d", id, major, minor, variant); switch (id) { case HFA384X_COMP_ID_STA: printf(" (station firmware)\n"); break; case HFA384X_COMP_ID_FW_AP: printf(" (tertiary firmware)\n"); break; default: printf(" (unknown component id!)\n"); break; } } int hostapd_ioctl(const char *dev, struct prism2_hostapd_param *param, int len, int show_err) { int s; struct iwreq iwr; s = socket(PF_INET, SOCK_DGRAM, 0); if (s < 0) { perror("socket"); return -1; } memset(&iwr, 0, sizeof(iwr)); strncpy(iwr.ifr_name, dev, IFNAMSIZ); iwr.u.data.pointer = (caddr_t) param; iwr.u.data.length = len; if (ioctl(s, PRISM2_IOCTL_HOSTAPD, &iwr) < 0) { int ret; close(s); ret = errno; if (show_err) perror("ioctl[PRISM2_IOCTL_HOSTAPD]"); return ret; } close(s); return 0; } int hostapd_get_rid(const char *dev, struct prism2_hostapd_param *param, u16 rid, int show_err) { int res; memset(param, 0, PRISM2_HOSTAPD_MAX_BUF_SIZE); param->cmd = PRISM2_HOSTAPD_GET_RID; param->u.rid.rid = rid; param->u.rid.len = PRISM2_HOSTAPD_MAX_BUF_SIZE - PRISM2_HOSTAPD_RID_HDR_LEN; res = hostapd_ioctl(dev, param, PRISM2_HOSTAPD_MAX_BUF_SIZE, show_err); if (res >= 0 && param->u.rid.len > PRISM2_HOSTAPD_MAX_BUF_SIZE - PRISM2_HOSTAPD_RID_HDR_LEN) return -1; return res; } int hostapd_set_rid(const char *dev, u16 rid, u8 *data, size_t len, int show_err) { struct prism2_hostapd_param *param; int res; size_t blen = PRISM2_HOSTAPD_RID_HDR_LEN + len; if (blen < sizeof(*param)) blen = sizeof(*param); param = (struct prism2_hostapd_param *) malloc(blen); if (param == NULL) return -1; memset(param, 0, blen); param->cmd = PRISM2_HOSTAPD_SET_RID; param->u.rid.rid = rid; param->u.rid.len = len; memcpy(param->u.rid.data, data, len); res = hostapd_ioctl(dev, param, blen, show_err); free(param); return res; } int hostap_ioctl_readmif(const char *dev, int cr) { int s; struct iwreq iwr; u8 val; s = socket(PF_INET, SOCK_DGRAM, 0); if (s < 0) { perror("socket"); return -1; } memset(&iwr, 0, sizeof(iwr)); strncpy(iwr.ifr_name, dev, IFNAMSIZ); iwr.u.name[0] = cr * 2; if (ioctl(s, PRISM2_IOCTL_READMIF, &iwr) < 0) { perror("ioctl[PRISM2_IOCTL_READMIF]"); close(s); return -1; } close(s); val = iwr.u.name[0]; return (int) val; } static const u16 crc16_table[256] = { 0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241, 0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440, 0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40, 0x0a00, 0xcac1, 0xcb81, 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841, 0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40, 0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41, 0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641, 0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040, 0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240, 0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441, 0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41, 0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840, 0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41, 0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1, 0xec81, 0x2c40, 0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640, 0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041, 0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240, 0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441, 0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41, 0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840, 0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41, 0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40, 0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640, 0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041, 0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241, 0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440, 0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40, 0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841, 0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40, 0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41, 0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641, 0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040 }; static int crc16(u8 *buf, int len) { u16 crc; int i; crc = 0; for (i = 0; i < len; i++) crc = (crc >> 8) ^ crc16_table[(crc & 0xff) ^ *buf++]; return crc; } static int parse_wlan_pda(struct prism2_pda *pda_info, int update_crc) { int pos; u16 *pda, len, pdr; pda = (u16 *) pda_info->pda_buf; pos = 0; while (pos + 1 < PRISM2_PDA_SIZE / 2) { len = le_to_host16(pda[pos]); pdr = le_to_host16(pda[pos + 1]); if (len == 0 || pos + len > PRISM2_PDA_SIZE / 2) { printf("Invalid PDR 0x%04x len=%d\n", pdr, len); return 1; } pda_info->pdrs = (struct prism2_pdr *) realloc(pda_info->pdrs, (pda_info->pdr_count + 1) * sizeof(struct prism2_pdr)); assert(pda_info->pdrs != NULL); pda_info->pdrs[pda_info->pdr_count].pdr = pdr; pda_info->pdrs[pda_info->pdr_count].len = (len - 1) * 2; pda_info->pdrs[pda_info->pdr_count].data = (unsigned char *) (&pda[pos + 2]); pda_info->pdr_count++; if (pdr == PDR_PDA_END_RECORD && len == 2) { /* PDA end found */ if (crc16(pda_info->pda_buf, (pos + 3) * 2) != 0) { if (update_crc) { int crc = crc16(pda_info->pda_buf, (pos + 2) * 2); printf("Updating PDA checksum to match" " with data (%04x -> %04x).\n", pda[pos + 2], crc); pda[pos + 2] = crc; } else { printf("PDA checksum incorrect.\n"); return 1; } } return 0; } pos += len + 1; } printf("Could not find PDA end record.\n"); return 1; } int read_wlan_pda(const char *fname, struct prism2_pda *pda_info) { FILE *f; memset(pda_info, 0, sizeof(struct prism2_pda)); f = fopen(fname, "r"); if (f == NULL) return 1; if (fread(pda_info->pda_buf, 1, PRISM2_PDA_SIZE, f) != PRISM2_PDA_SIZE) { fclose(f); return 1; } fclose(f); return parse_wlan_pda(pda_info, 0); } #define LINE_BUF_LEN 2048 static int get_next_word(FILE *f, char *linebuf, char **_pos) { size_t len; char *pos, *end, *pos2; int ret; pos = *_pos; while (isspace(*pos)) pos++; if (*pos == '\0') { do { if (fgets(linebuf, LINE_BUF_LEN, f) == NULL) return -1; len = strcspn(linebuf, ";/#"); linebuf[len] = '\0'; pos = linebuf; while (isspace(*pos)) pos++; } while (*pos == '\0'); pos2 = pos; while (*pos2 != '\0') { if (*pos2 == ',') *pos2 = ' '; pos2++; } } ret = strtol(pos, &end, 16); if (end == pos) { pos = linebuf; printf("Expected a hex number at position marked with *:\n"); while (*pos != '\0') { if (pos == end) putchar('*'); putchar(*pos++); } printf("\n"); return -2; } pos = end; if (pos >= linebuf + LINE_BUF_LEN) pos = linebuf + LINE_BUF_LEN - 1; *_pos = pos; return ret; } int read_wlan_pda_text(const char *fname, struct prism2_pda *pda_info) { FILE *f; char linebuf[LINE_BUF_LEN], *pos; int words, w; u16 *pda; f = fopen(fname, "r"); if (f == NULL) return -1; memset(pda_info, 0, sizeof(struct prism2_pda)); memset(pda_info->pda_buf, 0xff, PRISM2_PDA_SIZE); pda = (u16 *) pda_info->pda_buf; linebuf[0] = '\0'; pos = linebuf; words = 0; while (words < PRISM2_PDA_SIZE / 2) { w = get_next_word(f, linebuf, &pos); if (w == -2) { printf("Parsing PDA data failed.\n"); fclose(f); return -1; } else if (w == -1) break; pda[words++] = host_to_le16(w); } fclose(f); if (words + 3 < PRISM2_PDA_SIZE / 2) { /* PDA text format is not required to include PDA end * record, so add a template in the end of the PDA. */ pda[words++] = host_to_le16(2); pda[words++] = host_to_le16(PDR_PDA_END_RECORD); pda[words++] = 0; /* will be overriden with correct CRC */ } return parse_wlan_pda(pda_info, 1); } const char * prism2_pdr_name(int pdr) { switch (pdr) { case PDR_PDA_END_RECORD: return "PDA End Record"; case PDR_PLATFORM_NAME: return "Platform name / Manufacturing part number"; case PDR_VERSION: return "PDA Version Record"; case PDR_NIC_SERIAL_NUM: return "NIC Serial Number"; case PDR_NIC_RAM_SIZE: return "NIC RAM Size"; case PDR_RF_MODE_SUPP_RANGE: return "RF Modem Supplier Range"; case PDR_MAC_CTRL_SUPP_RANGE: return "MAC Controller Supplier Range"; case PDR_NIC_ID_COMP: return "NIC ID (component ID)"; case PDR_MAC_ADDR: return "MAC Address"; case PDR_REG_DOMAIN_LIST: return "Regulatory Domain List"; case PDR_CHANNEL_LIST: return "Allowed Channel Set/Active Channel List"; case PDR_DEFAULT_CHANNEL: return "Default Channel"; case PDR_TEMPERATURE_TYPE: return "Temperature Type"; case PDR_IFR_SETTING: return "IFR Setting"; case PDR_RFR_SETTING: return "RFR Setting"; case PDR_3861_BASELINE_REG_SETTINGS: return "3861 Baseline Register Settings"; case PDR_3861_SHADOW_REG_SETTINGS: return "3861 Shadow Register Settings"; case PDR_3861_IFRF_REG_SETTINGS: return "3861 IF/RF Register Settings"; case PDR_3861_CHANNEL_CALIB_SP: return "3861 Channel Calibration Set Point"; case PDR_3861_CHANNEL_CALIB_INT: return "3861 Channel Calibration Integrator"; case PDR_MAX_RADIO_TX_POWER: return "Maximum Radio TX Power"; case PDR_MASTER_CHANNEL_LIST: return "Scannable/Master Channel List"; case PDR_3842_NIC_CONF: return "3842 PRISM II NIC Configuration"; case PDR_USB_ID: return "PRISM USB Identifier"; case PDR_PCI_ID: return "PRISM PCI Identifier"; case PDR_PCI_INTERFACE_CONF: return "PRISM PCI Interface Configuration"; case PDR_PCI_PM_CONF: return "PRISM PCI PM Configuration"; case PDR_ZIF_SYNTHESIZER_SETTINGS: return "ZIF Synthesizer Settings"; case PDR_RSSI_DBM_CONV: return "RSSI-to-dBm Conversion Constant"; case PDR_USB_POWER_TYPE: return "USB Power Type"; case PDR_USB_MAX_POWER: return "PRISM USB Max Power"; case PDR_USB_MANUF_STRING: return "USB Manufacture String"; case PDR_USB_PRODUCT_STRING: return "USB Product String"; case PDR_SW_DIVERSITY_CTRL: return "SW Diversity Control"; case PDR_HFO_DELAY: return "HFO Delay"; case PDR_3861_MANUF_TEST_CHANNEL_SP: return "3861 Manufacturing Test Channel Set Points"; case PDR_MANUF_TEST_CHANNEL_INT: return "Manufacturing Test Channel Integrators"; } return ""; } hostap-utils-0.4.7/util.h0000644000175000001440000000574110013466744013645 0ustar jmusers#ifndef UTIL_H #define UTIL_H #include #include #if __BYTE_ORDER == __LITTLE_ENDIAN #define le_to_host16(n) (n) #define host_to_le16(n) (n) #define be_to_host16(n) bswap_16(n) #define host_to_be16(n) bswap_16(n) #else #define le_to_host16(n) bswap_16(n) #define host_to_le16(n) bswap_16(n) #define be_to_host16(n) (n) #define host_to_be16(n) (n) #endif #include typedef uint64_t u64; typedef uint32_t u32; typedef uint16_t u16; typedef uint8_t u8; typedef int64_t s64; typedef int32_t s32; typedef int16_t s16; typedef int8_t s8; #ifndef ETH_ALEN #define ETH_ALEN 6 #endif #include "hostap_common.h" void hostap_show_nicid(u8 *data, int len); void hostap_show_priid(u8 *data, int len); void hostap_show_staid(u8 *data, int len); int hostapd_ioctl(const char *dev, struct prism2_hostapd_param *param, int len, int show_err); int hostapd_get_rid(const char *dev, struct prism2_hostapd_param *param, u16 rid, int show_err); int hostapd_set_rid(const char *dev, u16 rid, u8 *data, size_t len, int show_err); int hostap_ioctl_readmif(const char *dev, int cr); #define PRISM2_PDA_SIZE 1024 struct prism2_pdr { unsigned int pdr, len; unsigned char *data; }; struct prism2_pda { char pda_buf[PRISM2_PDA_SIZE]; struct prism2_pdr *pdrs; int pdr_count; }; int read_wlan_pda(const char *fname, struct prism2_pda *pda_info); int read_wlan_pda_text(const char *fname, struct prism2_pda *pda_info); #define PDR_PDA_END_RECORD 0x0000 #define PDR_PLATFORM_NAME 0x0001 #define PDR_VERSION 0x0002 #define PDR_NIC_SERIAL_NUM 0x0003 #define PDR_NIC_RAM_SIZE 0x0005 #define PDR_RF_MODE_SUPP_RANGE 0x0006 #define PDR_MAC_CTRL_SUPP_RANGE 0x0007 #define PDR_NIC_ID_COMP 0x0008 #define PDR_MAC_ADDR 0x0101 #define PDR_REG_DOMAIN_LIST 0x0103 #define PDR_CHANNEL_LIST 0x0104 #define PDR_DEFAULT_CHANNEL 0x0105 #define PDR_TEMPERATURE_TYPE 0x0107 #define PDR_IFR_SETTING 0x0200 #define PDR_RFR_SETTING 0x0201 #define PDR_3861_BASELINE_REG_SETTINGS 0x0202 #define PDR_3861_SHADOW_REG_SETTINGS 0x0203 #define PDR_3861_IFRF_REG_SETTINGS 0x0204 #define PDR_3861_CHANNEL_CALIB_SP 0x0300 #define PDR_3861_CHANNEL_CALIB_INT 0x0301 #define PDR_MAX_RADIO_TX_POWER 0x0302 #define PDR_MASTER_CHANNEL_LIST 0x0303 #define PDR_3842_NIC_CONF 0x0400 #define PDR_USB_ID 0x0401 #define PDR_PCI_ID 0x0402 #define PDR_PCI_INTERFACE_CONF 0x0403 #define PDR_PCI_PM_CONF 0x0404 #define PDR_ZIF_SYNTHESIZER_SETTINGS 0x0405 #define PDR_RSSI_DBM_CONV 0x0406 #define PDR_USB_POWER_TYPE 0x0407 #define PDR_USB_MAX_POWER 0x0409 #define PDR_USB_MANUF_STRING 0x0410 #define PDR_USB_PRODUCT_STRING 0x0411 #define PDR_SW_DIVERSITY_CTRL 0x0412 #define PDR_HFO_DELAY 0x0413 #define PDR_3861_MANUF_TEST_CHANNEL_SP 0x0900 #define PDR_MANUF_TEST_CHANNEL_INT 0x0901 struct pdr_supplier_range { u16 role; u16 iface_id; u16 variant; u16 bottom; u16 top; } __attribute__((packed)); struct pdr_compid { u16 id; u16 variant; u16 major; u16 minor; } __attribute__((packed)); const char * prism2_pdr_name(int pdr); #endif /* UTIL_H */ hostap-utils-0.4.7/wireless_copy.h0000644000175000001440000012010410315275556015552 0ustar jmusers/* 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 - * 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 /* for "caddr_t" et al */ #include /* for "struct sockaddr" et al */ #include /* for IFNAMSIZ and co... */ #else #include #include 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 ) * ---------- * - 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 /* 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 */ /* 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 /* 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 /* 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 */ hostap-utils-0.4.7/COPYING0000644000175000001440000004312710340222766013547 0ustar jmusers GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. hostap-utils-0.4.7/hostap_common.h0000644000175000001440000004620310340222766015531 0ustar jmusers#ifndef HOSTAP_COMMON_H #define HOSTAP_COMMON_H #define BIT(x) (1 << (x)) #define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] #define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x" #ifndef ETH_P_PAE #define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */ #endif /* ETH_P_PAE */ #define ETH_P_PREAUTH 0x88C7 /* IEEE 802.11i pre-authentication */ /* IEEE 802.11 defines */ #define WLAN_FC_PVER (BIT(1) | BIT(0)) #define WLAN_FC_TODS BIT(8) #define WLAN_FC_FROMDS BIT(9) #define WLAN_FC_MOREFRAG BIT(10) #define WLAN_FC_RETRY BIT(11) #define WLAN_FC_PWRMGT BIT(12) #define WLAN_FC_MOREDATA BIT(13) #define WLAN_FC_ISWEP BIT(14) #define WLAN_FC_ORDER BIT(15) #define WLAN_FC_GET_TYPE(fc) (((fc) & (BIT(3) | BIT(2))) >> 2) #define WLAN_FC_GET_STYPE(fc) \ (((fc) & (BIT(7) | BIT(6) | BIT(5) | BIT(4))) >> 4) #define WLAN_GET_SEQ_FRAG(seq) ((seq) & (BIT(3) | BIT(2) | BIT(1) | BIT(0))) #define WLAN_GET_SEQ_SEQ(seq) \ (((seq) & (~(BIT(3) | BIT(2) | BIT(1) | BIT(0)))) >> 4) #define WLAN_FC_TYPE_MGMT 0 #define WLAN_FC_TYPE_CTRL 1 #define WLAN_FC_TYPE_DATA 2 /* management */ #define WLAN_FC_STYPE_ASSOC_REQ 0 #define WLAN_FC_STYPE_ASSOC_RESP 1 #define WLAN_FC_STYPE_REASSOC_REQ 2 #define WLAN_FC_STYPE_REASSOC_RESP 3 #define WLAN_FC_STYPE_PROBE_REQ 4 #define WLAN_FC_STYPE_PROBE_RESP 5 #define WLAN_FC_STYPE_BEACON 8 #define WLAN_FC_STYPE_ATIM 9 #define WLAN_FC_STYPE_DISASSOC 10 #define WLAN_FC_STYPE_AUTH 11 #define WLAN_FC_STYPE_DEAUTH 12 /* control */ #define WLAN_FC_STYPE_PSPOLL 10 #define WLAN_FC_STYPE_RTS 11 #define WLAN_FC_STYPE_CTS 12 #define WLAN_FC_STYPE_ACK 13 #define WLAN_FC_STYPE_CFEND 14 #define WLAN_FC_STYPE_CFENDACK 15 /* data */ #define WLAN_FC_STYPE_DATA 0 #define WLAN_FC_STYPE_DATA_CFACK 1 #define WLAN_FC_STYPE_DATA_CFPOLL 2 #define WLAN_FC_STYPE_DATA_CFACKPOLL 3 #define WLAN_FC_STYPE_NULLFUNC 4 #define WLAN_FC_STYPE_CFACK 5 #define WLAN_FC_STYPE_CFPOLL 6 #define WLAN_FC_STYPE_CFACKPOLL 7 /* Authentication algorithms */ #define WLAN_AUTH_OPEN 0 #define WLAN_AUTH_SHARED_KEY 1 #define WLAN_AUTH_CHALLENGE_LEN 128 #define WLAN_CAPABILITY_ESS BIT(0) #define WLAN_CAPABILITY_IBSS BIT(1) #define WLAN_CAPABILITY_CF_POLLABLE BIT(2) #define WLAN_CAPABILITY_CF_POLL_REQUEST BIT(3) #define WLAN_CAPABILITY_PRIVACY BIT(4) /* Status codes */ #define WLAN_STATUS_SUCCESS 0 #define WLAN_STATUS_UNSPECIFIED_FAILURE 1 #define WLAN_STATUS_CAPS_UNSUPPORTED 10 #define WLAN_STATUS_REASSOC_NO_ASSOC 11 #define WLAN_STATUS_ASSOC_DENIED_UNSPEC 12 #define WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG 13 #define WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION 14 #define WLAN_STATUS_CHALLENGE_FAIL 15 #define WLAN_STATUS_AUTH_TIMEOUT 16 #define WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA 17 #define WLAN_STATUS_ASSOC_DENIED_RATES 18 /* 802.11b */ #define WLAN_STATUS_ASSOC_DENIED_NOSHORT 19 #define WLAN_STATUS_ASSOC_DENIED_NOPBCC 20 #define WLAN_STATUS_ASSOC_DENIED_NOAGILITY 21 /* IEEE 802.11i */ #define WLAN_STATUS_INVALID_IE 40 #define WLAN_STATUS_GROUP_CIPHER_NOT_VALID 41 #define WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID 42 #define WLAN_STATUS_AKMP_NOT_VALID 43 #define WLAN_STATUS_UNSUPPORTED_RSN_IE_VERSION 44 #define WLAN_STATUS_INVALID_RSN_IE_CAPAB 45 #define WLAN_STATUS_CIPHER_REJECTED_PER_POLICY 46 /* Reason codes */ #define WLAN_REASON_UNSPECIFIED 1 #define WLAN_REASON_PREV_AUTH_NOT_VALID 2 #define WLAN_REASON_DEAUTH_LEAVING 3 #define WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY 4 #define WLAN_REASON_DISASSOC_AP_BUSY 5 #define WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA 6 #define WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA 7 #define WLAN_REASON_DISASSOC_STA_HAS_LEFT 8 #define WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH 9 /* IEEE 802.11i */ #define WLAN_REASON_INVALID_IE 13 #define WLAN_REASON_MICHAEL_MIC_FAILURE 14 #define WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT 15 #define WLAN_REASON_GROUP_KEY_UPDATE_TIMEOUT 16 #define WLAN_REASON_IE_IN_4WAY_DIFFERS 17 #define WLAN_REASON_GROUP_CIPHER_NOT_VALID 18 #define WLAN_REASON_PAIRWISE_CIPHER_NOT_VALID 19 #define WLAN_REASON_AKMP_NOT_VALID 20 #define WLAN_REASON_UNSUPPORTED_RSN_IE_VERSION 21 #define WLAN_REASON_INVALID_RSN_IE_CAPAB 22 #define WLAN_REASON_IEEE_802_1X_AUTH_FAILED 23 #define WLAN_REASON_CIPHER_SUITE_REJECTED 24 /* Information Element IDs */ #define WLAN_EID_SSID 0 #define WLAN_EID_SUPP_RATES 1 #define WLAN_EID_FH_PARAMS 2 #define WLAN_EID_DS_PARAMS 3 #define WLAN_EID_CF_PARAMS 4 #define WLAN_EID_TIM 5 #define WLAN_EID_IBSS_PARAMS 6 #define WLAN_EID_CHALLENGE 16 #define WLAN_EID_RSN 48 #define WLAN_EID_GENERIC 221 /* HFA384X Configuration RIDs */ #define HFA384X_RID_CNFPORTTYPE 0xFC00 #define HFA384X_RID_CNFOWNMACADDR 0xFC01 #define HFA384X_RID_CNFDESIREDSSID 0xFC02 #define HFA384X_RID_CNFOWNCHANNEL 0xFC03 #define HFA384X_RID_CNFOWNSSID 0xFC04 #define HFA384X_RID_CNFOWNATIMWINDOW 0xFC05 #define HFA384X_RID_CNFSYSTEMSCALE 0xFC06 #define HFA384X_RID_CNFMAXDATALEN 0xFC07 #define HFA384X_RID_CNFWDSADDRESS 0xFC08 #define HFA384X_RID_CNFPMENABLED 0xFC09 #define HFA384X_RID_CNFPMEPS 0xFC0A #define HFA384X_RID_CNFMULTICASTRECEIVE 0xFC0B #define HFA384X_RID_CNFMAXSLEEPDURATION 0xFC0C #define HFA384X_RID_CNFPMHOLDOVERDURATION 0xFC0D #define HFA384X_RID_CNFOWNNAME 0xFC0E #define HFA384X_RID_CNFOWNDTIMPERIOD 0xFC10 #define HFA384X_RID_CNFWDSADDRESS1 0xFC11 /* AP f/w only */ #define HFA384X_RID_CNFWDSADDRESS2 0xFC12 /* AP f/w only */ #define HFA384X_RID_CNFWDSADDRESS3 0xFC13 /* AP f/w only */ #define HFA384X_RID_CNFWDSADDRESS4 0xFC14 /* AP f/w only */ #define HFA384X_RID_CNFWDSADDRESS5 0xFC15 /* AP f/w only */ #define HFA384X_RID_CNFWDSADDRESS6 0xFC16 /* AP f/w only */ #define HFA384X_RID_CNFMULTICASTPMBUFFERING 0xFC17 /* AP f/w only */ #define HFA384X_RID_UNKNOWN1 0xFC20 #define HFA384X_RID_UNKNOWN2 0xFC21 #define HFA384X_RID_CNFWEPDEFAULTKEYID 0xFC23 #define HFA384X_RID_CNFDEFAULTKEY0 0xFC24 #define HFA384X_RID_CNFDEFAULTKEY1 0xFC25 #define HFA384X_RID_CNFDEFAULTKEY2 0xFC26 #define HFA384X_RID_CNFDEFAULTKEY3 0xFC27 #define HFA384X_RID_CNFWEPFLAGS 0xFC28 #define HFA384X_RID_CNFWEPKEYMAPPINGTABLE 0xFC29 #define HFA384X_RID_CNFAUTHENTICATION 0xFC2A #define HFA384X_RID_CNFMAXASSOCSTA 0xFC2B /* AP f/w only */ #define HFA384X_RID_CNFTXCONTROL 0xFC2C #define HFA384X_RID_CNFROAMINGMODE 0xFC2D #define HFA384X_RID_CNFHOSTAUTHENTICATION 0xFC2E /* AP f/w only */ #define HFA384X_RID_CNFRCVCRCERROR 0xFC30 #define HFA384X_RID_CNFMMLIFE 0xFC31 #define HFA384X_RID_CNFALTRETRYCOUNT 0xFC32 #define HFA384X_RID_CNFBEACONINT 0xFC33 #define HFA384X_RID_CNFAPPCFINFO 0xFC34 /* AP f/w only */ #define HFA384X_RID_CNFSTAPCFINFO 0xFC35 #define HFA384X_RID_CNFPRIORITYQUSAGE 0xFC37 #define HFA384X_RID_CNFTIMCTRL 0xFC40 #define HFA384X_RID_UNKNOWN3 0xFC41 /* added in STA f/w 0.7.x */ #define HFA384X_RID_CNFTHIRTY2TALLY 0xFC42 /* added in STA f/w 0.8.0 */ #define HFA384X_RID_CNFENHSECURITY 0xFC43 /* AP f/w or STA f/w >= 1.6.3 */ #define HFA384X_RID_CNFDBMADJUST 0xFC46 /* added in STA f/w 1.3.1 */ #define HFA384X_RID_GENERICELEMENT 0xFC48 /* added in STA f/w 1.7.0; * write only */ #define HFA384X_RID_PROPAGATIONDELAY 0xFC49 /* added in STA f/w 1.7.6 */ #define HFA384X_RID_GROUPADDRESSES 0xFC80 #define HFA384X_RID_CREATEIBSS 0xFC81 #define HFA384X_RID_FRAGMENTATIONTHRESHOLD 0xFC82 #define HFA384X_RID_RTSTHRESHOLD 0xFC83 #define HFA384X_RID_TXRATECONTROL 0xFC84 #define HFA384X_RID_PROMISCUOUSMODE 0xFC85 #define HFA384X_RID_FRAGMENTATIONTHRESHOLD0 0xFC90 /* AP f/w only */ #define HFA384X_RID_FRAGMENTATIONTHRESHOLD1 0xFC91 /* AP f/w only */ #define HFA384X_RID_FRAGMENTATIONTHRESHOLD2 0xFC92 /* AP f/w only */ #define HFA384X_RID_FRAGMENTATIONTHRESHOLD3 0xFC93 /* AP f/w only */ #define HFA384X_RID_FRAGMENTATIONTHRESHOLD4 0xFC94 /* AP f/w only */ #define HFA384X_RID_FRAGMENTATIONTHRESHOLD5 0xFC95 /* AP f/w only */ #define HFA384X_RID_FRAGMENTATIONTHRESHOLD6 0xFC96 /* AP f/w only */ #define HFA384X_RID_RTSTHRESHOLD0 0xFC97 /* AP f/w only */ #define HFA384X_RID_RTSTHRESHOLD1 0xFC98 /* AP f/w only */ #define HFA384X_RID_RTSTHRESHOLD2 0xFC99 /* AP f/w only */ #define HFA384X_RID_RTSTHRESHOLD3 0xFC9A /* AP f/w only */ #define HFA384X_RID_RTSTHRESHOLD4 0xFC9B /* AP f/w only */ #define HFA384X_RID_RTSTHRESHOLD5 0xFC9C /* AP f/w only */ #define HFA384X_RID_RTSTHRESHOLD6 0xFC9D /* AP f/w only */ #define HFA384X_RID_TXRATECONTROL0 0xFC9E /* AP f/w only */ #define HFA384X_RID_TXRATECONTROL1 0xFC9F /* AP f/w only */ #define HFA384X_RID_TXRATECONTROL2 0xFCA0 /* AP f/w only */ #define HFA384X_RID_TXRATECONTROL3 0xFCA1 /* AP f/w only */ #define HFA384X_RID_TXRATECONTROL4 0xFCA2 /* AP f/w only */ #define HFA384X_RID_TXRATECONTROL5 0xFCA3 /* AP f/w only */ #define HFA384X_RID_TXRATECONTROL6 0xFCA4 /* AP f/w only */ #define HFA384X_RID_CNFSHORTPREAMBLE 0xFCB0 #define HFA384X_RID_CNFEXCLUDELONGPREAMBLE 0xFCB1 #define HFA384X_RID_CNFAUTHENTICATIONRSPTO 0xFCB2 #define HFA384X_RID_CNFBASICRATES 0xFCB3 #define HFA384X_RID_CNFSUPPORTEDRATES 0xFCB4 #define HFA384X_RID_CNFFALLBACKCTRL 0xFCB5 /* added in STA f/w 1.3.1 */ #define HFA384X_RID_WEPKEYDISABLE 0xFCB6 /* added in STA f/w 1.3.1 */ #define HFA384X_RID_WEPKEYMAPINDEX 0xFCB7 /* ? */ #define HFA384X_RID_BROADCASTKEYID 0xFCB8 /* ? */ #define HFA384X_RID_ENTSECFLAGEYID 0xFCB9 /* ? */ #define HFA384X_RID_CNFPASSIVESCANCTRL 0xFCBA /* added in STA f/w 1.5.0 */ #define HFA384X_RID_SSNHANDLINGMODE 0xFCBB /* added in STA f/w 1.7.0 */ #define HFA384X_RID_MDCCONTROL 0xFCBC /* added in STA f/w 1.7.0 */ #define HFA384X_RID_MDCCOUNTRY 0xFCBD /* added in STA f/w 1.7.0 */ #define HFA384X_RID_TXPOWERMAX 0xFCBE /* added in STA f/w 1.7.0 */ #define HFA384X_RID_CNFLFOENABLED 0xFCBF /* added in STA f/w 1.6.3 */ #define HFA384X_RID_CAPINFO 0xFCC0 /* added in STA f/w 1.7.0 */ #define HFA384X_RID_LISTENINTERVAL 0xFCC1 /* added in STA f/w 1.7.0 */ #define HFA384X_RID_SW_ANT_DIV 0xFCC2 /* added in STA f/w 1.7.0; Prism3 */ #define HFA384X_RID_LED_CTRL 0xFCC4 /* added in STA f/w 1.7.6 */ #define HFA384X_RID_HFODELAY 0xFCC5 /* added in STA f/w 1.7.6 */ #define HFA384X_RID_DISALLOWEDBSSID 0xFCC6 /* added in STA f/w 1.8.0 */ #define HFA384X_RID_TICKTIME 0xFCE0 #define HFA384X_RID_SCANREQUEST 0xFCE1 #define HFA384X_RID_JOINREQUEST 0xFCE2 #define HFA384X_RID_AUTHENTICATESTATION 0xFCE3 /* AP f/w only */ #define HFA384X_RID_CHANNELINFOREQUEST 0xFCE4 /* AP f/w only */ #define HFA384X_RID_HOSTSCAN 0xFCE5 /* added in STA f/w 1.3.1 */ /* HFA384X Information RIDs */ #define HFA384X_RID_MAXLOADTIME 0xFD00 #define HFA384X_RID_DOWNLOADBUFFER 0xFD01 #define HFA384X_RID_PRIID 0xFD02 #define HFA384X_RID_PRISUPRANGE 0xFD03 #define HFA384X_RID_CFIACTRANGES 0xFD04 #define HFA384X_RID_NICSERNUM 0xFD0A #define HFA384X_RID_NICID 0xFD0B #define HFA384X_RID_MFISUPRANGE 0xFD0C #define HFA384X_RID_CFISUPRANGE 0xFD0D #define HFA384X_RID_CHANNELLIST 0xFD10 #define HFA384X_RID_REGULATORYDOMAINS 0xFD11 #define HFA384X_RID_TEMPTYPE 0xFD12 #define HFA384X_RID_CIS 0xFD13 #define HFA384X_RID_STAID 0xFD20 #define HFA384X_RID_STASUPRANGE 0xFD21 #define HFA384X_RID_MFIACTRANGES 0xFD22 #define HFA384X_RID_CFIACTRANGES2 0xFD23 #define HFA384X_RID_PRODUCTNAME 0xFD24 /* added in STA f/w 1.3.1; * only Prism2.5(?) */ #define HFA384X_RID_PORTSTATUS 0xFD40 #define HFA384X_RID_CURRENTSSID 0xFD41 #define HFA384X_RID_CURRENTBSSID 0xFD42 #define HFA384X_RID_COMMSQUALITY 0xFD43 #define HFA384X_RID_CURRENTTXRATE 0xFD44 #define HFA384X_RID_CURRENTBEACONINTERVAL 0xFD45 #define HFA384X_RID_CURRENTSCALETHRESHOLDS 0xFD46 #define HFA384X_RID_PROTOCOLRSPTIME 0xFD47 #define HFA384X_RID_SHORTRETRYLIMIT 0xFD48 #define HFA384X_RID_LONGRETRYLIMIT 0xFD49 #define HFA384X_RID_MAXTRANSMITLIFETIME 0xFD4A #define HFA384X_RID_MAXRECEIVELIFETIME 0xFD4B #define HFA384X_RID_CFPOLLABLE 0xFD4C #define HFA384X_RID_AUTHENTICATIONALGORITHMS 0xFD4D #define HFA384X_RID_PRIVACYOPTIONIMPLEMENTED 0xFD4F #define HFA384X_RID_DBMCOMMSQUALITY 0xFD51 /* added in STA f/w 1.3.1 */ #define HFA384X_RID_CURRENTTXRATE1 0xFD80 /* AP f/w only */ #define HFA384X_RID_CURRENTTXRATE2 0xFD81 /* AP f/w only */ #define HFA384X_RID_CURRENTTXRATE3 0xFD82 /* AP f/w only */ #define HFA384X_RID_CURRENTTXRATE4 0xFD83 /* AP f/w only */ #define HFA384X_RID_CURRENTTXRATE5 0xFD84 /* AP f/w only */ #define HFA384X_RID_CURRENTTXRATE6 0xFD85 /* AP f/w only */ #define HFA384X_RID_OWNMACADDR 0xFD86 /* AP f/w only */ #define HFA384X_RID_SCANRESULTSTABLE 0xFD88 /* added in STA f/w 0.8.3 */ #define HFA384X_RID_HOSTSCANRESULTS 0xFD89 /* added in STA f/w 1.3.1 */ #define HFA384X_RID_AUTHENTICATIONUSED 0xFD8A /* added in STA f/w 1.3.4 */ #define HFA384X_RID_CNFFAASWITCHCTRL 0xFD8B /* added in STA f/w 1.6.3 */ #define HFA384X_RID_ASSOCIATIONFAILURE 0xFD8D /* added in STA f/w 1.8.0 */ #define HFA384X_RID_PHYTYPE 0xFDC0 #define HFA384X_RID_CURRENTCHANNEL 0xFDC1 #define HFA384X_RID_CURRENTPOWERSTATE 0xFDC2 #define HFA384X_RID_CCAMODE 0xFDC3 #define HFA384X_RID_SUPPORTEDDATARATES 0xFDC6 #define HFA384X_RID_LFO_VOLT_REG_TEST_RES 0xFDC7 /* added in STA f/w 1.7.1 */ #define HFA384X_RID_BUILDSEQ 0xFFFE #define HFA384X_RID_FWID 0xFFFF struct hfa384x_comp_ident { u16 id; u16 variant; u16 major; u16 minor; } __attribute__ ((packed)); #define HFA384X_COMP_ID_PRI 0x15 #define HFA384X_COMP_ID_STA 0x1f #define HFA384X_COMP_ID_FW_AP 0x14b struct hfa384x_sup_range { u16 role; u16 id; u16 variant; u16 bottom; u16 top; } __attribute__ ((packed)); struct hfa384x_build_id { u16 pri_seq; u16 sec_seq; } __attribute__ ((packed)); /* FD01 - Download Buffer */ struct hfa384x_rid_download_buffer { u16 page; u16 offset; u16 length; } __attribute__ ((packed)); /* BSS connection quality (RID FD43 range, RID FD51 dBm-normalized) */ struct hfa384x_comms_quality { u16 comm_qual; /* 0 .. 92 */ u16 signal_level; /* 27 .. 154 */ u16 noise_level; /* 27 .. 154 */ } __attribute__ ((packed)); /* netdevice private ioctls (used, e.g., with iwpriv from user space) */ /* New wireless extensions API - SET/GET convention (even ioctl numbers are * root only) */ #define PRISM2_IOCTL_PRISM2_PARAM (SIOCIWFIRSTPRIV + 0) #define PRISM2_IOCTL_GET_PRISM2_PARAM (SIOCIWFIRSTPRIV + 1) #define PRISM2_IOCTL_WRITEMIF (SIOCIWFIRSTPRIV + 2) #define PRISM2_IOCTL_READMIF (SIOCIWFIRSTPRIV + 3) #define PRISM2_IOCTL_MONITOR (SIOCIWFIRSTPRIV + 4) #define PRISM2_IOCTL_RESET (SIOCIWFIRSTPRIV + 6) #define PRISM2_IOCTL_INQUIRE (SIOCIWFIRSTPRIV + 8) #define PRISM2_IOCTL_WDS_ADD (SIOCIWFIRSTPRIV + 10) #define PRISM2_IOCTL_WDS_DEL (SIOCIWFIRSTPRIV + 12) #define PRISM2_IOCTL_SET_RID_WORD (SIOCIWFIRSTPRIV + 14) #define PRISM2_IOCTL_MACCMD (SIOCIWFIRSTPRIV + 16) #define PRISM2_IOCTL_ADDMAC (SIOCIWFIRSTPRIV + 18) #define PRISM2_IOCTL_DELMAC (SIOCIWFIRSTPRIV + 20) #define PRISM2_IOCTL_KICKMAC (SIOCIWFIRSTPRIV + 22) /* following are not in SIOCGIWPRIV list; check permission in the driver code */ #define PRISM2_IOCTL_DOWNLOAD (SIOCDEVPRIVATE + 13) #define PRISM2_IOCTL_HOSTAPD (SIOCDEVPRIVATE + 14) /* PRISM2_IOCTL_PRISM2_PARAM ioctl() subtypes: */ enum { /* PRISM2_PARAM_PTYPE = 1, */ /* REMOVED 2003-10-22 */ PRISM2_PARAM_TXRATECTRL = 2, PRISM2_PARAM_BEACON_INT = 3, PRISM2_PARAM_PSEUDO_IBSS = 4, PRISM2_PARAM_ALC = 5, /* PRISM2_PARAM_TXPOWER = 6, */ /* REMOVED 2003-10-22 */ PRISM2_PARAM_DUMP = 7, PRISM2_PARAM_OTHER_AP_POLICY = 8, PRISM2_PARAM_AP_MAX_INACTIVITY = 9, PRISM2_PARAM_AP_BRIDGE_PACKETS = 10, PRISM2_PARAM_DTIM_PERIOD = 11, PRISM2_PARAM_AP_NULLFUNC_ACK = 12, PRISM2_PARAM_MAX_WDS = 13, PRISM2_PARAM_AP_AUTOM_AP_WDS = 14, PRISM2_PARAM_AP_AUTH_ALGS = 15, PRISM2_PARAM_MONITOR_ALLOW_FCSERR = 16, PRISM2_PARAM_HOST_ENCRYPT = 17, PRISM2_PARAM_HOST_DECRYPT = 18, PRISM2_PARAM_BUS_MASTER_THRESHOLD_RX = 19, PRISM2_PARAM_BUS_MASTER_THRESHOLD_TX = 20, PRISM2_PARAM_HOST_ROAMING = 21, PRISM2_PARAM_BCRX_STA_KEY = 22, PRISM2_PARAM_IEEE_802_1X = 23, PRISM2_PARAM_ANTSEL_TX = 24, PRISM2_PARAM_ANTSEL_RX = 25, PRISM2_PARAM_MONITOR_TYPE = 26, PRISM2_PARAM_WDS_TYPE = 27, PRISM2_PARAM_HOSTSCAN = 28, PRISM2_PARAM_AP_SCAN = 29, PRISM2_PARAM_ENH_SEC = 30, PRISM2_PARAM_IO_DEBUG = 31, PRISM2_PARAM_BASIC_RATES = 32, PRISM2_PARAM_OPER_RATES = 33, PRISM2_PARAM_HOSTAPD = 34, PRISM2_PARAM_HOSTAPD_STA = 35, PRISM2_PARAM_WPA = 36, PRISM2_PARAM_PRIVACY_INVOKED = 37, PRISM2_PARAM_TKIP_COUNTERMEASURES = 38, PRISM2_PARAM_DROP_UNENCRYPTED = 39, PRISM2_PARAM_SCAN_CHANNEL_MASK = 40, }; enum { HOSTAP_ANTSEL_DO_NOT_TOUCH = 0, HOSTAP_ANTSEL_DIVERSITY = 1, HOSTAP_ANTSEL_LOW = 2, HOSTAP_ANTSEL_HIGH = 3 }; /* PRISM2_IOCTL_MACCMD ioctl() subcommands: */ enum { AP_MAC_CMD_POLICY_OPEN = 0, AP_MAC_CMD_POLICY_ALLOW = 1, AP_MAC_CMD_POLICY_DENY = 2, AP_MAC_CMD_FLUSH = 3, AP_MAC_CMD_KICKALL = 4 }; /* PRISM2_IOCTL_DOWNLOAD ioctl() dl_cmd: */ enum { PRISM2_DOWNLOAD_VOLATILE = 1 /* RAM */, /* Note! Old versions of prism2_srec have a fatal error in CRC-16 * calculation, which will corrupt all non-volatile downloads. * PRISM2_DOWNLOAD_NON_VOLATILE used to be 2, but it is now 3 to * prevent use of old versions of prism2_srec for non-volatile * download. */ PRISM2_DOWNLOAD_NON_VOLATILE = 3 /* FLASH */, PRISM2_DOWNLOAD_VOLATILE_GENESIS = 4 /* RAM in Genesis mode */, /* Persistent versions of volatile download commands (keep firmware * data in memory and automatically re-download after hw_reset */ PRISM2_DOWNLOAD_VOLATILE_PERSISTENT = 5, PRISM2_DOWNLOAD_VOLATILE_GENESIS_PERSISTENT = 6, }; struct prism2_download_param { u32 dl_cmd; u32 start_addr; u32 num_areas; struct prism2_download_area { u32 addr; /* wlan card address */ u32 len; caddr_t ptr; /* pointer to data in user space */ } data[0]; }; #define PRISM2_MAX_DOWNLOAD_AREA_LEN 131072 #define PRISM2_MAX_DOWNLOAD_LEN 262144 /* PRISM2_IOCTL_HOSTAPD ioctl() cmd: */ enum { PRISM2_HOSTAPD_FLUSH = 1, PRISM2_HOSTAPD_ADD_STA = 2, PRISM2_HOSTAPD_REMOVE_STA = 3, PRISM2_HOSTAPD_GET_INFO_STA = 4, /* REMOVED: PRISM2_HOSTAPD_RESET_TXEXC_STA = 5, */ PRISM2_SET_ENCRYPTION = 6, PRISM2_GET_ENCRYPTION = 7, PRISM2_HOSTAPD_SET_FLAGS_STA = 8, PRISM2_HOSTAPD_GET_RID = 9, PRISM2_HOSTAPD_SET_RID = 10, PRISM2_HOSTAPD_SET_ASSOC_AP_ADDR = 11, PRISM2_HOSTAPD_SET_GENERIC_ELEMENT = 12, PRISM2_HOSTAPD_MLME = 13, PRISM2_HOSTAPD_SCAN_REQ = 14, PRISM2_HOSTAPD_STA_CLEAR_STATS = 15, }; #define PRISM2_HOSTAPD_MAX_BUF_SIZE 1024 #define PRISM2_HOSTAPD_RID_HDR_LEN \ ((int) (&((struct prism2_hostapd_param *) 0)->u.rid.data)) #define PRISM2_HOSTAPD_GENERIC_ELEMENT_HDR_LEN \ ((int) (&((struct prism2_hostapd_param *) 0)->u.generic_elem.data)) /* Maximum length for algorithm names (-1 for nul termination) used in ioctl() */ #define HOSTAP_CRYPT_ALG_NAME_LEN 16 struct prism2_hostapd_param { u32 cmd; u8 sta_addr[ETH_ALEN]; union { struct { u16 aid; u16 capability; u8 tx_supp_rates; } add_sta; struct { u32 inactive_sec; } get_info_sta; struct { u8 alg[HOSTAP_CRYPT_ALG_NAME_LEN]; u32 flags; u32 err; u8 idx; u8 seq[8]; /* sequence counter (set: RX, get: TX) */ u16 key_len; u8 key[0]; } crypt; struct { u32 flags_and; u32 flags_or; } set_flags_sta; struct { u16 rid; u16 len; u8 data[0]; } rid; struct { u8 len; u8 data[0]; } generic_elem; struct { #define MLME_STA_DEAUTH 0 #define MLME_STA_DISASSOC 1 u16 cmd; u16 reason_code; } mlme; struct { u8 ssid_len; u8 ssid[32]; } scan_req; } u; }; #define HOSTAP_CRYPT_FLAG_SET_TX_KEY BIT(0) #define HOSTAP_CRYPT_FLAG_PERMANENT BIT(1) #define HOSTAP_CRYPT_ERR_UNKNOWN_ALG 2 #define HOSTAP_CRYPT_ERR_UNKNOWN_ADDR 3 #define HOSTAP_CRYPT_ERR_CRYPT_INIT_FAILED 4 #define HOSTAP_CRYPT_ERR_KEY_SET_FAILED 5 #define HOSTAP_CRYPT_ERR_TX_KEY_SET_FAILED 6 #define HOSTAP_CRYPT_ERR_CARD_CONF_FAILED 7 #endif /* HOSTAP_COMMON_H */