+ unsigned int retry_type = 0;
+ unsigned int retry_mask = 0;
+ unsigned int remain_mask = range.retry_capa & IW_RETRY_TYPE;
+
+ /* Let's check the mode */
+ printf("Current mode:on\n ");
+
+ /* Let's check the value and its type */
+ if(wrq.u.retry.flags & IW_RETRY_TYPE)
+ {
+ iw_print_retry_value(buffer, sizeof(buffer),
+ wrq.u.retry.value, wrq.u.retry.flags,
+ range.we_version_compiled);
+ printf("%s\n ", buffer);
+ }
+
+ while(1)
+ {
+ /* Deal with min/max/short/long for the current value */
+ retry_mask = 0;
+ /* If we have been returned a MIN value, ask for the MAX */
+ if(flags & IW_RETRY_MIN)
+ retry_mask = IW_RETRY_MAX;
+ /* If we have been returned a MAX value, ask for the MIN */
+ if(flags & IW_RETRY_MAX)
+ retry_mask = IW_RETRY_MIN;
+ /* Same for SHORT and LONG */
+ if(flags & IW_RETRY_SHORT)
+ retry_mask = IW_RETRY_LONG;
+ if(flags & IW_RETRY_LONG)
+ retry_mask = IW_RETRY_SHORT;
+ /* If we have something to ask for... */
+ if(retry_mask)
+ {
+ retry_mask |= retry_type;
+ get_retry_value(skfd, ifname, &wrq, retry_mask,
+ buffer, sizeof(buffer),
+ range.we_version_compiled);
+ }
+
+ /* And if we have both a limit and a lifetime,
+ * ask the other one */
+ remain_mask &= ~(wrq.u.retry.flags);
+ retry_type = remain_mask;
+ /* Nothing anymore : exit the loop */
+ if(!retry_type)
+ break;
+
+ /* Ask for this other type of value */
+ flags = get_retry_value(skfd, ifname, &wrq, retry_type,
+ buffer, sizeof(buffer),
+ range.we_version_compiled);
+ /* Loop back for min/max/short/long */
+ }
+ }
+ }
+ printf("\n");
+ }
+ return(0);
+}
+
+/************************ ACCESS POINT LIST ************************/
+/*
+ * Note : now that we have scanning support, this is depracted and
+ * won't survive long. Actually, next version it's out !
+ */
+
+/*------------------------------------------------------------------*/
+/*
+ * Display the list of ap addresses and the associated stats
+ * Exacly the same as the spy list, only with different IOCTL and messages
+ */
+static int
+print_ap_info(int skfd,
+ char * ifname,
+ char * args[], /* Command line args */
+ int count) /* Args count */
+{
+ struct iwreq wrq;
+ char buffer[(sizeof(struct iw_quality) +
+ sizeof(struct sockaddr)) * IW_MAX_AP];
+ char temp[128];
+ struct sockaddr * hwa;
+ struct iw_quality * qual;
+ iwrange range;
+ int has_range = 0;
+ int has_qual = 0;
+ int n;
+ int i;
+
+ /* Avoid "Unused parameter" warning */
+ args = args; count = count;
+
+ /* Collect stats */
+ wrq.u.data.pointer = (caddr_t) buffer;
+ wrq.u.data.length = IW_MAX_AP;
+ wrq.u.data.flags = 0;
+ if(iw_get_ext(skfd, ifname, SIOCGIWAPLIST, &wrq) < 0)
+ {
+ fprintf(stderr, "%-8.16s Interface doesn't have a list of Peers/Access-Points\n\n", ifname);
+ return(-1);
+ }
+
+ /* Number of addresses */
+ n = wrq.u.data.length;
+ has_qual = wrq.u.data.flags;
+
+ /* The two lists */
+ hwa = (struct sockaddr *) buffer;
+ qual = (struct iw_quality *) (buffer + (sizeof(struct sockaddr) * n));
+
+ /* Check if we have valid mac address type */
+ if(iw_check_mac_addr_type(skfd, ifname) < 0)
+ {
+ fprintf(stderr, "%-8.16s Interface doesn't support MAC addresses\n\n", ifname);
+ return(-2);
+ }
+
+ /* Get range info if we can */
+ if(iw_get_range_info(skfd, ifname, &(range)) >= 0)
+ has_range = 1;
+
+ /* Display it */
+ if(n == 0)
+ printf("%-8.16s No Peers/Access-Point in range\n", ifname);
+ else
+ printf("%-8.16s Peers/Access-Points in range:\n", ifname);
+ for(i = 0; i < n; i++)
+ {
+ if(has_qual)
+ {
+ /* Print stats for this address */
+ printf(" %s : ", iw_saether_ntop(&hwa[i], temp));
+ iw_print_stats(temp, sizeof(buffer), &qual[i], &range, has_range);
+ printf("%s\n", temp);
+ }
+ else
+ /* Only print the address */
+ printf(" %s\n", iw_saether_ntop(&hwa[i], temp));
+ }
+ printf("\n");
+ return(0);
+}
+
+/******************** WIRELESS EVENT CAPABILITY ********************/
+
+static const char * event_capa_req[] =
+{
+ [SIOCSIWNWID - SIOCIWFIRST] = "Set NWID (kernel generated)",
+ [SIOCSIWFREQ - SIOCIWFIRST] = "Set Frequency/Channel (kernel generated)",
+ [SIOCGIWFREQ - SIOCIWFIRST] = "New Frequency/Channel",
+ [SIOCSIWMODE - SIOCIWFIRST] = "Set Mode (kernel generated)",
+ [SIOCGIWTHRSPY - SIOCIWFIRST] = "Spy threshold crossed",
+ [SIOCGIWAP - SIOCIWFIRST] = "New Access Point/Cell address - roaming",
+ [SIOCGIWSCAN - SIOCIWFIRST] = "Scan request completed",
+ [SIOCSIWESSID - SIOCIWFIRST] = "Set ESSID (kernel generated)",
+ [SIOCGIWESSID - SIOCIWFIRST] = "New ESSID",
+ [SIOCGIWRATE - SIOCIWFIRST] = "New bit-rate",
+ [SIOCSIWENCODE - SIOCIWFIRST] = "Set Encoding (kernel generated)",
+ [SIOCGIWPOWER - SIOCIWFIRST] = NULL,
+};
+
+static const char * event_capa_evt[] =
+{
+ [IWEVTXDROP - IWEVFIRST] = "Tx packet dropped - retry exceeded",
+ [IWEVCUSTOM - IWEVFIRST] = "Custom driver event",
+ [IWEVREGISTERED - IWEVFIRST] = "Registered node",
+ [IWEVEXPIRED - IWEVFIRST] = "Expired node",
+};
+
+/*------------------------------------------------------------------*/
+/*
+ * Print the event capability for the device
+ */
+static int
+print_event_capa_info(int skfd,
+ char * ifname,
+ char * args[], /* Command line args */
+ int count) /* Args count */
+{
+ struct iw_range range;
+ int cmd;
+
+ /* Avoid "Unused parameter" warning */
+ args = args; count = count;
+
+ /* Extract range info */
+ if((iw_get_range_info(skfd, ifname, &range) < 0) ||
+ (range.we_version_compiled < 10))
+ fprintf(stderr, "%-8.16s no wireless event capability information.\n\n",
+ ifname);
+ else
+ {
+#ifdef DEBUG
+ /* Debugging ;-) */
+ for(cmd = 0x8B00; cmd < 0x8C0F; cmd++)
+ {
+ int idx = IW_EVENT_CAPA_INDEX(cmd);
+ int mask = IW_EVENT_CAPA_MASK(cmd);
+ printf("0x%X - %d - %X\n", cmd, idx, mask);
+ }
+#endif
+
+ printf("%-8.16s Wireless Events supported :\n", ifname);
+
+ for(cmd = SIOCIWFIRST; cmd <= SIOCGIWPOWER; cmd++)
+ {
+ int idx = IW_EVENT_CAPA_INDEX(cmd);
+ int mask = IW_EVENT_CAPA_MASK(cmd);
+ if(range.event_capa[idx] & mask)
+ printf(" 0x%04X : %s\n",
+ cmd, event_capa_req[cmd - SIOCIWFIRST]);
+ }
+ for(cmd = IWEVFIRST; cmd <= IWEVEXPIRED; cmd++)
+ {
+ int idx = IW_EVENT_CAPA_INDEX(cmd);
+ int mask = IW_EVENT_CAPA_MASK(cmd);
+ if(range.event_capa[idx] & mask)
+ printf(" 0x%04X : %s\n",
+ cmd, event_capa_evt[cmd - IWEVFIRST]);
+ }
+ printf("\n");
+ }
+ return(0);
+}
+
+/*************************** WPA SUPPORT ***************************/
+
+/*------------------------------------------------------------------*/
+/*
+ * Print the authentication parameters for the device
+ */
+static int
+print_auth_info(int skfd,
+ char * ifname,
+ char * args[], /* Command line args */
+ int count) /* Args count */
+{
+ struct iwreq wrq;
+ struct iw_range range;
+ unsigned int k;
+
+ /* Avoid "Unused parameter" warning */
+ args = args; count = count;
+
+ /* Extract range info */
+ if((iw_get_range_info(skfd, ifname, &range) < 0) ||
+ (range.we_version_compiled < 18))
+ fprintf(stderr, "%-8.16s no authentication information.\n\n",
+ ifname);
+ else
+ {
+ /* Print WPA/802.1x/802.11i security parameters */
+ if(!range.enc_capa)
+ {
+ printf("%-8.16s unknown authentication information.\n\n", ifname);
+ }
+ else
+ {
+ /* Display advanced encryption capabilities */
+ printf("%-8.16s Authentication capabilities :", ifname);
+ iw_print_mask_name(range.enc_capa,
+ iw_auth_capa_name, IW_AUTH_CAPA_NUM,
+ "\n\t\t");
+ printf("\n");
+
+ /* Extract all auth settings */
+ for(k = 0; k < IW_AUTH_SETTINGS_NUM; k++)
+ {
+ wrq.u.param.flags = iw_auth_settings[k].value;
+ if(iw_get_ext(skfd, ifname, SIOCGIWAUTH, &wrq) >= 0)
+ {
+ printf(" Current %s :", iw_auth_settings[k].label);
+ if(iw_auth_settings[k].names != NULL)
+ iw_print_mask_name(wrq.u.param.value,
+ iw_auth_settings[k].names,
+ iw_auth_settings[k].num_names,
+ "\n\t\t");
+ else
+ printf((wrq.u.param.value) ? " yes" : " no");
+ printf("\n");
+ }
+ }
+ }
+
+ printf("\n\n");
+ }
+ return(0);
+}
+
+/*------------------------------------------------------------------*/
+/*
+ * Print all the available wpa keys for the device
+ */
+static int
+print_wpakeys_info(int skfd,
+ char * ifname,
+ char * args[], /* Command line args */
+ int count) /* Args count */
+{
+ struct iwreq wrq;
+ struct iw_range range;
+ unsigned char extbuf[IW_EXTKEY_SIZE];
+ struct iw_encode_ext *extinfo;
+ unsigned int k;
+ char buffer[128];
+
+ /* Avoid "Unused parameter" warning */
+ args = args; count = count;
+
+ /* This always point to the same place */
+ extinfo = (struct iw_encode_ext *) extbuf;
+
+ /* Extract range info */
+ if(iw_get_range_info(skfd, ifname, &range) < 0)
+ fprintf(stderr, "%-8.16s no wpa key information.\n\n",
+ ifname);
+ else
+ {
+ printf("%-8.16s ", ifname);
+ /* Print key sizes */
+ if((range.num_encoding_sizes > 0) &&
+ (range.num_encoding_sizes < IW_MAX_ENCODING_SIZES))
+ {
+ printf("%d key sizes : %d", range.num_encoding_sizes,
+ range.encoding_size[0] * 8);
+ /* Print them all */
+ for(k = 1; k < range.num_encoding_sizes; k++)
+ printf(", %d", range.encoding_size[k] * 8);
+ printf("bits\n ");
+ }
+
+ /* Print the keys */
+ printf("%d keys available :\n", range.max_encoding_tokens);
+ for(k = 1; k <= range.max_encoding_tokens; k++)
+ {
+ /* Cleanup. Driver may not fill everything */
+ memset(extbuf, '\0', IW_EXTKEY_SIZE);
+
+ /* Get whole struct containing one WPA key */
+ wrq.u.data.pointer = (caddr_t) extbuf;
+ wrq.u.data.length = IW_EXTKEY_SIZE;
+ wrq.u.data.flags = k;
+ if(iw_get_ext(skfd, ifname, SIOCGIWENCODEEXT, &wrq) < 0)
+ {
+ fprintf(stderr, "Error reading wpa keys (SIOCGIWENCODEEXT): %s\n", strerror(errno));
+ break;
+ }