4 * Jean II - HPLB 97->99 - HPL 99->04
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-2004 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, " [mode {managed|ad-hoc|...}\n");
28 fprintf(stderr, " [freq N.NNNN[k|M|G]]\n");
29 fprintf(stderr, " [channel N]\n");
30 fprintf(stderr, " [ap {N|off|auto}]\n");
31 fprintf(stderr, " [sens N]\n");
32 fprintf(stderr, " [nick N]\n");
33 fprintf(stderr, " [rate {N|auto|fixed}]\n");
34 fprintf(stderr, " [rts {N|auto|fixed|off}]\n");
35 fprintf(stderr, " [frag {N|auto|fixed|off}]\n");
36 fprintf(stderr, " [enc {NNNN-NNNN|off}]\n");
37 fprintf(stderr, " [power {period N|timeout N}]\n");
38 fprintf(stderr, " [txpower N {mW|dBm}]\n");
39 fprintf(stderr, " [commit]\n");
40 fprintf(stderr, " Check man pages for more details.\n\n");
44 /************************* DISPLAY ROUTINES **************************/
46 /*------------------------------------------------------------------*/
48 * Get wireless informations & config from the device driver
49 * We will call all the classical wireless ioctl on the driver through
50 * the socket to know what is supported and to get the settings...
55 struct wireless_info * info)
59 memset((char *) info, 0, sizeof(struct wireless_info));
61 /* Get basic information */
62 if(iw_get_basic_config(skfd, ifname, &(info->b)) < 0)
64 /* If no wireless name : no wireless extensions */
65 /* But let's check if the interface exists at all */
68 strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
69 if(ioctl(skfd, SIOCGIFFLAGS, &ifr) < 0)
76 if(iw_get_range_info(skfd, ifname, &(info->range)) >= 0)
80 if(iw_get_ext(skfd, ifname, SIOCGIWSENS, &wrq) >= 0)
83 memcpy(&(info->sens), &(wrq.u.sens), sizeof(iwparam));
87 if(iw_get_ext(skfd, ifname, SIOCGIWAP, &wrq) >= 0)
89 info->has_ap_addr = 1;
90 memcpy(&(info->ap_addr), &(wrq.u.ap_addr), sizeof (sockaddr));
94 wrq.u.essid.pointer = (caddr_t) info->nickname;
95 wrq.u.essid.length = IW_ESSID_MAX_SIZE + 1;
96 wrq.u.essid.flags = 0;
97 if(iw_get_ext(skfd, ifname, SIOCGIWNICKN, &wrq) >= 0)
98 if(wrq.u.data.length > 1)
99 info->has_nickname = 1;
102 if(iw_get_ext(skfd, ifname, SIOCGIWRATE, &wrq) >= 0)
104 info->has_bitrate = 1;
105 memcpy(&(info->bitrate), &(wrq.u.bitrate), sizeof(iwparam));
108 /* Get RTS threshold */
109 if(iw_get_ext(skfd, ifname, SIOCGIWRTS, &wrq) >= 0)
112 memcpy(&(info->rts), &(wrq.u.rts), sizeof(iwparam));
115 /* Get fragmentation threshold */
116 if(iw_get_ext(skfd, ifname, SIOCGIWFRAG, &wrq) >= 0)
119 memcpy(&(info->frag), &(wrq.u.frag), sizeof(iwparam));
122 /* Get Power Management settings */
123 wrq.u.power.flags = 0;
124 if(iw_get_ext(skfd, ifname, SIOCGIWPOWER, &wrq) >= 0)
127 memcpy(&(info->power), &(wrq.u.power), sizeof(iwparam));
130 if((info->has_range) && (info->range.we_version_compiled > 9))
132 /* Get Transmit Power */
133 if(iw_get_ext(skfd, ifname, SIOCGIWTXPOW, &wrq) >= 0)
135 info->has_txpower = 1;
136 memcpy(&(info->txpower), &(wrq.u.txpower), sizeof(iwparam));
140 if((info->has_range) && (info->range.we_version_compiled > 10))
142 /* Get retry limit/lifetime */
143 if(iw_get_ext(skfd, ifname, SIOCGIWRETRY, &wrq) >= 0)
146 memcpy(&(info->retry), &(wrq.u.retry), sizeof(iwparam));
151 if(iw_get_stats(skfd, ifname, &(info->stats),
152 &info->range, info->has_range) >= 0)
160 /*------------------------------------------------------------------*/
162 * Print on the screen in a neat fashion all the info we have collected
166 display_info(struct wireless_info * info,
169 char buffer[128]; /* Temporary buffer */
171 /* One token is more of less 5 characters, 14 tokens per line */
172 int tokens = 3; /* For name */
174 /* Display device name and wireless name (name of the protocol used) */
175 printf("%-8.16s %s ", ifname, info->b.name);
177 /* Display ESSID (extended network), if any */
178 if(info->b.has_essid)
182 /* Does it have an ESSID index ? */
183 if((info->b.essid_on & IW_ENCODE_INDEX) > 1)
184 printf("ESSID:\"%s\" [%d] ", info->b.essid,
185 (info->b.essid_on & IW_ENCODE_INDEX));
187 printf("ESSID:\"%s\" ", info->b.essid);
190 printf("ESSID:off/any ");
193 /* Display NickName (station name), if any */
194 if(info->has_nickname)
195 printf("Nickname:\"%s\"", info->nickname);
198 if(info->b.has_essid || info->has_nickname)
204 /* Display Network ID */
207 /* Note : should display proper number of digit according to info
208 * in range structure */
209 if(info->b.nwid.disabled)
210 printf("NWID:off/any ");
212 printf("NWID:%X ", info->b.nwid.value);
216 /* Display the current mode of operation */
219 printf("Mode:%s ", iw_operation_mode[info->b.mode]);
223 /* Display frequency / channel */
226 double freq = info->b.freq; /* Frequency/channel */
227 int channel = -1; /* Converted to channel */
228 /* Some driver insist of returning channel instead of frequency.
229 * This fixes them up. Note that, driver should still return
230 * frequency, because other tools depend on it. */
231 if(info->has_range && (freq < KILO))
232 channel = iw_channel_to_freq((int) freq, &freq, &info->range);
234 iw_print_freq(buffer, sizeof(buffer), freq, -1, info->b.freq_flags);
235 printf("%s ", buffer);
239 /* Display the address of the current Access Point */
240 if(info->has_ap_addr)
242 /* A bit of clever formatting */
250 /* Oups ! No Access Point in Ad-Hoc mode */
251 if((info->b.has_mode) && (info->b.mode == IW_MODE_ADHOC))
254 printf("Access Point:");
255 printf(" %s ", iw_pr_ether(buffer, info->ap_addr.sa_data));
258 /* Display the currently used/set bit-rate */
259 if(info->has_bitrate)
261 /* A bit of clever formatting */
270 iw_print_bitrate(buffer, sizeof(buffer), info->bitrate.value);
271 printf("Bit Rate%c%s ", (info->bitrate.fixed ? '=' : ':'), buffer);
274 /* Display the Transmit Power */
275 if(info->has_txpower)
277 /* A bit of clever formatting */
286 iw_print_txpower(buffer, sizeof(buffer), &info->txpower);
287 printf("Tx-Power%c%s ", (info->txpower.fixed ? '=' : ':'), buffer);
290 /* Display sensitivity */
293 /* A bit of clever formatting */
303 printf("Sensitivity=");
305 printf("Sensitivity:");
308 /* Display in dBm ? */
309 if(info->sens.value < 0)
310 printf("%d dBm ", info->sens.value);
312 printf("%d/%d ", info->sens.value, info->range.sensitivity);
314 printf("%d ", info->sens.value);
320 /* Display retry limit/lifetime information */
325 if(info->retry.disabled)
329 /* Let's check the value and its type */
330 if(info->retry.flags & IW_RETRY_TYPE)
332 iw_print_retry_value(buffer, sizeof(buffer),
333 info->retry.value, info->retry.flags);
334 printf("%s", buffer);
337 /* Let's check if nothing (simply on) */
338 if(info->retry.flags == IW_RETRY_ON)
342 tokens += 5; /* Between 3 and 5, depend on flags */
345 /* Display the RTS threshold */
349 if(info->rts.disabled)
350 printf("RTS thr:off ");
359 printf("%d B ", info->rts.value);
364 /* Display the fragmentation threshold */
367 /* A bit of clever formatting */
376 if(info->frag.disabled)
377 printf("Fragment thr:off");
382 printf("Fragment thr=");
384 printf("Fragment thr:");
386 printf("%d B ", info->frag.value);
394 /* Display encryption information */
395 /* Note : we display only the "current" key, use iwlist to list all keys */
398 printf("Encryption key:");
399 if((info->b.key_flags & IW_ENCODE_DISABLED) || (info->b.key_size == 0))
403 /* Display the key */
404 iw_print_key(buffer, sizeof(buffer),
405 info->b.key, info->b.key_size, info->b.key_flags);
406 printf("%s", buffer);
409 if((info->b.key_flags & IW_ENCODE_INDEX) > 1)
410 printf(" [%d]", info->b.key_flags & IW_ENCODE_INDEX);
411 if(info->b.key_flags & IW_ENCODE_RESTRICTED)
412 printf(" Security mode:restricted");
413 if(info->b.key_flags & IW_ENCODE_OPEN)
414 printf(" Security mode:open");
419 /* Display Power Management information */
420 /* Note : we display only one parameter, period or timeout. If a device
421 * (such as HiperLan) has both, the user need to use iwlist... */
422 if(info->has_power) /* I hope the device has power ;-) */
424 printf("Power Management");
426 if(info->power.disabled)
430 /* Let's check the value and its type */
431 if(info->power.flags & IW_POWER_TYPE)
433 iw_print_pm_value(buffer, sizeof(buffer),
434 info->power.value, info->power.flags);
435 printf("%s ", buffer);
438 /* Let's check the mode */
439 iw_print_pm_mode(buffer, sizeof(buffer), info->power.flags);
440 printf("%s", buffer);
442 /* Let's check if nothing (simply on) */
443 if(info->power.flags == IW_POWER_ON)
449 /* Display statistics */
452 iw_print_stats(buffer, sizeof(buffer),
453 &info->stats.qual, &info->range, info->has_range);
454 printf("Link %s\n", buffer);
456 if(info->range.we_version_compiled > 11)
457 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",
458 info->stats.discard.nwid,
459 info->stats.discard.code,
460 info->stats.discard.fragment,
461 info->stats.discard.retries,
462 info->stats.discard.misc,
463 info->stats.miss.beacon);
465 printf(" Rx invalid nwid:%d invalid crypt:%d invalid misc:%d\n",
466 info->stats.discard.nwid,
467 info->stats.discard.code,
468 info->stats.discard.misc);
474 /*------------------------------------------------------------------*/
476 * Print on the screen in a neat fashion all the info we have collected
485 struct wireless_info info;
488 /* Avoid "Unused parameter" warning */
489 args = args; count = count;
491 rc = get_info(skfd, ifname, &info);
494 case 0: /* Success */
496 display_info(&info, ifname);
500 fprintf(stderr, "%-8.16s no wireless extensions.\n\n",
505 fprintf(stderr, "%-8.16s %s\n\n", ifname, strerror(-rc));
510 /************************* SETTING ROUTINES **************************/
512 /*------------------------------------------------------------------*/
514 * Macro to handle errors when setting WE
515 * Print a nice error message and exit...
516 * We define them as macro so that "return" do the right thing.
517 * The "do {...} while(0)" is a standard trick
519 #define ERR_SET_EXT(rname, request) \
520 fprintf(stderr, "Error for wireless request \"%s\" (%X) :\n", \
523 #define ABORT_ARG_NUM(rname, request) \
525 ERR_SET_EXT(rname, request); \
526 fprintf(stderr, " too few arguments.\n"); \
530 #define ABORT_ARG_TYPE(rname, request, arg) \
532 ERR_SET_EXT(rname, request); \
533 fprintf(stderr, " invalid argument \"%s\".\n", arg); \
537 #define ABORT_ARG_SIZE(rname, request, max) \
539 ERR_SET_EXT(rname, request); \
540 fprintf(stderr, " argument too big (max %d)\n", max); \
544 /*------------------------------------------------------------------*/
546 * Wrapper to push some Wireless Parameter in the driver
547 * Use standard wrapper and add pretty error message if fail...
549 #define IW_SET_EXT_ERR(skfd, ifname, request, wrq, rname) \
551 if(iw_set_ext(skfd, ifname, request, wrq) < 0) { \
552 ERR_SET_EXT(rname, request); \
553 fprintf(stderr, " SET failed on device %-1.16s ; %s.\n", \
554 ifname, strerror(errno)); \
558 /*------------------------------------------------------------------*/
560 * Wrapper to extract some Wireless Parameter out of the driver
561 * Use standard wrapper and add pretty error message if fail...
563 #define IW_GET_EXT_ERR(skfd, ifname, request, wrq, rname) \
565 if(iw_get_ext(skfd, ifname, request, wrq) < 0) { \
566 ERR_SET_EXT(rname, request); \
567 fprintf(stderr, " GET failed on device %-1.16s ; %s.\n", \
568 ifname, strerror(errno)); \
572 /*------------------------------------------------------------------*/
574 * Set the wireless options requested on command line
575 * This function is too long and probably should be split,
576 * because it look like the perfect definition of spaghetti code,
577 * but I'm way to lazy
580 set_info(int skfd, /* The socket */
581 char * args[], /* Command line args */
582 int count, /* Args count */
583 char * ifname) /* Dev name */
588 /* if nothing after the device name - will never happen */
591 fprintf(stderr, "Error : too few arguments.\n");
595 /* The other args on the line specify options to be set... */
596 for(i = 0; i < count; i++)
598 /* ---------- Commit changes to driver ---------- */
599 if(!strncmp(args[i], "commit", 6))
602 IW_SET_EXT_ERR(skfd, ifname, SIOCSIWCOMMIT, &wrq,
607 /* ---------- Set network ID ---------- */
608 if((!strcasecmp(args[i], "nwid")) ||
609 (!strcasecmp(args[i], "domain")))
613 ABORT_ARG_NUM("Set NWID", SIOCSIWNWID);
614 if((!strcasecmp(args[i], "off")) ||
615 (!strcasecmp(args[i], "any")))
616 wrq.u.nwid.disabled = 1;
618 if(!strcasecmp(args[i], "on"))
621 IW_GET_EXT_ERR(skfd, ifname, SIOCGIWNWID, &wrq,
623 wrq.u.nwid.disabled = 0;
626 if(sscanf(args[i], "%lX", (unsigned long *) &(wrq.u.nwid.value))
628 ABORT_ARG_TYPE("Set NWID", SIOCSIWNWID, args[i]);
630 wrq.u.nwid.disabled = 0;
631 wrq.u.nwid.fixed = 1;
634 IW_SET_EXT_ERR(skfd, ifname, SIOCSIWNWID, &wrq,
639 /* ---------- Set frequency / channel ---------- */
640 if((!strncmp(args[i], "freq", 4)) ||
641 (!strcmp(args[i], "channel")))
646 ABORT_ARG_NUM("Set Frequency", SIOCSIWFREQ);
647 if(!strcasecmp(args[i], "auto"))
651 wrq.u.freq.flags = 0;
655 if(!strcasecmp(args[i], "fixed"))
657 /* Get old bitrate */
658 IW_GET_EXT_ERR(skfd, ifname, SIOCGIWFREQ, &wrq,
660 wrq.u.freq.flags = IW_FREQ_FIXED;
662 else /* Should be a numeric value */
664 if(sscanf(args[i], "%lg", &(freq)) != 1)
665 ABORT_ARG_TYPE("Set Frequency", SIOCSIWFREQ, args[i]);
666 if(index(args[i], 'G')) freq *= GIGA;
667 if(index(args[i], 'M')) freq *= MEGA;
668 if(index(args[i], 'k')) freq *= KILO;
670 iw_float2freq(freq, &(wrq.u.freq));
672 wrq.u.freq.flags = IW_FREQ_FIXED;
674 /* Check for an additional argument */
675 if(((i+1) < count) &&
676 (!strcasecmp(args[i+1], "auto")))
678 wrq.u.freq.flags = 0;
681 if(((i+1) < count) &&
682 (!strcasecmp(args[i+1], "fixed")))
684 wrq.u.freq.flags = IW_FREQ_FIXED;
690 IW_SET_EXT_ERR(skfd, ifname, SIOCSIWFREQ, &wrq,
695 /* ---------- Set sensitivity ---------- */
696 if(!strncmp(args[i], "sens", 4))
699 ABORT_ARG_NUM("Set Sensitivity", SIOCSIWSENS);
700 if(sscanf(args[i], "%i", &(wrq.u.sens.value)) != 1)
701 ABORT_ARG_TYPE("Set Sensitivity", SIOCSIWSENS, args[i]);
703 IW_SET_EXT_ERR(skfd, ifname, SIOCSIWSENS, &wrq,
708 /* ---------- Set encryption stuff ---------- */
709 if((!strncmp(args[i], "enc", 3)) ||
710 (!strcmp(args[i], "key")))
712 unsigned char key[IW_ENCODING_TOKEN_MAX];
715 ABORT_ARG_NUM("Set Encode", SIOCSIWENCODE);
717 if(!strcasecmp(args[i], "on"))
719 /* Get old encryption information */
720 wrq.u.data.pointer = (caddr_t) key;
721 wrq.u.data.length = IW_ENCODING_TOKEN_MAX;
722 wrq.u.data.flags = 0;
723 IW_GET_EXT_ERR(skfd, ifname, SIOCGIWENCODE, &wrq,
725 wrq.u.data.flags &= ~IW_ENCODE_DISABLED; /* Enable */
734 wrq.u.data.pointer = (caddr_t) NULL;
735 wrq.u.data.flags = 0;
736 wrq.u.data.length = 0;
738 /* Allow arguments in any order (it's safe) */
743 /* -- Check for the key -- */
746 keylen = iw_in_key_full(skfd, ifname,
747 args[i], key, &wrq.u.data.flags);
750 wrq.u.data.length = keylen;
751 wrq.u.data.pointer = (caddr_t) key;
757 /* -- Check for token index -- */
759 (sscanf(args[i], "[%i]", &temp) == 1) &&
760 (temp > 0) && (temp < IW_ENCODE_INDEX))
762 wrq.u.encoding.flags |= temp;
767 /* -- Check the various flags -- */
768 if((i < count) && (!strcasecmp(args[i], "off")))
770 wrq.u.data.flags |= IW_ENCODE_DISABLED;
774 if((i < count) && (!strcasecmp(args[i], "open")))
776 wrq.u.data.flags |= IW_ENCODE_OPEN;
780 if((i < count) && (!strncasecmp(args[i], "restricted", 5)))
782 wrq.u.data.flags |= IW_ENCODE_RESTRICTED;
786 if((i < count) && (!strncasecmp(args[i], "temporary", 4)))
788 wrq.u.data.flags |= IW_ENCODE_TEMP;
793 while(gotone != oldone);
795 /* Pointer is absent in new API */
796 if(wrq.u.data.pointer == NULL)
797 wrq.u.data.flags |= IW_ENCODE_NOKEY;
799 /* Check if we have any invalid argument */
801 ABORT_ARG_TYPE("Set Encode", SIOCSIWENCODE, args[i]);
802 /* Get back to last processed argument */
806 IW_SET_EXT_ERR(skfd, ifname, SIOCSIWENCODE, &wrq,
811 /* ---------- Set ESSID ---------- */
812 if(!strcasecmp(args[i], "essid"))
814 char essid[IW_ESSID_MAX_SIZE + 1];
818 ABORT_ARG_NUM("Set ESSID", SIOCSIWESSID);
819 if((!strcasecmp(args[i], "off")) ||
820 (!strcasecmp(args[i], "any")))
822 wrq.u.essid.flags = 0;
826 if(!strcasecmp(args[i], "on"))
829 wrq.u.essid.pointer = (caddr_t) essid;
830 wrq.u.essid.length = IW_ESSID_MAX_SIZE + 1;
831 wrq.u.essid.flags = 0;
832 IW_GET_EXT_ERR(skfd, ifname, SIOCGIWESSID, &wrq,
834 wrq.u.essid.flags = 1;
838 /* '-' allow to escape the ESSID string, allowing
839 * to set it to the string "any" or "off".
840 * This is a big ugly, but it will do for now */
841 if(!strcmp(args[i], "-"))
845 ABORT_ARG_NUM("Set ESSID", SIOCSIWESSID);
848 /* Check the size of what the user passed us to avoid
849 * buffer overflows */
850 if(strlen(args[i]) > IW_ESSID_MAX_SIZE)
851 ABORT_ARG_SIZE("Set ESSID", SIOCSIWESSID, IW_ESSID_MAX_SIZE);
856 wrq.u.essid.flags = 1;
857 strcpy(essid, args[i]); /* Size checked, all clear */
859 /* Check for ESSID index */
860 if(((i+1) < count) &&
861 (sscanf(args[i+1], "[%i]", &temp) == 1) &&
862 (temp > 0) && (temp < IW_ENCODE_INDEX))
864 wrq.u.essid.flags = temp;
870 wrq.u.essid.pointer = (caddr_t) essid;
871 wrq.u.essid.length = strlen(essid) + 1;
872 IW_SET_EXT_ERR(skfd, ifname, SIOCSIWESSID, &wrq,
877 /* ---------- Set AP address ---------- */
878 if(!strcasecmp(args[i], "ap"))
881 ABORT_ARG_NUM("Set AP Address", SIOCSIWAP);
883 if((!strcasecmp(args[i], "auto")) ||
884 (!strcasecmp(args[i], "any")))
886 /* Send a broadcast address */
887 iw_broad_ether(&(wrq.u.ap_addr));
891 if(!strcasecmp(args[i], "off"))
893 /* Send a NULL address */
894 iw_null_ether(&(wrq.u.ap_addr));
898 /* Get the address and check if the interface supports it */
899 if(iw_in_addr(skfd, ifname, args[i++], &(wrq.u.ap_addr)) < 0)
900 ABORT_ARG_TYPE("Set AP Address", SIOCSIWAP, args[i-1]);
904 IW_SET_EXT_ERR(skfd, ifname, SIOCSIWAP, &wrq,
909 /* ---------- Set NickName ---------- */
910 if(!strncmp(args[i], "nick", 4))
914 ABORT_ARG_NUM("Set Nickname", SIOCSIWNICKN);
915 if(strlen(args[i]) > IW_ESSID_MAX_SIZE)
916 ABORT_ARG_SIZE("Set Nickname", SIOCSIWNICKN, IW_ESSID_MAX_SIZE);
918 wrq.u.essid.pointer = (caddr_t) args[i];
919 wrq.u.essid.length = strlen(args[i]) + 1;
920 IW_SET_EXT_ERR(skfd, ifname, SIOCSIWNICKN, &wrq,
925 /* ---------- Set Bit-Rate ---------- */
926 if((!strncmp(args[i], "bit", 3)) ||
927 (!strcmp(args[i], "rate")))
930 ABORT_ARG_NUM("Set Bit Rate", SIOCSIWRATE);
931 if(!strcasecmp(args[i], "auto"))
933 wrq.u.bitrate.value = -1;
934 wrq.u.bitrate.fixed = 0;
938 if(!strcasecmp(args[i], "fixed"))
940 /* Get old bitrate */
941 IW_GET_EXT_ERR(skfd, ifname, SIOCGIWRATE, &wrq,
943 wrq.u.bitrate.fixed = 1;
945 else /* Should be a numeric value */
949 if(sscanf(args[i], "%lg", &(brate)) != 1)
950 ABORT_ARG_TYPE("Set Bit Rate", SIOCSIWRATE, args[i]);
951 if(index(args[i], 'G')) brate *= GIGA;
952 if(index(args[i], 'M')) brate *= MEGA;
953 if(index(args[i], 'k')) brate *= KILO;
954 wrq.u.bitrate.value = (long) brate;
955 wrq.u.bitrate.fixed = 1;
957 /* Check for an additional argument */
958 if(((i+1) < count) &&
959 (!strcasecmp(args[i+1], "auto")))
961 wrq.u.bitrate.fixed = 0;
964 if(((i+1) < count) &&
965 (!strcasecmp(args[i+1], "fixed")))
967 wrq.u.bitrate.fixed = 1;
973 IW_SET_EXT_ERR(skfd, ifname, SIOCSIWRATE, &wrq,
978 /* ---------- Set RTS threshold ---------- */
979 if(!strncasecmp(args[i], "rts", 3))
983 ABORT_ARG_NUM("Set RTS Threshold", SIOCSIWRTS);
984 wrq.u.rts.value = -1;
986 wrq.u.rts.disabled = 0;
987 if(!strcasecmp(args[i], "off"))
988 wrq.u.rts.disabled = 1; /* i.e. max size */
990 if(!strcasecmp(args[i], "auto"))
994 if(!strcasecmp(args[i], "fixed"))
996 /* Get old RTS threshold */
997 IW_GET_EXT_ERR(skfd, ifname, SIOCGIWRTS, &wrq,
998 "Set RTS Threshold");
1001 else /* Should be a numeric value */
1002 if(sscanf(args[i], "%li", (unsigned long *) &(wrq.u.rts.value))
1004 ABORT_ARG_TYPE("Set RTS Threshold", SIOCSIWRTS, args[i]);
1007 IW_SET_EXT_ERR(skfd, ifname, SIOCSIWRTS, &wrq,
1008 "Set RTS Threshold");
1012 /* ---------- Set fragmentation threshold ---------- */
1013 if(!strncmp(args[i], "frag", 4))
1017 ABORT_ARG_NUM("Set Fragmentation Threshold", SIOCSIWFRAG);
1018 wrq.u.frag.value = -1;
1019 wrq.u.frag.fixed = 1;
1020 wrq.u.frag.disabled = 0;
1021 if(!strcasecmp(args[i], "off"))
1022 wrq.u.frag.disabled = 1; /* i.e. max size */
1024 if(!strcasecmp(args[i], "auto"))
1025 wrq.u.frag.fixed = 0;
1028 if(!strcasecmp(args[i], "fixed"))
1030 /* Get old fragmentation threshold */
1031 IW_GET_EXT_ERR(skfd, ifname, SIOCGIWFRAG, &wrq,
1032 "Set Fragmentation Threshold");
1033 wrq.u.frag.fixed = 1;
1035 else /* Should be a numeric value */
1036 if(sscanf(args[i], "%li",
1037 (unsigned long *) &(wrq.u.frag.value))
1039 ABORT_ARG_TYPE("Set Fragmentation Threshold", SIOCSIWFRAG,
1043 IW_SET_EXT_ERR(skfd, ifname, SIOCSIWFRAG, &wrq,
1044 "Set Fragmentation Threshold");
1048 /* ---------- Set operation mode ---------- */
1049 if(!strcmp(args[i], "mode"))
1055 ABORT_ARG_NUM("Set Mode", SIOCSIWMODE);
1057 if(sscanf(args[i], "%i", &k) != 1)
1060 while((k < IW_NUM_OPER_MODE) &&
1061 strncasecmp(args[i], iw_operation_mode[k], 3))
1064 if((k >= IW_NUM_OPER_MODE) || (k < 0))
1065 ABORT_ARG_TYPE("Set Mode", SIOCSIWMODE, args[i]);
1068 IW_SET_EXT_ERR(skfd, ifname, SIOCSIWMODE, &wrq,
1073 /* ---------- Set Power Management ---------- */
1074 if(!strncmp(args[i], "power", 3))
1077 ABORT_ARG_NUM("Set Power Management", SIOCSIWPOWER);
1079 if(!strcasecmp(args[i], "off"))
1080 wrq.u.power.disabled = 1; /* i.e. max size */
1082 if(!strcasecmp(args[i], "on"))
1084 /* Get old Power info */
1085 IW_GET_EXT_ERR(skfd, ifname, SIOCGIWPOWER, &wrq,
1086 "Set Power Management");
1087 wrq.u.power.disabled = 0;
1093 /* Default - nope */
1094 wrq.u.power.flags = IW_POWER_ON;
1095 wrq.u.power.disabled = 0;
1097 /* Check value modifier */
1098 if(!strcasecmp(args[i], "min"))
1100 wrq.u.power.flags |= IW_POWER_MIN;
1102 ABORT_ARG_NUM("Set Power Management", SIOCSIWPOWER);
1105 if(!strcasecmp(args[i], "max"))
1107 wrq.u.power.flags |= IW_POWER_MAX;
1109 ABORT_ARG_NUM("Set Power Management", SIOCSIWPOWER);
1112 /* Check value type */
1113 if(!strcasecmp(args[i], "period"))
1115 wrq.u.power.flags |= IW_POWER_PERIOD;
1117 ABORT_ARG_NUM("Set Power Management", SIOCSIWPOWER);
1120 if(!strcasecmp(args[i], "timeout"))
1122 wrq.u.power.flags |= IW_POWER_TIMEOUT;
1124 ABORT_ARG_NUM("Set Power Management", SIOCSIWPOWER);
1127 /* Is there any value to grab ? */
1128 if(sscanf(args[i], "%lg", &(temp)) == 1)
1130 temp *= MEGA; /* default = s */
1131 if(index(args[i], 'u')) temp /= MEGA;
1132 if(index(args[i], 'm')) temp /= KILO;
1133 wrq.u.power.value = (long) temp;
1134 if((wrq.u.power.flags & IW_POWER_TYPE) == 0)
1135 wrq.u.power.flags |= IW_POWER_PERIOD;
1140 /* Now, check the mode */
1143 if(!strcasecmp(args[i], "all"))
1144 wrq.u.power.flags |= IW_POWER_ALL_R;
1145 if(!strncasecmp(args[i], "unicast", 4))
1146 wrq.u.power.flags |= IW_POWER_UNICAST_R;
1147 if(!strncasecmp(args[i], "multicast", 5))
1148 wrq.u.power.flags |= IW_POWER_MULTICAST_R;
1149 if(!strncasecmp(args[i], "force", 5))
1150 wrq.u.power.flags |= IW_POWER_FORCE_S;
1151 if(!strcasecmp(args[i], "repeat"))
1152 wrq.u.power.flags |= IW_POWER_REPEATER;
1153 if(wrq.u.power.flags & IW_POWER_MODE)
1160 ABORT_ARG_TYPE("Set Power Management", SIOCSIWPOWER,
1165 IW_SET_EXT_ERR(skfd, ifname, SIOCSIWPOWER, &wrq,
1166 "Set Power Management");
1170 /* ---------- Set Transmit-Power ---------- */
1171 if(!strncmp(args[i], "txpower", 3))
1173 struct iw_range range;
1176 ABORT_ARG_NUM("Set Tx Power", SIOCSIWTXPOW);
1178 /* Extract range info */
1179 if(iw_get_range_info(skfd, ifname, &range) < 0)
1180 memset(&range, 0, sizeof(range));
1182 /* Prepare the request */
1183 wrq.u.txpower.value = -1;
1184 wrq.u.txpower.fixed = 1;
1185 wrq.u.txpower.disabled = 0;
1186 wrq.u.txpower.flags = IW_TXPOW_DBM;
1187 if(!strcasecmp(args[i], "off"))
1188 wrq.u.txpower.disabled = 1; /* i.e. turn radio off */
1190 if(!strcasecmp(args[i], "auto"))
1191 wrq.u.txpower.fixed = 0; /* i.e. use power control */
1194 if(!strcasecmp(args[i], "on"))
1196 /* Get old tx-power */
1197 IW_GET_EXT_ERR(skfd, ifname, SIOCGIWTXPOW, &wrq,
1199 wrq.u.txpower.disabled = 0;
1203 if(!strcasecmp(args[i], "fixed"))
1205 /* Get old tx-power */
1206 IW_GET_EXT_ERR(skfd, ifname, SIOCGIWTXPOW, &wrq,
1208 wrq.u.txpower.fixed = 1;
1209 wrq.u.txpower.disabled = 0;
1211 else /* Should be a numeric value */
1217 if(sscanf(args[i], "%i", &(power)) != 1)
1218 ABORT_ARG_TYPE("Set Tx Power", SIOCSIWTXPOW,
1221 /* Check if milliwatt */
1222 ismwatt = (index(args[i], 'm') != NULL);
1225 if(range.txpower_capa & IW_TXPOW_RELATIVE)
1229 ABORT_ARG_TYPE("Set Tx Power",
1234 if(range.txpower_capa & IW_TXPOW_MWATT)
1237 power = iw_dbm2mwatt(power);
1238 wrq.u.txpower.flags = IW_TXPOW_MWATT;
1243 power = iw_mwatt2dbm(power);
1244 wrq.u.txpower.flags = IW_TXPOW_DBM;
1246 wrq.u.txpower.value = power;
1248 /* Check for an additional argument */
1249 if(((i+1) < count) &&
1250 (!strcasecmp(args[i+1], "auto")))
1252 wrq.u.txpower.fixed = 0;
1255 if(((i+1) < count) &&
1256 (!strcasecmp(args[i+1], "fixed")))
1258 wrq.u.txpower.fixed = 1;
1265 IW_SET_EXT_ERR(skfd, ifname, SIOCSIWTXPOW, &wrq,
1270 /* ---------- Set Retry limit ---------- */
1271 if(!strncmp(args[i], "retry", 3))
1277 ABORT_ARG_NUM("Set Retry Limit", SIOCSIWRETRY);
1279 /* Default - nope */
1280 wrq.u.retry.flags = IW_RETRY_LIMIT;
1281 wrq.u.retry.disabled = 0;
1283 /* Check value modifier */
1284 if(!strcasecmp(args[i], "min"))
1286 wrq.u.retry.flags |= IW_RETRY_MIN;
1288 ABORT_ARG_NUM("Set Retry Limit", SIOCSIWRETRY);
1291 if(!strcasecmp(args[i], "max"))
1293 wrq.u.retry.flags |= IW_RETRY_MAX;
1295 ABORT_ARG_NUM("Set Retry Limit", SIOCSIWRETRY);
1298 /* Check value type */
1299 if(!strcasecmp(args[i], "limit"))
1301 wrq.u.retry.flags |= IW_RETRY_LIMIT;
1303 ABORT_ARG_NUM("Set Retry Limit", SIOCSIWRETRY);
1306 if(!strncasecmp(args[i], "lifetime", 4))
1308 wrq.u.retry.flags &= ~IW_RETRY_LIMIT;
1309 wrq.u.retry.flags |= IW_RETRY_LIFETIME;
1311 ABORT_ARG_NUM("Set Retry Limit", SIOCSIWRETRY);
1314 /* Is there any value to grab ? */
1315 if(sscanf(args[i], "%lg", &(temp)) == 1)
1317 /* Limit is absolute, on the other hand lifetime is seconds */
1318 if(!(wrq.u.retry.flags & IW_RETRY_LIMIT))
1320 /* Normalise lifetime */
1321 temp *= MEGA; /* default = s */
1322 if(index(args[i], 'u')) temp /= MEGA;
1323 if(index(args[i], 'm')) temp /= KILO;
1325 wrq.u.retry.value = (long) temp;
1331 ABORT_ARG_TYPE("Set Retry Limit", SIOCSIWRETRY, args[i]);
1334 IW_SET_EXT_ERR(skfd, ifname, SIOCSIWRETRY, &wrq,
1339 /* ---------- Other ---------- */
1340 /* Here we have an unrecognised arg... */
1341 fprintf(stderr, "Error : unrecognised wireless request \"%s\"\n",
1344 } /* for(index ... */
1348 /******************************* MAIN ********************************/
1350 /*------------------------------------------------------------------*/
1358 int skfd; /* generic raw socket desc. */
1361 /* Create a channel to the NET kernel. */
1362 if((skfd = iw_sockets_open()) < 0)
1368 /* No argument : show the list of all device + info */
1370 iw_enum_devices(skfd, &print_info, NULL, 0);
1372 /* Special case for help... */
1373 if((!strcmp(argv[1], "-h")) || (!strcmp(argv[1], "--help")))
1376 /* Special case for version... */
1377 if (!strcmp(argv[1], "-v") || !strcmp(argv[1], "--version"))
1378 goterr = iw_print_version_info("iwconfig");
1380 /* The device name must be the first argument */
1382 print_info(skfd, argv[1], NULL, 0);
1384 /* The other args on the line specify options to be set... */
1385 goterr = set_info(skfd, argv + 2, argc - 2, argv[1]);
1387 /* Close the socket. */
1388 iw_sockets_close(skfd);