4 * Jean II - HPLB 97->99 - HPL 99->01
6 * Main code for "iwconfig". This is the generic tool for most
8 * You need to link this code against "iwlib.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 */
16 /************************* MISC SUBROUTINES **************************/
18 /*------------------------------------------------------------------*/
25 fprintf(stderr, "Usage: iwconfig interface [essid {NN|on|off}]\n");
26 fprintf(stderr, " [nwid {NN|on|off}]\n");
27 fprintf(stderr, " [freq N.NNNN[k|M|G]]\n");
28 fprintf(stderr, " [channel N]\n");
29 fprintf(stderr, " [sens N]\n");
30 fprintf(stderr, " [nick N]\n");
31 fprintf(stderr, " [rate {N|auto|fixed}]\n");
32 fprintf(stderr, " [rts {N|auto|fixed|off}]\n");
33 fprintf(stderr, " [frag {N|auto|fixed|off}]\n");
34 fprintf(stderr, " [enc NNNN-NNNN]\n");
35 fprintf(stderr, " [power { period N|timeout N}]\n");
36 fprintf(stderr, " [txpower N {mW|dBm}]\n");
37 fprintf(stderr, " [commit]\n");
41 /************************* DISPLAY ROUTINES **************************/
43 /*------------------------------------------------------------------*/
45 * Get wireless informations & config from the device driver
46 * We will call all the classical wireless ioctl on the driver through
47 * the socket to know what is supported and to get the settings...
52 struct wireless_info * info)
56 memset((char *) info, 0, sizeof(struct wireless_info));
58 /* Get wireless name */
59 if(iw_get_ext(skfd, ifname, SIOCGIWNAME, &wrq) < 0)
60 /* If no wireless name : no wireless extensions */
63 strcpy(info->name, wrq.u.name);
66 if(iw_get_range_info(skfd, ifname, &(info->range)) >= 0)
70 if(iw_get_ext(skfd, ifname, SIOCGIWNWID, &wrq) >= 0)
73 memcpy(&(info->nwid), &(wrq.u.nwid), sizeof(iwparam));
76 /* Get frequency / channel */
77 if(iw_get_ext(skfd, ifname, SIOCGIWFREQ, &wrq) >= 0)
80 info->freq = iw_freq2float(&(wrq.u.freq));
84 if(iw_get_ext(skfd, ifname, SIOCGIWSENS, &wrq) >= 0)
87 memcpy(&(info->sens), &(wrq.u.sens), sizeof(iwparam));
90 /* Get encryption information */
91 wrq.u.data.pointer = (caddr_t) info->key;
92 wrq.u.data.length = IW_ENCODING_TOKEN_MAX;
94 if(iw_get_ext(skfd, ifname, SIOCGIWENCODE, &wrq) >= 0)
97 info->key_size = wrq.u.data.length;
98 info->key_flags = wrq.u.data.flags;
102 wrq.u.essid.pointer = (caddr_t) info->essid;
103 wrq.u.essid.length = IW_ESSID_MAX_SIZE;
104 wrq.u.essid.flags = 0;
105 if(iw_get_ext(skfd, ifname, SIOCGIWESSID, &wrq) >= 0)
108 info->essid_on = wrq.u.data.flags;
112 if(iw_get_ext(skfd, ifname, SIOCGIWAP, &wrq) >= 0)
114 info->has_ap_addr = 1;
115 memcpy(&(info->ap_addr), &(wrq.u.ap_addr), sizeof (sockaddr));
119 wrq.u.essid.pointer = (caddr_t) info->nickname;
120 wrq.u.essid.length = IW_ESSID_MAX_SIZE;
121 wrq.u.essid.flags = 0;
122 if(iw_get_ext(skfd, ifname, SIOCGIWNICKN, &wrq) >= 0)
123 if(wrq.u.data.length > 1)
124 info->has_nickname = 1;
127 if(iw_get_ext(skfd, ifname, SIOCGIWRATE, &wrq) >= 0)
129 info->has_bitrate = 1;
130 memcpy(&(info->bitrate), &(wrq.u.bitrate), sizeof(iwparam));
133 /* Get RTS threshold */
134 if(iw_get_ext(skfd, ifname, SIOCGIWRTS, &wrq) >= 0)
137 memcpy(&(info->rts), &(wrq.u.rts), sizeof(iwparam));
140 /* Get fragmentation threshold */
141 if(iw_get_ext(skfd, ifname, SIOCGIWFRAG, &wrq) >= 0)
144 memcpy(&(info->frag), &(wrq.u.frag), sizeof(iwparam));
147 /* Get operation mode */
148 if(iw_get_ext(skfd, ifname, SIOCGIWMODE, &wrq) >= 0)
150 if((wrq.u.mode < IW_NUM_OPER_MODE) && (wrq.u.mode >= 0))
152 info->mode = wrq.u.mode;
155 /* Get Power Management settings */
156 wrq.u.power.flags = 0;
157 if(iw_get_ext(skfd, ifname, SIOCGIWPOWER, &wrq) >= 0)
160 memcpy(&(info->power), &(wrq.u.power), sizeof(iwparam));
164 /* Get Transmit Power */
165 if(iw_get_ext(skfd, ifname, SIOCGIWTXPOW, &wrq) >= 0)
167 info->has_txpower = 1;
168 memcpy(&(info->txpower), &(wrq.u.txpower), sizeof(iwparam));
172 #if WIRELESS_EXT > 10
173 /* Get retry limit/lifetime */
174 if(iw_get_ext(skfd, ifname, SIOCGIWRETRY, &wrq) >= 0)
177 memcpy(&(info->retry), &(wrq.u.retry), sizeof(iwparam));
179 #endif /* WIRELESS_EXT > 10 */
182 if(iw_get_stats(skfd, ifname, &(info->stats)) >= 0)
190 /*------------------------------------------------------------------*/
192 * Print on the screen in a neat fashion all the info we have collected
196 display_info(struct wireless_info * info,
199 char buffer[128]; /* Temporary buffer */
201 /* One token is more of less 5 character, 14 tokens per line */
202 int tokens = 3; /* For name */
204 /* Display device name and wireless name (name of the protocol used) */
205 printf("%-8.8s %s ", ifname, info->name);
207 /* Display ESSID (extended network), if any */
212 /* Does it have an ESSID index ? */
213 if((info->essid_on & IW_ENCODE_INDEX) > 1)
214 printf("ESSID:\"%s\" [%d] ", info->essid,
215 (info->essid_on & IW_ENCODE_INDEX));
217 printf("ESSID:\"%s\" ", info->essid);
220 printf("ESSID:off/any ");
223 /* Display NickName (station name), if any */
224 if(info->has_nickname)
225 printf("Nickname:\"%s\"", info->nickname);
228 if(info->has_essid || info->has_nickname)
234 /* Display Network ID */
237 /* Note : should display proper number of digit according to info
238 * in range structure */
239 if(info->nwid.disabled)
240 printf("NWID:off/any ");
242 printf("NWID:%X ", info->nwid.value);
246 /* Display the current mode of operation */
249 printf("Mode:%s ", iw_operation_mode[info->mode]);
253 /* Display frequency / channel */
256 if(info->freq < KILO)
257 printf("Channel:%g ", info->freq);
260 if(info->freq >= GIGA)
261 printf("Frequency:%gGHz ", info->freq / GIGA);
264 if(info->freq >= MEGA)
265 printf("Frequency:%gMHz ", info->freq / MEGA);
267 printf("Frequency:%gkHz ", info->freq / KILO);
273 /* Display the address of the current Access Point */
274 if(info->has_ap_addr)
276 /* A bit of clever formatting */
284 /* Oups ! No Access Point in Ad-Hoc mode */
285 if((info->has_mode) && (info->mode == IW_MODE_ADHOC))
288 printf("Access Point:");
289 printf(" %s", iw_pr_ether(buffer, info->ap_addr.sa_data));
292 /* Display the currently used/set bit-rate */
293 if(info->has_bitrate)
295 /* A bit of clever formatting */
304 if(info->bitrate.fixed)
309 if(info->bitrate.value >= GIGA)
310 printf("%gGb/s", info->bitrate.value / GIGA);
312 if(info->bitrate.value >= MEGA)
313 printf("%gMb/s", info->bitrate.value / MEGA);
315 printf("%gkb/s", info->bitrate.value / KILO);
320 /* Display the Transmit Power */
321 if(info->has_txpower)
323 /* A bit of clever formatting */
332 if(info->txpower.disabled)
333 printf("Tx-Power:off ");
339 if(info->txpower.fixed)
344 /* Convert everything to dBm */
345 if(info->txpower.flags & IW_TXPOW_MWATT)
346 dbm = iw_mwatt2dbm(info->txpower.value);
348 dbm = info->txpower.value;
351 printf("%d dBm ", dbm);
356 /* Display sensitivity */
359 /* A bit of clever formatting */
369 printf("Sensitivity=");
371 printf("Sensitivity:");
374 /* Display in dBm ? */
375 if(info->sens.value < 0)
376 printf("%d dBm ", info->sens.value);
378 printf("%d/%d ", info->sens.value, info->range.sensitivity);
380 printf("%d ", info->sens.value);
386 #if WIRELESS_EXT > 10
387 /* Display retry limit/lifetime information */
392 if(info->retry.disabled)
396 /* Let's check the value and its type */
397 if(info->retry.flags & IW_RETRY_TYPE)
399 iw_print_retry_value(buffer,
400 info->retry.value, info->retry.flags);
401 printf("%s", buffer);
404 /* Let's check if nothing (simply on) */
405 if(info->retry.flags == IW_RETRY_ON)
409 tokens += 5; /* Between 3 and 5, depend on flags */
411 #endif /* WIRELESS_EXT > 10 */
413 /* Display the RTS threshold */
417 if(info->rts.disabled)
418 printf("RTS thr:off ");
427 printf("%d B ", info->rts.value);
432 /* Display the fragmentation threshold */
435 /* A bit of clever formatting */
444 if(info->frag.disabled)
445 printf("Fragment thr:off");
450 printf("Fragment thr=");
452 printf("Fragment thr:");
454 printf("%d B ", info->frag.value);
462 /* Display encryption information */
463 /* Note : we display only the "current" key, use iwlist to list all keys */
466 printf("Encryption key:");
467 if((info->key_flags & IW_ENCODE_DISABLED) || (info->key_size == 0))
471 /* Display the key */
472 iw_print_key(buffer, info->key, info->key_size, info->key_flags);
473 printf("%s", buffer);
476 if((info->key_flags & IW_ENCODE_INDEX) > 1)
477 printf(" [%d]", info->key_flags & IW_ENCODE_INDEX);
478 if(info->key_flags & IW_ENCODE_RESTRICTED)
479 printf(" Encryption mode:restricted");
480 if(info->key_flags & IW_ENCODE_OPEN)
481 printf(" Encryption mode:open");
486 /* Display Power Management information */
487 /* Note : we display only one parameter, period or timeout. If a device
488 * (such as HiperLan) has both, the user need to use iwlist... */
489 if(info->has_power) /* I hope the device has power ;-) */
491 printf("Power Management");
493 if(info->power.disabled)
497 /* Let's check the value and its type */
498 if(info->power.flags & IW_POWER_TYPE)
500 iw_print_pm_value(buffer, info->power.value, info->power.flags);
501 printf("%s", buffer);
504 /* Let's check the mode */
505 iw_print_pm_mode(buffer, info->power.flags);
506 printf("%s", buffer);
508 /* Let's check if nothing (simply on) */
509 if(info->power.flags == IW_POWER_ON)
515 /* Display statistics */
518 info->stats.qual.updated = 0x0; /* Not that reliable, disable */
519 iw_print_stats(buffer, &info->stats.qual, &info->range, info->has_range);
520 printf("Link %s\n", buffer);
522 #if WIRELESS_EXT > 11
523 printf(" Rx invalid nwid:%d Rx invalid crypt:%d Rx invalid frag:%d\n Tx excessive retries:%d Invalid misc:%d Missed beacon:%d\n",
524 info->stats.discard.nwid,
525 info->stats.discard.code,
526 info->stats.discard.fragment,
527 info->stats.discard.retries,
528 info->stats.discard.misc,
529 info->stats.miss.beacon);
530 #else /* WIRELESS_EXT > 11 */
531 printf(" Rx invalid nwid:%d invalid crypt:%d invalid misc:%d\n",
532 info->stats.discard.nwid,
533 info->stats.discard.code,
534 info->stats.discard.misc);
535 #endif /* WIRELESS_EXT > 11 */
541 /*------------------------------------------------------------------*/
543 * Print on the screen in a neat fashion all the info we have collected
550 struct wireless_info info;
552 if(get_info(skfd, ifname, &info) < 0)
554 fprintf(stderr, "%-8.8s no wireless extensions.\n\n",
560 display_info(&info, ifname);
563 /*------------------------------------------------------------------*/
565 * Get info on all devices and print it on the screen
568 print_devices(int skfd)
575 /* Get list of active devices */
576 ifc.ifc_len = sizeof(buff);
578 if(ioctl(skfd, SIOCGIFCONF, &ifc) < 0)
580 fprintf(stderr, "SIOCGIFCONF: %s\n", strerror(errno));
586 for(i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++)
587 print_info(skfd, ifr->ifr_name);
590 /************************* SETTING ROUTINES **************************/
592 /*------------------------------------------------------------------*/
594 * Macro to handle errors when setting WE
595 * Print a nice error message and exit...
596 * We define them as macro so that "return" do the right thing.
597 * The "do {...} while(0)" is a standard trick
599 #define ERR_SET_EXT(rname, request) \
600 fprintf(stderr, "Error for wireless request \"%s\" (%X) :\n", \
603 #define ABORT_ARG_NUM(rname, request) \
605 ERR_SET_EXT(rname, request); \
606 fprintf(stderr, " too few arguments.\n"); \
610 #define ABORT_ARG_TYPE(rname, request, arg) \
612 ERR_SET_EXT(rname, request); \
613 fprintf(stderr, " invalid argument \"%s\".\n", arg); \
617 #define ABORT_ARG_SIZE(rname, request, max) \
619 ERR_SET_EXT(rname, request); \
620 fprintf(stderr, " argument too big (max %d)\n", max); \
624 /*------------------------------------------------------------------*/
626 * Wrapper to push some Wireless Parameter in the driver
627 * Use standard wrapper and add pretty error message if fail...
629 #define IW_SET_EXT_ERR(skfd, ifname, request, wrq, rname) \
631 if(iw_set_ext(skfd, ifname, request, wrq) < 0) { \
632 ERR_SET_EXT(rname, request); \
633 fprintf(stderr, " SET failed on device %-1.8s ; %s.\n", \
634 ifname, strerror(errno)); \
638 /*------------------------------------------------------------------*/
640 * Wrapper to extract some Wireless Parameter out of the driver
641 * Use standard wrapper and add pretty error message if fail...
643 #define IW_GET_EXT_ERR(skfd, ifname, request, wrq, rname) \
645 if(iw_get_ext(skfd, ifname, request, wrq) < 0) { \
646 ERR_SET_EXT(rname, request); \
647 fprintf(stderr, " GET failed on device %-1.8s ; %s.\n", \
648 ifname, strerror(errno)); \
652 /*------------------------------------------------------------------*/
654 * Set the wireless options requested on command line
655 * This function is too long and probably should be split,
656 * because it look like the perfect definition of spaghetti code,
657 * but I'm way to lazy
660 set_info(int skfd, /* The socket */
661 char * args[], /* Command line args */
662 int count, /* Args count */
663 char * ifname) /* Dev name */
668 /* if nothing after the device name - will never happen */
671 fprintf(stderr, "Error : too few arguments.\n");
675 /* The other args on the line specify options to be set... */
676 for(i = 0; i < count; i++)
678 /* ---------- Commit changes to driver ---------- */
679 if(!strncmp(args[i], "commit", 6))
682 IW_SET_EXT_ERR(skfd, ifname, SIOCSIWCOMMIT, &wrq,
687 /* ---------- Set network ID ---------- */
688 if((!strcasecmp(args[i], "nwid")) ||
689 (!strcasecmp(args[i], "domain")))
693 ABORT_ARG_NUM("Set NWID", SIOCSIWNWID);
694 if((!strcasecmp(args[i], "off")) ||
695 (!strcasecmp(args[i], "any")))
696 wrq.u.nwid.disabled = 1;
698 if(!strcasecmp(args[i], "on"))
701 IW_GET_EXT_ERR(skfd, ifname, SIOCGIWNWID, &wrq,
703 wrq.u.nwid.disabled = 0;
706 if(sscanf(args[i], "%lX", (unsigned long *) &(wrq.u.nwid.value))
708 ABORT_ARG_TYPE("Set NWID", SIOCSIWNWID, args[i]);
710 wrq.u.nwid.disabled = 0;
711 wrq.u.nwid.fixed = 1;
714 IW_SET_EXT_ERR(skfd, ifname, SIOCSIWNWID, &wrq,
719 /* ---------- Set frequency / channel ---------- */
720 if((!strncmp(args[i], "freq", 4)) ||
721 (!strcmp(args[i], "channel")))
726 ABORT_ARG_NUM("Set Frequency", SIOCSIWFREQ);
727 if(sscanf(args[i], "%lg", &(freq)) != 1)
728 ABORT_ARG_TYPE("Set Frequency", SIOCSIWFREQ, args[i]);
729 if(index(args[i], 'G')) freq *= GIGA;
730 if(index(args[i], 'M')) freq *= MEGA;
731 if(index(args[i], 'k')) freq *= KILO;
733 iw_float2freq(freq, &(wrq.u.freq));
735 IW_SET_EXT_ERR(skfd, ifname, SIOCSIWFREQ, &wrq,
740 /* ---------- Set sensitivity ---------- */
741 if(!strncmp(args[i], "sens", 4))
744 ABORT_ARG_NUM("Set Sensitivity", SIOCSIWSENS);
745 if(sscanf(args[i], "%d", &(wrq.u.sens.value)) != 1)
746 ABORT_ARG_TYPE("Set Sensitivity", SIOCSIWSENS, args[i]);
748 IW_SET_EXT_ERR(skfd, ifname, SIOCSIWSENS, &wrq,
753 /* ---------- Set encryption stuff ---------- */
754 if((!strncmp(args[i], "enc", 3)) ||
755 (!strcmp(args[i], "key")))
757 unsigned char key[IW_ENCODING_TOKEN_MAX];
760 ABORT_ARG_NUM("Set Encode", SIOCSIWENCODE);
762 if(!strcasecmp(args[i], "on"))
764 /* Get old encryption information */
765 wrq.u.data.pointer = (caddr_t) key;
766 wrq.u.data.length = 0;
767 wrq.u.data.flags = 0;
768 IW_GET_EXT_ERR(skfd, ifname, SIOCGIWENCODE, &wrq,
770 wrq.u.data.flags &= ~IW_ENCODE_DISABLED; /* Enable */
780 wrq.u.data.pointer = (caddr_t) NULL;
781 wrq.u.data.flags = 0;
782 wrq.u.data.length = 0;
784 /* -- Check for the key -- */
785 if(!strncmp(args[i], "s:", 2))
787 /* First case : as an ASCII string */
788 wrq.u.data.length = strlen(args[i] + 2);
789 if(wrq.u.data.length > IW_ENCODING_TOKEN_MAX)
790 wrq.u.data.length = IW_ENCODING_TOKEN_MAX;
791 strncpy(key, args[i] + 2, wrq.u.data.length);
792 wrq.u.data.pointer = (caddr_t) key;
798 /* Second case : as hexadecimal digits */
799 buff = malloc(strlen(args[i]) + 1);
802 fprintf(stderr, "Set Encode : Malloc failed (string too long ?)\n");
805 strcpy(buff, args[i]);
807 p = strtok(buff, "-:;.,");
808 while((p != (char *) NULL) && (k < IW_ENCODING_TOKEN_MAX))
810 if(sscanf(p, "%2X", &temp) != 1)
815 key[k++] = (unsigned char) (temp & 0xFF);
816 if(strlen(p) > 2) /* Token not finished yet */
819 p = strtok((char *) NULL, "-:;.,");
826 wrq.u.data.length = k;
827 wrq.u.data.pointer = (caddr_t) key;
831 /* -- Check for token index -- */
833 (sscanf(args[i], "[%d]", &temp) == 1) &&
834 (temp > 0) && (temp < IW_ENCODE_INDEX))
836 wrq.u.encoding.flags |= temp;
841 /* -- Check the various flags -- */
844 if(!strcasecmp(args[i], "off"))
845 wrq.u.data.flags |= IW_ENCODE_DISABLED;
846 if(!strcasecmp(args[i], "open"))
847 wrq.u.data.flags |= IW_ENCODE_OPEN;
848 if(!strncasecmp(args[i], "restricted", 5))
849 wrq.u.data.flags |= IW_ENCODE_RESTRICTED;
850 if(wrq.u.data.flags & IW_ENCODE_FLAGS)
856 /* Pointer is absent in new API */
857 if(wrq.u.data.pointer == NULL)
858 wrq.u.data.flags = IW_ENCODE_NOKEY;
861 ABORT_ARG_TYPE("Set Encode", SIOCSIWENCODE, args[i]);
865 IW_SET_EXT_ERR(skfd, ifname, SIOCSIWENCODE, &wrq,
870 /* ---------- Set ESSID ---------- */
871 if(!strcasecmp(args[i], "essid"))
873 char essid[IW_ESSID_MAX_SIZE + 1];
877 ABORT_ARG_NUM("Set ESSID", SIOCSIWESSID);
878 if((!strcasecmp(args[i], "off")) ||
879 (!strcasecmp(args[i], "any")))
881 wrq.u.essid.flags = 0;
885 if(!strcasecmp(args[i], "on"))
888 wrq.u.essid.pointer = (caddr_t) essid;
889 wrq.u.essid.length = 0;
890 wrq.u.essid.flags = 0;
891 IW_GET_EXT_ERR(skfd, ifname, SIOCGIWESSID, &wrq,
893 wrq.u.essid.flags = 1;
896 /* Check the size of what the user passed us to avoid
897 * buffer overflows */
898 if(strlen(args[i]) > IW_ESSID_MAX_SIZE)
899 ABORT_ARG_SIZE("Set ESSID", SIOCSIWESSID, IW_ESSID_MAX_SIZE);
904 wrq.u.essid.flags = 1;
905 strcpy(essid, args[i]); /* Size checked, all clear */
907 /* Check for ESSID index */
908 if(((i+1) < count) &&
909 (sscanf(args[i+1], "[%d]", &temp) == 1) &&
910 (temp > 0) && (temp < IW_ENCODE_INDEX))
912 wrq.u.essid.flags = temp;
917 wrq.u.essid.pointer = (caddr_t) essid;
918 wrq.u.essid.length = strlen(essid) + 1;
919 IW_SET_EXT_ERR(skfd, ifname, SIOCSIWESSID, &wrq,
924 /* ---------- Set AP address ---------- */
925 if(!strcasecmp(args[i], "ap"))
928 ABORT_ARG_NUM("Set AP Address", SIOCSIWAP);
930 /* Get the address and check if the interface supports it */
931 if(iw_in_addr(skfd, ifname, args[i++], &(wrq.u.ap_addr)) < 0)
932 ABORT_ARG_TYPE("Set AP Address", SIOCSIWAP, args[i-1]);
934 IW_SET_EXT_ERR(skfd, ifname, SIOCSIWAP, &wrq,
939 /* ---------- Set NickName ---------- */
940 if(!strncmp(args[i], "nick", 4))
944 ABORT_ARG_NUM("Set Nickname", SIOCSIWNICKN);
945 if(strlen(args[i]) > IW_ESSID_MAX_SIZE)
946 ABORT_ARG_SIZE("Set Nickname", SIOCSIWNICKN, IW_ESSID_MAX_SIZE);
948 wrq.u.essid.pointer = (caddr_t) args[i];
949 wrq.u.essid.length = strlen(args[i]) + 1;
950 IW_SET_EXT_ERR(skfd, ifname, SIOCSIWNICKN, &wrq,
955 /* ---------- Set Bit-Rate ---------- */
956 if((!strncmp(args[i], "bit", 3)) ||
957 (!strcmp(args[i], "rate")))
960 ABORT_ARG_NUM("Set Bit Rate", SIOCSIWRATE);
961 if(!strcasecmp(args[i], "auto"))
963 wrq.u.bitrate.value = -1;
964 wrq.u.bitrate.fixed = 0;
968 if(!strcasecmp(args[i], "fixed"))
970 /* Get old bitrate */
971 IW_GET_EXT_ERR(skfd, ifname, SIOCGIWRATE, &wrq,
973 wrq.u.bitrate.fixed = 1;
975 else /* Should be a numeric value */
979 if(sscanf(args[i], "%lg", &(brate)) != 1)
980 ABORT_ARG_TYPE("Set Bit Rate", SIOCSIWRATE, args[i]);
981 if(index(args[i], 'G')) brate *= GIGA;
982 if(index(args[i], 'M')) brate *= MEGA;
983 if(index(args[i], 'k')) brate *= KILO;
984 wrq.u.bitrate.value = (long) brate;
985 wrq.u.bitrate.fixed = 1;
987 /* Check for an additional argument */
988 if(((i+1) < count) &&
989 (!strcasecmp(args[i+1], "auto")))
991 wrq.u.bitrate.fixed = 0;
994 if(((i+1) < count) &&
995 (!strcasecmp(args[i+1], "fixed")))
997 wrq.u.bitrate.fixed = 1;
1003 IW_SET_EXT_ERR(skfd, ifname, SIOCSIWRATE, &wrq,
1008 /* ---------- Set RTS threshold ---------- */
1009 if(!strncasecmp(args[i], "rts", 3))
1013 ABORT_ARG_NUM("Set RTS Threshold", SIOCSIWRTS);
1014 wrq.u.rts.value = -1;
1015 wrq.u.rts.fixed = 1;
1016 wrq.u.rts.disabled = 0;
1017 if(!strcasecmp(args[i], "off"))
1018 wrq.u.rts.disabled = 1; /* i.e. max size */
1020 if(!strcasecmp(args[i], "auto"))
1021 wrq.u.rts.fixed = 0;
1024 if(!strcasecmp(args[i], "fixed"))
1026 /* Get old RTS threshold */
1027 IW_GET_EXT_ERR(skfd, ifname, SIOCGIWRTS, &wrq,
1028 "Set RTS Threshold");
1029 wrq.u.rts.fixed = 1;
1031 else /* Should be a numeric value */
1032 if(sscanf(args[i], "%ld", (unsigned long *) &(wrq.u.rts.value))
1034 ABORT_ARG_TYPE("Set RTS Threshold", SIOCSIWRTS, args[i]);
1037 IW_SET_EXT_ERR(skfd, ifname, SIOCSIWRTS, &wrq,
1038 "Set RTS Threshold");
1042 /* ---------- Set fragmentation threshold ---------- */
1043 if(!strncmp(args[i], "frag", 4))
1047 ABORT_ARG_NUM("Set Fragmentation Threshold", SIOCSIWFRAG);
1048 wrq.u.frag.value = -1;
1049 wrq.u.frag.fixed = 1;
1050 wrq.u.frag.disabled = 0;
1051 if(!strcasecmp(args[i], "off"))
1052 wrq.u.frag.disabled = 1; /* i.e. max size */
1054 if(!strcasecmp(args[i], "auto"))
1055 wrq.u.frag.fixed = 0;
1058 if(!strcasecmp(args[i], "fixed"))
1060 /* Get old fragmentation threshold */
1061 IW_GET_EXT_ERR(skfd, ifname, SIOCGIWFRAG, &wrq,
1062 "Set Fragmentation Threshold");
1063 wrq.u.frag.fixed = 1;
1065 else /* Should be a numeric value */
1066 if(sscanf(args[i], "%ld",
1067 (unsigned long *) &(wrq.u.frag.value))
1069 ABORT_ARG_TYPE("Set Fragmentation Threshold", SIOCSIWFRAG,
1073 IW_SET_EXT_ERR(skfd, ifname, SIOCSIWFRAG, &wrq,
1074 "Set Fragmentation Threshold");
1078 /* ---------- Set operation mode ---------- */
1079 if(!strcmp(args[i], "mode"))
1085 ABORT_ARG_NUM("Set Mode", SIOCSIWMODE);
1087 if(sscanf(args[i], "%d", &k) != 1)
1090 while((k < IW_NUM_OPER_MODE) &&
1091 strncasecmp(args[i], iw_operation_mode[k], 3))
1094 if((k >= IW_NUM_OPER_MODE) || (k < 0))
1095 ABORT_ARG_TYPE("Set Mode", SIOCSIWMODE, args[i]);
1098 IW_SET_EXT_ERR(skfd, ifname, SIOCSIWMODE, &wrq,
1103 /* ---------- Set Power Management ---------- */
1104 if(!strncmp(args[i], "power", 3))
1107 ABORT_ARG_NUM("Set Power Management", SIOCSIWPOWER);
1109 if(!strcasecmp(args[i], "off"))
1110 wrq.u.power.disabled = 1; /* i.e. max size */
1112 if(!strcasecmp(args[i], "on"))
1114 /* Get old Power info */
1115 IW_GET_EXT_ERR(skfd, ifname, SIOCGIWPOWER, &wrq,
1116 "Set Power Management");
1117 wrq.u.power.disabled = 0;
1123 /* Default - nope */
1124 wrq.u.power.flags = IW_POWER_ON;
1125 wrq.u.power.disabled = 0;
1127 /* Check value modifier */
1128 if(!strcasecmp(args[i], "min"))
1130 wrq.u.power.flags |= IW_POWER_MIN;
1132 ABORT_ARG_NUM("Set Power Management", SIOCSIWPOWER);
1135 if(!strcasecmp(args[i], "max"))
1137 wrq.u.power.flags |= IW_POWER_MAX;
1139 ABORT_ARG_NUM("Set Power Management", SIOCSIWPOWER);
1142 /* Check value type */
1143 if(!strcasecmp(args[i], "period"))
1145 wrq.u.power.flags |= IW_POWER_PERIOD;
1147 ABORT_ARG_NUM("Set Power Management", SIOCSIWPOWER);
1150 if(!strcasecmp(args[i], "timeout"))
1152 wrq.u.power.flags |= IW_POWER_TIMEOUT;
1154 ABORT_ARG_NUM("Set Power Management", SIOCSIWPOWER);
1157 /* Is there any value to grab ? */
1158 if(sscanf(args[i], "%lg", &(temp)) == 1)
1160 temp *= MEGA; /* default = s */
1161 if(index(args[i], 'u')) temp /= MEGA;
1162 if(index(args[i], 'm')) temp /= KILO;
1163 wrq.u.power.value = (long) temp;
1164 if((wrq.u.power.flags & IW_POWER_TYPE) == 0)
1165 wrq.u.power.flags |= IW_POWER_PERIOD;
1170 /* Now, check the mode */
1173 if(!strcasecmp(args[i], "all"))
1174 wrq.u.power.flags |= IW_POWER_ALL_R;
1175 if(!strncasecmp(args[i], "unicast", 4))
1176 wrq.u.power.flags |= IW_POWER_UNICAST_R;
1177 if(!strncasecmp(args[i], "multicast", 5))
1178 wrq.u.power.flags |= IW_POWER_MULTICAST_R;
1179 if(!strncasecmp(args[i], "force", 5))
1180 wrq.u.power.flags |= IW_POWER_FORCE_S;
1181 if(!strcasecmp(args[i], "repeat"))
1182 wrq.u.power.flags |= IW_POWER_REPEATER;
1183 if(wrq.u.power.flags & IW_POWER_MODE)
1190 ABORT_ARG_TYPE("Set Power Management", SIOCSIWPOWER,
1195 IW_SET_EXT_ERR(skfd, ifname, SIOCSIWPOWER, &wrq,
1196 "Set Power Management");
1200 #if WIRELESS_EXT > 9
1201 /* ---------- Set Transmit-Power ---------- */
1202 if(!strncmp(args[i], "txpower", 3))
1204 struct iw_range range;
1207 ABORT_ARG_NUM("Set Tx Power", SIOCSIWTXPOW);
1209 /* Extract range info */
1210 if(iw_get_range_info(skfd, ifname, &range) < 0)
1211 memset(&range, 0, sizeof(range));
1213 /* Prepare the request */
1214 wrq.u.txpower.value = -1;
1215 wrq.u.txpower.fixed = 1;
1216 wrq.u.txpower.disabled = 0;
1217 wrq.u.data.flags = IW_TXPOW_DBM;
1218 if(!strcasecmp(args[i], "off"))
1219 wrq.u.txpower.disabled = 1; /* i.e. turn radio off */
1221 if(!strcasecmp(args[i], "auto"))
1222 wrq.u.txpower.fixed = 0; /* i.e. use power control */
1225 if(!strcasecmp(args[i], "fixed"))
1227 /* Get old tx-power */
1228 IW_GET_EXT_ERR(skfd, ifname, SIOCGIWTXPOW, &wrq,
1230 wrq.u.txpower.fixed = 1;
1232 else /* Should be a numeric value */
1238 if(sscanf(args[i], "%ld",
1239 (unsigned long *) &(power)) != 1)
1240 ABORT_ARG_TYPE("Set Tx Power", SIOCSIWTXPOW, args[i]);
1242 /* Check if milliwatt */
1243 ismwatt = (index(args[i], 'm') != NULL);
1246 if(!ismwatt && (range.txpower_capa & IW_TXPOW_MWATT))
1248 power = iw_dbm2mwatt(power);
1249 wrq.u.data.flags = IW_TXPOW_MWATT;
1251 if(ismwatt && !(range.txpower_capa & IW_TXPOW_MWATT))
1252 power = iw_mwatt2dbm(power);
1253 wrq.u.bitrate.value = power;
1255 /* Check for an additional argument */
1256 if(((i+1) < count) &&
1257 (!strcasecmp(args[i+1], "auto")))
1259 wrq.u.txpower.fixed = 0;
1262 if(((i+1) < count) &&
1263 (!strcasecmp(args[i+1], "fixed")))
1265 wrq.u.txpower.fixed = 1;
1271 IW_SET_EXT_ERR(skfd, ifname, SIOCSIWTXPOW, &wrq,
1277 #if WIRELESS_EXT > 10
1278 /* ---------- Set Retry limit ---------- */
1279 if(!strncmp(args[i], "retry", 3))
1285 ABORT_ARG_NUM("Set Retry Limit", SIOCSIWRETRY);
1287 /* Default - nope */
1288 wrq.u.retry.flags = IW_RETRY_LIMIT;
1289 wrq.u.retry.disabled = 0;
1291 /* Check value modifier */
1292 if(!strcasecmp(args[i], "min"))
1294 wrq.u.retry.flags |= IW_RETRY_MIN;
1296 ABORT_ARG_NUM("Set Retry Limit", SIOCSIWRETRY);
1299 if(!strcasecmp(args[i], "max"))
1301 wrq.u.retry.flags |= IW_RETRY_MAX;
1303 ABORT_ARG_NUM("Set Retry Limit", SIOCSIWRETRY);
1306 /* Check value type */
1307 if(!strcasecmp(args[i], "limit"))
1309 wrq.u.retry.flags |= IW_RETRY_LIMIT;
1311 ABORT_ARG_NUM("Set Retry Limit", SIOCSIWRETRY);
1314 if(!strncasecmp(args[i], "lifetime", 4))
1316 wrq.u.retry.flags |= IW_RETRY_LIFETIME;
1318 ABORT_ARG_NUM("Set Retry Limit", SIOCSIWRETRY);
1321 /* Is there any value to grab ? */
1322 if(sscanf(args[i], "%lg", &(temp)) == 1)
1324 /* Limit is absolute, on the other hand lifetime is seconds */
1325 if(!(wrq.u.retry.flags & IW_RETRY_LIMIT))
1327 /* Normalise lifetime */
1328 temp *= MEGA; /* default = s */
1329 if(index(args[i], 'u')) temp /= MEGA;
1330 if(index(args[i], 'm')) temp /= KILO;
1332 wrq.u.retry.value = (long) temp;
1338 ABORT_ARG_TYPE("Set Retry Limit", SIOCSIWRETRY, args[i]);
1341 IW_SET_EXT_ERR(skfd, ifname, SIOCSIWRETRY, &wrq,
1346 #endif /* WIRELESS_EXT > 10 */
1348 /* ---------- Other ---------- */
1349 /* Here we have an unrecognised arg... */
1350 fprintf(stderr, "Error : unrecognised wireless request \"%s\"\n",
1353 } /* for(index ... */
1357 /******************************* MAIN ********************************/
1359 /*------------------------------------------------------------------*/
1367 int skfd = -1; /* generic raw socket desc. */
1370 /* Create a channel to the NET kernel. */
1371 if((skfd = iw_sockets_open()) < 0)
1377 /* No argument : show the list of all device + info */
1380 print_devices(skfd);
1385 /* Special case for help... */
1386 if((!strncmp(argv[1], "-h", 9)) ||
1387 (!strcmp(argv[1], "--help")))
1394 /* The device name must be the first argument */
1397 print_info(skfd, argv[1]);
1402 /* The other args on the line specify options to be set... */
1403 goterr = set_info(skfd, argv + 2, argc - 2, argv[1]);
1405 /* Close the socket. */