OSDN Git Service

v21
[android-x86/external-wireless-tools.git] / wireless_tools / iwlist.c
1 /*
2  *      Wireless Tools
3  *
4  *              Jean II - HPLB '99 - HPL 99->01
5  *
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".
9  *
10  * This file is released under the GPL license.
11  */
12
13 #include "iwcommon.h"           /* Header */
14
15 /*********************** FREQUENCIES/CHANNELS ***********************/
16
17 /*------------------------------------------------------------------*/
18 /*
19  * Print the number of channels and available frequency for the device
20  */
21 static void
22 print_freq_info(int             skfd,
23                 char *          ifname)
24 {
25   float                 freq;
26   struct iw_range       range;
27   int                   k;
28
29   if(get_range_info(skfd, ifname, &range) < 0)
30       fprintf(stderr, "%-8.8s  no frequency information.\n\n",
31                       ifname);
32   else
33     {
34       if(range.num_frequency > 0)
35         {
36           printf("%-8.8s  %d channels in total; available frequencies :\n",
37                  ifname, range.num_channels);
38           /* Print them all */
39           for(k = 0; k < range.num_frequency; k++)
40             {
41               printf("\t  Channel %.2d : ", range.freq[k].i);
42               freq = freq2float(&(range.freq[k]));
43               if(freq >= GIGA)
44                 printf("%g GHz\n", freq / GIGA);
45               else
46                 if(freq >= MEGA)
47                   printf("%g MHz\n", freq / MEGA);
48                 else
49                   printf("%g kHz\n", freq / KILO);
50             }
51           printf("\n\n");
52         }
53       else
54         printf("%-8.8s  %d channels\n\n",
55                ifname, range.num_channels);
56     }
57 }
58
59 /*------------------------------------------------------------------*/
60 /*
61  * Get frequency info on all devices and print it on the screen
62  */
63 static void
64 print_freq_devices(int          skfd)
65 {
66   char          buff[1024];
67   struct ifconf ifc;
68   struct ifreq *ifr;
69   int i;
70
71   /* Get list of active devices */
72   ifc.ifc_len = sizeof(buff);
73   ifc.ifc_buf = buff;
74   if(ioctl(skfd, SIOCGIFCONF, &ifc) < 0)
75     {
76       fprintf(stderr, "SIOCGIFCONF: %s\n", strerror(errno));
77       return;
78     }
79   ifr = ifc.ifc_req;
80
81   /* Print them */
82   for(i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++)
83     print_freq_info(skfd, ifr->ifr_name);
84 }
85
86 /************************ ACCESS POINT LIST ************************/
87
88 /*------------------------------------------------------------------*/
89 /*
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
92  */
93 static void
94 print_ap_info(int       skfd,
95                char *   ifname)
96 {
97   struct iwreq          wrq;
98   char          buffer[(sizeof(struct iw_quality) +
99                         sizeof(struct sockaddr)) * IW_MAX_AP];
100   struct sockaddr *     hwa;
101   struct iw_quality *   qual;
102   iwrange       range;
103   int           has_range = 0;
104   int           has_qual = 0;
105   int           n;
106   int           i;
107
108   /* Collect stats */
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)
114     {
115       fprintf(stderr, "%-8.8s  Interface doesn't have a list of Access Points\n\n", ifname);
116       return;
117     }
118
119   /* Number of addresses */
120   n = wrq.u.data.length;
121   has_qual = wrq.u.data.flags;
122
123   /* The two lists */
124   hwa = (struct sockaddr *) buffer;
125   qual = (struct iw_quality *) (buffer + (sizeof(struct sockaddr) * n));
126
127   /* Check if we have valid address types */
128   if(check_addr_type(skfd, ifname) < 0)
129     {
130       fprintf(stderr, "%-8.8s  Interface doesn't support MAC & IP addresses\n\n", ifname);
131       return;
132     }
133
134   /* Get range info if we can */
135   if(get_range_info(skfd, ifname, &(range)) >= 0)
136     has_range = 1;
137
138   /* Display it */
139   if(n == 0)
140     printf("%-8.8s  No Access Point in range\n", ifname);
141   else
142     printf("%-8.8s  Access Points in range:\n", ifname);
143   for(i = 0; i < n; i++)
144     {
145       if(has_qual)
146         {
147           /* Print stats for this address */
148           printf("    %s : ", pr_ether(hwa[i].sa_data));
149           print_stats(stdout, &qual[i], &range, has_range);
150         }
151       else
152         /* Only print the address */
153         printf("    %s\n", pr_ether(hwa[i].sa_data));
154     }
155   printf("\n");
156 }
157
158 /*------------------------------------------------------------------*/
159 /*
160  * Get list of AP on all devices and print it on the screen
161  */
162 static void
163 print_ap_devices(int            skfd)
164 {
165   char          buff[1024];
166   struct ifconf ifc;
167   struct ifreq *ifr;
168   int i;
169
170   /* Get list of active devices */
171   ifc.ifc_len = sizeof(buff);
172   ifc.ifc_buf = buff;
173   if(ioctl(skfd, SIOCGIFCONF, &ifc) < 0)
174     {
175       fprintf(stderr, "SIOCGIFCONF: %s\n", strerror(errno));
176       return;
177     }
178   ifr = ifc.ifc_req;
179
180   /* Print them */
181   for(i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++)
182     print_ap_info(skfd, ifr->ifr_name);
183 }
184
185 /***************************** BITRATES *****************************/
186
187 /*------------------------------------------------------------------*/
188 /*
189  * Print the number of available bitrates for the device
190  */
191 static void
192 print_bitrate_info(int          skfd,
193                    char *       ifname)
194 {
195   float                 bitrate;
196   struct iw_range       range;
197   int                   k;
198
199   /* Extract range info */
200   if(get_range_info(skfd, ifname, &range) < 0)
201       fprintf(stderr, "%-8.8s  no bit-rate information.\n\n",
202                       ifname);
203   else
204     {
205       if((range.num_bitrates > 0) && (range.num_bitrates < IW_MAX_BITRATES))
206         {
207           printf("%-8.8s  %d available bit-rates :\n",
208                  ifname, range.num_bitrates);
209           /* Print them all */
210           for(k = 0; k < range.num_bitrates; k++)
211             {
212               printf("\t  ");
213               bitrate = range.bitrate[k];
214               if(bitrate >= GIGA)
215                 printf("%g Gb/s\n", bitrate / GIGA);
216               else
217                 if(bitrate >= MEGA)
218                   printf("%g Mb/s\n", bitrate / MEGA);
219                 else
220                   printf("%g kb/s\n", bitrate / KILO);
221             }
222           printf("\n\n");
223         }
224       else
225         printf("%-8.8s  No bit-rates ? Please update driver...\n\n", ifname);
226     }
227 }
228
229 /*------------------------------------------------------------------*/
230 /*
231  * Get bit-rate info on all devices and print it on the screen
232  */
233 static void
234 print_bitrate_devices(int               skfd)
235 {
236   char          buff[1024];
237   struct ifconf ifc;
238   struct ifreq *ifr;
239   int i;
240
241   /* Get list of active devices */
242   ifc.ifc_len = sizeof(buff);
243   ifc.ifc_buf = buff;
244   if(ioctl(skfd, SIOCGIFCONF, &ifc) < 0)
245     {
246       fprintf(stderr, "SIOCGIFCONF: %s\n", strerror(errno));
247       return;
248     }
249   ifr = ifc.ifc_req;
250
251   /* Print them */
252   for(i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++)
253     print_bitrate_info(skfd, ifr->ifr_name);
254 }
255
256 /************************* ENCRYPTION KEYS *************************/
257
258 /*------------------------------------------------------------------*/
259 /*
260  * Print the number of available encryption key for the device
261  */
262 static void
263 print_keys_info(int             skfd,
264                 char *          ifname)
265 {
266   struct iwreq          wrq;
267   struct iw_range       range;
268   unsigned char         key[IW_ENCODING_TOKEN_MAX];
269   int                   k;
270
271   /* Extract range info */
272   if(get_range_info(skfd, ifname, &range) < 0)
273       fprintf(stderr, "%-8.8s  no encryption keys information.\n\n",
274                       ifname);
275   else
276     {
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))
281         {
282           printf("%d key sizes : %d", range.num_encoding_sizes,
283                  range.encoding_size[0] * 8);
284           /* Print them all */
285           for(k = 1; k < range.num_encoding_sizes; k++)
286             printf(", %d", range.encoding_size[k] * 8);
287           printf("bits\n          ");
288         }
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++)
292         {
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)
298             {
299               fprintf(stderr, "SIOCGIWENCODE: %s\n", strerror(errno));
300               break;
301             }
302           if((wrq.u.data.flags & IW_ENCODE_DISABLED) ||
303              (wrq.u.data.length == 0))
304             printf("\t\t[%d]: off\n", k);
305           else
306             {
307               /* Display the key */
308               printf("\t\t[%d]: ", k);
309               print_key(stdout, key, wrq.u.data.length, wrq.u.data.flags);
310
311               /* Other info... */
312               printf(" (%d bits)", wrq.u.data.length * 8);
313               printf("\n");
314             }
315         }
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)
322         {
323           fprintf(stderr, "SIOCGIWENCODE: %s\n", strerror(errno));
324           return;
325         }
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");
332
333       printf("\n\n");
334     }
335 }
336
337 /*------------------------------------------------------------------*/
338 /*
339  * Get encryption info on all devices and print it on the screen
340  */
341 static void
342 print_keys_devices(int          skfd)
343 {
344   char          buff[1024];
345   struct ifconf ifc;
346   struct ifreq *ifr;
347   int i;
348
349   /* Get list of active devices */
350   ifc.ifc_len = sizeof(buff);
351   ifc.ifc_buf = buff;
352   if(ioctl(skfd, SIOCGIFCONF, &ifc) < 0)
353     {
354       fprintf(stderr, "SIOCGIFCONF: %s\n", strerror(errno));
355       return;
356     }
357   ifr = ifc.ifc_req;
358
359   /* Print them */
360   for(i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++)
361     print_keys_info(skfd, ifr->ifr_name);
362 }
363
364 /************************* POWER MANAGEMENT *************************/
365
366 /*------------------------------------------------------------------*/
367 /*
368  * Print Power Management info for each device
369  */
370 static inline int
371 get_pm_value(int                skfd,
372              char *             ifname,
373              struct iwreq *     pwrq,
374              int                flags)
375 {
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)
380     {
381       /* Let's check the value and its type */
382       if(pwrq->u.power.flags & IW_POWER_TYPE)
383         {
384           printf("\n                 ");
385           print_pm_value(stdout, pwrq->u.power.value, pwrq->u.power.flags);
386         }
387     }
388   return(pwrq->u.power.flags);
389 }
390
391 /*------------------------------------------------------------------*/
392 /*
393  * Print Power Management info for each device
394  */
395 static void
396 print_pm_info(int               skfd,
397               char *            ifname)
398 {
399   struct iwreq          wrq;
400   struct iw_range       range;
401
402   /* Extract range info */
403   if(get_range_info(skfd, ifname, &range) < 0)
404       fprintf(stderr, "%-8.8s  no power management information.\n\n",
405                       ifname);
406   else
407     {
408       printf("%-8.8s  ", ifname);
409 #if WIRELESS_EXT > 9
410       /* Display modes availables */
411       if(range.pm_capa & IW_POWER_MODE)
412         {
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          ");
424         }
425       /* Display min/max period availables */
426       if(range.pmp_flags & IW_POWER_PERIOD)
427         {
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  ; ");
432           else
433             printf("Fixed period  ; ");
434           /* Print the range */
435           print_pm_value(stdout, range.min_pmp, flags | IW_POWER_MIN);
436           printf("\n                          ");
437           print_pm_value(stdout, range.max_pmp, flags | IW_POWER_MAX);
438           printf("\n          ");
439           
440         }
441       /* Display min/max timeout availables */
442       if(range.pmt_flags & IW_POWER_TIMEOUT)
443         {
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 ; ");
448           else
449             printf("Fixed timeout ; ");
450           /* Print the range */
451           print_pm_value(stdout, range.min_pmt, flags | IW_POWER_MIN);
452           printf("\n                          ");
453           print_pm_value(stdout, range.max_pmt, flags | IW_POWER_MAX);
454           printf("\n          ");
455           
456         }
457 #endif /* WIRELESS_EXT > 9 */
458
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)
463         {
464           int   flags = wrq.u.power.flags;
465
466           /* Is it disabled ? */
467           if(wrq.u.power.disabled)
468             printf("Current mode:off\n          ");
469           else
470             {
471               int       pm_mask = 0;
472
473               /* Let's check the mode */
474               printf("Current");
475               print_pm_mode(stdout, flags);
476
477               /* Let's check if nothing (simply on) */
478               if((flags & IW_POWER_MODE) == IW_POWER_ON)
479                 printf(" mode:on");
480               printf("\n                 ");
481
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);
485
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... */
493               if(pm_mask)
494                 get_pm_value(skfd, ifname, &wrq, pm_mask);
495
496 #if WIRELESS_EXT > 9
497               /* And if we have both a period and a timeout, ask the other */
498               pm_mask = (range.pm_capa & (~(wrq.u.power.flags) &
499                                           IW_POWER_TYPE));
500               if(pm_mask)
501                 {
502                   int   base_mask = pm_mask;
503                   flags = get_pm_value(skfd, ifname, &wrq, pm_mask);
504                   pm_mask = 0;
505
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... */
513                   if(pm_mask)
514                     get_pm_value(skfd, ifname, &wrq, pm_mask);
515                 }
516 #endif /* WIRELESS_EXT > 9 */
517             }
518         }
519       printf("\n");
520     }
521 }
522
523 /*------------------------------------------------------------------*/
524 /*
525  * Get Power Management info on all devices and print it on the screen
526  */
527 static void
528 print_pm_devices(int            skfd)
529 {
530   char          buff[1024];
531   struct ifconf ifc;
532   struct ifreq *ifr;
533   int i;
534
535   /* Get list of active devices */
536   ifc.ifc_len = sizeof(buff);
537   ifc.ifc_buf = buff;
538   if(ioctl(skfd, SIOCGIFCONF, &ifc) < 0)
539     {
540       fprintf(stderr, "SIOCGIFCONF: %s\n", strerror(errno));
541       return;
542     }
543   ifr = ifc.ifc_req;
544
545   /* Print them */
546   for(i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++)
547     print_pm_info(skfd, ifr->ifr_name);
548 }
549
550 /************************** TRANSMIT POWER **************************/
551
552 /*------------------------------------------------------------------*/
553 /*
554  * Print the number of available transmit powers for the device
555  */
556 static void
557 print_txpower_info(int          skfd,
558                    char *       ifname)
559 {
560   struct iw_range       range;
561   int                   dbm;
562   int                   mwatt;
563   int                   k;
564
565 #if WIRELESS_EXT > 9
566   /* Extract range info */
567   if(get_range_info(skfd, ifname, &range) < 0)
568       fprintf(stderr, "%-8.8s  no transmit-power information.\n\n",
569                       ifname);
570   else
571     {
572       if((range.num_txpower > 0) && (range.num_txpower < IW_MAX_TXPOWER))
573         {
574           printf("%-8.8s  %d available transmit-powers :\n",
575                  ifname, range.num_txpower);
576           /* Print them all */
577           for(k = 0; k < range.num_txpower; k++)
578             {
579               if(range.txpower_capa & IW_TXPOW_MWATT)
580                 {
581                   dbm = mwatt2dbm(range.txpower[k]);
582                   mwatt = range.txpower[k];
583                 }
584               else
585                 {
586                   dbm = range.txpower[k];
587                   mwatt = dbm2mwatt(range.txpower[k]);
588                 }
589               printf("\t  %d dBm  \t(%d mW)\n", dbm, mwatt);
590             }
591           printf("\n\n");
592         }
593       else
594         printf("%-8.8s  No transmit-powers ? Please update driver...\n\n", ifname);
595     }
596 #endif /* WIRELESS_EXT > 9 */
597 }
598
599 /*------------------------------------------------------------------*/
600 /*
601  * Get tx-power info on all devices and print it on the screen
602  */
603 static void
604 print_txpower_devices(int               skfd)
605 {
606   char          buff[1024];
607   struct ifconf ifc;
608   struct ifreq *ifr;
609   int i;
610
611   /* Get list of active devices */
612   ifc.ifc_len = sizeof(buff);
613   ifc.ifc_buf = buff;
614   if(ioctl(skfd, SIOCGIFCONF, &ifc) < 0)
615     {
616       fprintf(stderr, "SIOCGIFCONF: %s\n", strerror(errno));
617       return;
618     }
619   ifr = ifc.ifc_req;
620
621   /* Print them */
622   for(i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++)
623     print_txpower_info(skfd, ifr->ifr_name);
624 }
625
626 /*********************** RETRY LIMIT/LIFETIME ***********************/
627
628 #if WIRELESS_EXT > 10
629 /*------------------------------------------------------------------*/
630 /*
631  * Print one retry value
632  */
633 static inline int
634 get_retry_value(int             skfd,
635                 char *          ifname,
636                 struct iwreq *  pwrq,
637                 int             flags)
638 {
639   /* Get Another retry value */
640   strcpy(pwrq->ifr_name, ifname);
641   pwrq->u.retry.flags = flags;
642   if(ioctl(skfd, SIOCGIWRETRY, pwrq) >= 0)
643     {
644       /* Let's check the value and its type */
645       if(pwrq->u.retry.flags & IW_RETRY_TYPE)
646         {
647           printf("\n                 ");
648           print_retry_value(stdout, pwrq->u.retry.value, pwrq->u.retry.flags);
649         }
650     }
651   return(pwrq->u.retry.flags);
652 }
653
654 /*------------------------------------------------------------------*/
655 /*
656  * Print Retry info for each device
657  */
658 static void
659 print_retry_info(int            skfd,
660               char *            ifname)
661 {
662   struct iwreq          wrq;
663   struct iw_range       range;
664
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",
668               ifname);
669   else
670     {
671       printf("%-8.8s  ", ifname);
672
673       /* Display min/max limit availables */
674       if(range.retry_flags & IW_RETRY_LIMIT)
675         {
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    ; ");
680           else
681             printf("Fixed limit    ; ");
682           /* Print the range */
683           print_retry_value(stdout, range.min_retry, flags | IW_RETRY_MIN);
684           printf("\n                           ");
685           print_retry_value(stdout, range.max_retry, flags | IW_RETRY_MAX);
686           printf("\n          ");
687           
688         }
689       /* Display min/max lifetime availables */
690       if(range.r_time_flags & IW_RETRY_LIFETIME)
691         {
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 ; ");
696           else
697             printf("Fixed lifetime ; ");
698           /* Print the range */
699           print_retry_value(stdout, range.min_r_time, flags | IW_RETRY_MIN);
700           printf("\n                           ");
701           print_retry_value(stdout, range.max_r_time, flags | IW_RETRY_MAX);
702           printf("\n          ");
703           
704         }
705
706       /* Get current retry settings */
707       strcpy(wrq.ifr_name, ifname);
708       wrq.u.retry.flags = 0;
709       if(ioctl(skfd, SIOCGIWRETRY, &wrq) >= 0)
710         {
711           int   flags = wrq.u.retry.flags;
712
713           /* Is it disabled ? */
714           if(wrq.u.retry.disabled)
715             printf("Current mode:off\n          ");
716           else
717             {
718               int       retry_mask = 0;
719
720               /* Let's check the mode */
721               printf("Current mode:on\n                 ");
722
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);
726
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... */
734               if(retry_mask)
735                 get_retry_value(skfd, ifname, &wrq, retry_mask);
736
737               /* And if we have both a period and a timeout, ask the other */
738               retry_mask = (range.retry_capa & (~(wrq.u.retry.flags) &
739                                           IW_RETRY_TYPE));
740               if(retry_mask)
741                 {
742                   int   base_mask = retry_mask;
743                   flags = get_retry_value(skfd, ifname, &wrq, retry_mask);
744                   retry_mask = 0;
745
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... */
753                   if(retry_mask)
754                     get_retry_value(skfd, ifname, &wrq, retry_mask);
755                 }
756             }
757         }
758       printf("\n");
759     }
760 }
761
762 /*------------------------------------------------------------------*/
763 /*
764  * Get retry info on all devices and print it on the screen
765  */
766 static void
767 print_retry_devices(int         skfd)
768 {
769   char          buff[1024];
770   struct ifconf ifc;
771   struct ifreq *ifr;
772   int i;
773
774   /* Get list of active devices */
775   ifc.ifc_len = sizeof(buff);
776   ifc.ifc_buf = buff;
777   if(ioctl(skfd, SIOCGIFCONF, &ifc) < 0)
778     {
779       fprintf(stderr, "SIOCGIFCONF: %s\n", strerror(errno));
780       return;
781     }
782   ifr = ifc.ifc_req;
783
784   /* Print them */
785   for(i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++)
786     print_retry_info(skfd, ifr->ifr_name);
787 }
788 #endif  /* WIRELESS_EXT > 10 */
789
790 /******************************* MAIN ********************************/
791
792 /*------------------------------------------------------------------*/
793 /*
794  * The main !
795  */
796 int
797 main(int        argc,
798      char **    argv)
799 {
800   int skfd = -1;                /* generic raw socket desc.     */
801
802   /* Create a channel to the NET kernel. */
803   if((skfd = sockets_open()) < 0)
804     {
805       perror("socket");
806       exit(-1);
807     }
808
809   /* Help */
810   if((argc == 1) || (argc > 3) ||
811      (!strncmp(argv[1], "-h", 9)) || (!strcmp(argv[1], "--help")))
812     {
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");
820       close(skfd);
821       exit(0);
822     }
823
824   /* Frequency list */
825   if((!strncmp(argv[1], "freq", 4)) ||
826      (!strncmp(argv[1], "channel", 7)))
827     {
828       print_freq_devices(skfd);
829       close(skfd);
830       exit(0);
831     }
832
833   /* Access Point list */
834   if(!strcasecmp(argv[1], "ap"))
835     {
836       print_ap_devices(skfd);
837       close(skfd);
838       exit(0);
839     }
840
841   /* Bit-rate list */
842   if((!strncmp(argv[1], "bit", 3)) ||
843      (!strcmp(argv[1], "rate")))
844     {
845       print_bitrate_devices(skfd);
846       close(skfd);
847       exit(0);
848     }
849
850   /* Encryption key list */
851   if((!strncmp(argv[1], "enc", 3)) ||
852      (!strncmp(argv[1], "key", 3)))
853     {
854       print_keys_devices(skfd);
855       close(skfd);
856       exit(0);
857     }
858
859   /* Power Management list */
860   if(!strncmp(argv[1], "power", 3))
861     {
862       print_pm_devices(skfd);
863       close(skfd);
864       exit(0);
865     }
866
867   /* Transmit Power list */
868   if(!strncmp(argv[1], "txpower", 3))
869     {
870       print_txpower_devices(skfd);
871       close(skfd);
872       exit(0);
873     }
874
875 #if WIRELESS_EXT > 10
876   /* Retry limit/lifetime */
877   if(!strncmp(argv[1], "retry", 4))
878     {
879       print_retry_devices(skfd);
880       close(skfd);
881       exit(0);
882     }
883 #endif
884
885   /* Special cases take two... */
886   /* Frequency list */
887   if((!strncmp(argv[2], "freq", 4)) ||
888      (!strncmp(argv[2], "channel", 7)))
889     {
890       print_freq_info(skfd, argv[1]);
891       close(skfd);
892       exit(0);
893     }
894
895   /* Access Point  list */
896   if(!strcasecmp(argv[2], "ap"))
897     {
898       print_ap_info(skfd, argv[1]);
899       close(skfd);
900       exit(0);
901     }
902
903   /* Bit-rate list */
904   if((!strncmp(argv[2], "bit", 3)) ||
905      (!strcmp(argv[2], "rate")))
906     {
907       print_bitrate_info(skfd, argv[1]);
908       close(skfd);
909       exit(0);
910     }
911
912   /* Encryption key list */
913   if((!strncmp(argv[2], "enc", 3)) ||
914      (!strncmp(argv[2], "key", 3)))
915     {
916       print_keys_info(skfd, argv[1]);
917       close(skfd);
918       exit(0);
919     }
920
921   /* Power Management list */
922   if(!strncmp(argv[2], "power", 3))
923     {
924       print_pm_info(skfd, argv[1]);
925       close(skfd);
926       exit(0);
927     }
928
929   /* Transmit Power list */
930   if(!strncmp(argv[2], "txpower", 3))
931     {
932       print_txpower_info(skfd, argv[1]);
933       close(skfd);
934       exit(0);
935     }
936
937 #if WIRELESS_EXT > 10
938   /* Retry limit/lifetime */
939   if(!strncmp(argv[2], "retry", 4))
940     {
941       print_retry_info(skfd, argv[1]);
942       close(skfd);
943       exit(0);
944     }
945 #endif
946
947   /* Close the socket. */
948   close(skfd);
949
950   return(1);
951 }