OSDN Git Service

v26
authorchris-kirby <chris.kirby@hpe.com>
Tue, 11 Oct 2016 21:08:05 +0000 (15:08 -0600)
committerchris-kirby <chris.kirby@hpe.com>
Tue, 11 Oct 2016 21:08:05 +0000 (15:08 -0600)
21 files changed:
wireless_tools/CHANGELOG.h
wireless_tools/DISTRIBUTIONS.txt
wireless_tools/INSTALL
wireless_tools/Makefile
wireless_tools/README
wireless_tools/iwconfig.8
wireless_tools/iwconfig.c
wireless_tools/iwevent.8
wireless_tools/iwevent.c
wireless_tools/iwlib.c
wireless_tools/iwlib.h
wireless_tools/iwlist.8
wireless_tools/iwlist.c
wireless_tools/iwpriv.8
wireless_tools/iwpriv.c
wireless_tools/iwredir.8 [new file with mode: 0644]
wireless_tools/iwredir.c [new file with mode: 0644]
wireless_tools/iwspy.8
wireless_tools/iwspy.c
wireless_tools/wireless.16.h [new file with mode: 0644]
wireless_tools/wireless.7

index b1944a0..92d9cd9 100644 (file)
  *     o Complain about version mistmatch at runtime only once [iwlib]
  *     o Fix IWNAME null termination [iwconfig, iwlib]
  *     o "iwgetid -p" to display protocol name and check WE support [iwgetid]
+ *
+ * wireless 26 :
+ * -----------
+ *     o #define IFLA_WIRELESS if needed [iwlib]
+ *     o Update man page with SuSE intruction (see below) [wireless.7]
+ *             (From Alexander Pevzner <pzz@pzz.msk.ru>)
+ *     o Allow to display all 8 bit rates instead of 7 [iwlist]
+ *     o Fix retry lifetime to not set IW_RETRY_LIMIT flag [iwconfig]
+ *             (From Christian Zoz <zoz@suse.de>)
+ *     o Update SuSE configuration instructions [DISTRIBUTIONS]
+ *     ---
+ *     o Update man page with regards to /proc/net/wireless [iwconfig.8]
+ *     o Add NOLIBM version of iw_dbm2mwatt()/iw_mwatt2dbm() [iwlib]
+ *     ---
+ *     o Fix "iwconfig ethX enc on" on WE-15 : set buffer size [iwconfig]
+ *     o Display /proc/net/wireless before "typical data" [iwspy]
+ *             (From Pavel Roskin <proski@gnu.org>)
+ *     o Fix uninstall [Makefile]
+ *     o Change "Encryption mode" to "Security mode" [iwconfig/iwlist]
+ *     ---
+ *     o Add kernel headers that will be removed from wireless.h [iwlib]
+ *     o Remove IW_MAX_GET_SPY, people should use AP-List [iwspy]
+ *     o Re-word List of "Access Points" to "Peers/Access-Points" [iwlist]
+ *     o Add support for SIOCGIWTHRSPY event [iwevent/iwlib]
+ *     o Add support for SIOCSIWTHRSPY/SIOCGIWTHRSPY ioctls [iwspy]
+ *     ---
+ *     o Add SIOCGIWNAME/Protocol event display [iwlist scan/iwevent]
+ *     o Add temporary encoding flag setting [iwconfig]
+ *     o Add login encoding setting [iwlib/iwconfig]
+ *     ---
+ *     o Fix corruption of encryption key setting when followed by another
+ *       setting starting with a valid hex char ('essid' -> 'E') [iwlib]
+ *     o Fix iw_in_key() so that it parses every char and not bundle of
+ *       two so that 'enc' is not the valid key '0E0C' [iwlib]
+ *     o Fix parsing of odd keys '123' is '0123' instead of '1203' [iwlib]
+ *     ---
+ *     o Implement WE version tool redirector (need WE-16) [iwredir]
+ *     o Add "make vinstall" to use redirector [Makefile]
+ *     o Fix compilation warning in WE < 16 [iwlib, iwspy]
+ *     o Allow to specify PREFIX on make command line [Makefile]
+ *     ---
+ *     o Update wireless.h (more frequencies) [wireless.h]
+ *     o Allow to escape ESSID="any" using "essid - any" [iwconfig]
+ *     o Updated Red-Hat 9 wireless config instructions [DISTRIBUTIONS]
+ *             (From Pavel Roskin <proski@gnu.org>)
+ *     o Replace all %d into %i so we can input hex/oct [iwlib, iwpriv]
+ *     ---
+ *     o If >= WE-16, display kernel version in "iwconfig --version" [iwlib]
+ *             (From Antonio Vilei <francesco.sigona@unile.it>)
+ *     o Fix "wrq.u.bitrate.value = power;" => txpower [iwconfig]
+ *             (From Casey Carter <Casey@Carter.net>)
+ *     o Make iwlib.h header C++ friendly. [iwlib]
+ *     ---
+ *             (From Pavel Roskin <proski@gnu.org>)
+ *     o Make sure that KERNEL_SRC point to a valid directory [Makefile]
+ *     o Print message if card support WE but has no version info [iwlib]
+ *             (From Simon Kelley <simon@thekelleys.org.uk>)
+ *     o If power has no mode, don't print garbage [iwlib]
+ *     ---
+ *             (Bug reported by Guus Sliepen <guus@sliepen.eu.org>)
+ *     o Don't cast "int power" to unsigned long in sscanf [iwconfig]
+ *             (From Pavel Roskin <proski@gnu.org>)
+ *     o Add $(LDFLAGS) for final linking [Makefile]
  */
 
 /* ----------------------------- TODO ----------------------------- */
index c6fb878..a9b77c2 100644 (file)
@@ -32,6 +32,31 @@ distribution, please use the PCMCIA method).
 absolutely no clue about how your distribution works. I'm just
 collecting random information here without beeing able to verify it.
 
+                               -----
+
+WIRELESS DRIVERS
+----------------
+       Most Linux wireless drivers support Wireless Extensions, and
+therefore may be configure via Wireless Tools and the methods
+described in this file.
+
+       However, a few drivers have no support or limited support for
+Wireless Extensions (like read only). In those cases, these are your
+options :
+               o read the driver documentation.
+               o use the driver specific interface or tools to
+configure the card, and try to integrate that in your distribution.
+               o implement Wireless Extension support in the driver.
+       In some cases, there are easier workaround. Different version
+of the driver may add Wireless Extension (often alongside the
+proprietary method). In some other case, there may be another driver
+supporting the same card and with support for Wireless Extensions.
+
+       Some Linux wireless drivers don't export all wireless settings
+via Wireless Extensions, not even through iwpriv. Those setting may be
+available through the driver specific interface. Refer to previous
+section for workarounds.
+
 ---------------------------------------------------------------------
 
 PCMCIA METHOD
@@ -144,6 +169,48 @@ but you may need to write your own mapping script which uses a
 combination of MAC address and scheme info to return a stanza name to
 ifupdown.
 
+                               -----
+
+       You may also want to check ifupdown-roaming :
+               http://panopticon.csustan.edu/thood/ifupdown-roaming.html
+
+---------------------------------------------------------------------
+
+SuSE 8.0 and later
+--------
+               (Contributed by Christian Zoz <zoz@suse.de>)
+       All network configuration is done in the directory
+/etc/sysconfig/network. It does not matter if it's a build in NIC or
+PCMCIA, USB, etc. The files network.opts and wireless.opts in
+/etc/pcmcia are not used any longer. There is /sbin/ifup to set up all
+kind of network interface.
+       There is a file /etc/sysconfig/network/wireless where you may
+set most of the options of iwconfig in seperate variables (they are
+named like the options). Additionally you may use
+WIRELESS_IWCONFIG_OPTIONS e.g. for setting key 2, 3 or 4 or
+unsupported iwconfig commands. This file is documented and its
+settings are used for any wlan NIC.
+       Configuration of wireless variable looks like :
+               WIRELESS_ESSID="<essid>"
+       Every variable from file wireless may be used in the interface
+configuration files /etc/sysconfig/network/ifcfg-* as well. As
+expectable this overwrites the global setting in wireless. For
+sophisticated use of the ifcfg-* files read 'man ifup'.
+
+       Hint for PCMCIA and USB users:
+       You need not to use the iterface name for the configuration as
+this may vary from one plugin to another. You may use a description of
+your hardware instead (ifcfg-<MACADDRESS> or ifcfg-pcmcia-1 for card
+in Slot 1)
+
+       Some of the variables can be set with YaST2 as well.
+
+       If you miss the 'schemes' functionality from the pcmcia-cs
+packages use the tool SCPM (System Configuration Profile Management)
+instead. This extends the pcmcia schemes to the whole system
+configuration. Read 'info scpm'. Since SuSE 8.1 there also is a YaST2
+modul for SCPM.
+
 ---------------------------------------------------------------------
 
 RED-HAT 7.2
@@ -216,6 +283,38 @@ friends. The above web page explain how to switch it to orinoco_cs.
 
 ---------------------------------------------------------------------
 
+RED-HAT 9.0 and later
+-----------
+               (Cut'n'pasted from Dax Kelson web page)
+       http://www.gurulabs.com/RedHatLinux9-review.html
+
+       A little known fact is that newer versions of RHL support
+multiple network profiles. This is useful for machines that commonly
+plug into different networks (think laptops). The easy way to create
+network profiles is to use the redhat-config-network command. The
+question then becomes, what happens when you type "ifup eth0"? The
+behavior wasn't defined in previous versions, however, now in RHL 9
+the following behavior is defined;
+
+       search path for:
+# ifup $DEV
+       is:
+/etc/sysconfig/networking/profiles/$CURRENT_PROFILE/ifcfg-$DEV
+/etc/sysconfig/networking/profiles/default/ifcfg-$DEV
+/etc/sysconfig/network-scripts/ifcfg-$DEV
+
+       A cool trick is to boot your RHL box directly into a profile
+from the GRUB boot screen. To do this, create a separate
+/etc/boot/grub.conf entry for each network profile, and in each entry
+add the kernel argument netprofile=profilename.
+
+                               -----
+
+       I'm pretty certain the profile scheme above also apply to
+wireless settings, which is good news...
+
+---------------------------------------------------------------------
+
 MANDRAKE 8.2 and later
 ------------
                (Grabbed from various source - Google is your friend)
@@ -249,33 +348,6 @@ Auto-Install procedure :
 
 ---------------------------------------------------------------------
 
