OSDN Git Service

v23
authorchris-kirby <chris.kirby@hpe.com>
Tue, 11 Oct 2016 21:00:06 +0000 (15:00 -0600)
committerchris-kirby <chris.kirby@hpe.com>
Tue, 11 Oct 2016 21:00:06 +0000 (15:00 -0600)
14 files changed:
wireless_tools/CHANGELOG.h
wireless_tools/INSTALL
wireless_tools/Makefile
wireless_tools/iwconfig.8
wireless_tools/iwconfig.c
wireless_tools/iwgetid.c
wireless_tools/iwlib.c
wireless_tools/iwlib.h
wireless_tools/iwlist.8
wireless_tools/iwlist.c
wireless_tools/iwpriv.c
wireless_tools/iwspy.c
wireless_tools/wireless.12.h [new file with mode: 0644]
wireless_tools/wireless.h

index e3d5308..67093d6 100644 (file)
@@ -1,11 +1,12 @@
 /*
  *     Wireless Tools
  *
 /*
  *     Wireless Tools
  *
- *             Jean II - HPLB 97->99 - HPL 99->01
+ *             Jean II - HPLB 97->99 - HPL 99->02
  *
  * The changelog...
  *
  *
  * The changelog...
  *
- * This file is released under the GPL license.
+ * This files is released under the GPL license.
+ *     Copyright (c) 1997-2002 Jean Tourrilhes <jt@hpl.hp.com>
  */
 
 /* --------------------------- HISTORY --------------------------- */
  */
 
 /* --------------------------- HISTORY --------------------------- */
  *     o Show typical/average quality in iwspy [iwspy]
  *     o Get Wireless Stats through ioctl instead of /proc [iwlib]
  *
  *     o Show typical/average quality in iwspy [iwspy]
  *     o Get Wireless Stats through ioctl instead of /proc [iwlib]
  *
+ * wireless 23 :
+ * -----------
+ *     o Split iw_check_addr_type() into two functions mac/if [iwlib]
+ *     o iw_in_addr() does appropriate iw_check_xxx itself  [iwlib]
+ *     o Allow iwspy on MAC address even if IP doesn't check [iwspy]
+ *     o Allow iwconfig ap on MAC address even if IP doesn't check [iwconfig]
+ *     ---
+ *     o Fix iwlist man page about extra commands [iwlist]
+ *     ---
+ *     o Fix Makefile rules for library compile (more generic) [Makefile]
+ *     ---
+ *     o Set max length for all GET request with a iw_point [various]
+ *     o Fix set IW_PRIV_TYPE_BYTE to be endian/align clean [iwpriv]
+ *     ---
+ *             (From Kernel Jake <kerneljake@hotmail.com>)
+ *     o Add '/' at the end of directories to create them [Makefile]
+ *             (From Pavel Roskin <proski@gnu.org>)
+ *     o Replace "cp" with "install" to get permissions proper [Makefile]
+ *     o Install Man-Pages at the proper location [Makefile]
+ *     o Add automatic header selection based on libc/kernel [iwlib.h]
+ *     ---
+ *     o Add "commit" to force parameters on the card [iwconfig]
+ *     o Wrap ioctl() in iw_set/get_ext() wrappers [all]
+ *     o Beautify set request error messages [iwconfig]
  */
 
 /* ----------------------------- TODO ----------------------------- */
  */
 
 /* ----------------------------- TODO ----------------------------- */
index 6093c2e..efa4eca 100644 (file)
@@ -16,14 +16,7 @@ You need :
                Note : CONFIG_NET_RADIO must be enabled
        o (Optional) A Pcmcia package supporting Wireless Extension
        o A driver supporting wireless extensions
                Note : CONFIG_NET_RADIO must be enabled
        o (Optional) A Pcmcia package supporting Wireless Extension
        o A driver supporting wireless extensions
-               -> Wavelan isa
-               -> Wavelan pcmcia
-               -> Netwave pcmcia
-               -> Wavelan IEEE pcmcia drivers
-               -> Aironet MPL driver
-               -> Proxim RangeLan2/Symphony driver
-               -> Raylink/WegGear2.4 driver
-               -> Check my web page for latest list of drivers,
+               -> Check my web pages for latest list of drivers,
                        otherwise patch your favourite driver...
        Note : more recent kernels and drivers are likely to support
                more wireless extension features...
                        otherwise patch your favourite driver...
        Note : more recent kernels and drivers are likely to support
                more wireless extension features...
@@ -34,16 +27,12 @@ Recommended versions :
        o Kernel (wireless extension definition) :
                -> Kernel 2.2.14 onward
                -> Kernel 2.3.24 onward
        o Kernel (wireless extension definition) :
                -> Kernel 2.2.14 onward
                -> Kernel 2.3.24 onward
+               -> Kernel 2.4.0 onward
        o Pcmcia package :
                -> Pcmcia 3.1.15 onward
        o Drivers with wireless extension support :
        o Pcmcia package :
                -> Pcmcia 3.1.15 onward
        o Drivers with wireless extension support :
-               -> Wavelan isa from kernels above
-               -> Wavelan pcmcia from pcmcia 3.1.1 onward
-               -> Netwave pcmcia from pcmcia 3.1.2 onward
-               -> Wavelan IEEE pcmcia GPL driver (wvlan_cs) 1.0.5 onward
-               -> Aironet MPL driver (airo_cs.c) 1.4 onward
-               -> Proxim RangeLan2/Symphony driver 1.4.3 onward
-               -> Raylink/WegGear2.4 driver 1.70 (note : read only)
+               -> Check my web pages for latest list of drivers,
+                       otherwise patch your favourite driver...
 
 Compile wireless tools :
 ----------------------
 
 Compile wireless tools :
 ----------------------
@@ -68,12 +57,13 @@ mandatory...
 Kernel headers (why it doesn't compile) :
 ---------------------------------------
        Some changes in the kernel headers and glibc headers are
 Kernel headers (why it doesn't compile) :
 ---------------------------------------
        Some changes in the kernel headers and glibc headers are
-making my life difficult.
-       If you have glibc and kernel 2.2.X headers (or greater), that
-should be all right. This is the default for most modern distributions.
-       In the other cases, depending on which version of the kernel
-headers (might be different from kernel) and library headers you have,
-you need to play with the options at the top of the Makefile.
+making my life difficult. We now have a mechanism to automatically
+select the proper header based on various bits of information (libc
+version & kernel version), but it may fail to do the right thing.
+       You may also see the message :
+               "Your kernel/libc combination is not supported"
+       If this happens to you, you will need to hack the rules at the
+top of iwlib.h and send me the patch.
 
        The second issue is that some distributions install some
 independant kernel headers in /usr/include. If you upgrade your
 
        The second issue is that some distributions install some
 independant kernel headers in /usr/include. If you upgrade your
index 236acbb..f4e0fcf 100644 (file)
@@ -4,8 +4,9 @@
 
 # Targets to build
 STATIC=libiw.a
 
 # Targets to build
 STATIC=libiw.a
-DYNAMIC=libiw.so.22
+DYNAMIC=libiw.so.23
 PROGS= iwconfig iwlist iwpriv iwspy iwgetid
 PROGS= iwconfig iwlist iwpriv iwspy iwgetid
+MANPAGES=iwconfig.8 iwlist.8 iwpriv.8 iwspy.8
 
 # Composition of the library :
 OBJS = iwlib.o
 
 # Composition of the library :
 OBJS = iwlib.o
@@ -16,26 +17,12 @@ IWLIBS=$(OBJS)
 
 # Installation directory. By default, go in local.
 # Distributions should probably use /usr/sbin, but they probably know better...
 
 # Installation directory. By default, go in local.
 # Distributions should probably use /usr/sbin, but they probably know better...
-INSTALL_DIR= /usr/local/sbin
-INSTALL_LIB= /usr/local/lib
-INSTALL_INC= /usr/local/include
+INSTALL_DIR= /usr/local/sbin/
+INSTALL_LIB= /usr/local/lib/
+INSTALL_INC= /usr/local/include/
+INSTALL_MAN= /usr/local/man
 
 
-# This is our header selection. Try to hide the mess and the misery :-(
-# Please choose *only one* of the define...
-
-# Kernel headers 2.4.X + Glibc 2.2 - Mandrake 8.0, Debian 2.3, RH 7.1
-#HEADERS= -DGLIBC22_HEADERS
-
-# Kernel headers 2.0.X + Glibc 2.0 - Debian 2.0, RH 5
-# Kernel headers 2.2.X + Glibc 2.1 - Debian 2.2, RH 6.1
-# Kernel headers 2.4.X + Glibc 2.1 - Debian 2.2 upgraded, RH 7.0
-HEADERS= -DGLIBC_HEADERS
-
-# Kernel headers 2.2.X + Glibc 2.0 - Debian 2.1
-#HEADERS= -DKLUDGE_HEADERS
-
-# Kernel headers 2.0.X + libc5 - old systems
-#HEADERS= -DLIBC5_HEADERS
+# Header selection is now supposed to be automatic...
 
 # Use private copy of Wireless Extension definition instead of the
 # system wide one in /usr/include/linux. Use with care.
 
 # Use private copy of Wireless Extension definition instead of the
 # system wide one in /usr/include/linux. Use with care.
@@ -76,21 +63,24 @@ iwgetid: iwgetid.o
        $(CC) $(CFLAGS) -o $@ $^
 
 # Compilation of the dynamic library
        $(CC) $(CFLAGS) -o $@ $^
 
 # Compilation of the dynamic library
-libiw.so.22: $(OBJS)
+$(DYNAMIC): $(OBJS)
        $(CC) -O2 -shared -o $@ -Wl,-soname,$@ -lm -lc $^
 
 # Compilation of the static library
        $(CC) -O2 -shared -o $@ -Wl,-soname,$@ -lm -lc $^
 
 # Compilation of the static library
-libiw.a: $(OBJS)
+$(STATIC): $(OBJS)
        $(RM) $@
        ar cru $@ $^
        ranlib $@
 
 # So crude but so effective ;-)
        $(RM) $@
        ar cru $@ $^
        ranlib $@
 
 # So crude but so effective ;-)
+# Less crude thanks to many contributions ;-)
 install::
 install::
-       cp $(PROGS) $(INSTALL_DIR)
-       cp $(STATIC) $(DYNAMIC) $(INSTALL_LIB)
-       echo "Don't forget to fix you /etc/ld.so.conf and run ldconfig."
-       cp iwlib.h $(INSTALL_INC)
+       install -m 755 $(PROGS) $(INSTALL_DIR)
+       install -m 644 $(STATIC) $(INSTALL_LIB)
+       install -m 755 $(DYNAMIC) $(INSTALL_LIB)
+       echo "Don't forget to fix your /etc/ld.so.conf and run ldconfig."
+       install -m 644 iwlib.h $(INSTALL_INC)
+       install -m 644 $(MANPAGES) $(INSTALL_MAN)/man8/
 
 clean::
        $(RM_CMD) 
 
 clean::
        $(RM_CMD) 
index fbc3483..814861f 100644 (file)
@@ -20,6 +20,8 @@ iwconfig \- configure a wireless network interface
 .BI "                   [rate " R "] [rts " RT "] [frag " FT "] [txpower " T ]
 .br
 .BI "                   [enc " E "] [key " K "] [power " P "] [retry " R ]
 .BI "                   [rate " R "] [rts " RT "] [frag " FT "] [txpower " T ]
 .br
 .BI "                   [enc " E "] [key " K "] [power " P "] [retry " R ]
+.br
+.BI "                   [commit]
 .\"
 .\" DESCRIPTION part
 .\"
 .\"
 .\" DESCRIPTION part
 .\"
@@ -324,6 +326,15 @@ is the short retry limit (non RTS/CTS packets).
 .I "   iwconfig eth0 retry lifetime 300m"
 .br
 .I "   iwconfig eth0 retry min limit 8"
 .I "   iwconfig eth0 retry lifetime 300m"
 .br
 .I "   iwconfig eth0 retry min limit 8"
+.TP
+.BR commit
+Some cards may not apply changes done through Wireless Extensions
+immediately (they may wait to agregate the changes or apply it only
+when the card is brought up). This command (when available) force
+the card to apply all pending changes.
+.br
+This is normally not needed, because the card will eventually apply
+the changes, but can be usefull for debugging.
 .\"
 .\" DISPLAY part
 .\"
 .\"
 .\" DISPLAY part
 .\"
index efc0a43..5b38484 100644 (file)
@@ -5,9 +5,10 @@
  *
  * Main code for "iwconfig". This is the generic tool for most
  * manipulations...
  *
  * Main code for "iwconfig". This is the generic tool for most
  * manipulations...
- * You need to link this code against "iwcommon.c" and "-lm".
+ * You need to link this code against "iwlib.c" and "-lm".
  *
  * This file is released under the GPL license.
  *
  * This file is released under the GPL license.
+ *     Copyright (c) 1997-2002 Jean Tourrilhes <jt@hpl.hp.com>
  */
 
 #include "iwlib.h"             /* Header */
  */
 
 #include "iwlib.h"             /* Header */
@@ -33,7 +34,7 @@ iw_usage(void)
   fprintf(stderr, "                          [enc NNNN-NNNN]\n");
   fprintf(stderr, "                          [power { period N|timeout N}]\n");
   fprintf(stderr, "                          [txpower N {mW|dBm}]\n");
   fprintf(stderr, "                          [enc NNNN-NNNN]\n");
   fprintf(stderr, "                          [power { period N|timeout N}]\n");
   fprintf(stderr, "                          [txpower N {mW|dBm}]\n");
-  exit(1);
+  fprintf(stderr, "                          [commit]\n");
 }
 
 
 }
 
 
