4 * Jean II - HPLB '99 - HPL 99->01
6 * This tool can access various piece of information on the card
7 * not part of iwconfig...
8 * You need to link this code against "iwlist.c" and "-lm".
10 * This file is released under the GPL license.
11 * Copyright (c) 1997-2002 Jean Tourrilhes <jt@hpl.hp.com>
14 #include "iwlib.h" /* Header */
17 /*********************** FREQUENCIES/CHANNELS ***********************/
19 /*------------------------------------------------------------------*/
21 * Print the number of channels and available frequency for the device
24 print_freq_info(int skfd,
26 char * args[], /* Command line args */
27 int count) /* Args count */
30 struct iw_range range;
33 /* Avoid "Unused parameter" warning */
34 args = args; count = count;
36 if(iw_get_range_info(skfd, ifname, &range) < 0)
37 fprintf(stderr, "%-8.8s no frequency information.\n\n",
41 if(range.num_frequency > 0)
43 printf("%-8.8s %d channels in total; available frequencies :\n",
44 ifname, range.num_channels);
46 for(k = 0; k < range.num_frequency; k++)
48 printf("\t Channel %.2d : ", range.freq[k].i);
49 freq = iw_freq2float(&(range.freq[k]));
51 printf("%g GHz\n", freq / GIGA);
54 printf("%g MHz\n", freq / MEGA);
56 printf("%g kHz\n", freq / KILO);
61 printf("%-8.8s %d channels\n\n",
62 ifname, range.num_channels);
67 /************************ ACCESS POINT LIST ************************/
69 /*------------------------------------------------------------------*/
71 * Display the list of ap addresses and the associated stats
72 * Exacly the same as the spy list, only with different IOCTL and messages
75 print_ap_info(int skfd,
77 char * args[], /* Command line args */
78 int count) /* Args count */
81 char buffer[(sizeof(struct iw_quality) +
82 sizeof(struct sockaddr)) * IW_MAX_AP];
84 struct sockaddr * hwa;
85 struct iw_quality * qual;
92 /* Avoid "Unused parameter" warning */
93 args = args; count = count;
96 wrq.u.data.pointer = (caddr_t) buffer;
97 wrq.u.data.length = IW_MAX_AP;
99 if(iw_get_ext(skfd, ifname, SIOCGIWAPLIST, &wrq) < 0)
101 fprintf(stderr, "%-8.8s Interface doesn't have a list of Access Points\n\n", ifname);
105 /* Number of addresses */
106 n = wrq.u.data.length;
107 has_qual = wrq.u.data.flags;
110 hwa = (struct sockaddr *) buffer;
111 qual = (struct iw_quality *) (buffer + (sizeof(struct sockaddr) * n));
113 /* Check if we have valid mac address type */
114 if(iw_check_mac_addr_type(skfd, ifname) < 0)
116 fprintf(stderr, "%-8.8s Interface doesn't support MAC addresses\n\n", ifname);
120 /* Get range info if we can */
121 if(iw_get_range_info(skfd, ifname, &(range)) >= 0)
126 printf("%-8.8s No Access Point in range\n", ifname);
128 printf("%-8.8s Access Points in range:\n", ifname);
129 for(i = 0; i < n; i++)
133 /* Print stats for this address */
134 printf(" %s : ", iw_pr_ether(temp, hwa[i].sa_data));
135 iw_print_stats(temp, &qual[i], &range, has_range);
136 printf("%s\n", temp);
139 /* Only print the address */
140 printf(" %s\n", iw_pr_ether(temp, hwa[i].sa_data));
146 /***************************** BITRATES *****************************/
148 /*------------------------------------------------------------------*/
150 * Print the number of available bitrates for the device
153 print_bitrate_info(int skfd,
155 char * args[], /* Command line args */
156 int count) /* Args count */
158 struct iw_range range;
162 /* Avoid "Unused parameter" warning */
163 args = args; count = count;
165 /* Extract range info */
166 if(iw_get_range_info(skfd, ifname, &range) < 0)
167 fprintf(stderr, "%-8.8s no bit-rate information.\n\n",
171 if((range.num_bitrates > 0) && (range.num_bitrates < IW_MAX_BITRATES))
173 printf("%-8.8s %d available bit-rates :\n",
174 ifname, range.num_bitrates);
176 for(k = 0; k < range.num_bitrates; k++)
178 iw_print_bitrate(buffer, range.bitrate[k]);
179 /* Maybe this should be %10s */
180 printf("\t %s\n", buffer);
185 printf("%-8.8s No bit-rates ? Please update driver...\n\n", ifname);
190 /************************* ENCRYPTION KEYS *************************/
192 /*------------------------------------------------------------------*/
194 * Print the number of available encryption key for the device
197 print_keys_info(int skfd,
199 char * args[], /* Command line args */
200 int count) /* Args count */
203 struct iw_range range;
204 unsigned char key[IW_ENCODING_TOKEN_MAX];
208 /* Avoid "Unused parameter" warning */
209 args = args; count = count;
211 /* Extract range info */
212 if(iw_get_range_info(skfd, ifname, &range) < 0)
213 fprintf(stderr, "%-8.8s no encryption keys information.\n\n",
217 printf("%-8.8s ", ifname);
218 /* Print key sizes */
219 if((range.num_encoding_sizes > 0) &&
220 (range.num_encoding_sizes < IW_MAX_ENCODING_SIZES))
222 printf("%d key sizes : %d", range.num_encoding_sizes,
223 range.encoding_size[0] * 8);
225 for(k = 1; k < range.num_encoding_sizes; k++)
226 printf(", %d", range.encoding_size[k] * 8);
229 /* Print the keys and associate mode */
230 printf("%d keys available :\n", range.max_encoding_tokens);
231 for(k = 1; k <= range.max_encoding_tokens; k++)
233 wrq.u.data.pointer = (caddr_t) key;
234 wrq.u.data.length = IW_ENCODING_TOKEN_MAX;
235 wrq.u.data.flags = k;
236 if(iw_get_ext(skfd, ifname, SIOCGIWENCODE, &wrq) < 0)
238 fprintf(stderr, "SIOCGIWENCODE: %s\n", strerror(errno));
241 if((wrq.u.data.flags & IW_ENCODE_DISABLED) ||
242 (wrq.u.data.length == 0))
243 printf("\t\t[%d]: off\n", k);
246 /* Display the key */
247 iw_print_key(buffer, key, wrq.u.data.length, wrq.u.data.flags);
248 printf("\t\t[%d]: %s", k, buffer);
251 printf(" (%d bits)", wrq.u.data.length * 8);
255 /* Print current key and mode */
256 wrq.u.data.pointer = (caddr_t) key;
257 wrq.u.data.length = IW_ENCODING_TOKEN_MAX;
258 wrq.u.data.flags = 0; /* Set index to zero to get current */
259 if(iw_get_ext(skfd, ifname, SIOCGIWENCODE, &wrq) < 0)
261 fprintf(stderr, "SIOCGIWENCODE: %s\n", strerror(errno));
264 printf(" Current Transmit Key: [%d]\n",
265 wrq.u.data.flags & IW_ENCODE_INDEX);
266 if(wrq.u.data.flags & IW_ENCODE_RESTRICTED)
267 printf(" Encryption mode:restricted\n");
268 if(wrq.u.data.flags & IW_ENCODE_OPEN)
269 printf(" Encryption mode:open\n");
276 /************************* POWER MANAGEMENT *************************/
278 /*------------------------------------------------------------------*/
280 * Print Power Management info for each device
283 get_pm_value(int skfd,
289 /* Get Another Power Management value */
290 pwrq->u.power.flags = flags;
291 if(iw_get_ext(skfd, ifname, SIOCGIWPOWER, pwrq) >= 0)
293 /* Let's check the value and its type */
294 if(pwrq->u.power.flags & IW_POWER_TYPE)
296 iw_print_pm_value(buffer, pwrq->u.power.value, pwrq->u.power.flags);
297 printf("\n %s", buffer);
300 return(pwrq->u.power.flags);
303 /*------------------------------------------------------------------*/
305 * Print Power Management info for each device
308 print_pm_info(int skfd,
310 char * args[], /* Command line args */
311 int count) /* Args count */
314 struct iw_range range;
317 /* Avoid "Unused parameter" warning */
318 args = args; count = count;
320 /* Extract range info */
321 if(iw_get_range_info(skfd, ifname, &range) < 0)
322 fprintf(stderr, "%-8.8s no power management information.\n\n",
326 printf("%-8.8s ", ifname);
328 /* Display modes availables */
329 if(range.pm_capa & IW_POWER_MODE)
331 printf("Supported modes :\n ");
332 if(range.pm_capa & (IW_POWER_UNICAST_R | IW_POWER_MULTICAST_R))
333 printf("\t\to Receive all packets (unicast & multicast)\n ");
334 if(range.pm_capa & IW_POWER_UNICAST_R)
335 printf("\t\to Receive Unicast only (discard multicast)\n ");
336 if(range.pm_capa & IW_POWER_MULTICAST_R)
337 printf("\t\to Receive Multicast only (discard unicast)\n ");
338 if(range.pm_capa & IW_POWER_FORCE_S)
339 printf("\t\to Force sending using Power Management\n ");
340 if(range.pm_capa & IW_POWER_REPEATER)
341 printf("\t\to Repeat multicast\n ");
343 /* Display min/max period availables */
344 if(range.pmp_flags & IW_POWER_PERIOD)
346 int flags = (range.pmp_flags & ~(IW_POWER_MIN | IW_POWER_MAX));
347 /* Display if auto or fixed */
348 if(range.pmp_flags & IW_POWER_MIN)
349 printf("Auto period ; ");
351 printf("Fixed period ; ");
352 /* Print the range */
353 iw_print_pm_value(buffer, range.min_pmp, flags | IW_POWER_MIN);
354 printf("%s\n ", buffer);
355 iw_print_pm_value(buffer, range.max_pmp, flags | IW_POWER_MAX);
356 printf("%s\n ", buffer);
359 /* Display min/max timeout availables */
360 if(range.pmt_flags & IW_POWER_TIMEOUT)
362 int flags = (range.pmt_flags & ~(IW_POWER_MIN | IW_POWER_MAX));
363 /* Display if auto or fixed */
364 if(range.pmt_flags & IW_POWER_MIN)
365 printf("Auto timeout ; ");
367 printf("Fixed timeout ; ");
368 /* Print the range */
369 iw_print_pm_value(buffer, range.min_pmt, flags | IW_POWER_MIN);
370 printf("%s\n ", buffer);
371 iw_print_pm_value(buffer, range.max_pmt, flags | IW_POWER_MAX);
372 printf("%s\n ", buffer);
375 #endif /* WIRELESS_EXT > 9 */
377 /* Get current Power Management settings */
378 wrq.u.power.flags = 0;
379 if(iw_get_ext(skfd, ifname, SIOCGIWPOWER, &wrq) >= 0)
381 int flags = wrq.u.power.flags;
383 /* Is it disabled ? */
384 if(wrq.u.power.disabled)
385 printf("Current mode:off\n ");
390 /* Let's check the mode */
391 iw_print_pm_mode(buffer, flags);
392 printf("Current %s", buffer);
394 /* Let's check if nothing (simply on) */
395 if((flags & IW_POWER_MODE) == IW_POWER_ON)
399 /* Let's check the value and its type */
400 if(wrq.u.power.flags & IW_POWER_TYPE)
402 iw_print_pm_value(buffer,
403 wrq.u.power.value, wrq.u.power.flags);
404 printf("%s", buffer);
407 /* If we have been returned a MIN value, ask for the MAX */
408 if(flags & IW_POWER_MIN)
409 pm_mask = IW_POWER_MAX;
410 /* If we have been returned a MAX value, ask for the MIN */
411 if(flags & IW_POWER_MAX)
412 pm_mask = IW_POWER_MIN;
413 /* If we have something to ask for... */
415 get_pm_value(skfd, ifname, &wrq, pm_mask, buffer);
418 /* And if we have both a period and a timeout, ask the other */
419 pm_mask = (range.pm_capa & (~(wrq.u.power.flags) &
423 int base_mask = pm_mask;
424 flags = get_pm_value(skfd, ifname, &wrq, pm_mask, buffer);
427 /* If we have been returned a MIN value, ask for the MAX */
428 if(flags & IW_POWER_MIN)
429 pm_mask = IW_POWER_MAX | base_mask;
430 /* If we have been returned a MAX value, ask for the MIN */
431 if(flags & IW_POWER_MAX)
432 pm_mask = IW_POWER_MIN | base_mask;
433 /* If we have something to ask for... */
435 get_pm_value(skfd, ifname, &wrq, pm_mask, buffer);
437 #endif /* WIRELESS_EXT > 9 */
445 /************************** TRANSMIT POWER **************************/
447 /*------------------------------------------------------------------*/
449 * Print the number of available transmit powers for the device
452 print_txpower_info(int skfd,
454 char * args[], /* Command line args */
455 int count) /* Args count */
457 struct iw_range range;
462 /* Avoid "Unused parameter" warning */
463 args = args; count = count;
466 /* Extract range info */
467 if(iw_get_range_info(skfd, ifname, &range) < 0)
468 fprintf(stderr, "%-8.8s no transmit-power information.\n\n",
472 if((range.num_txpower > 0) && (range.num_txpower < IW_MAX_TXPOWER))
474 printf("%-8.8s %d available transmit-powers :\n",
475 ifname, range.num_txpower);
477 for(k = 0; k < range.num_txpower; k++)
479 if(range.txpower_capa & IW_TXPOW_MWATT)
481 dbm = iw_mwatt2dbm(range.txpower[k]);
482 mwatt = range.txpower[k];
486 dbm = range.txpower[k];
487 mwatt = iw_dbm2mwatt(range.txpower[k]);
489 printf("\t %d dBm \t(%d mW)\n", dbm, mwatt);
494 printf("%-8.8s No transmit-powers ? Please update driver...\n\n", ifname);
496 #endif /* WIRELESS_EXT > 9 */
500 /*********************** RETRY LIMIT/LIFETIME ***********************/
502 #if WIRELESS_EXT > 10
503 /*------------------------------------------------------------------*/
505 * Print one retry value
508 get_retry_value(int skfd,
514 /* Get Another retry value */
515 pwrq->u.retry.flags = flags;
516 if(iw_get_ext(skfd, ifname, SIOCGIWRETRY, pwrq) >= 0)
518 /* Let's check the value and its type */
519 if(pwrq->u.retry.flags & IW_RETRY_TYPE)
521 iw_print_retry_value(buffer,
522 pwrq->u.retry.value, pwrq->u.retry.flags);
523 printf("%s\n ", buffer);
526 return(pwrq->u.retry.flags);
529 /*------------------------------------------------------------------*/
531 * Print Retry info for each device
534 print_retry_info(int skfd,
536 char * args[], /* Command line args */
537 int count) /* Args count */
540 struct iw_range range;
543 /* Avoid "Unused parameter" warning */
544 args = args; count = count;
546 /* Extract range info */
547 if(iw_get_range_info(skfd, ifname, &range) < 0)
548 fprintf(stderr, "%-8.8s no retry limit/lifetime information.\n\n",
552 printf("%-8.8s ", ifname);
554 /* Display min/max limit availables */
555 if(range.retry_flags & IW_RETRY_LIMIT)
557 int flags = (range.retry_flags & ~(IW_RETRY_MIN | IW_RETRY_MAX));
558 /* Display if auto or fixed */
559 if(range.retry_flags & IW_RETRY_MIN)
560 printf("Auto limit ; ");
562 printf("Fixed limit ; ");
563 /* Print the range */
564 iw_print_retry_value(buffer, range.min_retry, flags | IW_RETRY_MIN);
565 printf("%s\n ", buffer);
566 iw_print_retry_value(buffer, range.max_retry, flags | IW_RETRY_MAX);
567 printf("%s\n ", buffer);
570 /* Display min/max lifetime availables */
571 if(range.r_time_flags & IW_RETRY_LIFETIME)
573 int flags = (range.r_time_flags & ~(IW_RETRY_MIN | IW_RETRY_MAX));
574 /* Display if auto or fixed */
575 if(range.r_time_flags & IW_RETRY_MIN)
576 printf("Auto lifetime ; ");
578 printf("Fixed lifetime ; ");
579 /* Print the range */
580 iw_print_retry_value(buffer, range.min_r_time, flags | IW_RETRY_MIN);
581 printf("%s\n ", buffer);
582 iw_print_retry_value(buffer, range.max_r_time, flags | IW_RETRY_MAX);
583 printf("%s\n ", buffer);
587 /* Get current retry settings */
588 wrq.u.retry.flags = 0;
589 if(iw_get_ext(skfd, ifname, SIOCGIWRETRY, &wrq) >= 0)
591 int flags = wrq.u.retry.flags;
593 /* Is it disabled ? */
594 if(wrq.u.retry.disabled)
595 printf("Current mode:off\n ");
600 /* Let's check the mode */
601 printf("Current mode:on\n ");
603 /* Let's check the value and its type */
604 if(wrq.u.retry.flags & IW_RETRY_TYPE)
606 iw_print_retry_value(buffer,
607 wrq.u.retry.value, wrq.u.retry.flags);
608 printf("%s", buffer);
611 /* If we have been returned a MIN value, ask for the MAX */
612 if(flags & IW_RETRY_MIN)
613 retry_mask = IW_RETRY_MAX;
614 /* If we have been returned a MAX value, ask for the MIN */
615 if(flags & IW_RETRY_MAX)
616 retry_mask = IW_RETRY_MIN;
617 /* If we have something to ask for... */
619 get_retry_value(skfd, ifname, &wrq, retry_mask, buffer);
621 /* And if we have both a period and a timeout, ask the other */
622 retry_mask = (range.retry_capa & (~(wrq.u.retry.flags) &
626 int base_mask = retry_mask;
627 flags = get_retry_value(skfd, ifname, &wrq, retry_mask,
631 /* If we have been returned a MIN value, ask for the MAX */
632 if(flags & IW_RETRY_MIN)
633 retry_mask = IW_RETRY_MAX | base_mask;
634 /* If we have been returned a MAX value, ask for the MIN */
635 if(flags & IW_RETRY_MAX)
636 retry_mask = IW_RETRY_MIN | base_mask;
637 /* If we have something to ask for... */
639 get_retry_value(skfd, ifname, &wrq, retry_mask, buffer);
648 #endif /* WIRELESS_EXT > 10 */
650 /***************************** SCANNING *****************************/
652 * This one behave quite differently from the others
654 #if WIRELESS_EXT > 13
655 /*------------------------------------------------------------------*/
657 * Print one element from the scanning results
660 print_scanning_token(struct iw_event * event, /* Extracted token */
661 int ap_num, /* AP number */
662 struct iw_range * iwrange, /* Range info */
665 char buffer[128]; /* Temporary buffer */
667 /* Now, let's decode the event */
671 printf(" Cell %02d - Address: %s\n", ap_num,
672 iw_pr_ether(buffer, event->u.ap_addr.sa_data));
676 if(event->u.nwid.disabled)
677 printf(" NWID:off/any\n");
679 printf(" NWID:%X\n", event->u.nwid.value);
683 float freq; /* Frequency/channel */
684 freq = iw_freq2float(&(event->u.freq));
685 iw_print_freq(buffer, freq);
686 printf(" %s\n", buffer);
691 iw_operation_mode[event->u.mode]);
695 char essid[IW_ESSID_MAX_SIZE+1];
696 if((event->u.essid.pointer) && (event->u.essid.length))
697 memcpy(essid, event->u.essid.pointer, event->u.essid.length);
698 essid[event->u.essid.length] = '\0';
699 if(event->u.essid.flags)
701 /* Does it have an ESSID index ? */
702 if((event->u.essid.flags & IW_ENCODE_INDEX) > 1)
703 printf(" ESSID:\"%s\" [%d]\n", essid,
704 (event->u.essid.flags & IW_ENCODE_INDEX));
706 printf(" ESSID:\"%s\"\n", essid);
709 printf(" ESSID:off/any\n");
714 unsigned char key[IW_ENCODING_TOKEN_MAX];
715 if(event->u.data.pointer)
716 memcpy(key, event->u.essid.pointer, event->u.data.length);
718 event->u.data.flags |= IW_ENCODE_NOKEY;
719 printf(" Encryption key:");
720 if(event->u.data.flags & IW_ENCODE_DISABLED)
724 /* Display the key */
725 iw_print_key(buffer, key, event->u.data.length,
726 event->u.data.flags);
727 printf("%s", buffer);
730 if((event->u.data.flags & IW_ENCODE_INDEX) > 1)
731 printf(" [%d]", event->u.data.flags & IW_ENCODE_INDEX);
732 if(event->u.data.flags & IW_ENCODE_RESTRICTED)
733 printf(" Encryption mode:restricted");
734 if(event->u.data.flags & IW_ENCODE_OPEN)
735 printf(" Encryption mode:open");
741 iw_print_bitrate(buffer, event->u.bitrate.value);
742 printf(" Bit Rate:%s\n", buffer);
746 event->u.qual.updated = 0x0; /* Not that reliable, disable */
747 iw_print_stats(buffer, &event->u.qual, iwrange, has_range);
748 printf(" %s\n", buffer);
752 printf(" (Unknown Wireless Token 0x%04X)\n",
754 } /* switch(event->cmd) */
756 /* May have changed */
760 /*------------------------------------------------------------------*/
762 * Perform a scanning on one device
765 print_scanning_info(int skfd,
767 char * args[], /* Command line args */
768 int count) /* Args count */
771 unsigned char buffer[IW_SCAN_MAX_DATA]; /* Results */
772 struct timeval tv; /* Select timeout */
773 int timeout = 5000000; /* 5s */
775 /* Avoid "Unused parameter" warning */
776 args = args; count = count;
778 /* Init timeout value -> 250ms*/
783 * Here we should look at the command line args and set the IW_SCAN_ flags
786 wrq.u.param.flags = IW_SCAN_DEFAULT;
787 wrq.u.param.value = 0; /* Later */
789 /* Initiate Scanning */
790 if(iw_set_ext(skfd, ifname, SIOCSIWSCAN, &wrq) < 0)
794 fprintf(stderr, "%-8.8s Interface doesn't support scanning : %s\n\n",
795 ifname, strerror(errno));
798 /* If we don't have the permission to initiate the scan, we may
799 * still have permission to read left-over results.
800 * But, don't wait !!! */
802 /* Not cool, it display for non wireless interfaces... */
803 fprintf(stderr, "%-8.8s (Could not trigger scanning, just reading left-over results)\n", ifname);
807 timeout -= tv.tv_usec;
812 fd_set rfds; /* File descriptors for select */
813 int last_fd; /* Last fd */
816 /* Guess what ? We must re-generate rfds each time */
820 /* In here, add the rtnetlink fd in the list */
822 /* Wait until something happens */
823 ret = select(last_fd + 1, &rfds, NULL, NULL, &tv);
825 /* Check if there was an error */
828 if(errno == EAGAIN || errno == EINTR)
830 fprintf(stderr, "Unhandled signal - exiting...\n");
834 /* Check if there was a timeout */
837 /* Try to read the results */
838 wrq.u.data.pointer = buffer;
839 wrq.u.data.flags = 0;
840 wrq.u.data.length = sizeof(buffer);
841 if(iw_get_ext(skfd, ifname, SIOCGIWSCAN, &wrq) < 0)
843 /* Check if results not available yet */
846 /* Restart timer for only 100ms*/
849 timeout -= tv.tv_usec;
851 continue; /* Try again later */
855 fprintf(stderr, "%-8.8s Failed to read scan data : %s\n\n",
856 ifname, strerror(errno));
860 /* We have the results, go to process them */
864 /* In here, check if event and event type
865 * if scan event, read results. All errors bad & no reset timeout */
868 if(wrq.u.data.length)
871 struct stream_descr stream;
874 struct iw_range range;
877 /* Debugging code. In theory useless, because it's debugged ;-) */
879 printf("Scan result [%02X", buffer[0]);
880 for(i = 1; i < wrq.u.data.length; i++)
881 printf(":%02X", buffer[i]);
884 has_range = (iw_get_range_info(skfd, ifname, &range) >= 0);
885 printf("%-8.8s Scan completed :\n", ifname);
886 iw_init_event_stream(&stream, buffer, wrq.u.data.length);
889 /* Extract an event and print it */
890 ret = iw_extract_event_stream(&stream, &iwe);
892 ap_num = print_scanning_token(&iwe, ap_num, &range, has_range);
898 printf("%-8.8s No scan results\n", ifname);
902 #endif /* WIRELESS_EXT > 13 */
904 /************************* COMMON UTILITIES *************************/
906 * This section was written by Michael Tokarev <mjt@tls.msk.ru>
907 * But modified by me ;-)
911 typedef struct iwlist_entry {
918 static const struct iwlist_entry iwlist_cmds[] = {
919 { "frequency", print_freq_info, 0, 0 },
920 { "channel", print_freq_info, 0, 0 },
921 { "ap", print_ap_info, 0, 0 },
922 { "accesspoints", print_ap_info, 0, 0 },
923 { "bitrate", print_bitrate_info, 0, 0 },
924 { "rate", print_bitrate_info, 0, 0 },
925 { "encryption", print_keys_info, 0, 0 },
926 { "key", print_keys_info, 0, 0 },
927 { "power", print_pm_info, 0, 0 },
928 { "txpower", print_txpower_info, 0, 0 },
929 #if WIRELESS_EXT > 10
930 { "retry", print_retry_info, 0, 0 },
932 #if WIRELESS_EXT > 13
933 { "scanning", print_scanning_info, 0, 5 },
935 { NULL, NULL, 0, 0 },
938 /*------------------------------------------------------------------*/
940 * Find the most appropriate command matching the command line
942 static inline const iwlist_cmd *
943 find_command(const char * cmd)
945 const iwlist_cmd * found = NULL;
947 unsigned int len = strlen(cmd);
950 /* Go through all commands */
951 for(i = 0; iwlist_cmds[i].cmd != NULL; ++i)
953 /* No match -> next one */
954 if(strncasecmp(iwlist_cmds[i].cmd, cmd, len) != 0)
957 /* Exact match -> perfect */
958 if(len == strlen(iwlist_cmds[i].cmd))
959 return &iwlist_cmds[i];
964 found = &iwlist_cmds[i];
967 if (iwlist_cmds[i].fn != found->fn)
973 fprintf(stderr, "iwlist: unknown command `%s'\n", cmd);
979 fprintf(stderr, "iwlist: command `%s' is ambiguous\n", cmd);
986 /*------------------------------------------------------------------*/
990 static void iw_usage(int status)
992 FILE* f = status ? stderr : stdout;
995 fprintf(f, "Usage: iwlist [interface] %s\n", iwlist_cmds[0].cmd);
996 for(i = 1; iwlist_cmds[i].cmd != NULL; ++i)
997 fprintf(f, " [interface] %s\n", iwlist_cmds[i].cmd);
1001 /******************************* MAIN ********************************/
1003 /*------------------------------------------------------------------*/
1011 int skfd; /* generic raw socket desc. */
1012 char *dev; /* device name */
1013 char *cmd; /* command */
1014 char **args; /* Command arguments */
1015 int count; /* Number of arguments */
1016 const iwlist_cmd *iwcmd;
1018 if(argc == 1 || argc > 3)
1021 if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help"))
1039 /* find a command */
1040 iwcmd = find_command(cmd);
1044 /* Check arg numbers */
1045 if(count < iwcmd->min_count)
1047 fprintf(stderr, "iwlist: command `%s' needs more arguments\n", cmd);
1050 if(count > iwcmd->max_count)
1052 fprintf(stderr, "iwlist: command `%s' needs fewer arguments\n", cmd);
1056 /* Create a channel to the NET kernel. */
1057 if((skfd = iw_sockets_open()) < 0)
1063 /* do the actual work */
1065 (*iwcmd->fn)(skfd, dev, args, count);
1067 iw_enum_devices(skfd, iwcmd->fn, args, count);
1069 /* Close the socket. */