-SuSE 8.0 and later
---------
-               (Cut'n'pasted from Unofficial SuSE FAQ, by Keith Winston)
-       http://www.smaug42.com/susefaq/ethernetproblems.html#AEN768
-       The old PCMCIA network scripts used to read
-/etc/pcmcia/wireless.opts to get the wireless options like mode,
-ESSID, encryption key, etc. Well, the wireless.opts file is still
-there but it is NOT used. It would have been nice if there was some
-documentation about it. Instead, the new scripts read this info from
-another brand new file called /etc/sysconfig/network/wireless. You can
-edit this file to store your wireless options. If you don't use key 1,
-you may have to put the other key in the WIRELESS_IWCONFIG_OPTIONS
-variable.
-
-                               -----
-
-               <Need confirmation :>
-       Configuration of wireless settings looks like :
-               WIRELESS_ESSID="<essid>"
-       It also seem that the same directives can be added to the file :
-               /etc/sysconfig/network/ifcfg-ethX
-       Note that there seems to be other problems with SuSE, such as
-the Pcmcia scripts binding the linux-wlan-ng driver to Orinoco cards
-(which of course won't work - see link in FAQ above).
-
----------------------------------------------------------------------
-
 
        Have fun...
 
index fa39d77..37bf8d4 100644 (file)
@@ -62,4 +62,35 @@ the tools from compiling.
        The trick is to copy the file .../include/linux/wireless.h
 from the kernel to the /usr/include headers.
 
+Multi-kernel installation (expert only) :
+---------------------------------------
+       People who run different kernel on the same system may have
+problems due to the fact that those kernel have different version of
+Wireless Extensions and the Wireless Tools need to match the version
+of Wireless Extension used.
+
+       It is now possible to install multiple versions of the
+Wireless Tools on a system and get the proper version used based on
+the kernel running, using a redirector. However, this support is still
+experimental and for expert users only.
+       The redirector will work properly only with kernel using
+Wireless Extensions version 16 and higher. Earlier version of Wireless
+Extensions will be detected as either v15 (v12, v13, v14 and v15) or
+as v11 (v11 and earlier).
+
+       The installation looks typically like :
+------------------------------------
+make clean
+make FORCE_WEXT_VERSION=11
+make vinstall FORCE_WEXT_VERSION=11
+make clean
+make FORCE_WEXT_VERSION=15
+make vinstall FORCE_WEXT_VERSION=15
+make clean
+make FORCE_WEXT_VERSION=16
+make vinstall FORCE_WEXT_VERSION=16
+[...]
+------------------------------------
+
+
        Jean <jt@hpl.hp.com>
index 7a7dec9..15c8cb5 100644 (file)
@@ -4,7 +4,9 @@
 
 ## Installation directory. By default, go in /usr/local
 ## Distributions should probably use /usr, but they probably know better...
-PREFIX = /usr/local
+ifndef PREFIX
+  PREFIX = /usr/local
+endif
 
 ## Compiler to use
 CC = gcc
@@ -17,7 +19,7 @@ CC = gcc
 ## of the system wide one in /usr/include/linux. Use with care.
 ## Can be used to create multiple versions of the tools on the same system
 ## for multiple kernels or get around broken distributions.
-# FORCE_WEXT_VERSION = 14
+# FORCE_WEXT_VERSION = 16
 
 ## Uncomment this to build tools using dynamic version of the library
 # BUILD_SHARED = y
@@ -32,10 +34,11 @@ CC = gcc
 
 # Targets to build
 STATIC=libiw.a
-DYNAMIC=libiw.so.25
+DYNAMIC=libiw.so.26
 PROGS= iwconfig iwlist iwpriv iwspy iwgetid iwevent
 MANPAGES8=iwconfig.8 iwlist.8 iwpriv.8 iwspy.8 iwgetid.8 iwevent.8
 MANPAGES7=wireless.7
+EXTRAPROGS= macaddr iwredir
 
 # Composition of the library :
 OBJS = iwlib.o
@@ -67,6 +70,9 @@ RM = rm -f
 RM_CMD = $(RM) *.BAK *.bak *.o *.so ,* *~ *.a *.orig *.rej
 
 ifdef KERNEL_SRC
+  ifeq ($(wildcard $(KERNEL_SRC)/include/linux/wireless.h),)
+    $(error Kernel source is missing or incomplete)
+  endif
   KERNEL_INCLUDES = -I $(KERNEL_SRC)/include
 endif
 
@@ -86,7 +92,7 @@ PICFLAG=-fPIC
 all:: $(STATIC) $(DYNAMIC) $(PROGS)
 
 %: %.o
-       $(CC) $(XCFLAGS) -o $@ $^ $(LIBS)
+       $(CC) $(LDFLAGS) $(XCFLAGS) -o $@ $^ $(LIBS)
 %.o: %.c
        $(CC) $(XCFLAGS) -c $<
 %.so: %.c
@@ -104,11 +110,13 @@ iwgetid: iwgetid.o
 
 iwevent: iwevent.o $(IWLIB)
 
+iwredir: iwredir.o
+
 macaddr: macaddr.o $(IWLIB)
 
 # Compilation of the dynamic library
 $(DYNAMIC): $(OBJS:.o=.so)
-       $(CC) -shared -o $@ -Wl,-soname,$@ -lm -lc $^
+       $(CC) -shared -o $@ -Wl,-soname,$@ $(LIBS) -lc $^
 
 # Compilation of the static library
 $(STATIC): $(OBJS)
@@ -118,7 +126,7 @@ $(STATIC): $(OBJS)
 
 # So crude but so effective ;-)
 # Less crude thanks to many contributions ;-)
-install::
+install:: all
        install -m 755 -d $(INSTALL_DIR)
        install -m 755 $(PROGS) $(INSTALL_DIR)
        install -m 755 -d $(INSTALL_LIB)
@@ -138,7 +146,7 @@ clean::
 
 realclean::
        $(RM_CMD) 
-       $(RM) $(STATIC) $(DYNAMIC) $(PROGS) macaddr
+       $(RM) $(STATIC) $(DYNAMIC) $(PROGS) $(EXTRAPROGS)
 
 uninstall::
        for f in $(PROGS); do \
@@ -150,10 +158,39 @@ uninstall::
        $(RM) $(INSTALL_INC)/iwlib.h
        for f in $(MANPAGES8); do \
          $(RM) $(INSTALL_MAN)/man8/$$f; \
+       done
        for f in $(MANPAGES7); do \
          $(RM) $(INSTALL_MAN)/man7/$$f; \
        done
 
+# Versioned install...
+# We rename each of the tool with a suffix corresponding to the version
+# of WE it was compiled with. We use "iwredir" for the redirection...
+
+vinstall:: iwredir install
+       @wev=$(FORCE_WEXT_VERSION) ; \
+       if [ "$$wev" == "" ] ; then \
+         wev=`./iwredir -wev`; \
+       else :; fi ; \
+       echo "Installing tools for WE-$$wev..." ; \
+       for f in $(PROGS); do \
+         mv $(INSTALL_DIR)/$$f $(INSTALL_DIR)/$$f$$wev; \
+       done;
+       install -m 755 iwredir $(INSTALL_DIR)
+       for f in $(PROGS); do \
+         ln $(INSTALL_DIR)/iwredir $(INSTALL_DIR)/$$f; \
+       done;
+
+vuninstall:: uninstall
+       @wev=$(FORCE_WEXT_VERSION) ; \
+       if [ "$$wev" == "" ] ; then \
+         wev=`./iwredir -wev`; \
+       else :; fi ; \
+       for f in $(PROGS); do \
+         rm $(INSTALL_DIR)/$$f$$wev; \
+       done;
+       $(RM) $(INSTALL_DIR)/iwredir;
+
 depend::
        makedepend -s "# DO NOT DELETE" -- $(INCLUDES) -- $(SRCS)
 # DO NOT DELETE
index e1ab782..93886bf 100644 (file)
@@ -17,17 +17,20 @@ INSTALL
        This file contains installation instruction and requirements.
        A *must* read.
 
+DISTRIBUTION.txt
+----------------
+       This file will document how to configure wireless cards at
+boot time with various Linux distributions (using Wireless
+Extensions). Please read it carefully before asking questions.
+       In this file, I try to collect all the specifics of Wireless
+Extensions integration in the most common Linux distributions. I need
+your help to complete this file.
+
 PCMCIA.txt
 ----------
        This file describes how to use Pcmcia init script to configure
 Wireless Extensions and how to use Pcmcia schemes.
 
-DISTRIBUTION
-------------
-       This file will document the specifics of Wireless Extensions
-with a few different distributions. I need your help to complete this
-file.
-
 man pages (iwconfig.8, iwlist.8, iwpriv.8, iwspy.8)
 ---------
        VERY IMPORTANT : I try to keep the man page up to date, so
index 377a3f2..fefaa93 100644 (file)
@@ -230,7 +230,7 @@ packet size disable the scheme. You may also set this parameter to
 .I "   iwconfig eth0 frag off"
 .TP
 .BR key / enc [ryption]
-Used to manipulate encryption or scrambling keys and encryption mode.
+Used to manipulate encryption or scrambling keys and security mode.
 .br
 To set the current encryption key, just enter the key in hex digits as
 .IR XXXX-XXXX-XXXX-XXXX " or " XXXXXXXX .
@@ -246,11 +246,19 @@ To change which key is the current active key, just enter
 (without entering any key value).
 .br
 .IR off " and " on
-disable and reenable encryption,
+disable and reenable encryption.
+.br
+The security mode may be
+.I open
+or
+.IR restricted ,
+and its meaning depend on the card used. With most card, in
 .I open
-set the system in open mode (accept non-encrypted packets) and
+mode no authentication is used and the card may also accept
+non-encrypted sessions, whereas in
 .I restricted
-discard non-encrypted packets.
+mode only encrypted sessions are accepted and the card will use
+authentication if available.
 .br
 If you need to set multiple keys, or set a key and change the active
 key, you need to use multiple
@@ -401,7 +409,7 @@ settings (depending on availability).
 .br
 See above for explanations of what these parameters mean.
 .br
-If the label for bitrate is followed by
+If the label for some values (such as bitrate) is followed by
 .RB ` = ',
 it means that the parameter is fixed and forced to that value, if it
 is followed by
@@ -412,27 +420,57 @@ If
 .I /proc/net/wireless
 exists,
 .I iwconfig
-will also display its content :
+will also display its content. Note that those values will depend on
+the driver and the hardware specifics, so you need to refer to your
+driver documentation for proper interpretation of those values.
 .TP
 .B Link quality
-Quality of the link or the modulation (what is the level of contention
-or interference, or how good the received signal is).
+Overall quality of the link. May be based on the level of contention
+or interference, the bit or frame error rate, how good the received
+signal is, some timing synchronisation, or other hardware metric. This
+is an aggregate value, and depend totally on the driver and hardware.
 .TP
 .B Signal level
-Received signal strength (how strong the received signal is).
+Received signal strength (RSSI - how strong the received signal
+is). May be arbitrary units or dBm,
+.I iwconfig
+uses driver meta information to interpret the raw value given by
+.I /proc/net/wireless
+and display the proper unit or maximum value (using 8 bit arithmetic). In
+.I Ad-Hoc
+mode, this may be undefined and you should use
+.IR iwspy .
 .TP
 .B Noise level
-Background noise level (when no packet is transmited).
+Background noise level (when no packet is transmited). Similar
+comments as for
+.BR "Signal level" .
+.TP
+.B Rx invalid nwid
+Number of packets received with a different NWID or ESSID. Used to
+detect configuration problems or adjacent network existence (on the
+same frequency).
 .TP
-.B invalid nwid
-Number of packets received with a different NWID. Used to detect
-configuration problems or adjacent network existence.
+.B Rx invalid crypt
+Number of packets that the hardware was unable to decrypt. This can be
+used to detect invalid encryption settings.
 .TP
-.B invalid crypt
-Number of packets that the hardware was unable to decrypt.
+.B Rx invalid frag
+Number of packets for which the hardware was not able to properly
+re-assemble the link layer fragments (most likely one was missing).
 .TP
-.B invalid misc
+.B Tx excessive retries
+Number of packets that the hardware failed to deliver. Most MAC
+protocol will retry the packet a number of time before giving up.
+.TP
+.B Invalid misc
 Other packets lost in relation with specific wireless operations.
+.TP
+.B Missed beacon
+Number of periodic beacons from the Cell or the Access Point we have
+missed. Beacons are sent at regular interval to maintain the cell
+coordination, failure to receive them usually indicate that we are out
+of range.
 .\"
 .\" AUTHOR part
 .\"
@@ -450,8 +488,6 @@ Jean Tourrilhes \- jt@hpl.hp.com
 .BR ifconfig (8),
 .BR iwspy (8),
 .BR iwlist (8),
+.BR iwevent (8),
 .BR iwpriv (8),
-.BR wavelan (4),
-.BR wavelan_cs (4),
-.BR wvlan_cs (4),
-.BR netwave_cs (4).
+.BR wireless (7).
index c8ffe07..3fa0611 100644 (file)
@@ -467,9 +467,9 @@ display_info(struct wireless_info * info,
          if((info->key_flags & IW_ENCODE_INDEX) > 1)
            printf(" [%d]", info->key_flags & IW_ENCODE_INDEX);
          if(info->key_flags & IW_ENCODE_RESTRICTED)
-           printf("   Encryption mode:restricted");
+           printf("   Security mode:restricted");
          if(info->key_flags & IW_ENCODE_OPEN)
-           printf("   Encryption mode:open");
+           printf("   Security mode:open");
          printf("\n          ");
        }
     }
@@ -608,7 +608,7 @@ print_info(int              skfd,
        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", \
+               fprintf(stderr, "    SET failed on device %-1.16s ; %s.\n", \
                        ifname, strerror(errno)); \
                return(-5); \
        } } while(0)
@@ -622,7 +622,7 @@ print_info(int              skfd,
        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", \
+               fprintf(stderr, "    GET failed on device %-1.16s ; %s.\n", \
                        ifname, strerror(errno)); \
                return(-6); \
        } } while(0)
@@ -720,7 +720,7 @@ set_info(int                skfd,           /* The socket */
        {
          if(++i >= count)
            ABORT_ARG_NUM("Set Sensitivity", SIOCSIWSENS);
-         if(sscanf(args[i], "%d", &(wrq.u.sens.value)) != 1)
+         if(sscanf(args[i], "%i", &(wrq.u.sens.value)) != 1)
            ABORT_ARG_TYPE("Set Sensitivity", SIOCSIWSENS, args[i]);
 
          IW_SET_EXT_ERR(skfd, ifname, SIOCSIWSENS, &wrq,
@@ -741,7 +741,7 @@ set_info(int                skfd,           /* The socket */
            {
              /* Get old encryption information */
              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;
              IW_GET_EXT_ERR(skfd, ifname, SIOCGIWENCODE, &wrq,
                             "Set Encode");
@@ -766,7 +766,8 @@ set_info(int                skfd,           /* The socket */
                  /* -- Check for the key -- */
                  if(i < count)
                    {
-                     keylen = iw_in_key(args[i], key);
+                     keylen = iw_in_key_full(skfd, ifname,
+                                             args[i], key, &wrq.u.data.flags);
                      if(keylen > 0)
                        {
                          wrq.u.data.length = keylen;
@@ -778,7 +779,7 @@ set_info(int                skfd,           /* The socket */
 
                  /* -- Check for token index -- */
                  if((i < count) &&
-                    (sscanf(args[i], "[%d]", &temp) == 1) &&
+                    (sscanf(args[i], "[%i]", &temp) == 1) &&
                     (temp > 0) && (temp < IW_ENCODE_INDEX))
                    {
                      wrq.u.encoding.flags |= temp;
@@ -805,6 +806,14 @@ set_info(int               skfd,           /* The socket */
                      ++i;
                      gotone++;
                    }
+#if WIRELESS_EXT > 15
+                 if((i < count) && (!strncasecmp(args[i], "temporary", 4)))
+                   {
+                     wrq.u.data.flags |= IW_ENCODE_TEMP;
+                     ++i;
+                     gotone++;
+                   }
+#endif
                }
              while(gotone != oldone);
 
@@ -843,33 +852,45 @@ set_info(int              skfd,           /* The socket */
              {
                /* Get old essid */
                wrq.u.essid.pointer = (caddr_t) essid;
-               wrq.u.essid.length = 0;
+               wrq.u.essid.length = IW_ESSID_MAX_SIZE + 1;
                wrq.u.essid.flags = 0;
                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)
-               ABORT_ARG_SIZE("Set ESSID", SIOCSIWESSID, IW_ESSID_MAX_SIZE);
-             else
-               {
-                 int           temp;
+             {
+               /* '-' allow to escape the ESSID string, allowing
+                * to set it to the string "any" or "off".
+                * This is a big ugly, but it will do for now */
+               if(!strcmp(args[i], "-"))
+                 {
+                   i++;
+                   if(i >= count)
+                     ABORT_ARG_NUM("Set ESSID", SIOCSIWESSID);
+                 }
+
+               /* Check the size of what the user passed us to avoid
+                * buffer overflows */
+               if(strlen(args[i]) > IW_ESSID_MAX_SIZE)
+                 ABORT_ARG_SIZE("Set ESSID", SIOCSIWESSID, IW_ESSID_MAX_SIZE);
+               else
+                 {
+                   int         temp;
 
-                 wrq.u.essid.flags = 1;
-                 strcpy(essid, args[i]);       /* Size checked, all clear */
+                   wrq.u.essid.flags = 1;
+                   strcpy(essid, args[i]);     /* Size checked, all clear */
 
-                 /* Check for ESSID index */
-                 if(((i+1) < count) &&
-                    (sscanf(args[i+1], "[%d]", &temp) == 1) &&
-                    (temp > 0) && (temp < IW_ENCODE_INDEX))
-                   {
-                     wrq.u.essid.flags = temp;
-                     ++i;
-                   }
-               }
+                   /* Check for ESSID index */
+                   if(((i+1) < count) &&
+                      (sscanf(args[i+1], "[%i]", &temp) == 1) &&
+                      (temp > 0) && (temp < IW_ENCODE_INDEX))
+                     {
+                       wrq.u.essid.flags = temp;
+                       ++i;
+                     }
+                 }
+             }
 
          wrq.u.essid.pointer = (caddr_t) essid;
          wrq.u.essid.length = strlen(essid) + 1;
@@ -1003,7 +1024,7 @@ set_info(int              skfd,           /* The socket */
                    wrq.u.rts.fixed = 1;
                  }
                else                    /* Should be a numeric value */
-                 if(sscanf(args[i], "%ld", (unsigned long *) &(wrq.u.rts.value))
+                 if(sscanf(args[i], "%li", (unsigned long *) &(wrq.u.rts.value))
                     != 1)
                    ABORT_ARG_TYPE("Set RTS Threshold", SIOCSIWRTS, args[i]);
            }
@@ -1037,7 +1058,7 @@ set_info(int              skfd,           /* The socket */
                    wrq.u.frag.fixed = 1;
                  }
                else                    /* Should be a numeric value */
-                 if(sscanf(args[i], "%ld",
+                 if(sscanf(args[i], "%li",
                            (unsigned long *) &(wrq.u.frag.value))
                     != 1)
                    ABORT_ARG_TYPE("Set Fragmentation Threshold", SIOCSIWFRAG,
@@ -1058,7 +1079,7 @@ set_info(int              skfd,           /* The socket */
          if(i >= count)
            ABORT_ARG_NUM("Set Mode", SIOCSIWMODE);
 
-         if(sscanf(args[i], "%d", &k) != 1)
+         if(sscanf(args[i], "%i", &k) != 1)
            {
              k = 0;
              while((k < IW_NUM_OPER_MODE) &&
@@ -1209,8 +1230,7 @@ set_info(int              skfd,           /* The socket */
                    int         ismwatt = 0;
 
                    /* Get the value */
-                   if(sscanf(args[i], "%ld",
-                             (unsigned long *) &(power)) != 1)
+                   if(sscanf(args[i], "%i", &(power)) != 1)
                      ABORT_ARG_TYPE("Set Tx Power", SIOCSIWTXPOW, args[i]);
 
                    /* Check if milliwatt */
@@ -1229,7 +1249,7 @@ set_info(int              skfd,           /* The socket */
                          power = iw_mwatt2dbm(power);
                        wrq.u.data.flags = IW_TXPOW_DBM;
                      }
-                   wrq.u.bitrate.value = power;
+                   wrq.u.txpower.value = power;
 
                    /* Check for an additional argument */
                    if(((i+1) < count) &&
@@ -1292,6 +1312,7 @@ set_info(int              skfd,           /* The socket */
          else
            if(!strncasecmp(args[i], "lifetime", 4))
              {
+               wrq.u.retry.flags &= ~IW_RETRY_LIMIT;
                wrq.u.retry.flags |= IW_RETRY_LIFETIME;
                if(++i >= count)
                  ABORT_ARG_NUM("Set Retry Limit", SIOCSIWRETRY);
index 719e131..7c17923 100644 (file)
@@ -68,8 +68,10 @@ available (see
 .TP
 .B Tx packet dropped
 A packet directed at this address has been dropped because the
-interface believes this node doesn't answer anymore. An early
-indication that the node may have left the cell or gone out of range.
+interface believes this node doesn't answer anymore (usually maximum
+of MAC level retry exceeded). An early indication that the node may
+have left the cell or gone out of range, but may be due to fading or
+excessive contention.
 .TP
 .B Custom driver event
 Event specific to the driver. Please check the driver documentation.
@@ -83,6 +85,10 @@ Access Point (mode master).
 The registration of the client/peer on this interface has
 expired. Will be generated mostly when the interface act as an Access
 Point (mode master).
+.TP
+.B Spy threshold crossed
+The signal strength for one of the address in the spy list went under
+the low threshold or went above than the high threshold.
 .PP
 Only some of those events will be generated on some wireless
 interfaces by the wireless driver, and their support depend on the
@@ -98,6 +104,6 @@ Jean Tourrilhes \- jt@hpl.hp.com
 .\"
 .SH SEE ALSO
 .BR iwconfig (8),
-.BR ifconfig (8),
+.BR iwlist (8),
 .BR iwspy (8),
 .BR iwpriv (8).
index 54bf96b..4b1e6b9 100644 (file)
 #include <time.h>
 #include <sys/time.h>
 
+/* Ugly backward compatibility :-( */
+#ifndef IFLA_WIRELESS
+#define IFLA_WIRELESS  (IFLA_MASTER + 1)
+#endif /* IFLA_WIRELESS */
+
 /************************ RTNETLINK HELPERS ************************/
 /*
  * The following code is extracted from :
@@ -104,8 +109,9 @@ static inline int rtnl_open(struct rtnl_handle *rth, unsigned subscriptions)
  */
 static inline int
 print_event_token(struct iw_event *    event,  /* Extracted token */
+                 char *                ifname,
                  struct iw_range *     iwrange,        /* Range info */
-                 int                   has_range)
+                 int                   has_iwrange)
 {
   char         buffer[128];    /* Temporary buffer */
 
@@ -172,9 +178,9 @@ print_event_token(struct iw_event * event,  /* Extracted token */
            if((event->u.data.flags & IW_ENCODE_INDEX) > 1)
              printf(" [%d]", event->u.data.flags & IW_ENCODE_INDEX);
            if(event->u.data.flags & IW_ENCODE_RESTRICTED)
-             printf("   Encryption mode:restricted");
+             printf("   Security mode:restricted");
            if(event->u.data.flags & IW_ENCODE_OPEN)
-             printf("   Encryption mode:open");
+             printf("   Security mode:open");
            printf("\n");
          }
       }
@@ -211,16 +217,49 @@ print_event_token(struct iw_event *       event,  /* Extracted token */
             iw_pr_ether(buffer, event->u.addr.sa_data));
       break;
 #endif /* WIRELESS_EXT > 14 */
+#if WIRELESS_EXT > 15
+    case SIOCGIWTHRSPY:
+      {
+       struct iw_thrspy        threshold;
+       int                     skfd;
+       struct iw_range         range;
+       int                     has_range = 0;
+       if((event->u.data.pointer) && (event->u.data.length))
+         {
+           memcpy(&threshold, event->u.data.pointer,
+                  sizeof(struct iw_thrspy));
+           if((skfd = iw_sockets_open()) >= 0)
+             {
+               has_range = (iw_get_range_info(skfd, ifname, &range) >= 0);
+               close(skfd);
+             }
+           printf("Spy threshold crossed on address:%s\n",
+                  iw_pr_ether(buffer, threshold.addr.sa_data));
+           threshold.qual.updated = 0x0;       /* Not that reliable, disable */
+           iw_print_stats(buffer, &threshold.qual, &range, has_range);
+           printf("                            Link %s\n", buffer);
+         }
+       else
+         printf("Invalid Spy Threshold event\n");
+      }
+      break;
+#else
+      /* Avoid "Unused parameter" warning */
+      ifname = ifname;
+#endif /* WIRELESS_EXT > 15 */
       /* ----- junk ----- */
       /* other junk not currently in use */
     case SIOCGIWRATE:
       iw_print_bitrate(buffer, event->u.bitrate.value);
       printf("Bit Rate:%s\n", buffer);
       break;
+    case SIOCGIWNAME:
+      printf("Protocol:%-1.16s\n", event->u.name);
+      break;
     case IWEVQUAL:
       {
        event->u.qual.updated = 0x0;    /* Not that reliable, disable */
-       iw_print_stats(buffer, &event->u.qual, iwrange, has_range);
+       iw_print_stats(buffer, &event->u.qual, iwrange, has_iwrange);
        printf("Link %s\n", buffer);
        break;
       }
@@ -273,7 +312,7 @@ print_event_stream(char *   ifname,
          else
            printf("                           ");
          if(ret > 0)
-           print_event_token(&iwe, NULL, 0);
+           print_event_token(&iwe, ifname, NULL, 0);
          else
            printf("(Invalid event)\n");
        }
index 64c2d78..ca7aed0 100644 (file)
@@ -1,12 +1,12 @@
 /*
  *     Wireless Tools
  *
- *             Jean II - HPLB 97->99 - HPL 99->01
+ *             Jean II - HPLB 97->99 - HPL 99->03
  *
  * 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>
+ *     Copyright (c) 1997-2003 Jean Tourrilhes <jt@hpl.hp.com>
  */
 
 /***************************** INCLUDES *****************************/
@@ -17,9 +17,9 @@
 
 /* Various versions information */
 /* Recommended Wireless Extension version */
-#define WE_VERSION     15
+#define WE_VERSION     16      /* ### don't forget #warning ### */
 /* Version of Wireless Tools */
-#define WT_VERSION     25
+#define WT_VERSION     26
 
 /*
  * Verify a few things about Wireless Extensions.
 #error "Use Wireless Tools v19 or update your kernel headers !"
 #endif
 #if WIRELESS_EXT < WE_VERSION && !defined(WEXT_HEADER)
-#warning "Wireless Extension earlier than v15 detected,"
+#warning "Wireless Extension earlier than v16 detected,"
 #warning "Not all tools features will be compiled in !"
 #warning "No worry, I'll try to make the best of it ;-)"
 #endif
 #if WIRELESS_EXT > WE_VERSION && !defined(WEXT_HEADER)
-#warning "Wireless Extension later than v15 detected,"
+#warning "Wireless Extension later than v16 detected,"
 #warning "Maybe you should get a more recent version"
 #warning "of the Wireless Tools package !"
 #endif
@@ -183,7 +183,11 @@ iw_enum_devices(int                skfd,
 
          if(!s)
            /* Failed to parse, complain and continue */
+#ifndef IW_RESTRIC_ENUM
+           fprintf(stderr, "Cannot parse " PROC_NET_DEV "\n");
+#else
            fprintf(stderr, "Cannot parse " PROC_NET_WIRELESS "\n");
+#endif
          else
            /* Got it, print info about this interface */
            (*fn)(skfd, name, args, count);
@@ -303,6 +307,11 @@ print_iface_version_info(int       skfd,
   /* Avoid "Unused parameter" warning */
   args = args; count = count;
 
+  /* If no wireless name : no wireless extensions.
+   * This enable us to treat the SIOCGIWRANGE failure below properly. */
+  if(iw_get_ext(skfd, ifname, SIOCGIWNAME, &wrq) < 0)
+    return(-1);
+
   /* Cleanup */
   memset(buffer, 0, sizeof(buffer));
 
@@ -310,7 +319,11 @@ print_iface_version_info(int       skfd,
   wrq.u.data.length = sizeof(buffer);
   wrq.u.data.flags = 0;
   if(iw_get_ext(skfd, ifname, SIOCGIWRANGE, &wrq) < 0)
-    return(-1);
+    {
+      /* Interface support WE (see above), but not IWRANGE */
+      fprintf(stderr, "%-8.8s  Driver has no Wireless Extension version information.\n\n", ifname);
+      return(0);
+    }
 
   /* Copy stuff at the right place, ignore extra */
   range = (struct iw_range *) buffer;
@@ -329,7 +342,7 @@ print_iface_version_info(int        skfd,
   else
     {
 #if 0
-      fprintf(stderr, "%-8.8s  no Wireless Extension version information.\n\n",
+      fprintf(stderr, "%-8.8s  Wireless Extension version too old.\n\n",
                      ifname);
 #endif
     }
@@ -345,7 +358,11 @@ print_iface_version_info(int       skfd,
 int
 iw_print_version_info(char *   toolname)
 {
-  int skfd;                    /* generic raw socket desc.     */
+  int          skfd;                   /* generic raw socket desc.     */
+  char         buff[1024];
+  FILE *       fh;
+  char *       p;
+  int          v;
 
   /* Create a channel to the NET kernel. */
   if((skfd = iw_sockets_open()) < 0)
@@ -362,6 +379,29 @@ iw_print_version_info(char *       toolname)
   printf("          Currently compiled with Wireless Extension v%d.\n\n",
         WIRELESS_EXT);
 
+  /* Check if /proc/net/wireless is available */
+  fh = fopen(PROC_NET_WIRELESS, "r");
+  if(fh != NULL)
+    {
+      /* Read the first line of buffer */
+      fgets(buff, sizeof(buff), fh);
+
+      /* Check if it's WE-16 or later */
+      if(strstr(buff, "| WE") != NULL)
+       {
+         /* Read the second line of buffer */
+         fgets(buff, sizeof(buff), fh);
+
+         /* Get to the last separator, to get the version */
+         p = strrchr(buff, '|');
+         if((p != NULL) && (sscanf(p + 1, "%d", &v) == 1))
+           /* That was it ! */
+           printf("Kernel    Currently compiled with Wireless Extension v%d.\n\n", v);
+       }
+      /* Cleanup */
+      fclose(fh);
+    }
+
   /* Version for each device */
   iw_enum_devices(skfd, &print_iface_version_info, NULL, 0);
 
@@ -774,7 +814,23 @@ iw_print_bitrate(char *    buffer,
 int
 iw_dbm2mwatt(int       in)
 {
+#ifdef WE_NOLIBM
+  /* Version without libm : slower */
+  int          ip = in / 10;
+  int          fp = in % 10;
+  int          k;
+  double       res = 1.0;
+
+  /* Split integral and floating part to avoid accumulating rounding errors */
+  for(k = 0; k < ip; k++)
+    res *= 10;
+  for(k = 0; k < fp; k++)
+    res *= LOG10_MAGIC;
+  return((int) res);
+#else  /* WE_NOLIBM */
+  /* Version with libm : faster */
   return((int) (floor(pow(10.0, (((double) in) / 10.0)))));
+#endif /* WE_NOLIBM */
 }
 
 /*------------------------------------------------------------------*/
@@ -784,7 +840,27 @@ iw_dbm2mwatt(int   in)
 int
 iw_mwatt2dbm(int       in)
 {
+#ifdef WE_NOLIBM
+  /* Version without libm : slower */
+  double       fin = (double) in;
+  int          res = 0;
+
+  /* Split integral and floating part to avoid accumulating rounding errors */
+  while(fin > 10.0)
+    {
+      res += 10;
+      fin /= 10.0;
+    }
+  while(fin > 1.000001)        /* Eliminate rounding errors, take ceil */
+    {
+      res += 1;
+      fin /= LOG10_MAGIC;
+    }
+  return(res);
+#else  /* WE_NOLIBM */
+  /* Version with libm : faster */
   return((int) (ceil(10.0 * log10((double) in))));
+#endif /* WE_NOLIBM */
 }
 
 /********************** STATISTICS SUBROUTINES **********************/
@@ -813,6 +889,7 @@ iw_get_stats(int    skfd,
   char         buf[256];
   char *       bp;
   int          t;
+  skfd = skfd; /* Avoid "Unused parameter" warning */
   if(f==NULL)
     return -1;
   /* Loop on all devices */
@@ -981,9 +1058,6 @@ iw_in_key(char *           input,
          unsigned char *       key)
 {
   int          keylen = 0;
-  char *       buff;
-  char *       p;
-  int          temp;
 
   /* Check the type of key */
   if(!strncmp(input, "s:", 2))
@@ -1002,34 +1076,120 @@ iw_in_key(char *               input,
       }
     else
       {
+       char *  buff;
+       char *  hex;
+       char *  out;
+       char *  p;
+
        /* Third case : as hexadecimal digits */
-       buff = malloc(strlen(input) + 1);
+       buff = malloc(IW_ENCODING_TOKEN_MAX + strlen(input) + 1);
        if(buff == NULL)
          {
            fprintf(stderr, "Malloc failed (string too long ?)\n");
            return(-1);
          }
-       /* Preserve original buffer */
-       strcpy(buff, input);
+       /* Preserve original buffers (both in & out) */
+       hex = buff + IW_ENCODING_TOKEN_MAX;
+       strcpy(hex, input);
+       out = buff;
 
        /* Parse */
-       p = strtok(buff, "-:;.,");
+       p = strtok(hex, "-:;.,");
        while((p != (char *) NULL) && (keylen < IW_ENCODING_TOKEN_MAX))
          {
-           if(sscanf(p, "%2X", &temp) != 1)
-             return(-1);               /* Error */
-           key[keylen++] = (unsigned char) (temp & 0xFF);
-           if(strlen(p) > 2)   /* Token not finished yet */
-             p += 2;
+           int temph;
+           int templ;
+           int count;
+           int len;
+           /* Get each char separatly (and not by two) so that we don't
+            * get confused by 'enc' (=> '0E'+'0C') and similar */
+           count = sscanf(p, "%1X%1X", &temph, &templ);
+           if(count < 1)
+             return(-1);               /* Error -> non-hex char */
+           /* Fixup odd strings such as '123' is '01'+'23' and not '12'+'03'*/
+           len = strlen(p);
+           if(len % 2)
+             count = 1;
+           /* Put back two chars as one byte */
+           if(count == 2)
+             templ |= temph << 4;
+           else
+             templ = temph;
+           out[keylen++] = (unsigned char) (templ & 0xFF);
+           /* Check where to get next char from */
+           if(len > count)     /* Token not finished yet */
+             p += count;
            else
              p = strtok((char *) NULL, "-:;.,");
          }
+       memcpy(key, out, keylen);
        free(buff);
       }
 
   return(keylen);
 }
 
+/*------------------------------------------------------------------*/
+/*
+ * Parse a key from the command line.
+ * Return size of the key, or 0 (no key) or -1 (error)
+ */
+int
+iw_in_key_full(int             skfd,
+              char *           ifname,
+              char *           input,
+              unsigned char *  key,
+              __u16 *          flags)
+{
+  int          keylen = 0;
+  char *       p;
+
+  if(!strncmp(input, "l:", 2))
+    {
+#if WIRELESS_EXT > 15
+      struct iw_range  range;
+#endif
+
+      /* Extra case : as a login (user:passwd - Cisco LEAP) */
+      keylen = strlen(input + 2) + 1;          /* skip "l:", add '\0' */
+      /* Most user/password is 8 char, so 18 char total, < 32 */
+      if(keylen > IW_ENCODING_TOKEN_MAX)
+       keylen = IW_ENCODING_TOKEN_MAX;
+      memcpy(key, input + 2, keylen);
+
+      /* Separate the two strings */
+      p = strchr(key, ':');
+      if(p == NULL)
+       {
+         fprintf(stderr, "Error: Invalid login format\n");
+         return(-1);
+       }
+      *p = '\0';
+
+#if WIRELESS_EXT > 15
+      printf("flags = %X, index = %X\n", *flags, range.encoding_login_index);
+      if((*flags & IW_ENCODE_INDEX) == 0)
+       {
+         /* Extract range info */
+         if(iw_get_range_info(skfd, ifname, &range) < 0)
+           memset(&range, 0, sizeof(range));
+         printf("flags = %X, index = %X\n", *flags, range.encoding_login_index);
+         /* Set the index the driver expects */
+         *flags |= range.encoding_login_index & IW_ENCODE_INDEX;
+       }
+      printf("flags = %X, index = %X\n", *flags, range.encoding_login_index);
+#else
+      /* Avoid "Unused parameter" warning */
+      skfd = skfd; ifname = ifname; flags = flags;
+#endif
+    }
+  else
+    /* Simpler routine above */
+    keylen = iw_in_key(input, key);
+
+  return(keylen);
+}
+
 /******************* POWER MANAGEMENT SUBROUTINES *******************/
 
 /*------------------------------------------------------------------*/
@@ -1108,6 +1268,8 @@ iw_print_pm_mode(char *   buffer,
       strcpy(buffer, "mode:Repeat multicasts");
       break;
     default:
+      strcpy(buffer, "");
+      break;
     }
 }
 
@@ -1530,8 +1692,8 @@ static const char standard_ioctl_hdr[] = {
        IW_HEADER_TYPE_POINT,   /* SIOCGIWSTATS */
        IW_HEADER_TYPE_POINT,   /* SIOCSIWSPY */
        IW_HEADER_TYPE_POINT,   /* SIOCGIWSPY */
-       IW_HEADER_TYPE_NULL,    /* -- hole -- */
-       IW_HEADER_TYPE_NULL,    /* -- hole -- */
+       IW_HEADER_TYPE_POINT,   /* SIOCSIWTHRSPY */
+       IW_HEADER_TYPE_POINT,   /* SIOCGIWTHRSPY */
        IW_HEADER_TYPE_ADDR,    /* SIOCSIWAP */
        IW_HEADER_TYPE_ADDR,    /* SIOCGIWAP */
        IW_HEADER_TYPE_NULL,    /* -- hole -- */
index 5818a08..f15edc8 100644 (file)
 #include <linux/in.h>          /* For struct sockaddr_in */
 #endif /* LIBC5_HEADERS */
 
+/* Those 3 headers were previously included in wireless.h */
+#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... */
+
 #ifdef WEXT_HEADER
 /* Private copy of Wireless extensions */
 #include WEXT_HEADER
 #include <linux/wireless.h>
 #endif /* !WEXT_HEADER */
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /****************************** DEBUG ******************************/
 
 
 #define KILO   1e3
 #define MEGA   1e6
 #define GIGA   1e9
+/* For doing log10/exp10 without libm */
+#define LOG10_MAGIC    1.25892541179
 
 /* Backward compatibility for Wireless Extension 9 */
 #ifndef IW_POWER_MODIFIER
 #define IW_ENCODE_NOKEY         0x0800  /* Key is write only, so not here */
 #define IW_ENCODE_MODE         0xF000  /* Modes defined below */
 #endif /* IW_ENCODE_NOKEY */
+#ifndef IW_ENCODE_TEMP
+#define IW_ENCODE_TEMP         0x0400  /* Temporary key */
+#endif /* IW_ENCODE_TEMP */
 
 /* More backward compatibility */
 #ifndef SIOCSIWCOMMIT
@@ -257,6 +271,7 @@ typedef int (*iw_enum_handler)(int  skfd,
 /*
  * All the functions in iwcommon.c
  */
+
 /* ---------------------- SOCKET SUBROUTINES -----------------------*/
 int
        iw_sockets_open(void);
@@ -328,6 +343,12 @@ void
 int
        iw_in_key(char *                input,
                  unsigned char *       key);
+int
+       iw_in_key_full(int              skfd,
+                      char *           ifname,
+                      char *           input,
+                      unsigned char *  key,
+                      __u16 *          flags);
 /* ----------------- POWER MANAGEMENT SUBROUTINES ----------------- */
 void
        iw_print_pm_value(char *        buffer,
@@ -474,4 +495,8 @@ iw_null_ether(struct sockaddr *sap)
   memset((char *) sap->sa_data, 0x00, ETH_ALEN);
 }
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* IWLIB_H */
index 3623626..731031b 100644 (file)
@@ -50,11 +50,6 @@ 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
-.BR ap / accesspoint
-Give the list of Access Points in range, and optionally the quality of
-link to them. This feature is obsolte and now deprecated in favor of
-scanning support (below), and it will disappear in the future.
-.TP
 .BR scan [ning]
 Give the list of Access Points and Ad-Hoc cells in range, and
 optionally a whole bunch of information about them (ESSID, Quality,
@@ -69,6 +64,15 @@ impacted by the current setting of the driver. Also, this command is
 supposed to take extra arguments to control the scanning behaviour,
 but this is currently not implemented.
 .TP
+.BR ap / accesspoint / peers
+Give the list of Access Points in range, and optionally the quality of
+link to them. This feature is obsolte and now deprecated in favor of
+scanning support (above), and most drivers don't support it.
+.br
+Some drivers may use this command to return a specific list of Peers
+or Access Points, such as the list of Peers associated/registered with
+the card. See your driver documentation for details.
+.TP
 .BR rate / bit [rate]
 List the bit-rates supported by the device.
 .TP
@@ -99,7 +103,8 @@ wireless interfaces.
 .\"
 .SH SEE ALSO
 .BR iwconfig (8),
-.BR ifconfig (8),
 .BR iwspy (8).
-.BR iwpriv (8).
+.BR iwevent (8),
+.BR iwpriv (8),
+.BR wireless (7).
 
index 8b751c2..72fec02 100644 (file)
@@ -117,7 +117,7 @@ print_ap_info(int   skfd,
   wrq.u.data.flags = 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);
+      fprintf(stderr, "%-8.8s  Interface doesn't have a list of Peers/Access-Points\n\n", ifname);
       return(-1);
     }
 
@@ -142,9 +142,9 @@ print_ap_info(int   skfd,
 
   /* Display it */
   if(n == 0)
-    printf("%-8.8s  No Access Point in range\n", ifname);
+    printf("%-8.8s  No Peers/Access-Point in range\n", ifname);
   else
-    printf("%-8.8s  Access Points in range:\n", ifname);
+    printf("%-8.8s  Peers/Access-Points in range:\n", ifname);
   for(i = 0; i < n; i++)
     {
       if(has_qual)
@@ -188,7 +188,7 @@ print_bitrate_info(int              skfd,
                      ifname);
   else
     {
-      if((range.num_bitrates > 0) && (range.num_bitrates < IW_MAX_BITRATES))
+      if((range.num_bitrates > 0) && (range.num_bitrates <= IW_MAX_BITRATES))
        {
          printf("%-8.8s  %d available bit-rates :\n",
                 ifname, range.num_bitrates);
@@ -291,9 +291,9 @@ print_keys_info(int         skfd,
       printf("          Current Transmit Key: [%d]\n",
             wrq.u.data.flags & IW_ENCODE_INDEX);
       if(wrq.u.data.flags & IW_ENCODE_RESTRICTED)
-       printf("          Encryption mode:restricted\n");
+       printf("          Security mode:restricted\n");
       if(wrq.u.data.flags & IW_ENCODE_OPEN)
-       printf("          Encryption mode:open\n");
+       printf("          Security mode:open\n");
 
       printf("\n\n");
     }
@@ -745,6 +745,9 @@ print_scanning_token(struct iw_event *      event,  /* Extracted token */
       printf("                    Mode:%s\n",
             iw_operation_mode[event->u.mode]);
       break;
+    case SIOCGIWNAME:
+      printf("                    Protocol:%-1.16s\n", event->u.name);
+      break;
     case SIOCGIWESSID:
       {
        char essid[IW_ESSID_MAX_SIZE+1];
@@ -785,9 +788,9 @@ print_scanning_token(struct iw_event *      event,  /* Extracted token */
            if((event->u.data.flags & IW_ENCODE_INDEX) > 1)
              printf(" [%d]", event->u.data.flags & IW_ENCODE_INDEX);
            if(event->u.data.flags & IW_ENCODE_RESTRICTED)
-             printf("   Encryption mode:restricted");
+             printf("   Security mode:restricted");
            if(event->u.data.flags & IW_ENCODE_OPEN)
-             printf("   Encryption mode:open");
+             printf("   Security mode:open");
            printf("\n");
          }
       }
@@ -986,6 +989,7 @@ static const struct iwlist_entry iwlist_cmds[] = {
   { "channel",         print_freq_info,        0, 0 },
   { "ap",              print_ap_info,          0, 0 },
   { "accesspoints",    print_ap_info,          0, 0 },
+  { "peers",           print_ap_info,          0, 0 },
   { "bitrate",         print_bitrate_info,     0, 0 },
   { "rate",            print_bitrate_info,     0, 0 },
   { "encryption",      print_keys_info,        0, 0 },
index d662840..0b2140a 100644 (file)
@@ -128,11 +128,8 @@ Jean Tourrilhes \- jt@hpl.hp.com
 .\" SEE ALSO part
 .\"
 .SH SEE ALSO
-.BR ifconfig (8),
 .BR iwconfig (8),
 .BR iwlist (8),
+.BR iwevent (8),
 .BR iwspy (8),
-.BR wavelan (4),
-.BR wavelan_cs (4),
-.BR wvlan_cs (4),
-.BR netwave_cs (4).
+.BR wireless (7).
index 986ffd8..1786e4d 100644 (file)
@@ -223,7 +223,7 @@ set_private_cmd(int         skfd,           /* Socket */
   /* Check if we have a token index.
    * Do it know so that sub-ioctl takes precendence, and so that we
    * don't have to bother with it later on... */
-  if((count > 1) && (sscanf(args[0], "[%d]", &temp) == 1))
+  if((count > 1) && (sscanf(args[0], "[%i]", &temp) == 1))
     {
       subcmd = temp;
       args++;
@@ -284,7 +284,7 @@ set_private_cmd(int         skfd,           /* Socket */
 
          /* Fetch args */
          for(; i < wrq.u.data.length; i++) {
-           sscanf(args[i], "%d", &temp);
+           sscanf(args[i], "%i", &temp);
            buffer[i] = (char) temp;
          }
          break;
@@ -297,7 +297,7 @@ set_private_cmd(int         skfd,           /* Socket */
 
          /* Fetch args */
          for(; i < wrq.u.data.length; i++) {
-           sscanf(args[i], "%d", &temp);
+           sscanf(args[i], "%i", &temp);
            ((__s32 *) buffer)[i] = (__s32) temp;
          }
          break;
@@ -339,7 +339,7 @@ set_private_cmd(int         skfd,           /* Socket */
            if(index(args[i], 'G')) freq *= GIGA;
            if(index(args[i], 'M')) freq *= MEGA;
            if(index(args[i], 'k')) freq *= KILO;
-           sscanf(args[i], "%d", &temp);
+           sscanf(args[i], "%i", &temp);
            iw_float2freq(freq, ((struct iw_freq *) buffer) + i);
          }
          break;
@@ -802,7 +802,7 @@ port_type(int               skfd,           /* Socket */
     ptype = k;
   else
     /* ...or as an integer */
-    if(sscanf(args[i], "%d", (int *) &ptype) != 1)
+    if(sscanf(args[i], "%i", (int *) &ptype) != 1)
       {
        iw_usage();
        return(-1);
diff --git a/wireless_tools/iwredir.8 b/wireless_tools/iwredir.8
new file mode 100644 (file)
index 0000000..2a4d60b
--- /dev/null
@@ -0,0 +1,89 @@
+.\" Jean II - HPL - 03
+.\" iwredir.8
+.\"
+.TH IWREDIR 8 "31 October 1996" "net-tools" "Linux Programmer's Manual"
+.\"
+.\" NAME part
+.\"
+.SH NAME
+iwredir \- WE-version wireless tool redirectot
+.\"
+.\" SYNOPSIS part
+.\"
+.SH SYNOPSIS
+.BI "iw" XXX " [ " args " ]"
+.br
+.BI "iwredir -wev
+.\"
+.\" DESCRIPTION part
+.\"
+.SH DESCRIPTION
+.B Iwredir
+is used to enable the use multiple version of the Wireless Tools on
+the same system.
+.B Iwredir
+pick the proper version of the wireless tools based on the version of
+Wireless Extension of the current kernel.
+.PP
+A version of the Wireless Tools need to be compiled for each version
+of Wireless Extensions expected to be used (this require specific
+.I make
+instructions), and each tool name need to be suffixed by the WE
+version (ex.
+.I iwconfig16
+for the binary of iwconfig compiled for Wireless Extension 16).
+.br
+Then,
+.B iwredir
+need to be installed under the name of each of the tool that need
+redirection
+.RI "(" iwconfig ", " iwlist "...)."
+.br
+.B Iwredir
+just adds the version of WE from the current kernel to the name it was
+called and executed the resulting command name. If the user invoque
+.I iwlist
+(that is now replaced with
+.IR iwredir )
+and the current kernel has WE version
+.IR 17 ,
+the final command executed will be
+.IR iwlist17 .
+.br
+.B Iwredir
+will read the Wireless Extension version of the current kernel from
+.IR /proc/net/wireless .
+.PP
+.B Iwredir
+works only for Wireless Extension 16 and later, all previous version
+of WE are assumed to be version 15 or version 11.
+.B Iwredir
+is usually not installed by default and is expected to be used only by
+.I advanced
+users.
+.\"
+.\" PARAMETER part
+.\"
+.SH PARAMETERS
+.TP
+.BR -wev
+Give the Wireless Extension version that
+.B iwredir
+will use for redirection. This is mostly used in the Wireless Tools
+Makefile when doing a versioned installation of the tools.
+.\"
+.\" FILES part
+.\"
+.SH FILES
+.I /proc/net/wireless
+.\"
+.\" SEE ALSO part
+.\"
+.SH SEE ALSO
+.BR iwconfig (8),
+.BR iwlist (8),
+.BR iwspy (8),
+.BR iwevent (8),
+.BR iwpriv (8),
+.BR wireless (7).
+
diff --git a/wireless_tools/iwredir.c b/wireless_tools/iwredir.c
new file mode 100644 (file)
index 0000000..ef99249
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ *     Wireless Tools
+ *
+ *             Jean II - HPL 03
+ *
+ * Main code for "iwredir". This is a hack to match multiple version
+ * of the tools with multiple kernels on the same system...
+ *
+ * This file is released under the GPL license.
+ *     Copyright (c) 2003 Jean Tourrilhes <jt@hpl.hp.com>
+ */
+
+/***************************** INCLUDES *****************************/
+
+#include "iwlib.h"             /* Header */
+
+/*********************** VERSION SUBROUTINES ***********************/
+
+/*------------------------------------------------------------------*/
+/*
+ * Extract WE version number from /proc/net/wireless
+ * If we have WE-16 and later, the WE version is available at the
+ * end of the header line of the file.
+ * For version prior to that, we can only detect the change from
+ * v11 to v12, so we do an approximate job. Fortunately, v12 to v15
+ * are highly binary compatible (on the struct level).
+ */
+static int
+iw_get_kernel_we_version(void)
+{
+  char         buff[1024];
+  FILE *       fh;
+  char *       p;
+  int          v;
+
+  /* Check if /proc/net/wireless is available */
+  fh = fopen(PROC_NET_WIRELESS, "r");
+
+  if(fh == NULL)
+    {
+      fprintf(stderr, "Cannot read " PROC_NET_WIRELESS "\n");
+      return(-1);
+    }
+
+  /* Read the first line of buffer */
+  fgets(buff, sizeof(buff), fh);
+
+  if(strstr(buff, "| WE") == NULL)
+    {
+      /* Prior to WE16, so explicit version not present */
+
+      /* Black magic */
+      if(strstr(buff, "| Missed") == NULL)
+       v = 11;
+      else
+       v = 15;
+      fclose(fh);
+      return(v);
+    }
+
+  /* Read the second line of buffer */
+  fgets(buff, sizeof(buff), fh);
+
+  /* Get to the last separator, to get the version */
+  p = strrchr(buff, '|');
+  if((p == NULL) || (sscanf(p + 1, "%d", &v) != 1))
+    {
+      fprintf(stderr, "Cannot parse " PROC_NET_WIRELESS "\n");
+      fclose(fh);
+      return(-1);
+    }
+
+  fclose(fh);
+  return(v);
+}
+
+/******************************* MAIN ********************************/
+
+/*------------------------------------------------------------------*/
+/*
+ * The main !
+ */
+int
+main(int       argc,
+     char **   argv)
+{
+  int  version = 0;
+  int  goterr = 0;
+  char file[512];
+  int  flen;
+
+  /* Get current version */
+  version = iw_get_kernel_we_version();
+  if(version <= 0)
+    version = 15;      /* We can only read only WE16 and higher */
+
+  /* Special case for Wireless Extension Version... */
+  /* This is mostly used in the Makefile, we use an "unlikely" option
+   * to maximise transparency to the tool we masquerade - Jean II */
+  if((argc > 1) && !strcmp(argv[1], "-wev"))
+    {
+      printf("%d\n", version);
+      return(version);
+    }
+
+  /* Mangle the command name */
+  flen = strlen(argv[0]);
+  if((flen + 3) >= 512)
+    {
+      fprintf(stderr, "Command name too long [%s]\n", argv[0]);
+      return(-1);
+    }
+  memcpy(file, argv[0], flen + 1);
+  sprintf(file + flen, "%d", version);
+
+  /* Execute (won't return) */
+  goterr = execvp(file, argv);
+
+  /* In case of error */
+  fprintf(stderr, "Can't execute command %s: %s\n", file, strerror(errno));
+  return(goterr);
+}
+
+
index 9eec627..cbe6195 100644 (file)
@@ -16,6 +16,10 @@ iwspy \- Get wireless statistics from specific nodes
 .BI "iwspy " interface " [+] " DNSNAME " | " IPADDR " | " HWADDR " [...]"
 .br
 .BI "iwspy " interface " off"
+.br
+.BI "iwspy " interface " setthr " "low high"
+.br
+.BI "iwspy " interface " getthr"
 .\"
 .\" DESCRIPTION part
 .\"
@@ -63,7 +67,29 @@ should use this option to avoid conflicts.
 .TP
 .B off
 Remove the current list of addresses and disable the spy functionality
-.\"
+.TP
+.B setthr
+Set the
+.I low
+and
+.I high
+signal strength threshold for the iwspy event (for driver that support
+it).
+.br
+Every time the signal strengh for any of the address monitored
+with iwspy goes lower than the low threshold or goes higher than the
+high threshold, a Wireless Event will be generated.
+.br
+This can be used to monitor link outages without having to run iwspy
+periodically.
+.TP
+.B getthr
+Retrieve the current
+.I low
+and
+.I high
+signal strength threshold for the iwspy event.
+\"
 .\" FILES part
 .\"
 .SH FILES
@@ -73,7 +99,8 @@ Remove the current list of addresses and disable the spy functionality
 .\"
 .SH SEE ALSO
 .BR iwconfig (8),
-.BR ifconfig (8),
-.BR iwlist (8).
-.BR iwpriv (8).
+.BR iwlist (8),
+.BR iwevent (8),
+.BR iwpriv (8),
+.BR wireless (7).
 
index 21726e6..1bc2deb 100644 (file)
 
 #include "iwlib.h"             /* Header */
 
-/* Backward compatibility */
-#ifndef IW_MAX_GET_SPY
-#define IW_MAX_GET_SPY 64
-#endif /* IW_MAX_GET_SPY */
-
 /************************* DISPLAY ROUTINES **************************/
 
 /*------------------------------------------------------------------*/
@@ -31,7 +26,7 @@ print_spy_info(int    skfd,
 {
   struct iwreq         wrq;
   char         buffer[(sizeof(struct iw_quality) +
-                       sizeof(struct sockaddr)) * IW_MAX_GET_SPY];
+                       sizeof(struct sockaddr)) * IW_MAX_SPY];
   char         temp[128];
   struct sockaddr *    hwa;
   struct iw_quality *  qual;
@@ -45,7 +40,7 @@ print_spy_info(int    skfd,
 
   /* Collect stats */
   wrq.u.data.pointer = (caddr_t) buffer;
-  wrq.u.data.length = IW_MAX_GET_SPY;
+  wrq.u.data.length = IW_MAX_SPY;
   wrq.u.data.flags = 0;
   if(iw_get_ext(skfd, ifname, SIOCGIWSPY, &wrq) < 0)
     {
@@ -87,8 +82,17 @@ print_spy_info(int   skfd,
 #if WIRELESS_EXT > 11
   if((n > 0) && (has_range))
     {
-      iw_print_stats(temp, &range.avg_qual, &range, has_range);
-      printf("    typical/average   : %s\n", temp);
+      iwstats  stats;
+
+      /* Get /proc/net/wireless */
+      if(iw_get_stats(skfd, ifname, &stats) >= 0)
+       {
+         iw_print_stats(buffer, &stats.qual, &range, has_range);
+         printf("    Link/Cell/AP      : %s\n", buffer);
+         /* Display the static data */
+         iw_print_stats(temp, &range.avg_qual, &range, has_range);
+         printf("    Typical/Reference : %s\n", temp);
+       }
     }
 #endif /* WIRELESS_EXT > 11 */
 
@@ -96,6 +100,78 @@ print_spy_info(int  skfd,
   return(0);
 }
 
+/*------------------------------------------------------------------*/
+/*
+ * Get spy thresholds from the driver and display
+ */
+static int
+get_spy_threshold(int          skfd,           /* The socket */
+                 char *        ifname,         /* Dev name */
+                 char *        args[],         /* Command line args */
+                 int           count)          /* Args count */
+{
+#if WIRELESS_EXT > 15
+  struct iwreq         wrq;
+  struct iw_thrspy     threshold;
+  iwrange      range;
+  int                  has_range = 0;
+
+  /* Avoid "Unused parameter" warning */
+  args = args; count = count;
+
+  /* Time to send thresholds to the driver */
+  wrq.u.data.pointer = (caddr_t) &threshold;
+  wrq.u.data.length = 1;
+  wrq.u.data.flags = 0;
+  if(iw_set_ext(skfd, ifname, SIOCGIWTHRSPY, &wrq) < 0)
+    {
+      fprintf(stderr, "Interface doesn't support thresholds...\n");
+      fprintf(stderr, "SIOCGIWTHRSPY: %s\n", strerror(errno));
+      return(-1);
+    }
+
+  /* Get range info if we can */
+  if(iw_get_range_info(skfd, ifname, &(range)) >= 0)
+    has_range = 1;
+
+  /* Display thresholds */
+  if((has_range) && (threshold.low.level))
+    {
+      /* If the statistics are in dBm */
+      if(threshold.low.level > range.max_qual.level)
+       {
+         /* Statistics are in dBm (absolute power measurement) */
+         printf("%-8.8s  Low threshold:%d dBm  High threshold:%d dBm\n\n",
+                ifname,
+                threshold.low.level - 0x100, threshold.high.level - 0x100);
+       }
+      else
+       {
+         /* Statistics are relative values (0 -> max) */
+         printf("%-8.8s  Low threshold:%d/%d  High threshold:%d/%d\n\n",
+                ifname,
+                threshold.low.level, range.max_qual.level,
+                threshold.high.level, range.max_qual.level);
+       }
+    }
+  else
+    {
+      /* We can't read the range, so we don't know... */
+      printf("%-8.8s  Low threshold:%d  High threshold:%d\n\n",
+            ifname,
+            threshold.low.level, threshold.high.level);
+    }
+
+  return(0);
+#else /* WIRELESS_EXT > 15 */
+  /* Avoid "Unused parameter" warning */
+  skfd = skfd; ifname = ifname; args = args; count = count;
+
+  fprintf(stderr, "Feature not available...\n");
+  return(-1);
+#endif /* WIRELESS_EXT > 15 */
+}
+
 /************************* SETTING ROUTINES **************************/
 
 /*------------------------------------------------------------------*/
@@ -104,9 +180,9 @@ print_spy_info(int  skfd,
  */
 static int
 set_spy_info(int               skfd,           /* The socket */
+            char *             ifname,         /* Dev name */
             char *             args[],         /* Command line args */
-            int                count,          /* Args count */
-            char *             ifname)         /* Dev name */
+            int                count)          /* Args count */
 {
   struct iwreq         wrq;
   int                  i;
@@ -189,6 +265,78 @@ set_spy_info(int           skfd,           /* The socket */
   return(0);
 }
 
+/*------------------------------------------------------------------*/
+/*
+ * Set spy thresholds in the driver from command line
+ */
+static int
+set_spy_threshold(int          skfd,           /* The socket */
+                 char *        ifname,         /* Dev name */
+                 char *        args[],         /* Command line args */
+                 int           count)          /* Args count */
+{
+#if WIRELESS_EXT > 15
+  struct iwreq         wrq;
+  struct iw_thrspy     threshold;
+  int                  low_thr;
+  int                  high_thr;
+
+  /* Init */
+  memset(&threshold, '\0', sizeof(threshold));
+
+  /* "off" : disable functionality (set 0 addresses) */
+  if(!strcmp(args[0], "off"))
+    {
+      /* Just send null threshold, will disable it */
+    }
+  else
+    {
+      /* Try to get our threshold */
+      if(count < 2)
+       {
+         fprintf(stderr, "%-8.8s  Need two threshold values\n", ifname);
+         return(-1);
+       }
+      if((sscanf(args[0], "%i", &low_thr) != 1) ||
+        (sscanf(args[1], "%i", &high_thr) != 1))
+       {
+         fprintf(stderr, "%-8.8s  Invalid threshold values\n", ifname);
+         return(-1);
+       }
+      /* Basic sanity check */
+      if(high_thr < low_thr)
+       {
+         fprintf(stderr, "%-8.8s  Inverted threshold range\n", ifname);
+         return(-1);
+       }
+      /* Copy thresholds */
+      threshold.low.level = low_thr;
+      threshold.low.updated = 0x2;
+      threshold.high.level = high_thr;
+      threshold.high.updated = 0x2;
+    }
+
+  /* Time to send thresholds to the driver */
+  wrq.u.data.pointer = (caddr_t) &threshold;
+  wrq.u.data.length = 1;
+  wrq.u.data.flags = 0;
+  if(iw_set_ext(skfd, ifname, SIOCSIWTHRSPY, &wrq) < 0)
+    {
+      fprintf(stderr, "Interface doesn't accept thresholds...\n");
+      fprintf(stderr, "SIOCSIWTHRSPY: %s\n", strerror(errno));
+      return(-1);
+    }
+
+  return(0);
+#else /* WIRELESS_EXT > 15 */
+  /* Avoid "Unused parameter" warning */
+  skfd = skfd; ifname = ifname; args = args; count = count;
+
+  fprintf(stderr, "Feature not available...\n");
+  return(-1);
+#endif /* WIRELESS_EXT > 15 */
+}
+
 /******************************* MAIN ********************************/
 
 /*------------------------------------------------------------------*/
@@ -227,8 +375,15 @@ main(int   argc,
        if(argc == 2)
          print_spy_info(skfd, argv[1], NULL, 0);
        else
-         /* Otherwise, it's a list of address to set in the spy list */
-         goterr = set_spy_info(skfd, argv + 2, argc - 2, argv[1]);
+         /* Special commands */
+         if(!strcmp(argv[2], "setthr"))
+           goterr = set_spy_threshold(skfd, argv[1], argv + 3, argc - 3);
+         else
+           if(!strcmp(argv[2], "getthr"))
+             goterr = get_spy_threshold(skfd, argv[1], argv + 3, argc - 3);
+           else
+             /* Otherwise, it's a list of address to set in the spy list */
+             goterr = set_spy_info(skfd, argv[1], argv + 2, argc - 2);
 
   /* Close the socket. */
   close(skfd);
diff --git a/wireless_tools/wireless.16.h b/wireless_tools/wireless.16.h
new file mode 100644 (file)
index 0000000..965a83b
--- /dev/null
@@ -0,0 +1,733 @@
+/*
+ * This file define a set of standard wireless extensions
+ *
+ * Version :   16      2.4.03
+ *
+ * Authors :   Jean Tourrilhes - HPL - <jt@hpl.hp.com>
+ * Copyright (c) 1997-2002 Jean Tourrilhes, All Rights Reserved.
+ */
+
+#ifndef _LINUX_WIRELESS_H
+#define _LINUX_WIRELESS_H
+
+/************************** DOCUMENTATION **************************/
+/*
+ * Initial APIs (1996 -> onward) :
+ * -----------------------------
+ * 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)
+ *
+ * New driver API (2002 -> 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
+ *
+ * Wireless Events (2002 -> onward) :
+ * --------------------------------
+ * Events are defined at the end of this file, and implemented 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.
+ *
+ * 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 *****************************/
+
+/* To minimise problems in user space, I might remove those headers
+ * at some point. Jean II */
+#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... */
+
+/***************************** 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   16
+
+/*
+ * 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)
+ *
+ * V12 to V13
+ * ----------
+ *     - Document creation of new driver API.
+ *     - Extract union iwreq_data from struct iwreq (for new driver API).
+ *     - Rename SIOCSIWNAME as SIOCSIWCOMMIT
+ *
+ * V13 to V14
+ * ----------
+ *     - Wireless Events support : define struct iw_event
+ *     - Define additional specific event numbers
+ *     - Add "addr" and "param" fields in union iwreq_data
+ *     - AP scanning stuff (SIOCSIWSCAN and friends)
+ *
+ * V14 to V15
+ * ----------
+ *     - Add IW_PRIV_TYPE_ADDR for struct sockaddr private arg
+ *     - Make struct iw_freq signed (both m & e), add explicit padding
+ *     - Add IWEVCUSTOM for driver specific event/scanning token
+ *     - Add IW_MAX_GET_SPY for driver returning a lot of addresses
+ *     - Add IW_TXPOW_RANGE for range of Tx Powers
+ *     - Add IWEVREGISTERED & IWEVEXPIRED events for Access Points
+ *     - Add IW_MODE_MONITOR for passive monitor
+ *
+ * V15 to V16
+ * ----------
+ *     - Increase the number of bitrates in iw_range to 32 (for 802.11g)
+ *     - Increase the number of frequencies in iw_range to 32 (for 802.11b+a)
+ *     - Reshuffle struct iw_range for increases, add filler
+ *     - Increase IW_MAX_AP to 64 for driver returning a lot of addresses
+ *     - Remove IW_MAX_GET_SPY because conflict with enhanced spy support
+ *     - Add SIOCSIWTHRSPY/SIOCGIWTHRSPY and "struct iw_thrspy"
+ *     - Add IW_ENCODE_TEMP and iw_range->encoding_login_index
+ */
+
+/**************************** CONSTANTS ****************************/
+
+/* -------------------------- IOCTL LIST -------------------------- */
+
+/* Wireless Identification */
+#define SIOCSIWCOMMIT  0x8B00          /* Commit pending changes to driver */
+#define SIOCGIWNAME    0x8B01          /* get name == wireless protocol */
+/* SIOCGIWNAME is used to verify the presence of Wireless Extensions.
+ * Common values : "IEEE 802.11-DS", "IEEE 802.11-FH", "IEEE 802.11b"...
+ * Don't put the name of your driver there, it's useless. */
+
+/* Basic operations */
+#define SIOCSIWNWID    0x8B02          /* set network id (pre-802.11) */
+#define SIOCGIWNWID    0x8B03          /* get network id (the cell) */
+#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 */
+/* SIOCGIWSTATS is strictly used between user space and the kernel, and
+ * is never passed to the driver (i.e. the driver will never see it). */
+
+/* Spy support (statistics per MAC address - used for Mobile IP support) */
+#define SIOCSIWSPY     0x8B10          /* set spy addresses */
+#define SIOCGIWSPY     0x8B11          /* get spy info (quality of link) */
+#define SIOCSIWTHRSPY  0x8B12          /* set spy threshold (spy event) */
+#define SIOCGIWTHRSPY  0x8B13          /* get spy threshold */
+
+/* Access Point manipulation */
+#define SIOCSIWAP      0x8B14          /* set access point MAC addresses */
+#define SIOCGIWAP      0x8B15          /* get access point MAC addresses */
+#define SIOCGIWAPLIST  0x8B17          /* Deprecated in favor of scanning */
+#define SIOCSIWSCAN    0x8B18          /* trigger scanning (list cells) */
+#define SIOCGIWSCAN    0x8B19          /* get scanning results */
+
+/* 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... */
+
+/* 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 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 ;-).
+ * 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)
+
+/* ----------------------- WIRELESS EVENTS ----------------------- */
+/* Those are *NOT* ioctls, do not issue request on them !!! */
+/* Most events use the same identifier as ioctl requests */
+
+#define IWEVTXDROP     0x8C00          /* Packet dropped to excessive retry */
+#define IWEVQUAL       0x8C01          /* Quality part of statistics (scan) */
+#define IWEVCUSTOM     0x8C02          /* Driver specific ascii string */
+#define IWEVREGISTERED 0x8C03          /* Discovered a new node (AP mode) */
+#define IWEVEXPIRED    0x8C04          /* Expired a node (AP mode) */
+
+#define IWEVFIRST      0x8C00
+
+/* ------------------------- 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  /* struct iw_freq */
+#define IW_PRIV_TYPE_ADDR      0x6000  /* struct sockaddr */
+
+#define IW_PRIV_SIZE_FIXED     0x0800  /* Variable or fixed number 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     32
+/* 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                32
+
+/* Maximum tx powers in the range struct */
+#define IW_MAX_TXPOWER         8
+/* Note : if you more than 8 TXPowers, just set the max and min or
+ * a few of them in the struct iw_range. */
+
+/* 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              64
+
+/* 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) */
+#define IW_MODE_MONITOR        6       /* Passive monitor (listen only) */
+
+/* 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 */
+#define IW_ENCODE_TEMP         0x0400  /* Temporary key */
+
+/* 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_TYPE          0x00FF  /* Type of value */
+#define IW_TXPOW_DBM           0x0000  /* Value is in dBm */
+#define IW_TXPOW_MWATT         0x0001  /* Value is in mW */
+#define IW_TXPOW_RANGE         0x1000  /* Range of value between min/max */
+
+/* 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 */
+
+/* Scanning request flags */
+#define IW_SCAN_DEFAULT                0x0000  /* Default scan of the driver */
+#define IW_SCAN_ALL_ESSID      0x0001  /* Scan all ESSIDs */
+#define IW_SCAN_THIS_ESSID     0x0002  /* Scan only this ESSID */
+#define IW_SCAN_ALL_FREQ       0x0004  /* Scan all Frequencies */
+#define IW_SCAN_THIS_FREQ      0x0008  /* Scan only this Frequency */
+#define IW_SCAN_ALL_MODE       0x0010  /* Scan all Modes */
+#define IW_SCAN_THIS_MODE      0x0020  /* Scan only this Mode */
+#define IW_SCAN_ALL_RATE       0x0040  /* Scan all Bit-Rates */
+#define IW_SCAN_THIS_RATE      0x0080  /* Scan only this Bit-Rate */
+/* Maximum size of returned data */
+#define IW_SCAN_MAX_DATA       4096    /* In bytes */
+
+/* Max number of char in custom event - use multiple of them if needed */
+#define IW_CUSTOM_MAX          256     /* In bytes */
+
+/****************************** 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
+{
+       __s32           m;              /* Mantissa */
+       __s16           e;              /* Exponent */
+       __u8            i;              /* List index (when in range struct) */
+       __u8            pad;            /* Unused - just for alignement */
+};
+
+/*
+ *     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 */
+};
+
+/*
+ *     Quality range (for spy threshold)
+ */
+struct iw_thrspy
+{
+       struct sockaddr         addr;           /* Source address (hw/mac) */
+       struct iw_quality       qual;           /* Quality of the link */
+       struct iw_quality       low;            /* Low threshold */
+       struct iw_quality       high;           /* High threshold */
+};
+
+/* ------------------------ 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 ------------------------ */
+/*
+ * 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 iw_quality qual;         /* Quality part of statistics */
+
+       struct sockaddr ap_addr;        /* Access point address */
+       struct sockaddr addr;           /* Destination address (hw/mac) */
+
+       struct iw_param param;          /* Other small parameters */
+       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...
+ * Do I need to remind you about structure size (32 octets) ?
+ */
+struct iwreq 
+{
+       union
+       {
+               char    ifrn_name[IFNAMSIZ];    /* if name, e.g. "eth0" */
+       } ifr_ifrn;
+
+       /* Data part (defined just above) */
+       union   iwreq_data      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 */
+
+       /* Old Frequency (backward compat - moved lower ) */
+       __u16           old_num_channels;
+       __u8            old_num_frequency;
+       /* Filler to keep "version" at the same offset */
+       __s32           old_freq[6];
+
+       /* signal level threshold range */
+       __s32   sensitivity;
+
+       /* Quality of link & SNR stuff */
+       /* Quality range (link, level, noise)
+        * If the quality is absolute, it will be in the range [0 ; max_qual],
+        * if the quality is dBm, it will be in the range [max_qual ; 0].
+        * Don't forget that we use 8 bit arithmetics... */
+       struct iw_quality       max_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... */
+       struct iw_quality       avg_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 */
+       /* For drivers that need a "login/passwd" form */
+       __u8    encoding_login_index;   /* token index for login token */
+
+       /* 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 */
+
+       /* 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,
+        * because each entry contain its channel index */
+};
+
+/*
+ * 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 */
+};
+
+/* ----------------------- WIRELESS EVENTS ----------------------- */
+/*
+ * Wireless events are carried through the rtnetlink socket to user
+ * space. They are encapsulated in the IFLA_WIRELESS field of
+ * a RTM_NEWLINK message.
+ */
+
+/*
+ * A Wireless Event. Contains basically the same data as the ioctl...
+ */
+struct iw_event
+{
+       __u16           len;                    /* Real lenght of this stuff */
+       __u16           cmd;                    /* Wireless IOCTL */
+       union iwreq_data        u;              /* IOCTL fixed payload */
+};
+
+/* Size of the Event prefix (including padding and alignement junk) */
+#define IW_EV_LCP_LEN  (sizeof(struct iw_event) - sizeof(union iwreq_data))
+/* Size of the various events */
+#define IW_EV_CHAR_LEN (IW_EV_LCP_LEN + IFNAMSIZ)
+#define IW_EV_UINT_LEN (IW_EV_LCP_LEN + sizeof(__u32))
+#define IW_EV_FREQ_LEN (IW_EV_LCP_LEN + sizeof(struct iw_freq))
+#define IW_EV_POINT_LEN        (IW_EV_LCP_LEN + sizeof(struct iw_point))
+#define IW_EV_PARAM_LEN        (IW_EV_LCP_LEN + sizeof(struct iw_param))
+#define IW_EV_ADDR_LEN (IW_EV_LCP_LEN + sizeof(struct sockaddr))
+#define IW_EV_QUAL_LEN (IW_EV_LCP_LEN + sizeof(struct iw_quality))
+
+/* Note : in the case of iw_point, the extra data will come at the
+ * end of the event */
+
+#endif /* _LINUX_WIRELESS_H */
index 9ee50cb..eebb235 100644 (file)
@@ -58,6 +58,32 @@ wireless_mode ad_hoc
 .br
 .I /usr/share/doc/wireless.##/README.Debian
 .\"
+.\" SuSE 8.0 part
+.\"
+.SH SuSE 8.0
+SuSE 8.0 (and later) has integrated wireless configuration in their
+network scripts.
+.TP
+.B Tool :
+.B Yast2
+.TP
+.B File :
+.I /etc/sysconfig/network/wireless
+.br
+.I /etc/sysconfig/network/ifcfg-*
+.TP
+.B Form :
+.RI WIRELESS_ "<function>" = "<value>"
+.br
+WIRELESS_ESSID="Home"
+.br
+WIRELESS_MODE=ad_hoc
+.TP
+.B See also :
+man ifup
+.br
+info scpm
+.\"
 .\" PCMCIA part
 .\"
 .SH ORIGINAL PCMCIA SCRIPTS