@@ -55,8 +56,7 @@ get_info(int                  skfd,
   memset((char *) info, 0, sizeof(struct wireless_info));
 
   /* Get wireless name */
   memset((char *) info, 0, sizeof(struct wireless_info));
 
   /* Get wireless name */
-  strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
-  if(ioctl(skfd, SIOCGIWNAME, &wrq) < 0)
+  if(iw_get_ext(skfd, ifname, SIOCGIWNAME, &wrq) < 0)
     /* If no wireless name : no wireless extensions */
     return(-1);
   else
     /* If no wireless name : no wireless extensions */
     return(-1);
   else
@@ -67,35 +67,31 @@ get_info(int                        skfd,
     info->has_range = 1;
 
   /* Get network ID */
     info->has_range = 1;
 
   /* Get network ID */
-  strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
-  if(ioctl(skfd, SIOCGIWNWID, &wrq) >= 0)
+  if(iw_get_ext(skfd, ifname, SIOCGIWNWID, &wrq) >= 0)
     {
       info->has_nwid = 1;
       memcpy(&(info->nwid), &(wrq.u.nwid), sizeof(iwparam));
     }
 
   /* Get frequency / channel */
     {
       info->has_nwid = 1;
       memcpy(&(info->nwid), &(wrq.u.nwid), sizeof(iwparam));
     }
 
   /* Get frequency / channel */
-  strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
-  if(ioctl(skfd, SIOCGIWFREQ, &wrq) >= 0)
+  if(iw_get_ext(skfd, ifname, SIOCGIWFREQ, &wrq) >= 0)
     {
       info->has_freq = 1;
       info->freq = iw_freq2float(&(wrq.u.freq));
     }
 
   /* Get sensitivity */
     {
       info->has_freq = 1;
       info->freq = iw_freq2float(&(wrq.u.freq));
     }
 
   /* Get sensitivity */
-  strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
-  if(ioctl(skfd, SIOCGIWSENS, &wrq) >= 0)
+  if(iw_get_ext(skfd, ifname, SIOCGIWSENS, &wrq) >= 0)
     {
       info->has_sens = 1;
       memcpy(&(info->sens), &(wrq.u.sens), sizeof(iwparam));
     }
 
   /* Get encryption information */
     {
       info->has_sens = 1;
       memcpy(&(info->sens), &(wrq.u.sens), sizeof(iwparam));
     }
 
   /* Get encryption information */
-  strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
   wrq.u.data.pointer = (caddr_t) info->key;
   wrq.u.data.pointer = (caddr_t) info->key;
-  wrq.u.data.length = 0;
+  wrq.u.data.length = IW_ENCODING_TOKEN_MAX;
   wrq.u.data.flags = 0;
   wrq.u.data.flags = 0;
-  if(ioctl(skfd, SIOCGIWENCODE, &wrq) >= 0)
+  if(iw_get_ext(skfd, ifname, SIOCGIWENCODE, &wrq) >= 0)
     {
       info->has_key = 1;
       info->key_size = wrq.u.data.length;
     {
       info->has_key = 1;
       info->key_size = wrq.u.data.length;
@@ -103,60 +99,53 @@ get_info(int                       skfd,
     }
 
   /* Get ESSID */
     }
 
   /* Get ESSID */
-  strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
   wrq.u.essid.pointer = (caddr_t) info->essid;
   wrq.u.essid.pointer = (caddr_t) info->essid;
-  wrq.u.essid.length = 0;
+  wrq.u.essid.length = IW_ESSID_MAX_SIZE;
   wrq.u.essid.flags = 0;
   wrq.u.essid.flags = 0;
-  if(ioctl(skfd, SIOCGIWESSID, &wrq) >= 0)
+  if(iw_get_ext(skfd, ifname, SIOCGIWESSID, &wrq) >= 0)
     {
       info->has_essid = 1;
       info->essid_on = wrq.u.data.flags;
     }
 
   /* Get AP address */
     {
       info->has_essid = 1;
       info->essid_on = wrq.u.data.flags;
     }
 
   /* Get AP address */
-  strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
-  if(ioctl(skfd, SIOCGIWAP, &wrq) >= 0)
+  if(iw_get_ext(skfd, ifname, SIOCGIWAP, &wrq) >= 0)
     {
       info->has_ap_addr = 1;
       memcpy(&(info->ap_addr), &(wrq.u.ap_addr), sizeof (sockaddr));
     }
 
   /* Get NickName */
     {
       info->has_ap_addr = 1;
       memcpy(&(info->ap_addr), &(wrq.u.ap_addr), sizeof (sockaddr));
     }
 
   /* Get NickName */
-  strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
   wrq.u.essid.pointer = (caddr_t) info->nickname;
   wrq.u.essid.pointer = (caddr_t) info->nickname;
-  wrq.u.essid.length = 0;
+  wrq.u.essid.length = IW_ESSID_MAX_SIZE;
   wrq.u.essid.flags = 0;
   wrq.u.essid.flags = 0;
-  if(ioctl(skfd, SIOCGIWNICKN, &wrq) >= 0)
+  if(iw_get_ext(skfd, ifname, SIOCGIWNICKN, &wrq) >= 0)
     if(wrq.u.data.length > 1)
       info->has_nickname = 1;
 
   /* Get bit rate */
     if(wrq.u.data.length > 1)
       info->has_nickname = 1;
 
   /* Get bit rate */
-  strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
-  if(ioctl(skfd, SIOCGIWRATE, &wrq) >= 0)
+  if(iw_get_ext(skfd, ifname, SIOCGIWRATE, &wrq) >= 0)
     {
       info->has_bitrate = 1;
       memcpy(&(info->bitrate), &(wrq.u.bitrate), sizeof(iwparam));
     }
 
   /* Get RTS threshold */
     {
       info->has_bitrate = 1;
       memcpy(&(info->bitrate), &(wrq.u.bitrate), sizeof(iwparam));
     }
 
   /* Get RTS threshold */
-  strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
-  if(ioctl(skfd, SIOCGIWRTS, &wrq) >= 0)
+  if(iw_get_ext(skfd, ifname, SIOCGIWRTS, &wrq) >= 0)
     {
       info->has_rts = 1;
       memcpy(&(info->rts), &(wrq.u.rts), sizeof(iwparam));
     }
 
   /* Get fragmentation threshold */
     {
       info->has_rts = 1;
       memcpy(&(info->rts), &(wrq.u.rts), sizeof(iwparam));
     }
 
   /* Get fragmentation threshold */
-  strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
-  if(ioctl(skfd, SIOCGIWFRAG, &wrq) >= 0)
+  if(iw_get_ext(skfd, ifname, SIOCGIWFRAG, &wrq) >= 0)
     {
       info->has_frag = 1;
       memcpy(&(info->frag), &(wrq.u.frag), sizeof(iwparam));
     }
 
   /* Get operation mode */
     {
       info->has_frag = 1;
       memcpy(&(info->frag), &(wrq.u.frag), sizeof(iwparam));
     }
 
   /* Get operation mode */
-  strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
-  if(ioctl(skfd, SIOCGIWMODE, &wrq) >= 0)
+  if(iw_get_ext(skfd, ifname, SIOCGIWMODE, &wrq) >= 0)
     {
       if((wrq.u.mode < IW_NUM_OPER_MODE) && (wrq.u.mode >= 0))
        info->has_mode = 1;
     {
       if((wrq.u.mode < IW_NUM_OPER_MODE) && (wrq.u.mode >= 0))
        info->has_mode = 1;
@@ -164,9 +153,8 @@ get_info(int                        skfd,
     }
 
   /* Get Power Management settings */
     }
 
   /* Get Power Management settings */
-  strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
   wrq.u.power.flags = 0;
   wrq.u.power.flags = 0;
-  if(ioctl(skfd, SIOCGIWPOWER, &wrq) >= 0)
+  if(iw_get_ext(skfd, ifname, SIOCGIWPOWER, &wrq) >= 0)
     {
       info->has_power = 1;
       memcpy(&(info->power), &(wrq.u.power), sizeof(iwparam));
     {
       info->has_power = 1;
       memcpy(&(info->power), &(wrq.u.power), sizeof(iwparam));
@@ -174,8 +162,7 @@ get_info(int                        skfd,
 
 #if WIRELESS_EXT > 9
   /* Get Transmit Power */
 
 #if WIRELESS_EXT > 9
   /* Get Transmit Power */
-  strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
-  if(ioctl(skfd, SIOCGIWTXPOW, &wrq) >= 0)
+  if(iw_get_ext(skfd, ifname, SIOCGIWTXPOW, &wrq) >= 0)
     {
       info->has_txpower = 1;
       memcpy(&(info->txpower), &(wrq.u.txpower), sizeof(iwparam));
     {
       info->has_txpower = 1;
       memcpy(&(info->txpower), &(wrq.u.txpower), sizeof(iwparam));
@@ -184,8 +171,7 @@ get_info(int                        skfd,
 
 #if WIRELESS_EXT > 10
   /* Get retry limit/lifetime */
 
 #if WIRELESS_EXT > 10
   /* Get retry limit/lifetime */
-  strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
-  if(ioctl(skfd, SIOCGIWRETRY, &wrq) >= 0)
+  if(iw_get_ext(skfd, ifname, SIOCGIWRETRY, &wrq) >= 0)
     {
       info->has_retry = 1;
       memcpy(&(info->retry), &(wrq.u.retry), sizeof(iwparam));
     {
       info->has_retry = 1;
       memcpy(&(info->retry), &(wrq.u.retry), sizeof(iwparam));
@@ -605,6 +591,66 @@ print_devices(int  skfd)
 
 /*------------------------------------------------------------------*/
 /*
 
 /*------------------------------------------------------------------*/
 /*
+ * Macro to handle errors when setting WE
+ * Print a nice error message and exit...
+ * We define them as macro so that "return" do the right thing.
+ * The "do {...} while(0)" is a standard trick
+ */
+#define ERR_SET_EXT(rname, request) \
+       fprintf(stderr, "Error for wireless request \"%s\" (%X) :\n", \
+               rname, request)
+
+#define ABORT_ARG_NUM(rname, request) \
+       do { \
+               ERR_SET_EXT(rname, request); \
+               fprintf(stderr, "    too few arguments.\n"); \
+               return(-1); \
+       } while(0)
+
+#define ABORT_ARG_TYPE(rname, request, arg) \
+       do { \
+               ERR_SET_EXT(rname, request); \
+               fprintf(stderr, "    invalid argument \"%s\".\n", arg); \
+               return(-2); \
+       } while(0)
+
+#define ABORT_ARG_SIZE(rname, request, max) \
+       do { \
+               ERR_SET_EXT(rname, request); \
+               fprintf(stderr, "    argument too big (max %d)\n", max); \
+               return(-3); \
+       } while(0)
+
+/*------------------------------------------------------------------*/
+/*
+ * Wrapper to push some Wireless Parameter in the driver
+ * Use standard wrapper and add pretty error message if fail...
+ */
+#define IW_SET_EXT_ERR(skfd, ifname, request, wrq, rname) \
+       do { \
+       if(iw_set_ext(skfd, ifname, request, wrq) < 0) { \
+               ERR_SET_EXT(rname, request); \
+               fprintf(stderr, "    SET failed on device %-1.8s ; %s.\n", \
+                       ifname, strerror(errno)); \
+               return(-5); \
+       } } while(0)
+
+/*------------------------------------------------------------------*/
+/*
+ * Wrapper to extract some Wireless Parameter out of the driver
+ * Use standard wrapper and add pretty error message if fail...
+ */
+#define IW_GET_EXT_ERR(skfd, ifname, request, wrq, rname) \
+       do { \
+       if(iw_get_ext(skfd, ifname, request, wrq) < 0) { \
+               ERR_SET_EXT(rname, request); \
+               fprintf(stderr, "    GET failed on device %-1.8s ; %s.\n", \
+                       ifname, strerror(errno)); \
+               return(-6); \
+       } } while(0)
+
+/*------------------------------------------------------------------*/
+/*
  * Set the wireless options requested on command line
  * This function is too long and probably should be split,
  * because it look like the perfect definition of spaghetti code,
  * Set the wireless options requested on command line
  * This function is too long and probably should be split,
  * because it look like the perfect definition of spaghetti code,
@@ -619,23 +665,32 @@ set_info(int              skfd,           /* The socket */
   struct iwreq         wrq;
   int                  i;
 
   struct iwreq         wrq;
   int                  i;
 
-  /* Set dev name */
-  strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
-
-  /* if nothing after the device name */
-  if(count<1)
-    iw_usage();
+  /* if nothing after the device name - will never happen */
+  if(count < 1)
+    {
+      fprintf(stderr, "Error : too few arguments.\n");
+      return(-1);
+    }
 
   /* The other args on the line specify options to be set... */
   for(i = 0; i < count; i++)
     {
 
   /* The other args on the line specify options to be set... */
   for(i = 0; i < count; i++)
     {
+      /* ---------- Commit changes to driver ---------- */
+      if(!strncmp(args[i], "commit", 6))
+       {
+         /* No args */
+         IW_SET_EXT_ERR(skfd, ifname, SIOCSIWCOMMIT, &wrq,
+                        "Commit changes");
+         continue;
+       }
+
       /* ---------- Set network ID ---------- */
       if((!strcasecmp(args[i], "nwid")) ||
         (!strcasecmp(args[i], "domain")))
        {
          i++;
          if(i >= count)
       /* ---------- Set network ID ---------- */
       if((!strcasecmp(args[i], "nwid")) ||
         (!strcasecmp(args[i], "domain")))
        {
          i++;
          if(i >= count)
-           iw_usage();
+           ABORT_ARG_NUM("Set NWID", SIOCSIWNWID);
          if((!strcasecmp(args[i], "off")) ||
             (!strcasecmp(args[i], "any")))
            wrq.u.nwid.disabled = 1;
          if((!strcasecmp(args[i], "off")) ||
             (!strcasecmp(args[i], "any")))
            wrq.u.nwid.disabled = 1;
@@ -643,27 +698,21 @@ set_info(int              skfd,           /* The socket */
            if(!strcasecmp(args[i], "on"))
              {
                /* Get old nwid */
            if(!strcasecmp(args[i], "on"))
              {
                /* Get old nwid */
-               if(ioctl(skfd, SIOCGIWNWID, &wrq) < 0)
-                 {
-                   fprintf(stderr, "SIOCGIWNWID: %s\n", strerror(errno));
-                   return(-1);
-                 }
-               strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
+               IW_GET_EXT_ERR(skfd, ifname, SIOCGIWNWID, &wrq,
+                              "Set NWID");
                wrq.u.nwid.disabled = 0;
              }
            else
              if(sscanf(args[i], "%lX", (unsigned long *) &(wrq.u.nwid.value))
                 != 1)
                wrq.u.nwid.disabled = 0;
              }
            else
              if(sscanf(args[i], "%lX", (unsigned long *) &(wrq.u.nwid.value))
                 != 1)
-               iw_usage();
+               ABORT_ARG_TYPE("Set NWID", SIOCSIWNWID, args[i]);
              else
                wrq.u.nwid.disabled = 0;
          wrq.u.nwid.fixed = 1;
 
              else
                wrq.u.nwid.disabled = 0;
          wrq.u.nwid.fixed = 1;
 
-         if(ioctl(skfd, SIOCSIWNWID, &wrq) < 0)
-           {
-             fprintf(stderr, "SIOCSIWNWID: %s\n", strerror(errno));
-             return(-1);
-           }
+         /* Set new nwid */
+         IW_SET_EXT_ERR(skfd, ifname, SIOCSIWNWID, &wrq,
+                        "Set NWID");
          continue;
        }
 
          continue;
        }
 
@@ -674,20 +723,17 @@ set_info(int              skfd,           /* The socket */
          double                freq;
 
          if(++i >= count)
          double                freq;
 
          if(++i >= count)
-           iw_usage();
+           ABORT_ARG_NUM("Set Frequency", SIOCSIWFREQ);
          if(sscanf(args[i], "%lg", &(freq)) != 1)
          if(sscanf(args[i], "%lg", &(freq)) != 1)
-           iw_usage();
+           ABORT_ARG_TYPE("Set Frequency", SIOCSIWFREQ, args[i]);
          if(index(args[i], 'G')) freq *= GIGA;
          if(index(args[i], 'M')) freq *= MEGA;
          if(index(args[i], 'k')) freq *= KILO;
 
          iw_float2freq(freq, &(wrq.u.freq));
 
          if(index(args[i], 'G')) freq *= GIGA;
          if(index(args[i], 'M')) freq *= MEGA;
          if(index(args[i], 'k')) freq *= KILO;
 
          iw_float2freq(freq, &(wrq.u.freq));
 
-         if(ioctl(skfd, SIOCSIWFREQ, &wrq) < 0)
-           {
-             fprintf(stderr, "SIOCSIWFREQ: %s\n", strerror(errno));
-             return(-1);
-           }
+         IW_SET_EXT_ERR(skfd, ifname, SIOCSIWFREQ, &wrq,
+                        "Set Frequency");
          continue;
        }
 
          continue;
        }
 
@@ -695,15 +741,12 @@ set_info(int              skfd,           /* The socket */
       if(!strncmp(args[i], "sens", 4))
        {
          if(++i >= count)
       if(!strncmp(args[i], "sens", 4))
        {
          if(++i >= count)
-           iw_usage();
+           ABORT_ARG_NUM("Set Sensitivity", SIOCSIWSENS);
          if(sscanf(args[i], "%d", &(wrq.u.sens.value)) != 1)
          if(sscanf(args[i], "%d", &(wrq.u.sens.value)) != 1)
-           iw_usage();
+           ABORT_ARG_TYPE("Set Sensitivity", SIOCSIWSENS, args[i]);
 
 
-         if(ioctl(skfd, SIOCSIWSENS, &wrq) < 0)
-           {
-             fprintf(stderr, "SIOCSIWSENS: %s\n", strerror(errno));
-             return(-1);
-           }
+         IW_SET_EXT_ERR(skfd, ifname, SIOCSIWSENS, &wrq,
+                        "Set Sensitivity");
          continue;
        }
 
          continue;
        }
 
@@ -714,7 +757,7 @@ set_info(int                skfd,           /* The socket */
          unsigned char key[IW_ENCODING_TOKEN_MAX];
 
          if(++i >= count)
          unsigned char key[IW_ENCODING_TOKEN_MAX];
 
          if(++i >= count)
-           iw_usage();
+           ABORT_ARG_NUM("Set Encode", SIOCSIWENCODE);
 
          if(!strcasecmp(args[i], "on"))
            {
 
          if(!strcasecmp(args[i], "on"))
            {
@@ -722,12 +765,8 @@ set_info(int               skfd,           /* The socket */
              wrq.u.data.pointer = (caddr_t) key;
              wrq.u.data.length = 0;
              wrq.u.data.flags = 0;
              wrq.u.data.pointer = (caddr_t) key;
              wrq.u.data.length = 0;
              wrq.u.data.flags = 0;
-             if(ioctl(skfd, SIOCGIWENCODE, &wrq) < 0)
-               {
-                 fprintf(stderr, "SIOCGIWENCODE: %s\n", strerror(errno));
-                 return(-1);
-               }
-             strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
+             IW_GET_EXT_ERR(skfd, ifname, SIOCGIWENCODE, &wrq,
+                            "Set Encode");
              wrq.u.data.flags &= ~IW_ENCODE_DISABLED;  /* Enable */
            }
          else
              wrq.u.data.flags &= ~IW_ENCODE_DISABLED;  /* Enable */
            }
          else
@@ -760,8 +799,8 @@ set_info(int                skfd,           /* The socket */
                  buff = malloc(strlen(args[i]) + 1);
                  if(buff == NULL)
                    {
                  buff = malloc(strlen(args[i]) + 1);
                  if(buff == NULL)
                    {
-                     fprintf(stderr, "Setting key : Malloc failed (string too long ?)\n");
-                     return(-1);
+                     fprintf(stderr, "Set Encode : Malloc failed (string too long ?)\n");
+                     return(-10);
                    }
                  strcpy(buff, args[i]);
 
                    }
                  strcpy(buff, args[i]);
 
@@ -814,18 +853,17 @@ set_info(int              skfd,           /* The socket */
                      gotone = 1;
                    }
                }
                      gotone = 1;
                    }
                }
+             /* Pointer is absent in new API */
+             if(wrq.u.data.pointer == NULL)
+               wrq.u.data.flags = IW_ENCODE_NOKEY;
 
              if(!gotone)
 
              if(!gotone)
-               iw_usage();
+               ABORT_ARG_TYPE("Set Encode", SIOCSIWENCODE, args[i]);
              --i;
            }
 
              --i;
            }
 
-         if(ioctl(skfd, SIOCSIWENCODE, &wrq) < 0)
-           {
-             fprintf(stderr, "SIOCSIWENCODE(%d): %s\n",
-                     errno, strerror(errno));
-             return(-1);
-           }
+         IW_SET_EXT_ERR(skfd, ifname, SIOCSIWENCODE, &wrq,
+                        "Set Encode");
          continue;
        }
 
          continue;
        }
 
@@ -836,7 +874,7 @@ set_info(int                skfd,           /* The socket */
 
          i++;
          if(i >= count)
 
          i++;
          if(i >= count)
-           iw_usage();
+           ABORT_ARG_NUM("Set ESSID", SIOCSIWESSID);
          if((!strcasecmp(args[i], "off")) ||
             (!strcasecmp(args[i], "any")))
            {
          if((!strcasecmp(args[i], "off")) ||
             (!strcasecmp(args[i], "any")))
            {
@@ -850,23 +888,15 @@ set_info(int              skfd,           /* The socket */
                wrq.u.essid.pointer = (caddr_t) essid;
                wrq.u.essid.length = 0;
                wrq.u.essid.flags = 0;
                wrq.u.essid.pointer = (caddr_t) essid;
                wrq.u.essid.length = 0;
                wrq.u.essid.flags = 0;
-               if(ioctl(skfd, SIOCGIWESSID, &wrq) < 0)
-                 {
-                   fprintf(stderr, "SIOCGIWESSID: %s\n", strerror(errno));
-                   return(-1);
-                 }
-               strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
+               IW_GET_EXT_ERR(skfd, ifname, SIOCGIWESSID, &wrq,
+                              "Set ESSID");
                wrq.u.essid.flags = 1;
              }
            else
              /* Check the size of what the user passed us to avoid
               * buffer overflows */
              if(strlen(args[i]) > IW_ESSID_MAX_SIZE)
                wrq.u.essid.flags = 1;
              }
            else
              /* Check the size of what the user passed us to avoid
               * buffer overflows */
              if(strlen(args[i]) > IW_ESSID_MAX_SIZE)
-               {
-                 fprintf(stderr, "ESSID too long (max %d): ``%s''\n",
-                         IW_ESSID_MAX_SIZE, args[i]);
-                 iw_usage();
-               }
+               ABORT_ARG_SIZE("Set ESSID", SIOCSIWESSID, IW_ESSID_MAX_SIZE);
              else
                {
                  int           temp;
              else
                {
                  int           temp;
@@ -886,11 +916,8 @@ set_info(int               skfd,           /* The socket */
 
          wrq.u.essid.pointer = (caddr_t) essid;
          wrq.u.essid.length = strlen(essid) + 1;
 
          wrq.u.essid.pointer = (caddr_t) essid;
          wrq.u.essid.length = strlen(essid) + 1;
-         if(ioctl(skfd, SIOCSIWESSID, &wrq) < 0)
-           {
-             fprintf(stderr, "SIOCSIWESSID: %s\n", strerror(errno));
-             return(-1);
-           }
+         IW_SET_EXT_ERR(skfd, ifname, SIOCSIWESSID, &wrq,
+                        "Set ESSID");
          continue;
        }
 
          continue;
        }
 
@@ -898,24 +925,14 @@ set_info(int              skfd,           /* The socket */
       if(!strcasecmp(args[i], "ap"))
        {
          if(++i >= count)
       if(!strcasecmp(args[i], "ap"))
        {
          if(++i >= count)
-           iw_usage();
+           ABORT_ARG_NUM("Set AP Address", SIOCSIWAP);
 
 
-         /* Check if we have valid address types */
-         if(iw_check_addr_type(skfd, ifname) < 0)
-           {
-             fprintf(stderr, "%-8.8s  Interface doesn't support MAC & IP addresses\n", ifname);
-             return(-1);
-           }
-
-         /* Get the address */
+         /* Get the address and check if the interface supports it */
          if(iw_in_addr(skfd, ifname, args[i++], &(wrq.u.ap_addr)) < 0)
          if(iw_in_addr(skfd, ifname, args[i++], &(wrq.u.ap_addr)) < 0)
-           iw_usage();
+           ABORT_ARG_TYPE("Set AP Address", SIOCSIWAP, args[i-1]);
 
 
-         if(ioctl(skfd, SIOCSIWAP, &wrq) < 0)
-           {
-             fprintf(stderr, "SIOCSIWAP: %s\n", strerror(errno));
-             return(-1);
-           }
+         IW_SET_EXT_ERR(skfd, ifname, SIOCSIWAP, &wrq,
+                        "Set AP Address");
          continue;
        }
 
          continue;
        }
 
@@ -924,21 +941,14 @@ set_info(int              skfd,           /* The socket */
        {
          i++;
          if(i >= count)
        {
          i++;
          if(i >= count)
-           iw_usage();
+           ABORT_ARG_NUM("Set Nickname", SIOCSIWNICKN);
          if(strlen(args[i]) > IW_ESSID_MAX_SIZE)
          if(strlen(args[i]) > IW_ESSID_MAX_SIZE)
-           {
-             fprintf(stderr, "Name too long (max %d) : ``%s''\n",
-                     IW_ESSID_MAX_SIZE, args[i]);
-             iw_usage();
-           }
+           ABORT_ARG_SIZE("Set Nickname", SIOCSIWNICKN, IW_ESSID_MAX_SIZE);
 
          wrq.u.essid.pointer = (caddr_t) args[i];
          wrq.u.essid.length = strlen(args[i]) + 1;
 
          wrq.u.essid.pointer = (caddr_t) args[i];
          wrq.u.essid.length = strlen(args[i]) + 1;
-         if(ioctl(skfd, SIOCSIWNICKN, &wrq) < 0)
-           {
-             fprintf(stderr, "SIOCSIWNICKN: %s\n", strerror(errno));
-             return(-1);
-           }
+         IW_SET_EXT_ERR(skfd, ifname, SIOCSIWNICKN, &wrq,
+                        "Set Nickname");
          continue;
        }
 
          continue;
        }
 
@@ -947,7 +957,7 @@ set_info(int                skfd,           /* The socket */
         (!strcmp(args[i], "rate")))
        {
          if(++i >= count)
         (!strcmp(args[i], "rate")))
        {
          if(++i >= count)
-           iw_usage();
+           ABORT_ARG_NUM("Set Bit Rate", SIOCSIWRATE);
          if(!strcasecmp(args[i], "auto"))
            {
              wrq.u.bitrate.value = -1;
          if(!strcasecmp(args[i], "auto"))
            {
              wrq.u.bitrate.value = -1;
@@ -958,12 +968,8 @@ set_info(int               skfd,           /* The socket */
              if(!strcasecmp(args[i], "fixed"))
                {
                  /* Get old bitrate */
              if(!strcasecmp(args[i], "fixed"))
                {
                  /* Get old bitrate */
-                 if(ioctl(skfd, SIOCGIWRATE, &wrq) < 0)
-                   {
-                     fprintf(stderr, "SIOCGIWRATE: %s\n", strerror(errno));
-                     return(-1);
-                   }
-                 strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
+                 IW_GET_EXT_ERR(skfd, ifname, SIOCGIWRATE, &wrq,
+                                "Set Bit Rate");
                  wrq.u.bitrate.fixed = 1;
                }
              else                      /* Should be a numeric value */
                  wrq.u.bitrate.fixed = 1;
                }
              else                      /* Should be a numeric value */
@@ -971,7 +977,7 @@ set_info(int                skfd,           /* The socket */
                  double                brate;
 
                  if(sscanf(args[i], "%lg", &(brate)) != 1)
                  double                brate;
 
                  if(sscanf(args[i], "%lg", &(brate)) != 1)
-                   iw_usage();
+                   ABORT_ARG_TYPE("Set Bit Rate", SIOCSIWRATE, args[i]);
                  if(index(args[i], 'G')) brate *= GIGA;
                  if(index(args[i], 'M')) brate *= MEGA;
                  if(index(args[i], 'k')) brate *= KILO;
                  if(index(args[i], 'G')) brate *= GIGA;
                  if(index(args[i], 'M')) brate *= MEGA;
                  if(index(args[i], 'k')) brate *= KILO;
@@ -994,11 +1000,8 @@ set_info(int              skfd,           /* The socket */
                }
            }
 
                }
            }
 
-         if(ioctl(skfd, SIOCSIWRATE, &wrq) < 0)
-           {
-             fprintf(stderr, "SIOCSIWRATE: %s\n", strerror(errno));
-             return(-1);
-           }
+         IW_SET_EXT_ERR(skfd, ifname, SIOCSIWRATE, &wrq,
+                        "Set Bit Rate");
          continue;
        }
 
          continue;
        }
 
@@ -1007,7 +1010,7 @@ set_info(int              skfd,           /* The socket */
        {
          i++;
          if(i >= count)
        {
          i++;
          if(i >= count)
-           iw_usage();
+           ABORT_ARG_NUM("Set RTS Threshold", SIOCSIWRTS);
          wrq.u.rts.value = -1;
          wrq.u.rts.fixed = 1;
          wrq.u.rts.disabled = 0;
          wrq.u.rts.value = -1;
          wrq.u.rts.fixed = 1;
          wrq.u.rts.disabled = 0;
@@ -1021,25 +1024,18 @@ set_info(int            skfd,           /* The socket */
                if(!strcasecmp(args[i], "fixed"))
                  {
                    /* Get old RTS threshold */
                if(!strcasecmp(args[i], "fixed"))
                  {
                    /* Get old RTS threshold */
-                   if(ioctl(skfd, SIOCGIWRTS, &wrq) < 0)
-                     {
-                       fprintf(stderr, "SIOCGIWRTS: %s\n", strerror(errno));
-                       return(-1);
-                     }
-                   strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
+                   IW_GET_EXT_ERR(skfd, ifname, SIOCGIWRTS, &wrq,
+                                  "Set RTS Threshold");
                    wrq.u.rts.fixed = 1;
                  }
                else                    /* Should be a numeric value */
                  if(sscanf(args[i], "%ld", (unsigned long *) &(wrq.u.rts.value))
                     != 1)
                    wrq.u.rts.fixed = 1;
                  }
                else                    /* Should be a numeric value */
                  if(sscanf(args[i], "%ld", (unsigned long *) &(wrq.u.rts.value))
                     != 1)
-                   iw_usage();
+                   ABORT_ARG_TYPE("Set RTS Threshold", SIOCSIWRTS, args[i]);
            }
 
            }
 
-         if(ioctl(skfd, SIOCSIWRTS, &wrq) < 0)
-           {
-             fprintf(stderr, "SIOCSIWRTS: %s\n", strerror(errno));
-             return(-1);
-           }
+         IW_SET_EXT_ERR(skfd, ifname, SIOCSIWRTS, &wrq,
+                        "Set RTS Threshold");
          continue;
        }
 
          continue;
        }
 
@@ -1048,7 +1044,7 @@ set_info(int              skfd,           /* The socket */
        {
          i++;
          if(i >= count)
        {
          i++;
          if(i >= count)
-           iw_usage();
+           ABORT_ARG_NUM("Set Fragmentation Threshold", SIOCSIWFRAG);
          wrq.u.frag.value = -1;
          wrq.u.frag.fixed = 1;
          wrq.u.frag.disabled = 0;
          wrq.u.frag.value = -1;
          wrq.u.frag.fixed = 1;
          wrq.u.frag.disabled = 0;
@@ -1062,25 +1058,20 @@ set_info(int            skfd,           /* The socket */
                if(!strcasecmp(args[i], "fixed"))
                  {
                    /* Get old fragmentation threshold */
                if(!strcasecmp(args[i], "fixed"))
                  {
                    /* Get old fragmentation threshold */
-                   if(ioctl(skfd, SIOCGIWFRAG, &wrq) < 0)
-                     {
-                       fprintf(stderr, "SIOCGIWFRAG: %s\n", strerror(errno));
-                       return(-1);
-                     }
-                   strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
+                   IW_GET_EXT_ERR(skfd, ifname, SIOCGIWFRAG, &wrq,
+                                  "Set Fragmentation Threshold");
                    wrq.u.frag.fixed = 1;
                  }
                else                    /* Should be a numeric value */
                    wrq.u.frag.fixed = 1;
                  }
                else                    /* Should be a numeric value */
-                 if(sscanf(args[i], "%ld", (unsigned long *) &(wrq.u.frag.value))
+                 if(sscanf(args[i], "%ld",
+                           (unsigned long *) &(wrq.u.frag.value))
                     != 1)
                     != 1)
-                   iw_usage();
+                   ABORT_ARG_TYPE("Set Fragmentation Threshold", SIOCSIWFRAG,
+                                  args[i]);
            }
 
            }
 
-         if(ioctl(skfd, SIOCSIWFRAG, &wrq) < 0)
-           {
-             fprintf(stderr, "SIOCSIWFRAG: %s\n", strerror(errno));
-             return(-1);
-           }
+         IW_SET_EXT_ERR(skfd, ifname, SIOCSIWFRAG, &wrq,
+                        "Set Fragmentation Threshold");
          continue;
        }
 
          continue;
        }
 
@@ -1091,7 +1082,7 @@ set_info(int              skfd,           /* The socket */
 
          i++;
          if(i >= count)
 
          i++;
          if(i >= count)
-           iw_usage();
+           ABORT_ARG_NUM("Set Mode", SIOCSIWMODE);
 
          if(sscanf(args[i], "%d", &k) != 1)
            {
 
          if(sscanf(args[i], "%d", &k) != 1)
            {
@@ -1101,14 +1092,11 @@ set_info(int            skfd,           /* The socket */
                k++;
            }
          if((k >= IW_NUM_OPER_MODE) || (k < 0))
                k++;
            }
          if((k >= IW_NUM_OPER_MODE) || (k < 0))
-           iw_usage();
+           ABORT_ARG_TYPE("Set Mode", SIOCSIWMODE, args[i]);
 
          wrq.u.mode = k;
 
          wrq.u.mode = k;
-         if(ioctl(skfd, SIOCSIWMODE, &wrq) < 0)
-           {
-             fprintf(stderr, "SIOCSIWMODE: %s\n", strerror(errno));
-             return(-1);
-           }
+         IW_SET_EXT_ERR(skfd, ifname, SIOCSIWMODE, &wrq,
+                        "Set Mode");
          continue;
        }
 
          continue;
        }
 
@@ -1116,7 +1104,7 @@ set_info(int              skfd,           /* The socket */
       if(!strncmp(args[i], "power", 3))
        {
          if(++i >= count)
       if(!strncmp(args[i], "power", 3))
        {
          if(++i >= count)
-           iw_usage();
+           ABORT_ARG_NUM("Set Power Management", SIOCSIWPOWER);
 
          if(!strcasecmp(args[i], "off"))
            wrq.u.power.disabled = 1;   /* i.e. max size */
 
          if(!strcasecmp(args[i], "off"))
            wrq.u.power.disabled = 1;   /* i.e. max size */
@@ -1124,12 +1112,8 @@ set_info(int             skfd,           /* The socket */
            if(!strcasecmp(args[i], "on"))
              {
                /* Get old Power info */
            if(!strcasecmp(args[i], "on"))
              {
                /* Get old Power info */
-               if(ioctl(skfd, SIOCGIWPOWER, &wrq) < 0)
-                 {
-                   fprintf(stderr, "SIOCGIWPOWER: %s\n", strerror(errno));
-                   return(-1);
-                 }
-               strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
+               IW_GET_EXT_ERR(skfd, ifname, SIOCGIWPOWER, &wrq,
+                              "Set Power Management");
                wrq.u.power.disabled = 0;
              }
            else
                wrq.u.power.disabled = 0;
              }
            else
@@ -1145,14 +1129,14 @@ set_info(int            skfd,           /* The socket */
                  {
                    wrq.u.power.flags |= IW_POWER_MIN;
                    if(++i >= count)
                  {
                    wrq.u.power.flags |= IW_POWER_MIN;
                    if(++i >= count)
-                     iw_usage();
+                     ABORT_ARG_NUM("Set Power Management", SIOCSIWPOWER);
                  }
                else
                  if(!strcasecmp(args[i], "max"))
                    {
                      wrq.u.power.flags |= IW_POWER_MAX;
                      if(++i >= count)
                  }
                else
                  if(!strcasecmp(args[i], "max"))
                    {
                      wrq.u.power.flags |= IW_POWER_MAX;
                      if(++i >= count)
-                       iw_usage();
+                       ABORT_ARG_NUM("Set Power Management", SIOCSIWPOWER);
                    }
 
                /* Check value type */
                    }
 
                /* Check value type */
@@ -1160,14 +1144,14 @@ set_info(int            skfd,           /* The socket */
                  {
                    wrq.u.power.flags |= IW_POWER_PERIOD;
                    if(++i >= count)
                  {
                    wrq.u.power.flags |= IW_POWER_PERIOD;
                    if(++i >= count)
-                     iw_usage();
+                     ABORT_ARG_NUM("Set Power Management", SIOCSIWPOWER);
                  }
                else
                  if(!strcasecmp(args[i], "timeout"))
                    {
                      wrq.u.power.flags |= IW_POWER_TIMEOUT;
                      if(++i >= count)
                  }
                else
                  if(!strcasecmp(args[i], "timeout"))
                    {
                      wrq.u.power.flags |= IW_POWER_TIMEOUT;
                      if(++i >= count)
-                       iw_usage();
+                       ABORT_ARG_NUM("Set Power Management", SIOCSIWPOWER);
                    }
 
                /* Is there any value to grab ? */
                    }
 
                /* Is there any value to grab ? */
@@ -1203,16 +1187,13 @@ set_info(int            skfd,           /* The socket */
                      }
                  }
                if(!gotone)
                      }
                  }
                if(!gotone)
-                 iw_usage();
+                 ABORT_ARG_TYPE("Set Power Management", SIOCSIWPOWER,
+                                args[i]);
                --i;
              }
 
                --i;
              }
 
-         if(ioctl(skfd, SIOCSIWPOWER, &wrq) < 0)
-           {
-             fprintf(stderr, "SIOCSIWPOWER(%d): %s\n",
-                     errno, strerror(errno));
-             return(-1);
-           }
+         IW_SET_EXT_ERR(skfd, ifname, SIOCSIWPOWER, &wrq,
+                      "Set Power Management");
          continue;
        }
 
          continue;
        }
 
@@ -1223,14 +1204,13 @@ set_info(int            skfd,           /* The socket */
          struct iw_range       range;
 
          if(++i >= count)
          struct iw_range       range;
 
          if(++i >= count)
-           iw_usage();
+           ABORT_ARG_NUM("Set Tx Power", SIOCSIWTXPOW);
 
          /* Extract range info */
          if(iw_get_range_info(skfd, ifname, &range) < 0)
            memset(&range, 0, sizeof(range));
 
          /* Prepare the request */
 
          /* Extract range info */
          if(iw_get_range_info(skfd, ifname, &range) < 0)
            memset(&range, 0, sizeof(range));
 
          /* Prepare the request */
-         strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
          wrq.u.txpower.value = -1;
          wrq.u.txpower.fixed = 1;
          wrq.u.txpower.disabled = 0;
          wrq.u.txpower.value = -1;
          wrq.u.txpower.fixed = 1;
          wrq.u.txpower.disabled = 0;
@@ -1245,12 +1225,8 @@ set_info(int             skfd,           /* The socket */
                if(!strcasecmp(args[i], "fixed"))
                  {
                    /* Get old tx-power */
                if(!strcasecmp(args[i], "fixed"))
                  {
                    /* Get old tx-power */
-                   if(ioctl(skfd, SIOCGIWTXPOW, &wrq) < 0)
-                     {
-                       fprintf(stderr, "SIOCGIWTXPOW: %s\n", strerror(errno));
-                       return(-1);
-                     }
-                   strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
+                   IW_GET_EXT_ERR(skfd, ifname, SIOCGIWTXPOW, &wrq,
+                                  "Set Tx Power");
                    wrq.u.txpower.fixed = 1;
                  }
                else                    /* Should be a numeric value */
                    wrq.u.txpower.fixed = 1;
                  }
                else                    /* Should be a numeric value */
@@ -1261,7 +1237,7 @@ set_info(int              skfd,           /* The socket */
                    /* Get the value */
                    if(sscanf(args[i], "%ld",
                              (unsigned long *) &(power)) != 1)
                    /* Get the value */
                    if(sscanf(args[i], "%ld",
                              (unsigned long *) &(power)) != 1)
-                     iw_usage();
+                     ABORT_ARG_TYPE("Set Tx Power", SIOCSIWTXPOW, args[i]);
 
                    /* Check if milliwatt */
                    ismwatt = (index(args[i], 'm') != NULL);
 
                    /* Check if milliwatt */
                    ismwatt = (index(args[i], 'm') != NULL);
@@ -1292,24 +1268,21 @@ set_info(int            skfd,           /* The socket */
                  }
              }
 
                  }
              }
 
-         if(ioctl(skfd, SIOCSIWTXPOW, &wrq) < 0)
-           {
-             fprintf(stderr, "SIOCSIWTXPOW: %s\n", strerror(errno));
-             return(-1);
-           }
+         IW_SET_EXT_ERR(skfd, ifname, SIOCSIWTXPOW, &wrq,
+                        "Set Tx Power");
          continue;
        }
 #endif
 
 #if WIRELESS_EXT > 10
          continue;
        }
 #endif
 
 #if WIRELESS_EXT > 10
-      /* ---------- Set Power Management ---------- */
+      /* ---------- Set Retry limit ---------- */
       if(!strncmp(args[i], "retry", 3))
        {
          double                temp;
          int           gotone = 0;
 
          if(++i >= count)
       if(!strncmp(args[i], "retry", 3))
        {
          double                temp;
          int           gotone = 0;
 
          if(++i >= count)
-           iw_usage();
+           ABORT_ARG_NUM("Set Retry Limit", SIOCSIWRETRY);
 
          /* Default - nope */
          wrq.u.retry.flags = IW_RETRY_LIMIT;
 
          /* Default - nope */
          wrq.u.retry.flags = IW_RETRY_LIMIT;
@@ -1320,14 +1293,14 @@ set_info(int            skfd,           /* The socket */
            {
              wrq.u.retry.flags |= IW_RETRY_MIN;
              if(++i >= count)
            {
              wrq.u.retry.flags |= IW_RETRY_MIN;
              if(++i >= count)
-               iw_usage();
+               ABORT_ARG_NUM("Set Retry Limit", SIOCSIWRETRY);
            }
          else
            if(!strcasecmp(args[i], "max"))
              {
                wrq.u.retry.flags |= IW_RETRY_MAX;
                if(++i >= count)
            }
          else
            if(!strcasecmp(args[i], "max"))
              {
                wrq.u.retry.flags |= IW_RETRY_MAX;
                if(++i >= count)
-                 iw_usage();
+                 ABORT_ARG_NUM("Set Retry Limit", SIOCSIWRETRY);
              }
 
          /* Check value type */
              }
 
          /* Check value type */
@@ -1335,14 +1308,14 @@ set_info(int            skfd,           /* The socket */
            {
              wrq.u.retry.flags |= IW_RETRY_LIMIT;
              if(++i >= count)
            {
              wrq.u.retry.flags |= IW_RETRY_LIMIT;
              if(++i >= count)
-               iw_usage();
+               ABORT_ARG_NUM("Set Retry Limit", SIOCSIWRETRY);
            }
          else
            if(!strncasecmp(args[i], "lifetime", 4))
              {
                wrq.u.retry.flags |= IW_RETRY_LIFETIME;
                if(++i >= count)
            }
          else
            if(!strncasecmp(args[i], "lifetime", 4))
              {
                wrq.u.retry.flags |= IW_RETRY_LIFETIME;
                if(++i >= count)
-                 iw_usage();
+                 ABORT_ARG_NUM("Set Retry Limit", SIOCSIWRETRY);
              }
 
          /* Is there any value to grab ? */
              }
 
          /* Is there any value to grab ? */
@@ -1362,15 +1335,11 @@ set_info(int            skfd,           /* The socket */
            }
 
          if(!gotone)
            }
 
          if(!gotone)
-           iw_usage();
+           ABORT_ARG_TYPE("Set Retry Limit", SIOCSIWRETRY, args[i]);
          --i;
 
          --i;
 
-         if(ioctl(skfd, SIOCSIWRETRY, &wrq) < 0)
-           {
-             fprintf(stderr, "SIOCSIWRETRY(%d): %s\n",
-                     errno, strerror(errno));
-             return(-1);
-           }
+         IW_SET_EXT_ERR(skfd, ifname, SIOCSIWRETRY, &wrq,
+                        "Set Retry Limit");
          continue;
        }
 
          continue;
        }
 
@@ -1378,8 +1347,8 @@ set_info(int              skfd,           /* The socket */
 
       /* ---------- Other ---------- */
       /* Here we have an unrecognised arg... */
 
       /* ---------- Other ---------- */
       /* Here we have an unrecognised arg... */
-      fprintf(stderr, "Invalid argument : %s\n", args[i]);
-      iw_usage();
+      fprintf(stderr, "Error : unrecognised wireless request \"%s\"\n",
+             args[i]);
       return(-1);
     }          /* for(index ... */
   return(0);
       return(-1);
     }          /* for(index ... */
   return(0);
index 226c8c5..c550431 100644 (file)
@@ -6,6 +6,7 @@
  * Just print the ESSID or NWID...
  *
  * This file is released under the GPL license.
  * Just print the ESSID or NWID...
  *
  * This file is released under the GPL license.
+ *     Copyright (c) 1997-2002 Jean Tourrilhes <jt@hpl.hp.com>
  */
 
 #include "iwlib.h"             /* Header */
  */
 
 #include "iwlib.h"             /* Header */
index ed3e357..421f4e1 100644 (file)
@@ -6,6 +6,7 @@
  * Common subroutines to all the wireless tools...
  *
  * This file is released under the GPL license.
  * Common subroutines to all the wireless tools...
  *
  * This file is released under the GPL license.
+ *     Copyright (c) 1997-2002 Jean Tourrilhes <jt@hpl.hp.com>
  */
 
 #include "iwlib.h"             /* Header */
  */
 
 #include "iwlib.h"             /* Header */
@@ -74,13 +75,12 @@ iw_get_range_info(int               skfd,
   char                 buffer[sizeof(iwrange) * 2];    /* Large enough */
 
   /* Cleanup */
   char                 buffer[sizeof(iwrange) * 2];    /* Large enough */
 
   /* Cleanup */
-  memset(buffer, 0, sizeof(range));
+  memset(buffer, 0, sizeof(iwrange) * 2);
 
 
-  strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
   wrq.u.data.pointer = (caddr_t) buffer;
   wrq.u.data.pointer = (caddr_t) buffer;
-  wrq.u.data.length = 0;
+  wrq.u.data.length = sizeof(iwrange) * 2;
   wrq.u.data.flags = 0;
   wrq.u.data.flags = 0;
-  if(ioctl(skfd, SIOCGIWRANGE, &wrq) < 0)
+  if(iw_get_ext(skfd, ifname, SIOCGIWRANGE, &wrq) < 0)
     return(-1);
 
   /* Copy stuff at the right place, ignore extra */
     return(-1);
 
   /* Copy stuff at the right place, ignore extra */
@@ -135,11 +135,10 @@ iw_get_priv_info(int              skfd,
   struct iwreq         wrq;
 
   /* Ask the driver */
   struct iwreq         wrq;
 
   /* Ask the driver */
-  strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
   wrq.u.data.pointer = (caddr_t) priv;
   wrq.u.data.pointer = (caddr_t) priv;
-  wrq.u.data.length = 0;
+  wrq.u.data.length = 32;
   wrq.u.data.flags = 0;
   wrq.u.data.flags = 0;
-  if(ioctl(skfd, SIOCGIWPRIV, &wrq) < 0)
+  if(iw_get_ext(skfd, ifname, SIOCGIWPRIV, &wrq) < 0)
     return(-1);
 
   /* Return the number of ioctls */
     return(-1);
 
   /* Return the number of ioctls */
@@ -164,35 +163,31 @@ iw_get_basic_config(int                   skfd,
   memset((char *) info, 0, sizeof(struct wireless_config));
 
   /* Get wireless name */
   memset((char *) info, 0, sizeof(struct wireless_config));
 
   /* Get wireless name */
-  strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
-  if(ioctl(skfd, SIOCGIWNAME, &wrq) < 0)
+  if(iw_get_ext(skfd, ifname, SIOCGIWNAME, &wrq) < 0)
     /* If no wireless name : no wireless extensions */
     return(-1);
   else
     strcpy(info->name, wrq.u.name);
 
   /* Get network ID */
     /* If no wireless name : no wireless extensions */
     return(-1);
   else
     strcpy(info->name, wrq.u.name);
 
   /* Get network ID */
-  strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
-  if(ioctl(skfd, SIOCGIWNWID, &wrq) >= 0)
+  if(iw_get_ext(skfd, ifname, SIOCGIWNWID, &wrq) >= 0)
     {
       info->has_nwid = 1;
       memcpy(&(info->nwid), &(wrq.u.nwid), sizeof(iwparam));
     }
 
   /* Get frequency / channel */
     {
       info->has_nwid = 1;
       memcpy(&(info->nwid), &(wrq.u.nwid), sizeof(iwparam));
     }
 
   /* Get frequency / channel */
-  strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
-  if(ioctl(skfd, SIOCGIWFREQ, &wrq) >= 0)
+  if(iw_get_ext(skfd, ifname, SIOCGIWFREQ, &wrq) >= 0)
     {
       info->has_freq = 1;
       info->freq = iw_freq2float(&(wrq.u.freq));
     }
 
   /* Get encryption information */
     {
       info->has_freq = 1;
       info->freq = iw_freq2float(&(wrq.u.freq));
     }
 
   /* Get encryption information */
-  strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
   wrq.u.data.pointer = (caddr_t) info->key;
   wrq.u.data.pointer = (caddr_t) info->key;
-  wrq.u.data.length = 0;
+  wrq.u.data.length = IW_ENCODING_TOKEN_MAX;
   wrq.u.data.flags = 0;
   wrq.u.data.flags = 0;
-  if(ioctl(skfd, SIOCGIWENCODE, &wrq) >= 0)
+  if(iw_get_ext(skfd, ifname, SIOCGIWENCODE, &wrq) >= 0)
     {
       info->has_key = 1;
       info->key_size = wrq.u.data.length;
     {
       info->has_key = 1;
       info->key_size = wrq.u.data.length;
@@ -200,19 +195,17 @@ iw_get_basic_config(int                   skfd,
     }
 
   /* Get ESSID */
     }
 
   /* Get ESSID */
-  strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
   wrq.u.essid.pointer = (caddr_t) info->essid;
   wrq.u.essid.pointer = (caddr_t) info->essid;
-  wrq.u.essid.length = 0;
+  wrq.u.essid.length = IW_ESSID_MAX_SIZE;
   wrq.u.essid.flags = 0;
   wrq.u.essid.flags = 0;
-  if(ioctl(skfd, SIOCGIWESSID, &wrq) >= 0)
+  if(iw_get_ext(skfd, ifname, SIOCGIWESSID, &wrq) >= 0)
     {
       info->has_essid = 1;
       info->essid_on = wrq.u.data.flags;
     }
 
   /* Get operation mode */
     {
       info->has_essid = 1;
       info->essid_on = wrq.u.data.flags;
     }
 
   /* Get operation mode */
-  strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
-  if(ioctl(skfd, SIOCGIWMODE, &wrq) >= 0)
+  if(iw_get_ext(skfd, ifname, SIOCGIWMODE, &wrq) >= 0)
     {
       if((wrq.u.mode < 6) && (wrq.u.mode >= 0))
        info->has_mode = 1;
     {
       if((wrq.u.mode < 6) && (wrq.u.mode >= 0))
        info->has_mode = 1;
@@ -238,19 +231,17 @@ iw_set_basic_config(int                   skfd,
   int                  ret = 0;
 
   /* Get wireless name (check if interface is valid) */
   int                  ret = 0;
 
   /* Get wireless name (check if interface is valid) */
-  strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
-  if(ioctl(skfd, SIOCGIWNAME, &wrq) < 0)
+  if(iw_get_ext(skfd, ifname, SIOCGIWNAME, &wrq) < 0)
     /* If no wireless name : no wireless extensions */
     return(-2);
 
   /* Set Network ID, if available (this is for non-802.11 cards) */
   if(info->has_nwid)
     {
     /* If no wireless name : no wireless extensions */
     return(-2);
 
   /* Set Network ID, if available (this is for non-802.11 cards) */
   if(info->has_nwid)
     {
-      strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
       memcpy(&(wrq.u.nwid), &(info->nwid), sizeof(iwparam));
       wrq.u.nwid.fixed = 1;    /* Hum... When in Rome... */
 
       memcpy(&(wrq.u.nwid), &(info->nwid), sizeof(iwparam));
       wrq.u.nwid.fixed = 1;    /* Hum... When in Rome... */
 
-      if(ioctl(skfd, SIOCSIWNWID, &wrq) < 0)
+      if(iw_set_ext(skfd, ifname, SIOCSIWNWID, &wrq) < 0)
        {
          fprintf(stderr, "SIOCSIWNWID: %s\n", strerror(errno));
          ret = -1;
        {
          fprintf(stderr, "SIOCSIWNWID: %s\n", strerror(errno));
          ret = -1;
@@ -260,10 +251,9 @@ iw_set_basic_config(int                    skfd,
   /* Set frequency / channel */
   if(info->has_freq)
     {
   /* Set frequency / channel */
   if(info->has_freq)
     {
-      strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
       iw_float2freq(info->freq, &(wrq.u.freq));
 
       iw_float2freq(info->freq, &(wrq.u.freq));
 
-      if(ioctl(skfd, SIOCSIWFREQ, &wrq) < 0)
+      if(iw_set_ext(skfd, ifname, SIOCSIWFREQ, &wrq) < 0)
        {
          fprintf(stderr, "SIOCSIWFREQ: %s\n", strerror(errno));
          ret = -1;
        {
          fprintf(stderr, "SIOCSIWFREQ: %s\n", strerror(errno));
          ret = -1;
@@ -279,12 +269,11 @@ iw_set_basic_config(int                   skfd,
       if((flags & IW_ENCODE_INDEX) > 0)
        {
          /* Set the index */
       if((flags & IW_ENCODE_INDEX) > 0)
        {
          /* Set the index */
-         strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
          wrq.u.data.pointer = (caddr_t) NULL;
          wrq.u.data.pointer = (caddr_t) NULL;
-         wrq.u.data.flags = flags & (IW_ENCODE_INDEX);
+         wrq.u.data.flags = (flags & (IW_ENCODE_INDEX)) | IW_ENCODE_NOKEY;
          wrq.u.data.length = 0;
 
          wrq.u.data.length = 0;
 
-         if(ioctl(skfd, SIOCSIWENCODE, &wrq) < 0)
+         if(iw_set_ext(skfd, ifname, SIOCSIWENCODE, &wrq) < 0)
            {
              fprintf(stderr, "SIOCSIWENCODE(%d): %s\n",
                      errno, strerror(errno));
            {
              fprintf(stderr, "SIOCSIWENCODE(%d): %s\n",
                      errno, strerror(errno));
@@ -296,12 +285,11 @@ iw_set_basic_config(int                   skfd,
       flags = flags & (~IW_ENCODE_INDEX);
 
       /* Set the key itself (set current key in this case) */
       flags = flags & (~IW_ENCODE_INDEX);
 
       /* Set the key itself (set current key in this case) */
-      strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
       wrq.u.data.pointer = (caddr_t) info->key;
       wrq.u.data.length = info->key_size;
       wrq.u.data.flags = flags;
 
       wrq.u.data.pointer = (caddr_t) info->key;
       wrq.u.data.length = info->key_size;
       wrq.u.data.flags = flags;
 
-      if(ioctl(skfd, SIOCSIWENCODE, &wrq) < 0)
+      if(iw_set_ext(skfd, ifname, SIOCSIWENCODE, &wrq) < 0)
        {
          fprintf(stderr, "SIOCSIWENCODE(%d): %s\n",
                  errno, strerror(errno));
        {
          fprintf(stderr, "SIOCSIWENCODE(%d): %s\n",
                  errno, strerror(errno));
@@ -312,12 +300,11 @@ iw_set_basic_config(int                   skfd,
   /* Set ESSID (extended network), if available */
   if(info->has_essid)
     {
   /* Set ESSID (extended network), if available */
   if(info->has_essid)
     {
-      strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
       wrq.u.essid.pointer = (caddr_t) info->essid;
       wrq.u.essid.length = strlen(info->essid) + 1;
       wrq.u.data.flags = info->essid_on;
 
       wrq.u.essid.pointer = (caddr_t) info->essid;
       wrq.u.essid.length = strlen(info->essid) + 1;
       wrq.u.data.flags = info->essid_on;
 
-      if(ioctl(skfd, SIOCSIWESSID, &wrq) < 0)
+      if(iw_set_ext(skfd, ifname, SIOCSIWESSID, &wrq) < 0)
        {
          fprintf(stderr, "SIOCSIWESSID: %s\n", strerror(errno));
          ret = -1;
        {
          fprintf(stderr, "SIOCSIWESSID: %s\n", strerror(errno));
          ret = -1;
@@ -330,7 +317,7 @@ iw_set_basic_config(int                     skfd,
       strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
       wrq.u.mode = info->mode;
 
       strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
       wrq.u.mode = info->mode;
 
-      if(ioctl(skfd, SIOCSIWMODE, &wrq) < 0)
+      if(iw_get_ext(skfd, ifname, SIOCSIWMODE, &wrq) < 0)
        {
          fprintf(stderr, "SIOCSIWMODE: %s\n", strerror(errno));
          ret = -1;
        {
          fprintf(stderr, "SIOCSIWMODE: %s\n", strerror(errno));
          ret = -1;
@@ -415,7 +402,7 @@ iw_get_stats(int    skfd,
   wrq.u.data.length = 0;
   wrq.u.data.flags = 1;                /* Clear updated flag */
   strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
   wrq.u.data.length = 0;
   wrq.u.data.flags = 1;                /* Clear updated flag */
   strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
-  if(ioctl(skfd, SIOCGIWSTATS, &wrq) < 0)
+  if(iw_get_ext(skfd, ifname, SIOCGIWSTATS, &wrq) < 0)
     return(-1);
 
   return(0);
     return(-1);
 
   return(0);
@@ -702,48 +689,82 @@ iw_print_retry_value(char *       buffer,
 
 /*------------------------------------------------------------------*/
 /*
 
 /*------------------------------------------------------------------*/
 /*
- * Check if interface support the right address types...
+ * Check if interface support the right MAC address type...
  */
 int
  */
 int
-iw_check_addr_type(int         skfd,
-                  char *       ifname)
+iw_check_mac_addr_type(int             skfd,
+                      char *           ifname)
 {
   struct ifreq         ifr;
 
 {
   struct ifreq         ifr;
 
-  /* Get the type of interface address */
+  /* Get the type of hardware address */
   strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
   strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
-  if((ioctl(skfd, SIOCGIFADDR, &ifr) < 0) ||
-     (ifr.ifr_addr.sa_family !=  AF_INET))
+  if((ioctl(skfd, SIOCGIFHWADDR, &ifr) < 0) ||
+     (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER))
     {
       /* Deep trouble... */
     {
       /* Deep trouble... */
-      fprintf(stderr, "Interface %s doesn't support IP addresses\n", ifname);
+      fprintf(stderr, "Interface %s doesn't support MAC addresses\n",
+            ifname);
       return(-1);
     }
 
 #ifdef DEBUG
       return(-1);
     }
 
 #ifdef DEBUG
-  printf("Interface : %d - 0x%lX\n", ifr.ifr_addr.sa_family,
-        *((unsigned long *) ifr.ifr_addr.sa_data));
+  printf("Hardware : %d - %s\n", ifr.ifr_hwaddr.sa_family,
+        pr_ether(ifr.ifr_hwaddr.sa_data));
 #endif
 
 #endif
 
-  /* Get the type of hardware address */
+  return(0);
+}
+
+
+/*------------------------------------------------------------------*/
+/*
+ * Check if interface support the right interface address type...
+ */
+int
+iw_check_if_addr_type(int              skfd,
+                     char *            ifname)
+{
+  struct ifreq         ifr;
+
+  /* Get the type of interface address */
   strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
   strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
-  if((ioctl(skfd, SIOCGIFHWADDR, &ifr) < 0) ||
-     (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER))
+  if((ioctl(skfd, SIOCGIFADDR, &ifr) < 0) ||
+     (ifr.ifr_addr.sa_family !=  AF_INET))
     {
       /* Deep trouble... */
     {
       /* Deep trouble... */
-      fprintf(stderr, "Interface %s doesn't support MAC addresses\n",
-            ifname);
+      fprintf(stderr, "Interface %s doesn't support IP addresses\n", ifname);
       return(-1);
     }
 
 #ifdef DEBUG
       return(-1);
     }
 
 #ifdef DEBUG
-  printf("Hardware : %d - %s\n", ifr.ifr_hwaddr.sa_family,
-        pr_ether(ifr.ifr_hwaddr.sa_data));
+  printf("Interface : %d - 0x%lX\n", ifr.ifr_addr.sa_family,
+        *((unsigned long *) ifr.ifr_addr.sa_data));
 #endif
 
   return(0);
 }
 
 #endif
 
   return(0);
 }
 
+#if 0
+/*------------------------------------------------------------------*/
+/*
+ * Check if interface support the right address types...
+ */
+int
+iw_check_addr_type(int         skfd,
+                  char *       ifname)
+{
+  /* Check the interface address type */
+  if(iw_check_if_addr_type(skfd, ifname) < 0)
+    return(-1);
+
+  /* Check the interface address type */
+  if(iw_check_mac_addr_type(skfd, ifname) < 0)
+    return(-1);
+
+  return(0);
+}
+#endif
 
 /*------------------------------------------------------------------*/
 /*
 
 /*------------------------------------------------------------------*/
 /*
@@ -887,6 +908,13 @@ iw_in_addr(int             skfd,
       struct sockaddr  if_address;
       struct arpreq    arp_query;
 
       struct sockaddr  if_address;
       struct arpreq    arp_query;
 
+      /* Check if we have valid interface address type */
+      if(iw_check_if_addr_type(skfd, ifname) < 0)
+       {
+         fprintf(stderr, "%-8.8s  Interface doesn't support IP addresses\n", ifname);
+         return(-1);
+       }
+
       /* Read interface address */
       if(iw_in_inet(bufp, &if_address) < 0)
        {
       /* Read interface address */
       if(iw_in_inet(bufp, &if_address) < 0)
        {
@@ -922,12 +950,21 @@ iw_in_addr(int            skfd,
 #endif
     }
   else /* If it's an hardware address */
 #endif
     }
   else /* If it's an hardware address */
-    /* Get the hardware address */
-    if(iw_in_ether(bufp, sap) < 0)
-      {
-       fprintf(stderr, "Invalid hardware address %s\n", bufp);
-       return(-1);
-      }
+    {
+      /* Check if we have valid mac address type */
+      if(iw_check_mac_addr_type(skfd, ifname) < 0)
+       {
+         fprintf(stderr, "%-8.8s  Interface doesn't support MAC addresses\n", ifname);
+         return(-1);
+       }
+
+      /* Get the hardware address */
+      if(iw_in_ether(bufp, sap) < 0)
+       {
+         fprintf(stderr, "Invalid hardware address %s\n", bufp);
+         return(-1);
+       }
+    }
 
 #ifdef DEBUG
   printf("Hw Address = %s\n", pr_ether(sap->sa_data));
 
 #ifdef DEBUG
   printf("Hw Address = %s\n", pr_ether(sap->sa_data));
index 723475b..b195b82 100644 (file)
@@ -1,11 +1,12 @@
 /*
  *     Wireless Tools
  *
 /*
  *     Wireless Tools
  *
- *             Jean II - HPLB 97->99 - HPL 99->01
+ *             Jean II - HPLB 97->99 - HPL 99->02
  *
  * Common header for the Wireless Extension library...
  *
  * This file is released under the GPL license.
  *
  * Common header for the Wireless Extension library...
  *
  * This file is released under the GPL license.
+ *     Copyright (c) 1997-2002 Jean Tourrilhes <jt@hpl.hp.com>
  */
 
 #ifndef IWLIB_H
  */
 
 #ifndef IWLIB_H
 #include <netdb.h>             /* gethostbyname, getnetbyname */
 
 /* This is our header selection. Try to hide the mess and the misery :-(
 #include <netdb.h>             /* gethostbyname, getnetbyname */
 
 /* This is our header selection. Try to hide the mess and the misery :-(
- * The selection has been moved in the Makefile, here we have only
- * the ugly part. Don't look, you would go blind ;-) */
+ * Don't look, you would go blind ;-) */
 
 
-#ifdef KLUDGE_HEADERS
-#include <socketbits.h>
-#endif /* KLUDGE_HEADERS */
+#ifndef LINUX_VERSION_CODE
+#include <linux/version.h>
+#endif
 
 
-#if defined(KLUDGE_HEADERS) || defined(GLIBC_HEADERS)
-#include <linux/if_arp.h>      /* For ARPHRD_ETHER */
-#include <linux/socket.h>      /* For AF_INET & struct sockaddr */
-#include <linux/in.h>          /* For struct sockaddr_in */
-#endif /* KLUDGE_HEADERS || GLIBC_HEADERS */
+/* Kernel headers 2.4.X + Glibc 2.2 - Mandrake 8.0, Debian 2.3, RH 7.1 */
+#if defined(__GLIBC__) \
+    && __GLIBC__ == 2 \
+    && __GLIBC_MINOR__ >= 2 \
+    && LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+#define GLIBC22_HEADERS
+
+/* Kernel headers 2.4.X + Glibc 2.1 - Debian 2.2 upgraded, RH 7.0
+ * Kernel headers 2.2.X + Glibc 2.1 - Debian 2.2, RH 6.1 */
+#elif defined(__GLIBC__) \
+      && __GLIBC__ == 2 \
+      && __GLIBC_MINOR__ == 1 \
+      && LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
+#define GLIBC_HEADERS
+
+/* Kernel headers 2.2.X + Glibc 2.0 - Debian 2.1 */
+#elif defined(__GLIBC__) \
+      && __GLIBC__ == 2 \
+      && __GLIBC_MINOR__ == 0 \
+      && LINUX_VERSION_CODE >= KERNEL_VERSION(2,0,0) \
+      && LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)
+#define GLIBC_HEADERS
+#define KLUDGE_HEADERS
+
+/* Note : is it really worth supporting kernel 2.0.X, knowing that
+ * we require WE v9, which is only available in 2.2.X and higher ?
+ * I guess one could use 2.0.x with an upgraded wireless.h... */
+
+/* Kernel headers 2.0.X + Glibc 2.0 - Debian 2.0, RH 5 */
+#elif defined(__GLIBC__) \
+      && __GLIBC__ == 2 \
+      && __GLIBC_MINOR__ == 0 \
+      && LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0) \
+      && LINUX_VERSION_CODE >= KERNEL_VERSION(2,0,0)
+#define GLIBC_HEADERS
+
+/* Kernel headers 2.0.X + libc5 - old systems */
+#elif defined(_LINUX_C_LIB_VERSION_MAJOR) \
+      && _LINUX_C_LIB_VERSION_MAJOR == 5 \
+      && LINUX_VERSION_CODE >= KERNEL_VERSION(2,0,0) \
+      && LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)
+#define LIBC5_HEADERS
+
+/* Unsupported combination */
+#else
+#error "Your kernel/libc combination is not supported"
+#endif
 
 #ifdef GLIBC22_HEADERS 
 /* Added by Ross G. Miller <Ross_Miller@baylor.edu>, 3/28/01 */
 
 #ifdef GLIBC22_HEADERS 
 /* Added by Ross G. Miller <Ross_Miller@baylor.edu>, 3/28/01 */
 #include <sys/socket.h>
 #endif /* GLIBC22_HEADERS */    
 
 #include <sys/socket.h>
 #endif /* GLIBC22_HEADERS */    
 
+#ifdef KLUDGE_HEADERS
+#include <socketbits.h>
+#endif /* KLUDGE_HEADERS */
+
+#ifdef GLIBC_HEADERS
+#include <linux/if_arp.h>      /* For ARPHRD_ETHER */
+#include <linux/socket.h>      /* For AF_INET & struct sockaddr */
+#include <linux/in.h>          /* For struct sockaddr_in */
+#endif /* KLUDGE_HEADERS || GLIBC_HEADERS */
+
 #ifdef LIBC5_HEADERS
 #include <sys/socket.h>                /* For AF_INET & struct sockaddr & socket() */
 #include <linux/if_arp.h>      /* For ARPHRD_ETHER */
 #ifdef LIBC5_HEADERS
 #include <sys/socket.h>                /* For AF_INET & struct sockaddr & socket() */
 #include <linux/if_arp.h>      /* For ARPHRD_ETHER */
 #error "Wireless Extension v9 or newer required :-(\
 Use Wireless Tools v19 or update your kernel headers"
 #endif
 #error "Wireless Extension v9 or newer required :-(\
 Use Wireless Tools v19 or update your kernel headers"
 #endif
-#if WIRELESS_EXT < 11
-#warning "Wireless Extension v11 recommended...\
+#if WIRELESS_EXT < 12
+#warning "Wireless Extension v12 recommended...\
 You may update your kernel and/or system headers to get the new features..."
 #endif
 
 You may update your kernel and/or system headers to get the new features..."
 #endif
 
@@ -88,12 +140,17 @@ You may update your kernel and/or system headers to get the new features..."
 #define IW_POWER_MIN           0x0001  /* Value is a minimum  */
 #define IW_POWER_MAX           0x0002  /* Value is a maximum */
 #define IW_POWER_RELATIVE      0x0004  /* Value is not in seconds/ms/us */
 #define IW_POWER_MIN           0x0001  /* Value is a minimum  */
 #define IW_POWER_MAX           0x0002  /* Value is a maximum */
 #define IW_POWER_RELATIVE      0x0004  /* Value is not in seconds/ms/us */
-#endif IW_POWER_MODIFIER
+#endif /* IW_POWER_MODIFIER */
 
 #ifndef IW_ENCODE_NOKEY
 #define IW_ENCODE_NOKEY         0x0800  /* Key is write only, so not here */
 #define IW_ENCODE_MODE         0xF000  /* Modes defined below */
 
 #ifndef IW_ENCODE_NOKEY
 #define IW_ENCODE_NOKEY         0x0800  /* Key is write only, so not here */
 #define IW_ENCODE_MODE         0xF000  /* Modes defined below */
-#endif IW_ENCODE_NOKEY
+#endif /* IW_ENCODE_NOKEY */
+
+/* More backward compatibility */
+#ifndef SIOCSIWCOMMIT
+#define SIOCSIWCOMMIT  SIOCSIWNAME
+#endif /* SIOCSIWCOMMIT */
 
 /****************************** TYPES ******************************/
 
 
 /****************************** TYPES ******************************/
 
@@ -240,8 +297,16 @@ void
 #endif
 /* --------------------- ADDRESS SUBROUTINES ---------------------- */
 int
 #endif
 /* --------------------- ADDRESS SUBROUTINES ---------------------- */
 int
+       iw_check_mac_addr_type(int      skfd,
+                              char *   ifname);
+int
+       iw_check_if_addr_type(int       skfd,
+                             char *    ifname);
+#if 0
+int
        iw_check_addr_type(int  skfd,
                        char *  ifname);
        iw_check_addr_type(int  skfd,
                        char *  ifname);
+#endif
 char *
        iw_pr_ether(char *buffer, unsigned char *ptr);
 int
 char *
        iw_pr_ether(char *buffer, unsigned char *ptr);
 int
@@ -262,4 +327,46 @@ int
 extern const char *    iw_operation_mode[];
 #define IW_NUM_OPER_MODE       6
 
 extern const char *    iw_operation_mode[];
 #define IW_NUM_OPER_MODE       6
 
+/************************* INLINE FUNTIONS *************************/
+/*
+ * Function that are so simple that it's more efficient inlining them
+ */
+
+/*
+ * Note : I've defined wrapper for the ioctl request so that
+ * it will be easier to migrate to other kernel API if needed
+ */
+
+/*------------------------------------------------------------------*/
+/*
+ * Wrapper to push some Wireless Parameter in the driver
+ */
+static inline int
+iw_set_ext(int                 skfd,           /* Socket to the kernel */
+          char *               ifname,         /* Device name */
+          int                  request,        /* WE ID */
+          struct iwreq *       pwrq)           /* Fixed part of the request */
+{
+  /* Set device name */
+  strncpy(pwrq->ifr_name, ifname, IFNAMSIZ);
+  /* Do the request */
+  return(ioctl(skfd, request, pwrq));
+}
+
+/*------------------------------------------------------------------*/
+/*
+ * Wrapper to extract some Wireless Parameter out of the driver
+ */
+static inline int
+iw_get_ext(int                 skfd,           /* Socket to the kernel */
+          char *               ifname,         /* Device name */
+          int                  request,        /* WE ID */
+          struct iwreq *       pwrq)           /* Fixed part of the request */
+{
+  /* Set device name */
+  strncpy(pwrq->ifr_name, ifname, IFNAMSIZ);
+  /* Do the request */
+  return(ioctl(skfd, request, pwrq));
+}
+
 #endif /* IWLIB_H */
 #endif /* IWLIB_H */
index f362bae..3c86fef 100644 (file)
@@ -17,7 +17,7 @@ iwlist \- Get wireless statistics from specific nodes
 .br
 .BI "iwlist " interface " rate"
 .br
 .br
 .BI "iwlist " interface " rate"
 .br
-.BI "iwlist " interface " keys"
+.BI "iwlist " interface " key"
 .br
 .BI "iwlist " interface " power"
 .br
 .br
 .BI "iwlist " interface " power"
 .br
@@ -37,21 +37,21 @@ list of parameters.
 .\"
 .SH PARAMETERS
 .TP
 .\"
 .SH PARAMETERS
 .TP
-.B freq
+.BR freq / channel
 Give the list of available frequencies in the device and the number of
 defined channels. Please note that usually the driver returns the
 total number of channels and only the frequencies available in the
 present locale, so there is no one to one mapping between frequencies
 displayed and channel numbers.
 .TP
 Give the list of available frequencies in the device and the number of
 defined channels. Please note that usually the driver returns the
 total number of channels and only the frequencies available in the
 present locale, so there is no one to one mapping between frequencies
 displayed and channel numbers.
 .TP
-.B ap
+.BR ap / accesspoint
 Give the list of Access Points in range, and optionally the quality of
 link to them.
 .TP
 .BR rate / bit [rate]
 List the bit-rates supported by the device.
 .TP
 Give the list of Access Points in range, and optionally the quality of
 link to them.
 .TP
 .BR rate / bit [rate]
 List the bit-rates supported by the device.
 .TP
-.BR keys / enc [ryption]
+.BR key / enc [ryption]
 List the encryption key sizes supported and display all the encryption
 keys availables in the device.
 .TP
 List the encryption key sizes supported and display all the encryption
 keys availables in the device.
 .TP
index 50db6c9..30640e6 100644 (file)
@@ -5,9 +5,10 @@
  *
  * This tool can access various piece of information on the card
  * not part of iwconfig...
  *
  * This tool can access various piece of information on the card
  * not part of iwconfig...
- * You need to link this code against "iwcommon.c" and "-lm".
+ * You need to link this code against "iwlist.c" and "-lm".
  *
  * This file is released under the GPL license.
  *
  * This file is released under the GPL license.
+ *     Copyright (c) 1997-2002 Jean Tourrilhes <jt@hpl.hp.com>
  */
 
 #include "iwlib.h"             /* Header */
  */
 
 #include "iwlib.h"             /* Header */
@@ -80,11 +81,10 @@ print_ap_info(int   skfd,
   int          i;
 
   /* Collect stats */
   int          i;
 
   /* Collect stats */
-  strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
   wrq.u.data.pointer = (caddr_t) buffer;
   wrq.u.data.pointer = (caddr_t) buffer;
-  wrq.u.data.length = 0;
+  wrq.u.data.length = IW_MAX_AP;
   wrq.u.data.flags = 0;
   wrq.u.data.flags = 0;
-  if(ioctl(skfd, SIOCGIWAPLIST, &wrq) < 0)
+  if(iw_get_ext(skfd, ifname, SIOCGIWAPLIST, &wrq) < 0)
     {
       fprintf(stderr, "%-8.8s  Interface doesn't have a list of Access Points\n\n", ifname);
       return;
     {
       fprintf(stderr, "%-8.8s  Interface doesn't have a list of Access Points\n\n", ifname);
       return;
@@ -98,10 +98,10 @@ print_ap_info(int   skfd,
   hwa = (struct sockaddr *) buffer;
   qual = (struct iw_quality *) (buffer + (sizeof(struct sockaddr) * n));
 
   hwa = (struct sockaddr *) buffer;
   qual = (struct iw_quality *) (buffer + (sizeof(struct sockaddr) * n));
 
-  /* Check if we have valid address types */
-  if(iw_check_addr_type(skfd, ifname) < 0)
+  /* Check if we have valid mac address type */
+  if(iw_check_mac_addr_type(skfd, ifname) < 0)
     {
     {
-      fprintf(stderr, "%-8.8s  Interface doesn't support MAC & IP addresses\n\n", ifname);
+      fprintf(stderr, "%-8.8s  Interface doesn't support MAC addresses\n\n", ifname);
       return;
     }
 
       return;
     }
 
@@ -212,11 +212,10 @@ print_keys_info(int               skfd,
       printf("%d keys available :\n", range.max_encoding_tokens);
       for(k = 1; k <= range.max_encoding_tokens; k++)
        {
       printf("%d keys available :\n", range.max_encoding_tokens);
       for(k = 1; k <= range.max_encoding_tokens; k++)
        {
-         strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
          wrq.u.data.pointer = (caddr_t) key;
          wrq.u.data.pointer = (caddr_t) key;
-         wrq.u.data.length = 0;
+         wrq.u.data.length = IW_ENCODING_TOKEN_MAX;
          wrq.u.data.flags = k;
          wrq.u.data.flags = k;
-         if(ioctl(skfd, SIOCGIWENCODE, &wrq) < 0)
+         if(iw_get_ext(skfd, ifname, SIOCGIWENCODE, &wrq) < 0)
            {
              fprintf(stderr, "SIOCGIWENCODE: %s\n", strerror(errno));
              break;
            {
              fprintf(stderr, "SIOCGIWENCODE: %s\n", strerror(errno));
              break;
@@ -236,11 +235,10 @@ print_keys_info(int               skfd,
            }
        }
       /* Print current key and mode */
            }
        }
       /* Print current key and mode */
-      strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
       wrq.u.data.pointer = (caddr_t) key;
       wrq.u.data.pointer = (caddr_t) key;
-      wrq.u.data.length = 0;
+      wrq.u.data.length = IW_ENCODING_TOKEN_MAX;
       wrq.u.data.flags = 0;    /* Set index to zero to get current */
       wrq.u.data.flags = 0;    /* Set index to zero to get current */
-      if(ioctl(skfd, SIOCGIWENCODE, &wrq) < 0)
+      if(iw_get_ext(skfd, ifname, SIOCGIWENCODE, &wrq) < 0)
        {
          fprintf(stderr, "SIOCGIWENCODE: %s\n", strerror(errno));
          return;
        {
          fprintf(stderr, "SIOCGIWENCODE: %s\n", strerror(errno));
          return;
@@ -270,9 +268,8 @@ get_pm_value(int            skfd,
             char *             buffer)
 {
   /* Get Another Power Management value */
             char *             buffer)
 {
   /* Get Another Power Management value */
-  strncpy(pwrq->ifr_name, ifname, IFNAMSIZ);
   pwrq->u.power.flags = flags;
   pwrq->u.power.flags = flags;
-  if(ioctl(skfd, SIOCGIWPOWER, pwrq) >= 0)
+  if(iw_get_ext(skfd, ifname, SIOCGIWPOWER, pwrq) >= 0)
     {
       /* Let's check the value and its type */
       if(pwrq->u.power.flags & IW_POWER_TYPE)
     {
       /* Let's check the value and its type */
       if(pwrq->u.power.flags & IW_POWER_TYPE)
@@ -354,9 +351,8 @@ print_pm_info(int           skfd,
 #endif /* WIRELESS_EXT > 9 */
 
       /* Get current Power Management settings */
 #endif /* WIRELESS_EXT > 9 */
 
       /* Get current Power Management settings */
-      strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
       wrq.u.power.flags = 0;
       wrq.u.power.flags = 0;
-      if(ioctl(skfd, SIOCGIWPOWER, &wrq) >= 0)
+      if(iw_get_ext(skfd, ifname, SIOCGIWPOWER, &wrq) >= 0)
        {
          int   flags = wrq.u.power.flags;
 
        {
          int   flags = wrq.u.power.flags;
 
@@ -485,9 +481,8 @@ get_retry_value(int         skfd,
                char *          buffer)
 {
   /* Get Another retry value */
                char *          buffer)
 {
   /* Get Another retry value */
-  strncpy(pwrq->ifr_name, ifname, IFNAMSIZ);
   pwrq->u.retry.flags = flags;
   pwrq->u.retry.flags = flags;
-  if(ioctl(skfd, SIOCGIWRETRY, pwrq) >= 0)
+  if(iw_get_ext(skfd, ifname, SIOCGIWRETRY, pwrq) >= 0)
     {
       /* Let's check the value and its type */
       if(pwrq->u.retry.flags & IW_RETRY_TYPE)
     {
       /* Let's check the value and its type */
       if(pwrq->u.retry.flags & IW_RETRY_TYPE)
@@ -554,9 +549,8 @@ print_retry_info(int                skfd,
        }
 
       /* Get current retry settings */
        }
 
       /* Get current retry settings */
-      strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
       wrq.u.retry.flags = 0;
       wrq.u.retry.flags = 0;
-      if(ioctl(skfd, SIOCGIWRETRY, &wrq) >= 0)
+      if(iw_get_ext(skfd, ifname, SIOCGIWRETRY, &wrq) >= 0)
        {
          int   flags = wrq.u.retry.flags;
 
        {
          int   flags = wrq.u.retry.flags;
 
@@ -661,7 +655,7 @@ static const struct iwlist_entry iwlist_cmds[] = {
   { "accesspoints", print_ap_info },
   { "bitrate",      print_bitrate_info },
   { "rate",         print_bitrate_info },
   { "accesspoints", print_ap_info },
   { "bitrate",      print_bitrate_info },
   { "rate",         print_bitrate_info },
-  { "encription",   print_keys_info },
+  { "encryption",   print_keys_info },
   { "key",          print_keys_info },
   { "power",        print_pm_info },
   { "txpower",      print_txpower_info },
   { "key",          print_keys_info },
   { "power",        print_pm_info },
   { "txpower",      print_txpower_info },
index 65a0aee..2db4afd 100644 (file)
@@ -5,9 +5,10 @@
  *
  * Main code for "iwconfig". This is the generic tool for most
  * manipulations...
  *
  * Main code for "iwconfig". This is the generic tool for most
  * manipulations...
- * You need to link this code against "iwcommon.c" and "-lm".
+ * You need to link this code against "iwlib.c" and "-lm".
  *
  * This file is released under the GPL license.
  *
  * This file is released under the GPL license.
+ *     Copyright (c) 1997-2002 Jean Tourrilhes <jt@hpl.hp.com>
  */
 
 #include "iwlib.h"             /* Header */
  */
 
 #include "iwlib.h"             /* Header */
@@ -38,7 +39,7 @@ print_priv_info(int           skfd,
                char *          ifname)
 {
   int          k;
                char *          ifname)
 {
   int          k;
-  iwprivargs   priv[16];
+  iwprivargs   priv[32];
   int          n;
   char *       argtype[] = { "    ", "byte", "char", "", "int ", "float" };
 
   int          n;
   char *       argtype[] = { "    ", "byte", "char", "", "int ", "float" };
 
@@ -112,6 +113,7 @@ set_private(int             skfd,           /* Socket */
   int          k;
   iwprivargs   priv[16];
   int          number;
   int          k;
   iwprivargs   priv[16];
   int          number;
+  int          temp;
 
   /* Read the private ioctls */
   number = iw_get_priv_info(skfd, ifname, priv);
 
   /* Read the private ioctls */
   number = iw_get_priv_info(skfd, ifname, priv);
@@ -152,8 +154,10 @@ set_private(int            skfd,           /* Socket */
            wrq.u.data.length = priv[k].set_args & IW_PRIV_SIZE_MASK;
 
          /* Fetch args */
            wrq.u.data.length = priv[k].set_args & IW_PRIV_SIZE_MASK;
 
          /* Fetch args */
-         for(; i < wrq.u.data.length + 1; i++)
-           sscanf(args[i], "%d", (int *)(buffer + i - 1));
+         for(; i < wrq.u.data.length + 1; i++) {
+           sscanf(args[i], "%d", &temp);
+           buffer[i - 1] = (char) temp;
+         }
          break;
 
        case IW_PRIV_TYPE_INT:
          break;
 
        case IW_PRIV_TYPE_INT:
index cd41ccd..57d9b25 100644 (file)
@@ -4,9 +4,10 @@
  *             Jean II - HPLB '99
  *
  * This tool can manipulate the spy list : add addresses and display stat
  *             Jean II - HPLB '99
  *
  * This tool can manipulate the spy list : add addresses and display stat
- * You need to link this code against "iwcommon.c" and "-lm".
+ * You need to link this code against "iwlib.c" and "-lm".
  *
  * This file is released under the GPL license.
  *
  * This file is released under the GPL license.
+ *     Copyright (c) 1997-2002 Jean Tourrilhes <jt@hpl.hp.com>
  */
 
 #include "iwlib.h"             /* Header */
  */
 
 #include "iwlib.h"             /* Header */
@@ -33,11 +34,10 @@ print_spy_info(int  skfd,
   int          i;
 
   /* Collect stats */
   int          i;
 
   /* Collect stats */
-  strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
   wrq.u.data.pointer = (caddr_t) buffer;
   wrq.u.data.pointer = (caddr_t) buffer;
-  wrq.u.data.length = 0;
+  wrq.u.data.length = IW_MAX_SPY;
   wrq.u.data.flags = 0;
   wrq.u.data.flags = 0;
-  if(ioctl(skfd, SIOCGIWSPY, &wrq) < 0)
+  if(iw_get_ext(skfd, ifname, SIOCGIWSPY, &wrq) < 0)
     {
       fprintf(stderr, "%-8.8s  Interface doesn't support wireless statistic collection\n\n", ifname);
       return;
     {
       fprintf(stderr, "%-8.8s  Interface doesn't support wireless statistic collection\n\n", ifname);
       return;
@@ -46,12 +46,10 @@ print_spy_info(int  skfd,
   /* Number of addresses */
   n = wrq.u.data.length;
 
   /* Number of addresses */
   n = wrq.u.data.length;
 
-
-
-  /* Check if we have valid address types */
-  if(iw_check_addr_type(skfd, ifname) < 0)
+  /* Check if we have valid mac address type */
+  if(iw_check_mac_addr_type(skfd, ifname) < 0)
     {
     {
-      fprintf(stderr, "%-8.8s  Interface doesn't support MAC & IP addresses\n\n", ifname);
+      fprintf(stderr, "%-8.8s  Interface doesn't support MAC addresses\n\n", ifname);
       return;
     }
 
       return;
     }
 
@@ -136,13 +134,6 @@ set_spy_info(int           skfd,           /* The socket */
   i = 0;       /* first arg to read */
   nbr = 0;     /* Number of args readen so far */
 
   i = 0;       /* first arg to read */
   nbr = 0;     /* Number of args readen so far */
 
-  /* Check if we have valid address types */
-  if(iw_check_addr_type(skfd, ifname) < 0)
-    {
-      fprintf(stderr, "%-8.8s  Interface doesn't support MAC & IP addresses\n", ifname);
-      return(-1);
-    }
-
   /* "off" : disable functionality (set 0 addresses) */
   if(!strcmp(args[0], "off"))
     i = count; /* hack */
   /* "off" : disable functionality (set 0 addresses) */
   if(!strcmp(args[0], "off"))
     i = count; /* hack */
@@ -153,11 +144,17 @@ set_spy_info(int          skfd,           /* The socket */
       char     buffer[(sizeof(struct iw_quality) +
                        sizeof(struct sockaddr)) * IW_MAX_SPY];
 
       char     buffer[(sizeof(struct iw_quality) +
                        sizeof(struct sockaddr)) * IW_MAX_SPY];
 
-      strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
+      /* Check if we have valid mac address type */
+      if(iw_check_mac_addr_type(skfd, ifname) < 0)
+       {
+         fprintf(stderr, "%-8.8s  Interface doesn't support MAC addresses\n", ifname);
+         return(-1);
+       }
+
       wrq.u.data.pointer = (caddr_t) buffer;
       wrq.u.data.length = 0;
       wrq.u.data.flags = 0;
       wrq.u.data.pointer = (caddr_t) buffer;
       wrq.u.data.length = 0;
       wrq.u.data.flags = 0;
-      if(ioctl(skfd, SIOCGIWSPY, &wrq) < 0)
+      if(iw_get_ext(skfd, ifname, SIOCGIWSPY, &wrq) < 0)
        {
          fprintf(stderr, "Interface doesn't accept reading addresses...\n");
          fprintf(stderr, "SIOCGIWSPY: %s\n", strerror(errno));
        {
          fprintf(stderr, "Interface doesn't accept reading addresses...\n");
          fprintf(stderr, "SIOCGIWSPY: %s\n", strerror(errno));
@@ -174,6 +171,7 @@ set_spy_info(int            skfd,           /* The socket */
   /* Read other args on command line */
   while((i < count) && (nbr < IW_MAX_SPY))
     {
   /* Read other args on command line */
   while((i < count) && (nbr < IW_MAX_SPY))
     {
+      /* Get the address and check if the interface supports it */
       if(iw_in_addr(skfd, ifname, args[i++], &(hw_address[nbr])) < 0)
        continue;
       nbr++;
       if(iw_in_addr(skfd, ifname, args[i++], &(hw_address[nbr])) < 0)
        continue;
       nbr++;
@@ -193,11 +191,10 @@ set_spy_info(int          skfd,           /* The socket */
     }
 
   /* Time to do send addresses to the driver */
     }
 
   /* Time to do send addresses to the driver */
-  strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
   wrq.u.data.pointer = (caddr_t) hw_address;
   wrq.u.data.length = nbr;
   wrq.u.data.flags = 0;
   wrq.u.data.pointer = (caddr_t) hw_address;
   wrq.u.data.length = nbr;
   wrq.u.data.flags = 0;
-  if(ioctl(skfd, SIOCSIWSPY, &wrq) < 0)
+  if(iw_set_ext(skfd, ifname, SIOCSIWSPY, &wrq) < 0)
     {
       fprintf(stderr, "Interface doesn't accept addresses...\n");
       fprintf(stderr, "SIOCSIWSPY: %s\n", strerror(errno));
     {
       fprintf(stderr, "Interface doesn't accept addresses...\n");
       fprintf(stderr, "SIOCSIWSPY: %s\n", strerror(errno));
diff --git a/wireless_tools/wireless.12.h b/wireless_tools/wireless.12.h
new file mode 100644 (file)
index 0000000..4183d4a
--- /dev/null
@@ -0,0 +1,570 @@
+/*
+ * This file define a set of standard wireless extensions
+ *
+ * Version :   12      5.10.01
+ *
+ * Authors :   Jean Tourrilhes - HPL - <jt@hpl.hp.com>
+ */
+
+#ifndef _LINUX_WIRELESS_H
+#define _LINUX_WIRELESS_H
+
+/************************** DOCUMENTATION **************************/
+/*
+ * Basically, the wireless extensions are for now a set of standard ioctl
+ * call + /proc/net/wireless
+ *
+ * The entry /proc/net/wireless give statistics and information on the
+ * driver.
+ * This is better than having each driver having its entry because
+ * its centralised and we may remove the driver module safely.
+ *
+ * Ioctl are used to configure the driver and issue commands.  This is
+ * better than command line options of insmod because we may want to
+ * change dynamically (while the driver is running) some parameters.
+ *
+ * The ioctl mechanimsm are copied from standard devices ioctl.
+ * We have the list of command plus a structure descibing the
+ * data exchanged...
+ * Note that to add these ioctl, I was obliged to modify :
+ *     net/core/dev.c (two place + add include)
+ *     net/ipv4/af_inet.c (one place + add include)
+ *
+ * /proc/net/wireless is a copy of /proc/net/dev.
+ * We have a structure for data passed from the driver to /proc/net/wireless
+ * Too add this, I've modified :
+ *     net/core/dev.c (two other places)
+ *     include/linux/netdevice.h (one place)
+ *     include/linux/proc_fs.h (one place)
+ *
+ * Do not add here things that are redundant with other mechanisms
+ * (drivers init, ifconfig, /proc/net/dev, ...) and with are not
+ * wireless specific.
+ *
+ * These wireless extensions are not magic : each driver has to provide
+ * support for them...
+ *
+ * IMPORTANT NOTE : As everything in the kernel, this is very much a
+ * work in progress. Contact me if you have ideas of improvements...
+ */
+
+/***************************** INCLUDES *****************************/
+
+#include <linux/types.h>               /* for "caddr_t" et al          */
+#include <linux/socket.h>              /* for "struct sockaddr" et al  */
+#include <linux/if.h>                  /* for IFNAMSIZ and co... */
+
+/**************************** CONSTANTS ****************************/
+
+/* --------------------------- VERSION --------------------------- */
+/*
+ * This constant is used to know the availability of the wireless
+ * extensions and to know which version of wireless extensions it is
+ * (there is some stuff that will be added in the future...)
+ * I just plan to increment with each new version.
+ */
+#define WIRELESS_EXT   12
+
+/*
+ * Changes :
+ *
+ * V2 to V3
+ * --------
+ *     Alan Cox start some incompatibles changes. I've integrated a bit more.
+ *     - Encryption renamed to Encode to avoid US regulation problems
+ *     - Frequency changed from float to struct to avoid problems on old 386
+ *
+ * V3 to V4
+ * --------
+ *     - Add sensitivity
+ *
+ * V4 to V5
+ * --------
+ *     - Missing encoding definitions in range
+ *     - Access points stuff
+ *
+ * V5 to V6
+ * --------
+ *     - 802.11 support (ESSID ioctls)
+ *
+ * V6 to V7
+ * --------
+ *     - define IW_ESSID_MAX_SIZE and IW_MAX_AP
+ *
+ * V7 to V8
+ * --------
+ *     - Changed my e-mail address
+ *     - More 802.11 support (nickname, rate, rts, frag)
+ *     - List index in frequencies
+ *
+ * V8 to V9
+ * --------
+ *     - Support for 'mode of operation' (ad-hoc, managed...)
+ *     - Support for unicast and multicast power saving
+ *     - Change encoding to support larger tokens (>64 bits)
+ *     - Updated iw_params (disable, flags) and use it for NWID
+ *     - Extracted iw_point from iwreq for clarity
+ *
+ * V9 to V10
+ * ---------
+ *     - Add PM capability to range structure
+ *     - Add PM modifier : MAX/MIN/RELATIVE
+ *     - Add encoding option : IW_ENCODE_NOKEY
+ *     - Add TxPower ioctls (work like TxRate)
+ *
+ * V10 to V11
+ * ----------
+ *     - Add WE version in range (help backward/forward compatibility)
+ *     - Add retry ioctls (work like PM)
+ *
+ * V11 to V12
+ * ----------
+ *     - Add SIOCSIWSTATS to get /proc/net/wireless programatically
+ *     - Add DEV PRIVATE IOCTL to avoid collisions in SIOCDEVPRIVATE space
+ *     - Add new statistics (frag, retry, beacon)
+ *     - Add average quality (for user space calibration)
+ */
+
+/* -------------------------- IOCTL LIST -------------------------- */
+
+/* Basic operations */
+#define SIOCSIWNAME    0x8B00          /* Unused */
+#define SIOCGIWNAME    0x8B01          /* get name == wireless protocol */
+#define SIOCSIWNWID    0x8B02          /* set network id (the cell) */
+#define SIOCGIWNWID    0x8B03          /* get network id */
+#define SIOCSIWFREQ    0x8B04          /* set channel/frequency (Hz) */
+#define SIOCGIWFREQ    0x8B05          /* get channel/frequency (Hz) */
+#define SIOCSIWMODE    0x8B06          /* set operation mode */
+#define SIOCGIWMODE    0x8B07          /* get operation mode */
+#define SIOCSIWSENS    0x8B08          /* set sensitivity (dBm) */
+#define SIOCGIWSENS    0x8B09          /* get sensitivity (dBm) */
+
+/* Informative stuff */
+#define SIOCSIWRANGE   0x8B0A          /* Unused */
+#define SIOCGIWRANGE   0x8B0B          /* Get range of parameters */
+#define SIOCSIWPRIV    0x8B0C          /* Unused */
+#define SIOCGIWPRIV    0x8B0D          /* get private ioctl interface info */
+#define SIOCSIWSTATS   0x8B0E          /* Unused */
+#define SIOCGIWSTATS   0x8B0F          /* Get /proc/net/wireless stats */
+
+/* Mobile IP support */
+#define SIOCSIWSPY     0x8B10          /* set spy addresses */
+#define SIOCGIWSPY     0x8B11          /* get spy info (quality of link) */
+
+/* Access Point manipulation */
+#define SIOCSIWAP      0x8B14          /* set access point MAC addresses */
+#define SIOCGIWAP      0x8B15          /* get access point MAC addresses */
+#define SIOCGIWAPLIST  0x8B17          /* get list of access point in range */
+
+/* 802.11 specific support */
+#define SIOCSIWESSID   0x8B1A          /* set ESSID (network name) */
+#define SIOCGIWESSID   0x8B1B          /* get ESSID */
+#define SIOCSIWNICKN   0x8B1C          /* set node name/nickname */
+#define SIOCGIWNICKN   0x8B1D          /* get node name/nickname */
+/* As the ESSID and NICKN are strings up to 32 bytes long, it doesn't fit
+ * within the 'iwreq' structure, so we need to use the 'data' member to
+ * point to a string in user space, like it is done for RANGE...
+ * The "flags" member indicate if the ESSID is active or not (promiscuous).
+ */
+
+/* Other parameters useful in 802.11 and some other devices */
+#define SIOCSIWRATE    0x8B20          /* set default bit rate (bps) */
+#define SIOCGIWRATE    0x8B21          /* get default bit rate (bps) */
+#define SIOCSIWRTS     0x8B22          /* set RTS/CTS threshold (bytes) */
+#define SIOCGIWRTS     0x8B23          /* get RTS/CTS threshold (bytes) */
+#define SIOCSIWFRAG    0x8B24          /* set fragmentation thr (bytes) */
+#define SIOCGIWFRAG    0x8B25          /* get fragmentation thr (bytes) */
+#define SIOCSIWTXPOW   0x8B26          /* set transmit power (dBm) */
+#define SIOCGIWTXPOW   0x8B27          /* get transmit power (dBm) */
+#define SIOCSIWRETRY   0x8B28          /* set retry limits and lifetime */
+#define SIOCGIWRETRY   0x8B29          /* get retry limits and lifetime */
+
+/* Encoding stuff (scrambling, hardware security, WEP...) */
+#define SIOCSIWENCODE  0x8B2A          /* set encoding token & mode */
+#define SIOCGIWENCODE  0x8B2B          /* get encoding token & mode */
+/* Power saving stuff (power management, unicast and multicast) */
+#define SIOCSIWPOWER   0x8B2C          /* set Power Management settings */
+#define SIOCGIWPOWER   0x8B2D          /* get Power Management settings */
+
+/* -------------------- DEV PRIVATE IOCTL LIST -------------------- */
+
+/* These 16 ioctl are wireless device private.
+ * Each driver is free to use them for whatever purpose it chooses,
+ * however the driver *must* export the description of those ioctls
+ * with SIOCGIWPRIV and *must* use arguments as defined below.
+ * If you don't follow those rules, DaveM is going to hate you (reason :
+ * it make mixed 32/64bit operation impossible).
+ */
+#define SIOCIWFIRSTPRIV        0x8BE0
+#define SIOCIWLASTPRIV 0x8BFF
+/* Previously, we were using SIOCDEVPRIVATE, but we know have our
+ * separate range because of collisions with other tools such as
+ * 'mii-tool'.
+ * We now have 32 commands, so a bit more space ;-).
+ * Also, all 'odd' commands are only usable by root and don't return the
+ * content of ifr/iwr to user (but you are not obliged to use the set/get
+ * convention, just use every other two command).
+ * And I repeat : you are not obliged to use them with iwspy, but you
+ * must be compliant with it.
+ */
+
+/* ------------------------- IOCTL STUFF ------------------------- */
+
+/* The first and the last (range) */
+#define SIOCIWFIRST    0x8B00
+#define SIOCIWLAST     SIOCIWLASTPRIV          /* 0x8BFF */
+
+/* Even : get (world access), odd : set (root access) */
+#define IW_IS_SET(cmd) (!((cmd) & 0x1))
+#define IW_IS_GET(cmd) ((cmd) & 0x1)
+
+/* ------------------------- PRIVATE INFO ------------------------- */
+/*
+ * The following is used with SIOCGIWPRIV. It allow a driver to define
+ * the interface (name, type of data) for its private ioctl.
+ * Privates ioctl are SIOCIWFIRSTPRIV -> SIOCIWLASTPRIV
+ */
+
+#define IW_PRIV_TYPE_MASK      0x7000  /* Type of arguments */
+#define IW_PRIV_TYPE_NONE      0x0000
+#define IW_PRIV_TYPE_BYTE      0x1000  /* Char as number */
+#define IW_PRIV_TYPE_CHAR      0x2000  /* Char as character */
+#define IW_PRIV_TYPE_INT       0x4000  /* 32 bits int */
+#define IW_PRIV_TYPE_FLOAT     0x5000
+
+#define IW_PRIV_SIZE_FIXED     0x0800  /* Variable or fixed nuber of args */
+
+#define IW_PRIV_SIZE_MASK      0x07FF  /* Max number of those args */
+
+/*
+ * Note : if the number of args is fixed and the size < 16 octets,
+ * instead of passing a pointer we will put args in the iwreq struct...
+ */
+
+/* ----------------------- OTHER CONSTANTS ----------------------- */
+
+/* Maximum frequencies in the range struct */
+#define IW_MAX_FREQUENCIES     16
+/* Note : if you have something like 80 frequencies,
+ * don't increase this constant and don't fill the frequency list.
+ * The user will be able to set by channel anyway... */
+
+/* Maximum bit rates in the range struct */
+#define IW_MAX_BITRATES                8
+
+/* Maximum tx powers in the range struct */
+#define IW_MAX_TXPOWER         8
+
+/* Maximum of address that you may set with SPY */
+#define IW_MAX_SPY             8
+
+/* Maximum of address that you may get in the
+   list of access points in range */
+#define IW_MAX_AP              8
+
+/* Maximum size of the ESSID and NICKN strings */
+#define IW_ESSID_MAX_SIZE      32
+
+/* Modes of operation */
+#define IW_MODE_AUTO   0       /* Let the driver decides */
+#define IW_MODE_ADHOC  1       /* Single cell network */
+#define IW_MODE_INFRA  2       /* Multi cell network, roaming, ... */
+#define IW_MODE_MASTER 3       /* Synchronisation master or Access Point */
+#define IW_MODE_REPEAT 4       /* Wireless Repeater (forwarder) */
+#define IW_MODE_SECOND 5       /* Secondary master/repeater (backup) */
+
+/* Maximum number of size of encoding token available
+ * they are listed in the range structure */
+#define IW_MAX_ENCODING_SIZES  8
+
+/* Maximum size of the encoding token in bytes */
+#define IW_ENCODING_TOKEN_MAX  32      /* 256 bits (for now) */
+
+/* Flags for encoding (along with the token) */
+#define IW_ENCODE_INDEX                0x00FF  /* Token index (if needed) */
+#define IW_ENCODE_FLAGS                0xFF00  /* Flags defined below */
+#define IW_ENCODE_MODE         0xF000  /* Modes defined below */
+#define IW_ENCODE_DISABLED     0x8000  /* Encoding disabled */
+#define IW_ENCODE_ENABLED      0x0000  /* Encoding enabled */
+#define IW_ENCODE_RESTRICTED   0x4000  /* Refuse non-encoded packets */
+#define IW_ENCODE_OPEN         0x2000  /* Accept non-encoded packets */
+#define IW_ENCODE_NOKEY         0x0800  /* Key is write only, so not present */
+
+/* Power management flags available (along with the value, if any) */
+#define IW_POWER_ON            0x0000  /* No details... */
+#define IW_POWER_TYPE          0xF000  /* Type of parameter */
+#define IW_POWER_PERIOD                0x1000  /* Value is a period/duration of  */
+#define IW_POWER_TIMEOUT       0x2000  /* Value is a timeout (to go asleep) */
+#define IW_POWER_MODE          0x0F00  /* Power Management mode */
+#define IW_POWER_UNICAST_R     0x0100  /* Receive only unicast messages */
+#define IW_POWER_MULTICAST_R   0x0200  /* Receive only multicast messages */
+#define IW_POWER_ALL_R         0x0300  /* Receive all messages though PM */
+#define IW_POWER_FORCE_S       0x0400  /* Force PM procedure for sending unicast */
+#define IW_POWER_REPEATER      0x0800  /* Repeat broadcast messages in PM period */
+#define IW_POWER_MODIFIER      0x000F  /* Modify a parameter */
+#define IW_POWER_MIN           0x0001  /* Value is a minimum  */
+#define IW_POWER_MAX           0x0002  /* Value is a maximum */
+#define IW_POWER_RELATIVE      0x0004  /* Value is not in seconds/ms/us */
+
+/* Transmit Power flags available */
+#define IW_TXPOW_DBM           0x0000  /* Value is in dBm */
+#define IW_TXPOW_MWATT         0x0001  /* Value is in mW */
+
+/* Retry limits and lifetime flags available */
+#define IW_RETRY_ON            0x0000  /* No details... */
+#define IW_RETRY_TYPE          0xF000  /* Type of parameter */
+#define IW_RETRY_LIMIT         0x1000  /* Maximum number of retries*/
+#define IW_RETRY_LIFETIME      0x2000  /* Maximum duration of retries in us */
+#define IW_RETRY_MODIFIER      0x000F  /* Modify a parameter */
+#define IW_RETRY_MIN           0x0001  /* Value is a minimum  */
+#define IW_RETRY_MAX           0x0002  /* Value is a maximum */
+#define IW_RETRY_RELATIVE      0x0004  /* Value is not in seconds/ms/us */
+
+/****************************** TYPES ******************************/
+
+/* --------------------------- SUBTYPES --------------------------- */
+/*
+ *     Generic format for most parameters that fit in an int
+ */
+struct iw_param
+{
+  __s32                value;          /* The value of the parameter itself */
+  __u8         fixed;          /* Hardware should not use auto select */
+  __u8         disabled;       /* Disable the feature */
+  __u16                flags;          /* Various specifc flags (if any) */
+};
+
+/*
+ *     For all data larger than 16 octets, we need to use a
+ *     pointer to memory allocated in user space.
+ */
+struct iw_point
+{
+  caddr_t      pointer;        /* Pointer to the data  (in user space) */
+  __u16                length;         /* number of fields or size in bytes */
+  __u16                flags;          /* Optional params */
+};
+
+/*
+ *     A frequency
+ *     For numbers lower than 10^9, we encode the number in 'm' and
+ *     set 'e' to 0
+ *     For number greater than 10^9, we divide it by the lowest power
+ *     of 10 to get 'm' lower than 10^9, with 'm'= f / (10^'e')...
+ *     The power of 10 is in 'e', the result of the division is in 'm'.
+ */
+struct iw_freq
+{
+       __u32           m;              /* Mantissa */
+       __u16           e;              /* Exponent */
+       __u8            i;              /* List index (when in range struct) */
+};
+
+/*
+ *     Quality of the link
+ */
+struct iw_quality
+{
+       __u8            qual;           /* link quality (%retries, SNR,
+                                          %missed beacons or better...) */
+       __u8            level;          /* signal level (dBm) */
+       __u8            noise;          /* noise level (dBm) */
+       __u8            updated;        /* Flags to know if updated */
+};
+
+/*
+ *     Packet discarded in the wireless adapter due to
+ *     "wireless" specific problems...
+ *     Note : the list of counter and statistics in net_device_stats
+ *     is already pretty exhaustive, and you should use that first.
+ *     This is only additional stats...
+ */
+struct iw_discarded
+{
+       __u32           nwid;           /* Rx : Wrong nwid/essid */
+       __u32           code;           /* Rx : Unable to code/decode (WEP) */
+       __u32           fragment;       /* Rx : Can't perform MAC reassembly */
+       __u32           retries;        /* Tx : Max MAC retries num reached */
+       __u32           misc;           /* Others cases */
+};
+
+/*
+ *     Packet/Time period missed in the wireless adapter due to
+ *     "wireless" specific problems...
+ */
+struct iw_missed
+{
+       __u32           beacon;         /* Missed beacons/superframe */
+};
+
+/* ------------------------ WIRELESS STATS ------------------------ */
+/*
+ * Wireless statistics (used for /proc/net/wireless)
+ */
+struct iw_statistics
+{
+       __u16           status;         /* Status
+                                        * - device dependent for now */
+
+       struct iw_quality       qual;           /* Quality of the link
+                                                * (instant/mean/max) */
+       struct iw_discarded     discard;        /* Packet discarded counts */
+       struct iw_missed        miss;           /* Packet missed counts */
+};
+
+/* ------------------------ IOCTL REQUEST ------------------------ */
+/*
+ * The structure to exchange data for ioctl.
+ * This structure is the same as 'struct ifreq', but (re)defined for
+ * convenience...
+ *
+ * Note that it should fit on the same memory footprint !
+ * You should check this when increasing the above structures (16 octets)
+ * 16 octets = 128 bits. Warning, pointers might be 64 bits wide...
+ */
+struct iwreq 
+{
+       union
+       {
+               char    ifrn_name[IFNAMSIZ];    /* if name, e.g. "eth0" */
+       } ifr_ifrn;
+
+       /* Data part */
+       union
+       {
+               /* Config - generic */
+               char            name[IFNAMSIZ];
+               /* Name : used to verify the presence of  wireless extensions.
+                * Name of the protocol/provider... */
+
+               struct iw_point essid;  /* Extended network name */
+               struct iw_param nwid;   /* network id (or domain - the cell) */
+               struct iw_freq  freq;   /* frequency or channel :
+                                        * 0-1000 = channel
+                                        * > 1000 = frequency in Hz */
+
+               struct iw_param sens;           /* signal level threshold */
+               struct iw_param bitrate;        /* default bit rate */
+               struct iw_param txpower;        /* default transmit power */
+               struct iw_param rts;            /* RTS threshold threshold */
+               struct iw_param frag;           /* Fragmentation threshold */
+               __u32           mode;           /* Operation mode */
+               struct iw_param retry;          /* Retry limits & lifetime */
+
+               struct iw_point encoding;       /* Encoding stuff : tokens */
+               struct iw_param power;          /* PM duration/timeout */
+
+               struct sockaddr ap_addr;        /* Access point address */
+
+               struct iw_point data;           /* Other large parameters */
+       }       u;
+};
+
+/* -------------------------- IOCTL DATA -------------------------- */
+/*
+ *     For those ioctl which want to exchange mode data that what could
+ *     fit in the above structure...
+ */
+
+/*
+ *     Range of parameters
+ */
+
+struct iw_range
+{
+       /* Informative stuff (to choose between different interface) */
+       __u32           throughput;     /* To give an idea... */
+       /* In theory this value should be the maximum benchmarked
+        * TCP/IP throughput, because with most of these devices the
+        * bit rate is meaningless (overhead an co) to estimate how
+        * fast the connection will go and pick the fastest one.
+        * I suggest people to play with Netperf or any benchmark...
+        */
+
+       /* NWID (or domain id) */
+       __u32           min_nwid;       /* Minimal NWID we are able to set */
+       __u32           max_nwid;       /* Maximal NWID we are able to set */
+
+       /* Frequency */
+       __u16           num_channels;   /* Number of channels [0; num - 1] */
+       __u8            num_frequency;  /* Number of entry in the list */
+       struct iw_freq  freq[IW_MAX_FREQUENCIES];       /* list */
+       /* Note : this frequency list doesn't need to fit channel numbers */
+
+       /* signal level threshold range */
+       __s32   sensitivity;
+
+       /* Quality of link & SNR stuff */
+       struct iw_quality       max_qual;       /* Quality of the link */
+
+       /* Rates */
+       __u8            num_bitrates;   /* Number of entries in the list */
+       __s32           bitrate[IW_MAX_BITRATES];       /* list, in bps */
+
+       /* RTS threshold */
+       __s32           min_rts;        /* Minimal RTS threshold */
+       __s32           max_rts;        /* Maximal RTS threshold */
+
+       /* Frag threshold */
+       __s32           min_frag;       /* Minimal frag threshold */
+       __s32           max_frag;       /* Maximal frag threshold */
+
+       /* Power Management duration & timeout */
+       __s32           min_pmp;        /* Minimal PM period */
+       __s32           max_pmp;        /* Maximal PM period */
+       __s32           min_pmt;        /* Minimal PM timeout */
+       __s32           max_pmt;        /* Maximal PM timeout */
+       __u16           pmp_flags;      /* How to decode max/min PM period */
+       __u16           pmt_flags;      /* How to decode max/min PM timeout */
+       __u16           pm_capa;        /* What PM options are supported */
+
+       /* Encoder stuff */
+       __u16   encoding_size[IW_MAX_ENCODING_SIZES];   /* Different token sizes */
+       __u8    num_encoding_sizes;     /* Number of entry in the list */
+       __u8    max_encoding_tokens;    /* Max number of tokens */
+
+       /* Transmit power */
+       __u16           txpower_capa;   /* What options are supported */
+       __u8            num_txpower;    /* Number of entries in the list */
+       __s32           txpower[IW_MAX_TXPOWER];        /* list, in bps */
+
+       /* Wireless Extension version info */
+       __u8            we_version_compiled;    /* Must be WIRELESS_EXT */
+       __u8            we_version_source;      /* Last update of source */
+
+       /* Retry limits and lifetime */
+       __u16           retry_capa;     /* What retry options are supported */
+       __u16           retry_flags;    /* How to decode max/min retry limit */
+       __u16           r_time_flags;   /* How to decode max/min retry life */
+       __s32           min_retry;      /* Minimal number of retries */
+       __s32           max_retry;      /* Maximal number of retries */
+       __s32           min_r_time;     /* Minimal retry lifetime */
+       __s32           max_r_time;     /* Maximal retry lifetime */
+
+       /* Average quality of link & SNR */
+       struct iw_quality       avg_qual;       /* Quality of the link */
+       /* This should contain the average/typical values of the quality
+        * indicator. This should be the threshold between a "good" and
+        * a "bad" link (example : monitor going from green to orange).
+        * Currently, user space apps like quality monitors don't have any
+        * way to calibrate the measurement. With this, they can split
+        * the range between 0 and max_qual in different quality level
+        * (using a geometric subdivision centered on the average).
+        * I expect that people doing the user space apps will feedback
+        * us on which value we need to put in each driver...
+        */
+};
+
+/*
+ * Private ioctl interface information
+ */
+struct iw_priv_args
+{
+       __u32           cmd;            /* Number of the ioctl to issue */
+       __u16           set_args;       /* Type and number of args */
+       __u16           get_args;       /* Type and number of args */
+       char            name[IFNAMSIZ]; /* Name of the extension */
+};
+
+#endif /* _LINUX_WIRELESS_H */
index 4183d4a..fa3c64f 100644 (file)
@@ -1,9 +1,10 @@
 /*
  * This file define a set of standard wireless extensions
  *
 /*
  * This file define a set of standard wireless extensions
  *
- * Version :   12      5.10.01
+ * Version :   13      6.12.01
  *
  * Authors :   Jean Tourrilhes - HPL - <jt@hpl.hp.com>
  *
  * Authors :   Jean Tourrilhes - HPL - <jt@hpl.hp.com>
+ * Copyright (c) 1997-2001 Jean Tourrilhes, All Rights Reserved.
  */
 
 #ifndef _LINUX_WIRELESS_H
  */
 
 #ifndef _LINUX_WIRELESS_H
@@ -11,6 +12,8 @@
 
 /************************** DOCUMENTATION **************************/
 /*
 
 /************************** DOCUMENTATION **************************/
 /*
+ * Initial APIs (1996 -> onward) :
+ * -----------------------------
  * Basically, the wireless extensions are for now a set of standard ioctl
  * call + /proc/net/wireless
  *
  * Basically, the wireless extensions are for now a set of standard ioctl
  * call + /proc/net/wireless
  *
  * We have the list of command plus a structure descibing the
  * data exchanged...
  * Note that to add these ioctl, I was obliged to modify :
  * We have the list of command plus a structure descibing the
  * data exchanged...
  * Note that to add these ioctl, I was obliged to modify :
- *     net/core/dev.c (two place + add include)
- *     net/ipv4/af_inet.c (one place + add include)
+ *     net/core/dev.c (two place + add include)
+ *     net/ipv4/af_inet.c (one place + add include)
  *
  * /proc/net/wireless is a copy of /proc/net/dev.
  * We have a structure for data passed from the driver to /proc/net/wireless
  * Too add this, I've modified :
  *
  * /proc/net/wireless is a copy of /proc/net/dev.
  * We have a structure for data passed from the driver to /proc/net/wireless
  * Too add this, I've modified :
- *     net/core/dev.c (two other places)
- *     include/linux/netdevice.h (one place)
- *     include/linux/proc_fs.h (one place)
+ *     net/core/dev.c (two other places)
+ *     include/linux/netdevice.h (one place)
+ *     include/linux/proc_fs.h (one place)
  *
  *
+ * New driver API (2001 -> onward) :
+ * -------------------------------
+ * This file is only concerned with the user space API and common definitions.
+ * The new driver API is defined and documented in :
+ *     # include/net/iw_handler.h
+ *
+ * Note as well that /proc/net/wireless implementation has now moved in :
+ *     # include/linux/wireless.c
+ *
+ * Other comments :
+ * --------------
  * Do not add here things that are redundant with other mechanisms
  * (drivers init, ifconfig, /proc/net/dev, ...) and with are not
  * wireless specific.
  * Do not add here things that are redundant with other mechanisms
  * (drivers init, ifconfig, /proc/net/dev, ...) and with are not
  * wireless specific.
 #include <linux/socket.h>              /* for "struct sockaddr" et al  */
 #include <linux/if.h>                  /* for IFNAMSIZ and co... */
 
 #include <linux/socket.h>              /* for "struct sockaddr" et al  */
 #include <linux/if.h>                  /* for IFNAMSIZ and co... */
 
-/**************************** CONSTANTS ****************************/
-
-/* --------------------------- VERSION --------------------------- */
+/***************************** VERSION *****************************/
 /*
  * This constant is used to know the availability of the wireless
  * extensions and to know which version of wireless extensions it is
  * (there is some stuff that will be added in the future...)
  * I just plan to increment with each new version.
  */
 /*
  * This constant is used to know the availability of the wireless
  * extensions and to know which version of wireless extensions it is
  * (there is some stuff that will be added in the future...)
  * I just plan to increment with each new version.
  */
-#define WIRELESS_EXT   12
+#define WIRELESS_EXT   13
 
 /*
  * Changes :
 
 /*
  * Changes :
  *     - Add DEV PRIVATE IOCTL to avoid collisions in SIOCDEVPRIVATE space
  *     - Add new statistics (frag, retry, beacon)
  *     - Add average quality (for user space calibration)
  *     - Add DEV PRIVATE IOCTL to avoid collisions in SIOCDEVPRIVATE space
  *     - Add new statistics (frag, retry, beacon)
  *     - Add average quality (for user space calibration)
+ *
+ * V12 to V13
+ * ----------
+ *     - Document creation of new driver API.
+ *     - Extract union iwreq_data from struct iwreq (for new driver API).
+ *     - Rename SIOCSIWNAME as SIOCSIWCOMMIT
  */
 
  */
 
+/**************************** CONSTANTS ****************************/
+
 /* -------------------------- IOCTL LIST -------------------------- */
 
 /* Basic operations */
 /* -------------------------- IOCTL LIST -------------------------- */
 
 /* Basic operations */
-#define SIOCSIWNAME    0x8B00          /* Unused */
+#define SIOCSIWCOMMIT  0x8B00          /* Commit pending changes to driver */
 #define SIOCGIWNAME    0x8B01          /* get name == wireless protocol */
 #define SIOCSIWNWID    0x8B02          /* set network id (the cell) */
 #define SIOCGIWNWID    0x8B03          /* get network id */
 #define SIOCGIWNAME    0x8B01          /* get name == wireless protocol */
 #define SIOCSIWNWID    0x8B02          /* set network id (the cell) */
 #define SIOCGIWNWID    0x8B03          /* get network id */
  */
 #define SIOCIWFIRSTPRIV        0x8BE0
 #define SIOCIWLASTPRIV 0x8BFF
  */
 #define SIOCIWFIRSTPRIV        0x8BE0
 #define SIOCIWLASTPRIV 0x8BFF
-/* Previously, we were using SIOCDEVPRIVATE, but we know have our
+/* Previously, we were using SIOCDEVPRIVATE, but we now have our
  * separate range because of collisions with other tools such as
  * 'mii-tool'.
  * We now have 32 commands, so a bit more space ;-).
  * separate range because of collisions with other tools such as
  * 'mii-tool'.
  * We now have 32 commands, so a bit more space ;-).
@@ -414,13 +434,49 @@ struct    iw_statistics
 
 /* ------------------------ IOCTL REQUEST ------------------------ */
 /*
 
 /* ------------------------ IOCTL REQUEST ------------------------ */
 /*
+ * This structure defines the payload of an ioctl, and is used 
+ * below.
+ *
+ * Note that this structure should fit on the memory footprint
+ * of iwreq (which is the same as ifreq), which mean a max size of
+ * 16 octets = 128 bits. Warning, pointers might be 64 bits wide...
+ * You should check this when increasing the structures defined
+ * above in this file...
+ */
+union  iwreq_data
+{
+       /* Config - generic */
+       char            name[IFNAMSIZ];
+       /* Name : used to verify the presence of  wireless extensions.
+        * Name of the protocol/provider... */
+
+       struct iw_point essid;          /* Extended network name */
+       struct iw_param nwid;           /* network id (or domain - the cell) */
+       struct iw_freq  freq;           /* frequency or channel :
+                                        * 0-1000 = channel
+                                        * > 1000 = frequency in Hz */
+
+       struct iw_param sens;           /* signal level threshold */
+       struct iw_param bitrate;        /* default bit rate */
+       struct iw_param txpower;        /* default transmit power */
+       struct iw_param rts;            /* RTS threshold threshold */
+       struct iw_param frag;           /* Fragmentation threshold */
+       __u32           mode;           /* Operation mode */
+       struct iw_param retry;          /* Retry limits & lifetime */
+
+       struct iw_point encoding;       /* Encoding stuff : tokens */
+       struct iw_param power;          /* PM duration/timeout */
+
+       struct sockaddr ap_addr;        /* Access point address */
+
+       struct iw_point data;           /* Other large parameters */
+};
+
+/*
  * The structure to exchange data for ioctl.
  * This structure is the same as 'struct ifreq', but (re)defined for
  * convenience...
  * The structure to exchange data for ioctl.
  * This structure is the same as 'struct ifreq', but (re)defined for
  * convenience...
- *
- * Note that it should fit on the same memory footprint !
- * You should check this when increasing the above structures (16 octets)
- * 16 octets = 128 bits. Warning, pointers might be 64 bits wide...
+ * Do I need to remind you about structure size (32 octets) ?
  */
 struct iwreq 
 {
  */
 struct iwreq 
 {
@@ -429,35 +485,8 @@ struct     iwreq
                char    ifrn_name[IFNAMSIZ];    /* if name, e.g. "eth0" */
        } ifr_ifrn;
 
                char    ifrn_name[IFNAMSIZ];    /* if name, e.g. "eth0" */
        } ifr_ifrn;
 
-       /* Data part */
-       union
-       {
-               /* Config - generic */
-               char            name[IFNAMSIZ];
-               /* Name : used to verify the presence of  wireless extensions.
-                * Name of the protocol/provider... */
-
-               struct iw_point essid;  /* Extended network name */
-               struct iw_param nwid;   /* network id (or domain - the cell) */
-               struct iw_freq  freq;   /* frequency or channel :
-                                        * 0-1000 = channel
-                                        * > 1000 = frequency in Hz */
-
-               struct iw_param sens;           /* signal level threshold */
-               struct iw_param bitrate;        /* default bit rate */
-               struct iw_param txpower;        /* default transmit power */
-               struct iw_param rts;            /* RTS threshold threshold */
-               struct iw_param frag;           /* Fragmentation threshold */
-               __u32           mode;           /* Operation mode */
-               struct iw_param retry;          /* Retry limits & lifetime */
-
-               struct iw_point encoding;       /* Encoding stuff : tokens */
-               struct iw_param power;          /* PM duration/timeout */
-
-               struct sockaddr ap_addr;        /* Access point address */
-
-               struct iw_point data;           /* Other large parameters */
-       }       u;
+       /* Data part (defined just above) */
+       union   iwreq_data      u;
 };
 
 /* -------------------------- IOCTL DATA -------------------------- */
 };
 
 /* -------------------------- IOCTL DATA -------------------------- */