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 "iwcommon.c" and "-lm".
10 * This file is released under the GPL license.
13 #include "iwcommon.h" /* Header */
15 /*********************** FREQUENCIES/CHANNELS ***********************/
17 /*------------------------------------------------------------------*/
19 * Print the number of channels and available frequency for the device
22 print_freq_info(int skfd,
26 struct iw_range range;
29 if(get_range_info(skfd, ifname, &range) < 0)
30 fprintf(stderr, "%-8.8s no frequency information.\n\n",
34 if(range.num_frequency > 0)
36 printf("%-8.8s %d channels in total; available frequencies :\n",
37 ifname, range.num_channels);
39 for(k = 0; k < range.num_frequency; k++)
41 printf("\t Channel %.2d : ", range.freq[k].i);
42 freq = freq2float(&(range.freq[k]));
44 printf("%g GHz\n", freq / GIGA);
47 printf("%g MHz\n", freq / MEGA);
49 printf("%g kHz\n", freq / KILO);
54 printf("%-8.8s %d channels\n\n",
55 ifname, range.num_channels);
59 /*------------------------------------------------------------------*/
61 * Get frequency info on all devices and print it on the screen
64 print_freq_devices(int skfd)
71 /* Get list of active devices */
72 ifc.ifc_len = sizeof(buff);
74 if(ioctl(skfd, SIOCGIFCONF, &ifc) < 0)
76 fprintf(stderr, "SIOCGIFCONF: %s\n", strerror(errno));
82 for(i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++)
83 print_freq_info(skfd, ifr->ifr_name);
86 /************************ ACCESS POINT LIST ************************/
88 /*------------------------------------------------------------------*/
90 * Display the list of ap addresses and the associated stats
91 * Exacly the same as the spy list, only with different IOCTL and messages
94 print_ap_info(int skfd,
98 char buffer[(sizeof(struct iw_quality) +
99 sizeof(struct sockaddr)) * IW_MAX_AP];
100 struct sockaddr * hwa;
101 struct iw_quality * qual;
109 strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
110 wrq.u.data.pointer = (caddr_t) buffer;
111 wrq.u.data.length = 0;
112 wrq.u.data.flags = 0;
113 if(ioctl(skfd, SIOCGIWAPLIST, &wrq) < 0)
115 fprintf(stderr, "%-8.8s Interface doesn't have a list of Access Points\n\n", ifname);
119 /* Number of addresses */
120 n = wrq.u.data.length;
121 has_qual = wrq.u.data.flags;
124 hwa = (struct sockaddr *) buffer;
125 qual = (struct iw_quality *) (buffer + (sizeof(struct sockaddr) * n));
127 /* Check if we have valid address types */
128 if(check_addr_type(skfd, ifname) < 0)
130 fprintf(stderr, "%-8.8s Interface doesn't support MAC & IP addresses\n\n", ifname);
134 /* Get range info if we can */
135 if(get_range_info(skfd, ifname, &(range)) >= 0)
140 printf("%-8.8s No Access Point in range\n", ifname);
142 printf("%-8.8s Access Points in range:\n", ifname);
143 for(i = 0; i < n; i++)
147 /* Print stats for this address */
148 printf(" %s : ", pr_ether(hwa[i].sa_data));
149 print_stats(stdout, &qual[i], &range, has_range);
152 /* Only print the address */
153 printf(" %s\n", pr_ether(hwa[i].sa_data));
158 /*------------------------------------------------------------------*/
160 * Get list of AP on all devices and print it on the screen
163 print_ap_devices(int skfd)
170 /* Get list of active devices */
171 ifc.ifc_len = sizeof(buff);
173 if(ioctl(skfd, SIOCGIFCONF, &ifc) < 0)
175 fprintf(stderr, "SIOCGIFCONF: %s\n", strerror(errno));
181 for(i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++)
182 print_ap_info(skfd, ifr->ifr_name);
185 /***************************** BITRATES *****************************/
187 /*------------------------------------------------------------------*/
189 * Print the number of available bitrates for the device
192 print_bitrate_info(int skfd,
196 struct iw_range range;
199 /* Extract range info */
200 if(get_range_info(skfd, ifname, &range) < 0)
201 fprintf(stderr, "%-8.8s no bit-rate information.\n\n",
205 if((range.num_bitrates > 0) && (range.num_bitrates < IW_MAX_BITRATES))
207 printf("%-8.8s %d available bit-rates :\n",
208 ifname, range.num_bitrates);
210 for(k = 0; k < range.num_bitrates; k++)
213 bitrate = range.bitrate[k];
215 printf("%g Gb/s\n", bitrate / GIGA);
218 printf("%g Mb/s\n", bitrate / MEGA);
220 printf("%g kb/s\n", bitrate / KILO);
225 printf("%-8.8s No bit-rates ? Please update driver...\n\n", ifname);
229 /*------------------------------------------------------------------*/
231 * Get bit-rate info on all devices and print it on the screen
234 print_bitrate_devices(int skfd)
241 /* Get list of active devices */
242 ifc.ifc_len = sizeof(buff);
244 if(ioctl(skfd, SIOCGIFCONF, &ifc) < 0)
246 fprintf(stderr, "SIOCGIFCONF: %s\n", strerror(errno));
252 for(i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++)
253 print_bitrate_info(skfd, ifr->ifr_name);
256 /************************* ENCRYPTION KEYS *************************/
258 /*------------------------------------------------------------------*/
260 * Print the number of available encryption key for the device
263 print_keys_info(int skfd,
267 struct iw_range range;
268 unsigned char key[IW_ENCODING_TOKEN_MAX];
271 /* Extract range info */
272 if(get_range_info(skfd, ifname, &range) < 0)
273 fprintf(stderr, "%-8.8s no encryption keys information.\n\n",
277 printf("%-8.8s ", ifname);
278 /* Print key sizes */
279 if((range.num_encoding_sizes > 0) &&
280 (range.num_encoding_sizes < IW_MAX_ENCODING_SIZES))
282 printf("%d key sizes : %d", range.num_encoding_sizes,
283 range.encoding_size[0] * 8);
285 for(k = 1; k < range.num_encoding_sizes; k++)
286 printf(", %d", range.encoding_size[k] * 8);
289 /* Print the keys and associate mode */
290 printf("%d keys available :\n", range.max_encoding_tokens);
291 for(k = 1; k <= range.max_encoding_tokens; k++)
293 strcpy(wrq.ifr_name, ifname);
294 wrq.u.data.pointer = (caddr_t) key;
295 wrq.u.data.length = 0;
296 wrq.u.data.flags = k;
297 if(ioctl(skfd, SIOCGIWENCODE, &wrq) < 0)
299 fprintf(stderr, "SIOCGIWENCODE: %s\n", strerror(errno));
302 if((wrq.u.data.flags & IW_ENCODE_DISABLED) ||
303 (wrq.u.data.length == 0))
304 printf("\t\t[%d]: off\n", k);
307 /* Display the key */
308 printf("\t\t[%d]: ", k);
309 print_key(stdout, key, wrq.u.data.length, wrq.u.data.flags);
312 printf(" (%d bits)", wrq.u.data.length * 8);
316 /* Print current key and mode */
317 strcpy(wrq.ifr_name, ifname);
318 wrq.u.data.pointer = (caddr_t) key;
319 wrq.u.data.length = 0;
320 wrq.u.data.flags = 0; /* Set index to zero to get current */
321 if(ioctl(skfd, SIOCGIWENCODE, &wrq) < 0)
323 fprintf(stderr, "SIOCGIWENCODE: %s\n", strerror(errno));
326 printf(" Current Transmit Key: [%d]\n",
327 wrq.u.data.flags & IW_ENCODE_INDEX);
328 if(wrq.u.data.flags & IW_ENCODE_RESTRICTED)
329 printf(" Encryption mode:restricted\n");
330 if(wrq.u.data.flags & IW_ENCODE_OPEN)
331 printf(" Encryption mode:open\n");
337 /*------------------------------------------------------------------*/
339 * Get encryption info on all devices and print it on the screen
342 print_keys_devices(int skfd)
349 /* Get list of active devices */
350 ifc.ifc_len = sizeof(buff);
352 if(ioctl(skfd, SIOCGIFCONF, &ifc) < 0)
354 fprintf(stderr, "SIOCGIFCONF: %s\n", strerror(errno));
360 for(i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++)
361 print_keys_info(skfd, ifr->ifr_name);
364 /************************* POWER MANAGEMENT *************************/
366 /*------------------------------------------------------------------*/
368 * Print Power Management info for each device
371 get_pm_value(int skfd,
376 /* Get Another Power Management value */
377 strcpy(pwrq->ifr_name, ifname);
378 pwrq->u.power.flags = flags;
379 if(ioctl(skfd, SIOCGIWPOWER, pwrq) >= 0)
381 /* Let's check the value and its type */
382 if(pwrq->u.power.flags & IW_POWER_TYPE)
385 print_pm_value(stdout, pwrq->u.power.value, pwrq->u.power.flags);
388 return(pwrq->u.power.flags);
391 /*------------------------------------------------------------------*/
393 * Print Power Management info for each device
396 print_pm_info(int skfd,
400 struct iw_range range;
402 /* Extract range info */
403 if(get_range_info(skfd, ifname, &range) < 0)
404 fprintf(stderr, "%-8.8s no power management information.\n\n",
408 printf("%-8.8s ", ifname);
410 /* Display modes availables */
411 if(range.pm_capa & IW_POWER_MODE)
413 printf("Supported modes :\n ");
414 if(range.pm_capa & (IW_POWER_UNICAST_R | IW_POWER_MULTICAST_R))
415 printf("\t\to Receive all packets (unicast & multicast)\n ");
416 if(range.pm_capa & IW_POWER_UNICAST_R)
417 printf("\t\to Receive Unicast only (discard multicast)\n ");
418 if(range.pm_capa & IW_POWER_MULTICAST_R)
419 printf("\t\to Receive Multicast only (discard unicast)\n ");
420 if(range.pm_capa & IW_POWER_FORCE_S)
421 printf("\t\to Force sending using Power Management\n ");
422 if(range.pm_capa & IW_POWER_REPEATER)
423 printf("\t\to Repeat multicast\n ");
425 /* Display min/max period availables */
426 if(range.pmp_flags & IW_POWER_PERIOD)
428 int flags = (range.pmp_flags & ~(IW_POWER_MIN | IW_POWER_MAX));
429 /* Display if auto or fixed */
430 if(range.pmp_flags & IW_POWER_MIN)
431 printf("Auto period ; ");
433 printf("Fixed period ; ");
434 /* Print the range */
435 print_pm_value(stdout, range.min_pmp, flags | IW_POWER_MIN);
437 print_pm_value(stdout, range.max_pmp, flags | IW_POWER_MAX);
441 /* Display min/max timeout availables */
442 if(range.pmt_flags & IW_POWER_TIMEOUT)
444 int flags = (range.pmt_flags & ~(IW_POWER_MIN | IW_POWER_MAX));
445 /* Display if auto or fixed */
446 if(range.pmt_flags & IW_POWER_MIN)
447 printf("Auto timeout ; ");
449 printf("Fixed timeout ; ");
450 /* Print the range */
451 print_pm_value(stdout, range.min_pmt, flags | IW_POWER_MIN);
453 print_pm_value(stdout, range.max_pmt, flags | IW_POWER_MAX);
457 #endif /* WIRELESS_EXT > 9 */
459 /* Get current Power Management settings */
460 strcpy(wrq.ifr_name, ifname);
461 wrq.u.power.flags = 0;
462 if(ioctl(skfd, SIOCGIWPOWER, &wrq) >= 0)
464 int flags = wrq.u.power.flags;
466 /* Is it disabled ? */
467 if(wrq.u.power.disabled)
468 printf("Current mode:off\n ");
473 /* Let's check the mode */
475 print_pm_mode(stdout, flags);
477 /* Let's check if nothing (simply on) */
478 if((flags & IW_POWER_MODE) == IW_POWER_ON)
482 /* Let's check the value and its type */
483 if(wrq.u.power.flags & IW_POWER_TYPE)
484 print_pm_value(stdout, wrq.u.power.value, wrq.u.power.flags);
486 /* If we have been returned a MIN value, ask for the MAX */
487 if(flags & IW_POWER_MIN)
488 pm_mask = IW_POWER_MAX;
489 /* If we have been returned a MAX value, ask for the MIN */
490 if(flags & IW_POWER_MAX)
491 pm_mask = IW_POWER_MIN;
492 /* If we have something to ask for... */
494 get_pm_value(skfd, ifname, &wrq, pm_mask);
497 /* And if we have both a period and a timeout, ask the other */
498 pm_mask = (range.pm_capa & (~(wrq.u.power.flags) &
502 int base_mask = pm_mask;
503 flags = get_pm_value(skfd, ifname, &wrq, pm_mask);
506 /* If we have been returned a MIN value, ask for the MAX */
507 if(flags & IW_POWER_MIN)
508 pm_mask = IW_POWER_MAX | base_mask;
509 /* If we have been returned a MAX value, ask for the MIN */
510 if(flags & IW_POWER_MAX)
511 pm_mask = IW_POWER_MIN | base_mask;
512 /* If we have something to ask for... */
514 get_pm_value(skfd, ifname, &wrq, pm_mask);
516 #endif /* WIRELESS_EXT > 9 */
523 /*------------------------------------------------------------------*/
525 * Get Power Management info on all devices and print it on the screen
528 print_pm_devices(int skfd)
535 /* Get list of active devices */
536 ifc.ifc_len = sizeof(buff);
538 if(ioctl(skfd, SIOCGIFCONF, &ifc) < 0)
540 fprintf(stderr, "SIOCGIFCONF: %s\n", strerror(errno));
546 for(i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++)
547 print_pm_info(skfd, ifr->ifr_name);
550 /************************** TRANSMIT POWER **************************/
552 /*------------------------------------------------------------------*/
554 * Print the number of available transmit powers for the device
557 print_txpower_info(int skfd,
560 struct iw_range range;
566 /* Extract range info */
567 if(get_range_info(skfd, ifname, &range) < 0)
568 fprintf(stderr, "%-8.8s no transmit-power information.\n\n",
572 if((range.num_txpower > 0) && (range.num_txpower < IW_MAX_TXPOWER))
574 printf("%-8.8s %d available transmit-powers :\n",
575 ifname, range.num_txpower);
577 for(k = 0; k < range.num_txpower; k++)
579 if(range.txpower_capa & IW_TXPOW_MWATT)
581 dbm = mwatt2dbm(range.txpower[k]);
582 mwatt = range.txpower[k];
586 dbm = range.txpower[k];
587 mwatt = dbm2mwatt(range.txpower[k]);
589 printf("\t %d dBm \t(%d mW)\n", dbm, mwatt);
594 printf("%-8.8s No transmit-powers ? Please update driver...\n\n", ifname);
596 #endif /* WIRELESS_EXT > 9 */
599 /*------------------------------------------------------------------*/
601 * Get tx-power info on all devices and print it on the screen
604 print_txpower_devices(int skfd)
611 /* Get list of active devices */
612 ifc.ifc_len = sizeof(buff);
614 if(ioctl(skfd, SIOCGIFCONF, &ifc) < 0)
616 fprintf(stderr, "SIOCGIFCONF: %s\n", strerror(errno));
622 for(i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++)
623 print_txpower_info(skfd, ifr->ifr_name);
626 /*********************** RETRY LIMIT/LIFETIME ***********************/
628 #if WIRELESS_EXT > 10
629 /*------------------------------------------------------------------*/
631 * Print one retry value
634 get_retry_value(int skfd,
639 /* Get Another retry value */
640 strcpy(pwrq->ifr_name, ifname);
641 pwrq->u.retry.flags = flags;
642 if(ioctl(skfd, SIOCGIWRETRY, pwrq) >= 0)
644 /* Let's check the value and its type */
645 if(pwrq->u.retry.flags & IW_RETRY_TYPE)
648 print_retry_value(stdout, pwrq->u.retry.value, pwrq->u.retry.flags);
651 return(pwrq->u.retry.flags);
654 /*------------------------------------------------------------------*/
656 * Print Retry info for each device
659 print_retry_info(int skfd,
663 struct iw_range range;
665 /* Extract range info */
666 if(get_range_info(skfd, ifname, &range) < 0)
667 fprintf(stderr, "%-8.8s no retry limit/lifetime information.\n\n",
671 printf("%-8.8s ", ifname);
673 /* Display min/max limit availables */
674 if(range.retry_flags & IW_RETRY_LIMIT)
676 int flags = (range.retry_flags & ~(IW_RETRY_MIN | IW_RETRY_MAX));
677 /* Display if auto or fixed */
678 if(range.retry_flags & IW_RETRY_MIN)
679 printf("Auto limit ; ");
681 printf("Fixed limit ; ");
682 /* Print the range */
683 print_retry_value(stdout, range.min_retry, flags | IW_RETRY_MIN);
685 print_retry_value(stdout, range.max_retry, flags | IW_RETRY_MAX);
689 /* Display min/max lifetime availables */
690 if(range.r_time_flags & IW_RETRY_LIFETIME)
692 int flags = (range.r_time_flags & ~(IW_RETRY_MIN | IW_RETRY_MAX));
693 /* Display if auto or fixed */
694 if(range.r_time_flags & IW_RETRY_MIN)
695 printf("Auto lifetime ; ");
697 printf("Fixed lifetime ; ");
698 /* Print the range */
699 print_retry_value(stdout, range.min_r_time, flags | IW_RETRY_MIN);
701 print_retry_value(stdout, range.max_r_time, flags | IW_RETRY_MAX);
706 /* Get current retry settings */
707 strcpy(wrq.ifr_name, ifname);
708 wrq.u.retry.flags = 0;
709 if(ioctl(skfd, SIOCGIWRETRY, &wrq) >= 0)
711 int flags = wrq.u.retry.flags;
713 /* Is it disabled ? */
714 if(wrq.u.retry.disabled)
715 printf("Current mode:off\n ");
720 /* Let's check the mode */
721 printf("Current mode:on\n ");
723 /* Let's check the value and its type */
724 if(wrq.u.retry.flags & IW_RETRY_TYPE)
725 print_retry_value(stdout, wrq.u.retry.value, wrq.u.retry.flags);
727 /* If we have been returned a MIN value, ask for the MAX */
728 if(flags & IW_RETRY_MIN)
729 retry_mask = IW_RETRY_MAX;
730 /* If we have been returned a MAX value, ask for the MIN */
731 if(flags & IW_RETRY_MAX)
732 retry_mask = IW_RETRY_MIN;
733 /* If we have something to ask for... */
735 get_retry_value(skfd, ifname, &wrq, retry_mask);
737 /* And if we have both a period and a timeout, ask the other */
738 retry_mask = (range.retry_capa & (~(wrq.u.retry.flags) &
742 int base_mask = retry_mask;
743 flags = get_retry_value(skfd, ifname, &wrq, retry_mask);
746 /* If we have been returned a MIN value, ask for the MAX */
747 if(flags & IW_RETRY_MIN)
748 retry_mask = IW_RETRY_MAX | base_mask;
749 /* If we have been returned a MAX value, ask for the MIN */
750 if(flags & IW_RETRY_MAX)
751 retry_mask = IW_RETRY_MIN | base_mask;
752 /* If we have something to ask for... */
754 get_retry_value(skfd, ifname, &wrq, retry_mask);
762 /*------------------------------------------------------------------*/
764 * Get retry info on all devices and print it on the screen
767 print_retry_devices(int skfd)
774 /* Get list of active devices */
775 ifc.ifc_len = sizeof(buff);
777 if(ioctl(skfd, SIOCGIFCONF, &ifc) < 0)
779 fprintf(stderr, "SIOCGIFCONF: %s\n", strerror(errno));
785 for(i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++)
786 print_retry_info(skfd, ifr->ifr_name);
788 #endif /* WIRELESS_EXT > 10 */
790 /******************************* MAIN ********************************/
792 /*------------------------------------------------------------------*/
800 int skfd = -1; /* generic raw socket desc. */
802 /* Create a channel to the NET kernel. */
803 if((skfd = sockets_open()) < 0)
810 if((argc == 1) || (argc > 3) ||
811 (!strncmp(argv[1], "-h", 9)) || (!strcmp(argv[1], "--help")))
813 fprintf(stderr, "Usage: iwlist [interface] freq\n");
814 fprintf(stderr, " [interface] ap\n");
815 fprintf(stderr, " [interface] bitrate\n");
816 fprintf(stderr, " [interface] keys\n");
817 fprintf(stderr, " [interface] power\n");
818 fprintf(stderr, " [interface] txpower\n");
819 fprintf(stderr, " [interface] retries\n");
825 if((!strncmp(argv[1], "freq", 4)) ||
826 (!strncmp(argv[1], "channel", 7)))
828 print_freq_devices(skfd);
833 /* Access Point list */
834 if(!strcasecmp(argv[1], "ap"))
836 print_ap_devices(skfd);
842 if((!strncmp(argv[1], "bit", 3)) ||
843 (!strcmp(argv[1], "rate")))
845 print_bitrate_devices(skfd);
850 /* Encryption key list */
851 if((!strncmp(argv[1], "enc", 3)) ||
852 (!strncmp(argv[1], "key", 3)))
854 print_keys_devices(skfd);
859 /* Power Management list */
860 if(!strncmp(argv[1], "power", 3))
862 print_pm_devices(skfd);
867 /* Transmit Power list */
868 if(!strncmp(argv[1], "txpower", 3))
870 print_txpower_devices(skfd);
875 #if WIRELESS_EXT > 10
876 /* Retry limit/lifetime */
877 if(!strncmp(argv[1], "retry", 4))
879 print_retry_devices(skfd);
885 /* Special cases take two... */
887 if((!strncmp(argv[2], "freq", 4)) ||
888 (!strncmp(argv[2], "channel", 7)))
890 print_freq_info(skfd, argv[1]);
895 /* Access Point list */
896 if(!strcasecmp(argv[2], "ap"))
898 print_ap_info(skfd, argv[1]);
904 if((!strncmp(argv[2], "bit", 3)) ||
905 (!strcmp(argv[2], "rate")))
907 print_bitrate_info(skfd, argv[1]);
912 /* Encryption key list */
913 if((!strncmp(argv[2], "enc", 3)) ||
914 (!strncmp(argv[2], "key", 3)))
916 print_keys_info(skfd, argv[1]);
921 /* Power Management list */
922 if(!strncmp(argv[2], "power", 3))
924 print_pm_info(skfd, argv[1]);
929 /* Transmit Power list */
930 if(!strncmp(argv[2], "txpower", 3))
932 print_txpower_info(skfd, argv[1]);
937 #if WIRELESS_EXT > 10
938 /* Retry limit/lifetime */
939 if(!strncmp(argv[2], "retry", 4))
941 print_retry_info(skfd, argv[1]);
947 /* Close the socket. */