OSDN Git Service

v19
[android-x86/external-wireless-tools.git] / wireless_tools / iwconfig.c
1 /*
2  *      Wireless Tools
3  *
4  *              Jean II - HPLB '99
5  *
6  * Main code for "iwconfig". This is the generic tool for most
7  * manipulations...
8  * You need to link this code against "iwcommon.c" and "-lm".
9  */
10
11 #include "iwcommon.h"           /* Header */
12
13 /************************* MISC SUBROUTINES **************************/
14
15 /*------------------------------------------------------------------*/
16 /*
17  * Print usage string
18  */
19 static void
20 iw_usage(void)
21 {
22   fprintf(stderr, "Usage: iwconfig interface [essid {NN|on|off}]\n");
23   fprintf(stderr, "                          [nwid {NN|on|off}]\n");
24   fprintf(stderr, "                          [freq N.NNNN[k|M|G]]\n");
25   fprintf(stderr, "                          [channel N]\n");
26   fprintf(stderr, "                          [sens N]\n");
27   fprintf(stderr, "                          [nick N]\n");
28   fprintf(stderr, "                          [rate {N|auto|fixed}]\n");
29   fprintf(stderr, "                          [rts {N|auto|fixed|off}]\n");
30   fprintf(stderr, "                          [frag {N|auto|fixed|off}]\n");
31   fprintf(stderr, "                          [enc NNNN-NNNN]\n");
32   exit(1);
33 }
34
35
36 /************************* DISPLAY ROUTINES **************************/
37
38 /*------------------------------------------------------------------*/
39 /*
40  * Read /proc/net/wireless to get the latest statistics
41  */
42 static int
43 iw_getstats(char *      ifname,
44             iwstats *   stats)
45 {
46   FILE *f=fopen("/proc/net/wireless","r");
47   char buf[256];
48   char *bp;
49   if(f==NULL)
50         return -1;
51   while(fgets(buf,255,f))
52   {
53         bp=buf;
54         while(*bp&&isspace(*bp))
55                 bp++;
56         if(strncmp(bp,ifname,strlen(ifname))==0 && bp[strlen(ifname)]==':')
57         {
58                 bp=strchr(bp,':');
59                 bp++;
60                 bp = strtok(bp, " .");
61                 sscanf(bp, "%X", (unsigned int *)&stats->status);
62                 bp = strtok(NULL, " .");
63                 sscanf(bp, "%d", (unsigned int *)&stats->qual.qual);
64                 bp = strtok(NULL, " .");
65                 sscanf(bp, "%d", (unsigned int *)&stats->qual.level);
66                 bp = strtok(NULL, " .");
67                 sscanf(bp, "%d", (unsigned int *)&stats->qual.noise);
68                 bp = strtok(NULL, " .");
69                 sscanf(bp, "%d", &stats->discard.nwid);
70                 bp = strtok(NULL, " .");
71                 sscanf(bp, "%d", &stats->discard.code);
72                 bp = strtok(NULL, " .");
73                 sscanf(bp, "%d", &stats->discard.misc);
74                 fclose(f);
75                 return 0;
76         }
77   }
78   fclose(f);
79   return 0;
80 }
81
82 /*------------------------------------------------------------------*/
83 /*
84  * Get wireless informations & config from the device driver
85  * We will call all the classical wireless ioctl on the driver through
86  * the socket to know what is supported and to get the settings...
87  */
88 static int
89 get_info(int                    skfd,
90          char *                 ifname,
91          struct wireless_info * info)
92 {
93   struct iwreq          wrq;
94
95   memset((char *) info, 0, sizeof(struct wireless_info));
96
97   /* Get wireless name */
98   strcpy(wrq.ifr_name, ifname);
99   if(ioctl(skfd, SIOCGIWNAME, &wrq) < 0)
100     /* If no wireless name : no wireless extensions */
101     return(-1);
102   else
103     strcpy(info->name, wrq.u.name);
104
105   /* Get network ID */
106   strcpy(wrq.ifr_name, ifname);
107   if(ioctl(skfd, SIOCGIWNWID, &wrq) >= 0)
108     {
109       info->has_nwid = 1;
110       info->nwid_on = wrq.u.nwid.on;
111       info->nwid = wrq.u.nwid.nwid;
112     }
113
114   /* Get frequency / channel */
115   strcpy(wrq.ifr_name, ifname);
116   if(ioctl(skfd, SIOCGIWFREQ, &wrq) >= 0)
117     {
118       info->has_freq = 1;
119       info->freq = freq2float(&(wrq.u.freq));
120     }
121
122   /* Get sensitivity */
123   strcpy(wrq.ifr_name, ifname);
124   if(ioctl(skfd, SIOCGIWSENS, &wrq) >= 0)
125     {
126       info->has_sens = 1;
127       info->sens = wrq.u.sensitivity;
128     }
129
130    /* Get encryption information */
131    strcpy(wrq.ifr_name, ifname);
132    if(ioctl(skfd, SIOCGIWENCODE, &wrq) >= 0)
133      {
134        info->has_enc = 1;
135        info->enc_method = wrq.u.encoding.method;
136        info->enc_key = wrq.u.encoding.code;
137      }
138
139 #if WIRELESS_EXT > 5
140   /* Get ESSID */
141   strcpy(wrq.ifr_name, ifname);
142   wrq.u.data.pointer = (caddr_t) info->essid;
143   wrq.u.data.length = 0;
144   wrq.u.data.flags = 0;
145   if(ioctl(skfd, SIOCGIWESSID, &wrq) >= 0)
146     {
147       info->has_essid = 1;
148       info->essid_on = wrq.u.data.flags;
149     }
150
151   /* Get AP address */
152   strcpy(wrq.ifr_name, ifname);
153   if(ioctl(skfd, SIOCGIWAP, &wrq) >= 0)
154     {
155       info->has_ap_addr = 1;
156       memcpy(&(info->ap_addr), &(wrq.u.ap_addr), sizeof (sockaddr));
157     }
158 #endif  /* WIRELESS_EXT > 5 */
159
160 #if WIRELESS_EXT > 7
161   /* Get NickName */
162   strcpy(wrq.ifr_name, ifname);
163   wrq.u.data.pointer = (caddr_t) info->nickname;
164   wrq.u.data.length = 0;
165   wrq.u.data.flags = 0;
166   if(ioctl(skfd, SIOCGIWNICKN, &wrq) >= 0)
167     if(wrq.u.data.length > 1)
168       info->has_nickname = 1;
169
170   /* Get bit rate */
171   strcpy(wrq.ifr_name, ifname);
172   if(ioctl(skfd, SIOCGIWRATE, &wrq) >= 0)
173     {
174       info->has_bitrate = 1;
175       info->bitrate_fixed = wrq.u.bitrate.fixed;
176       info->bitrate = wrq.u.bitrate.value;
177     }
178
179   /* Get RTS threshold */
180   strcpy(wrq.ifr_name, ifname);
181   if(ioctl(skfd, SIOCGIWRTS, &wrq) >= 0)
182     {
183       info->has_rts = 1;
184       info->rts_fixed = wrq.u.rts.fixed;
185       info->rts = wrq.u.rts.value;
186     }
187
188   /* Get fragmentation thershold */
189   strcpy(wrq.ifr_name, ifname);
190   if(ioctl(skfd, SIOCGIWFRAG, &wrq) >= 0)
191     {
192       info->has_frag = 1;
193       info->frag_fixed = wrq.u.frag.fixed;
194       info->frag = wrq.u.frag.value;
195     }
196 #endif  /* WIRELESS_EXT > 7 */
197
198   /* Get stats */
199   if(iw_getstats(ifname, &(info->stats)) == 0)
200     {
201       info->has_stats = 1;
202     }
203
204   /* Get ranges */
205   if(get_range_info(skfd, ifname, &(info->range)) >= 0)
206     info->has_range = 1;
207
208   return(0);
209 }
210
211 /*------------------------------------------------------------------*/
212 /*
213  * Print on the screen in a neat fashion all the info we have collected
214  * on a device.
215  */
216 static void
217 display_info(struct wireless_info *     info,
218              char *                     ifname)
219 {
220   /* Display device name and wireless name (name of the protocol used) */
221   printf("%-8.8s  %s  ", ifname, info->name);
222
223   /* Display ESSID (extended network), if any */
224   if(info->has_essid)
225     {
226       if(info->essid_on)
227         printf("ESSID:\"%s\"  ", info->essid);
228       else
229         printf("ESSID:off  ");
230     }
231
232   /* Display NickName (station name), if any */
233   if(info->has_nickname)
234     printf("Nickname:\"%s\"", info->nickname);
235
236   /* Formatting */
237   if(info->has_essid || info->has_nickname)
238     printf("\n          ");
239
240   /* Display Network ID */
241   if(info->has_nwid)
242     {
243       /* Note : should display right number of digit according to info
244        * in range structure */
245       if(info->nwid_on)
246         printf("NWID:%lX  ", info->nwid);
247       else
248         printf("NWID:off/any  ");
249     }
250
251   /* Display frequency / channel */
252   if(info->has_freq)
253     {
254       if(info->freq < KILO)
255         printf("Channel:%g  ", info->freq);
256       else
257         {
258           if(info->freq >= GIGA)
259             printf("Frequency:%gGHz  ", info->freq / GIGA);
260           else
261             {
262               if(info->freq >= MEGA)
263                 printf("Frequency:%gMHz  ", info->freq / MEGA);
264               else
265                 printf("Frequency:%gkHz  ", info->freq / KILO);
266             }
267         }
268     }
269
270   /* Display sensitivity */
271   if(info->has_sens)
272     {
273       if(info->has_range)
274         /* Display in dBm ? */
275         if(info->sens < 0)
276           printf("Sensitivity:%d dBm  ", info->sens);
277         else
278           printf("Sensitivity:%d/%d  ", info->sens, info->range.sensitivity);
279       else
280         printf("Sensitivity:%d  ", info->sens);
281     }
282
283   /* Display the address of the current Access Point */
284   if(info->has_ap_addr)
285     {
286       /* A bit of clever formatting */
287       if((info->has_nwid + 2*info->has_freq + 2*info->has_sens
288           + !info->has_essid) > 3)
289         printf("\n          ");
290
291       printf("Access Point: %s", pr_ether(info->ap_addr.sa_data));
292     }
293
294   printf("\n          ");
295
296   /* Display the currently used/set bit-rate */
297   if(info->has_bitrate)
298     {
299       printf("Bit Rate:");
300       if(info->bitrate >= GIGA)
301         printf("%g Gb/s", info->bitrate / GIGA);
302       else
303         if(info->bitrate >= MEGA)
304           printf("%g Mb/s", info->bitrate / MEGA);
305         else
306           printf("%g kb/s", info->bitrate / KILO);
307
308       /* Fixed ? */
309       if(info->bitrate_fixed)
310         printf(" (f)   ");
311       else
312         printf("   ");
313     }
314
315   /* Display the RTS threshold */
316   if(info->has_rts)
317     {
318       printf("RTS thr:%ld B", info->rts);
319
320       /* Fixed ? */
321       if(info->rts_fixed)
322         printf(" (f)   ");
323       else
324         printf("   ");
325     }
326
327   /* Display the fragmentation threshold */
328   if(info->has_bitrate)
329     {
330       printf("Frag thr:%ld B", info->frag);
331
332       /* Fixed ? */
333       if(info->frag_fixed)
334         printf(" (f)   ");
335       else
336         printf("   ");
337     }
338
339   /* Formating */
340   if((info->has_bitrate) || (info->has_rts) || (info->has_bitrate))
341     printf("\n          ");
342
343   if(info->has_enc)
344     {
345       printf("Encryption key:");
346       if(info->enc_method)
347         {
348           int           i = 0;
349           u_short       parts[4];
350           long long     key = info->enc_key;
351
352           for(i = 3; i >= 0; i--)
353             {
354               parts[i] = key & 0xFFFF;
355               key >>= 16;
356             }
357
358           i = 0;
359           while((parts[i] == 0) && (i < 3))
360             i++;
361           for(; i < 3; i++)
362             printf("%.4X-", parts[i]);
363           printf("%.4X", parts[3]);
364
365           if(info->enc_method > 1)
366             printf(" (%d)", info->enc_method);
367           printf("\n          ");
368         }
369       else
370         printf("off\n          ");
371     }
372
373   if(info->has_stats)
374     {
375       if(info->has_range && (info->stats.qual.level != 0))
376         /* If the statistics are in dBm */
377         if(info->stats.qual.level > info->range.max_qual.level)
378           printf("Link quality:%d/%d  Signal level:%d dBm  Noise level:%d dBm\n",
379                  info->stats.qual.qual, info->range.max_qual.qual,
380                  info->stats.qual.level - 0x100,
381                  info->stats.qual.noise - 0x100);
382         else
383           /* Statistics are relative values (0 -> max) */
384           printf("Link quality:%d/%d  Signal level:%d/%d  Noise level:%d/%d\n",
385                  info->stats.qual.qual, info->range.max_qual.qual,
386                  info->stats.qual.level, info->range.max_qual.level,
387                  info->stats.qual.noise, info->range.max_qual.noise);
388       else
389         /* We can't read the range, so we don't know... */
390         printf("Link quality:%d  Signal level:%d  Noise level:%d\n",
391                info->stats.qual.qual,
392                info->stats.qual.level,
393                info->stats.qual.noise);
394
395       printf("          Rx invalid nwid:%d  invalid crypt:%d  invalid misc:%d\n",
396              info->stats.discard.nwid,
397              info->stats.discard.code,
398              info->stats.discard.misc);
399     }
400
401   printf("\n");
402 }
403
404 /*------------------------------------------------------------------*/
405 /*
406  * Print on the screen in a neat fashion all the info we have collected
407  * on a device.
408  */
409 static void
410 print_info(int          skfd,
411            char *       ifname)
412 {
413   struct wireless_info  info;
414
415   if(get_info(skfd, ifname, &info) < 0)
416     {
417       fprintf(stderr, "%-8.8s  no wireless extensions.\n\n",
418               ifname);
419       return;
420     }
421
422   /* Display it ! */
423   display_info(&info, ifname);
424 }
425
426 /*------------------------------------------------------------------*/
427 /*
428  * Get info on all devices and print it on the screen
429  */
430 static void
431 print_devices(int       skfd)
432 {
433   char buff[1024];
434   struct ifconf ifc;
435   struct ifreq *ifr;
436   int i;
437
438   /* Get list of active devices */
439   ifc.ifc_len = sizeof(buff);
440   ifc.ifc_buf = buff;
441   if(ioctl(skfd, SIOCGIFCONF, &ifc) < 0)
442     {
443       fprintf(stderr, "SIOCGIFCONF: %s\n", strerror(errno));
444       return;
445     }
446   ifr = ifc.ifc_req;
447
448   /* Print them */
449   for(i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++)
450     print_info(skfd, ifr->ifr_name);
451 }
452
453 /************************* SETTING ROUTINES **************************/
454
455 /*------------------------------------------------------------------*/
456 /*
457  * Set the wireless options requested on command line
458  * This function is too long and probably should be split,
459  * because it look like the perfect definition of spaghetti code,
460  * but I'm way to lazy
461  */
462 static int
463 set_info(int            skfd,           /* The socket */
464          char *         args[],         /* Command line args */
465          int            count,          /* Args count */
466          char *         ifname)         /* Dev name */
467 {
468   struct iwreq          wrq;
469   int                   i;
470
471   /* Set dev name */
472   strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
473
474   /* if nothing after the device name */
475   if(count<1)
476     iw_usage();
477
478   /* The other args on the line specify options to be set... */
479   for(i = 0; i < count; i++)
480     {
481       /* ---------- Set network ID ---------- */
482       if((!strcasecmp(args[i], "nwid")) ||
483          (!strcasecmp(args[i], "domain")))
484         {
485           i++;
486           if(i >= count)
487             iw_usage();
488           if((!strcasecmp(args[i], "off")) ||
489              (!strcasecmp(args[i], "any")))
490             wrq.u.nwid.on = 0;
491           else
492             if(!strcasecmp(args[i], "on"))
493               {
494                 /* Get old nwid */
495                 if(ioctl(skfd, SIOCGIWNWID, &wrq) < 0)
496                   {
497                     fprintf(stderr, "SIOCGIWNWID: %s\n", strerror(errno));
498                     return(-1);
499                   }
500                 strcpy(wrq.ifr_name, ifname);
501                 wrq.u.nwid.on = 1;
502               }
503             else
504               if(sscanf(args[i], "%lX", (unsigned long *) &(wrq.u.nwid.nwid))
505                  != 1)
506                 iw_usage();
507               else
508                 wrq.u.nwid.on = 1;
509
510           if(ioctl(skfd, SIOCSIWNWID, &wrq) < 0)
511             {
512               fprintf(stderr, "SIOCSIWNWID: %s\n", strerror(errno));
513               return(-1);
514             }
515           continue;
516         }
517
518       /* ---------- Set frequency / channel ---------- */
519       if((!strncmp(args[i], "freq", 4)) ||
520          (!strcmp(args[i], "channel")))
521         {
522           double                freq;
523
524           if(++i >= count)
525             iw_usage();
526           if(sscanf(args[i], "%lg", &(freq)) != 1)
527             iw_usage();
528           if(index(args[i], 'G')) freq *= GIGA;
529           if(index(args[i], 'M')) freq *= MEGA;
530           if(index(args[i], 'k')) freq *= KILO;
531
532           float2freq(freq, &(wrq.u.freq));
533
534           if(ioctl(skfd, SIOCSIWFREQ, &wrq) < 0)
535             {
536               fprintf(stderr, "SIOCSIWFREQ: %s\n", strerror(errno));
537               return(-1);
538             }
539           continue;
540         }
541
542       /* ---------- Set sensitivity ---------- */
543       if(!strncmp(args[i], "sens", 4))
544         {
545           if(++i >= count)
546             iw_usage();
547           if(sscanf(args[i], "%d", &(wrq.u.sensitivity)) != 1)
548             iw_usage();
549
550           if(ioctl(skfd, SIOCSIWSENS, &wrq) < 0)
551             {
552               fprintf(stderr, "SIOCSIWSENS: %s\n", strerror(errno));
553               return(-1);
554             }
555           continue;
556         }
557
558       /* ---------- Set encryption stuff ---------- */
559       if(!strncmp(args[i], "enc", 3 ))
560         {
561           unsigned long long    key = 0;
562
563           if(++i >= count)
564             iw_usage();
565
566           if(!strcasecmp(args[i], "off"))
567             wrq.u.encoding.method = 0;
568           else
569             {
570               if(!strcasecmp(args[i], "on"))
571                 {
572                   /* Get old encryption information */
573                   if(ioctl(skfd, SIOCGIWENCODE, &wrq) < 0)
574                     {
575                       fprintf(stderr, "SIOCGIWENCODE: %s\n", strerror(errno));
576                       return(-1);
577                     }
578                   strcpy(wrq.ifr_name, ifname);
579                 }
580               else
581                 {
582                   char *        buff;
583                   char *        p;
584                   u_long        temp;
585
586                   p = buff = malloc(strlen(args[i] + 1));
587                   strcpy(buff, args[i]);
588
589                   p = strtok(buff, "-:;.,*#");
590                   while(p != (char *) NULL)
591                     {
592                       key = key << 16;
593                       if(sscanf(p, "%lX", &temp) != 1)
594                         iw_usage();
595                       key += temp;
596                       p = strtok((char *) NULL, "-:;.,*#");
597                     }
598
599                   free(buff);
600                   wrq.u.encoding.code = key;
601                 }
602               /* TODO : check for "(method)" in args list */
603               wrq.u.encoding.method = 1;
604             }
605
606           if(ioctl(skfd, SIOCSIWENCODE, &wrq) < 0)
607             {
608               fprintf(stderr, "SIOCSIWENCODE(%d): %s\n",
609                       errno, strerror(errno));
610               return(-1);
611             }
612           continue;
613         }
614
615 #if WIRELESS_EXT > 5
616       /* ---------- Set ESSID ---------- */
617       if(!strcasecmp(args[i], "essid"))
618         {
619           char          essid[IW_ESSID_MAX_SIZE + 1];
620
621           i++;
622           if(i >= count)
623             iw_usage();
624           if((!strcasecmp(args[i], "off")) ||
625              (!strcasecmp(args[i], "any")))
626             {
627               wrq.u.data.flags = 0;
628               essid[0] = '\0';
629             }
630           else
631             if(!strcasecmp(args[i], "on"))
632               {
633                 /* Get old essid */
634                 wrq.u.data.pointer = (caddr_t) essid;
635                 wrq.u.data.length = 0;
636                 wrq.u.data.flags = 0;
637                 if(ioctl(skfd, SIOCGIWESSID, &wrq) < 0)
638                   {
639                     fprintf(stderr, "SIOCGIWESSID: %s\n", strerror(errno));
640                     return(-1);
641                   }
642                 strcpy(wrq.ifr_name, ifname);
643                 wrq.u.data.flags = 1;
644               }
645             else
646               if(strlen(args[i]) > IW_ESSID_MAX_SIZE)
647                 {
648                   fprintf(stderr, "ESSID too long (max %d): ``%s''\n",
649                           IW_ESSID_MAX_SIZE, args[i]);
650                   iw_usage();
651                 }
652               else
653                 {
654                   wrq.u.data.flags = 1;
655                   strcpy(essid, args[i]);
656                 }
657
658           wrq.u.data.pointer = (caddr_t) essid;
659           wrq.u.data.length = strlen(essid) + 1;
660           if(ioctl(skfd, SIOCSIWESSID, &wrq) < 0)
661             {
662               fprintf(stderr, "SIOCSIWESSID: %s\n", strerror(errno));
663               return(-1);
664             }
665           continue;
666         }
667
668       /* ---------- Set AP address ---------- */
669       if(!strcasecmp(args[i], "ap"))
670         {
671           if(++i >= count)
672             iw_usage();
673
674           /* Check if we have valid address types */
675           if(check_addr_type(skfd, ifname) < 0)
676             {
677               fprintf(stderr, "%-8.8s  Interface doesn't support MAC & IP addresses\n", ifname);
678               return(-1);
679             }
680
681           /* Get the address */
682           if(in_addr(skfd, ifname, args[i++], &(wrq.u.ap_addr)) < 0)
683             iw_usage();
684
685           if(ioctl(skfd, SIOCSIWAP, &wrq) < 0)
686             {
687               fprintf(stderr, "SIOCSIWAP: %s\n", strerror(errno));
688               return(-1);
689             }
690           continue;
691         }
692 #endif  /* WIRELESS_EXT > 5 */
693
694 #if WIRELESS_EXT > 7
695       /* ---------- Set NickName ---------- */
696       if(!strncmp(args[i], "nick", 4))
697         {
698           i++;
699           if(i >= count)
700             iw_usage();
701           if(strlen(args[i]) > IW_ESSID_MAX_SIZE)
702             {
703               fprintf(stderr, "Name too long (max %d) : ``%s''\n",
704                       IW_ESSID_MAX_SIZE, args[i]);
705               iw_usage();
706             }
707
708           wrq.u.data.pointer = (caddr_t) args[i];
709           wrq.u.data.length = strlen(args[i]) + 1;
710           if(ioctl(skfd, SIOCSIWNICKN, &wrq) < 0)
711             {
712               fprintf(stderr, "SIOCSIWNICKN: %s\n", strerror(errno));
713               return(-1);
714             }
715           continue;
716         }
717
718       /* ---------- Set Bit-Rate ---------- */
719       if((!strncmp(args[i], "bit", 3)) ||
720          (!strcmp(args[i], "rate")))
721         {
722           i++;
723           if(i >= count)
724             iw_usage();
725           if(!strcasecmp(args[i], "auto"))
726             {
727               wrq.u.bitrate.value = -1;
728               wrq.u.bitrate.fixed = 0;
729             }
730           else
731             {
732               if(!strcasecmp(args[i], "fixed"))
733                 {
734                   /* Get old bitrate */
735                   if(ioctl(skfd, SIOCGIWRATE, &wrq) < 0)
736                     {
737                       fprintf(stderr, "SIOCGIWRATE: %s\n", strerror(errno));
738                       return(-1);
739                     }
740                   strcpy(wrq.ifr_name, ifname);
741                 }
742               else                      /* Should be a numeric value */
743                 {
744                   double                brate;
745
746                   if(sscanf(args[i], "%lg", &(brate)) != 1)
747                     iw_usage();
748                   if(index(args[i], 'G')) brate *= GIGA;
749                   if(index(args[i], 'M')) brate *= MEGA;
750                   if(index(args[i], 'k')) brate *= KILO;
751                   wrq.u.bitrate.value = (long) brate;
752                 }
753               wrq.u.bitrate.fixed = 1;
754             }
755
756           if(ioctl(skfd, SIOCSIWRATE, &wrq) < 0)
757             {
758               fprintf(stderr, "SIOCSIWRATE: %s\n", strerror(errno));
759               return(-1);
760             }
761           continue;
762         }
763
764       /* ---------- Set RTS threshold ---------- */
765       if(!strncmp(args[i], "rts", 3))
766         {
767           i++;
768           if(i >= count)
769             iw_usage();
770           if(!strcasecmp(args[i], "auto"))
771             {
772               wrq.u.rts.value = -1;
773               wrq.u.rts.fixed = 0;
774             }
775           else
776             {
777               if(!strcasecmp(args[i], "fixed"))
778                 {
779                   /* Get old RTS threshold */
780                   if(ioctl(skfd, SIOCGIWRTS, &wrq) < 0)
781                     {
782                       fprintf(stderr, "SIOCGIWRTS: %s\n", strerror(errno));
783                       return(-1);
784                     }
785                   strcpy(wrq.ifr_name, ifname);
786                 }
787               else
788                 if(!strcasecmp(args[i], "off"))
789                   wrq.u.rts.value = -1; /* i.e. max size */
790                 else                    /* Should be a numeric value */
791                   if(sscanf(args[i], "%ld", (unsigned long *) &(wrq.u.rts.value))
792                      != 1)
793                     iw_usage();
794
795               wrq.u.rts.fixed = 1;
796             }
797
798           if(ioctl(skfd, SIOCSIWRTS, &wrq) < 0)
799             {
800               fprintf(stderr, "SIOCSIWRTS: %s\n", strerror(errno));
801               return(-1);
802             }
803           continue;
804         }
805
806       /* ---------- Set fragmentation threshold ---------- */
807       if(!strncmp(args[i], "frag", 4))
808         {
809           i++;
810           if(i >= count)
811             iw_usage();
812           if(!strcasecmp(args[i], "auto"))
813             {
814               wrq.u.frag.value = -1;
815               wrq.u.frag.fixed = 0;
816             }
817           else
818             {
819               if(!strcasecmp(args[i], "fixed"))
820                 {
821                   /* Get old fragmentation threshold */
822                   if(ioctl(skfd, SIOCGIWFRAG, &wrq) < 0)
823                     {
824                       fprintf(stderr, "SIOCGIWFRAG: %s\n", strerror(errno));
825                       return(-1);
826                     }
827                   strcpy(wrq.ifr_name, ifname);
828                 }
829               else
830                 if(!strcasecmp(args[i], "off"))
831                   wrq.u.frag.value = -1;        /* i.e. max size */
832                 else                    /* Should be a numeric value */
833                   if(sscanf(args[i], "%ld", (unsigned long *) &(wrq.u.frag.value))
834                      != 1)
835                     iw_usage();
836
837               wrq.u.frag.fixed = 1;
838             }
839
840           if(ioctl(skfd, SIOCSIWFRAG, &wrq) < 0)
841             {
842               fprintf(stderr, "SIOCSIWFRAG: %s\n", strerror(errno));
843               return(-1);
844             }
845           continue;
846         }
847 #endif  /* WIRELESS_EXT > 7 */
848
849       /* Here we have an unrecognised arg... */
850       fprintf(stderr, "Invalid argument : %s\n", args[i]);
851       iw_usage();
852       return(-1);
853     }           /* for(index ... */
854   return(0);
855 }
856
857 /******************************* MAIN ********************************/
858
859 /*------------------------------------------------------------------*/
860 /*
861  * The main !
862  */
863 int
864 main(int        argc,
865      char **    argv)
866 {
867   int skfd = -1;                /* generic raw socket desc.     */
868   int goterr = 0;
869
870   /* Create a channel to the NET kernel. */
871   if((skfd = sockets_open()) < 0)
872     {
873       perror("socket");
874       exit(-1);
875     }
876
877   /* No argument : show the list of all device + info */
878   if(argc == 1)
879     {
880       print_devices(skfd);
881       close(skfd);
882       exit(0);
883     }
884
885   /* Special case for help... */
886   if((!strncmp(argv[1], "-h", 9)) ||
887      (!strcmp(argv[1], "--help")))
888     {
889       iw_usage();
890       close(skfd);
891       exit(0);
892     }
893
894   /* The device name must be the first argument */
895   if(argc == 2)
896     {
897       print_info(skfd, argv[1]);
898       close(skfd);
899       exit(0);
900     }
901
902   /* The other args on the line specify options to be set... */
903   goterr = set_info(skfd, argv + 2, argc - 2, argv[1]);
904
905   /* Close the socket. */
906   close(skfd);
907
908   return(goterr);
909 }
910
911