OSDN Git Service

v20
authorchris-kirby <chris.kirby@hpe.com>
Tue, 11 Oct 2016 20:49:10 +0000 (14:49 -0600)
committerchris-kirby <chris.kirby@hpe.com>
Tue, 11 Oct 2016 20:49:10 +0000 (14:49 -0600)
15 files changed:
wireless_tools/INSTALL
wireless_tools/README
wireless_tools/compat.h [deleted file]
wireless_tools/iwcommon.h
wireless_tools/iwconfig [deleted file]
wireless_tools/iwconfig.8
wireless_tools/iwconfig.c
wireless_tools/iwpriv [deleted file]
wireless_tools/iwpriv.8
wireless_tools/iwpriv.c
wireless_tools/iwspy [deleted file]
wireless_tools/iwspy.8
wireless_tools/iwspy.c
wireless_tools/sample_enc_cs.c [new file with mode: 0644]
wireless_tools/wireless.h [deleted file]

index 9f39ed4..7aa92c0 100644 (file)
@@ -1,35 +1,66 @@
+Very important note :
+-------------------
+       This release of the Wireless Tools is not compatible with Wireless
+       Extensions earlier than 9.
+       Kernels that support this version of the Wireless Tools are listed
+       below. For all kernels before that, please use the version v19 of
+       the Wireless Tools.
+       If your kernel has the relevant Wireless Extensions but the tools
+       refuse to compile, then your kernel headers in /usr/include are
+       pointing to the wrong place (very common with Debian).
+
 You need :
 --------
-       o A kernel supporting wireless extensions
-               -> from 2.1.17 onward
-               -> from 2.0.30 onward
-               -> patch available for 1.2.13
+       o Compiler and development environment
+       o A kernel supporting wireless extensions version 9 or higher
+               -> from 2.2.14 onward
+               -> from 2.3.24 onward
                Note : CONFIG_NET_RADIO must be enabled
-       o Driver supporting wireless extensions
-               -> Wavelan isa from kernel 2.1.17 onward
-               -> Wavelan pcmcia from pcmcia 2.9.2 onward
-               -> Netwave pcmcia from pcmcia 2.9.12 onward
+       o A driver supporting wireless extensions
+               -> Wavelan isa from kernels above
+               -> Wavelan pcmcia from pcmcia 3.1.2 onward
+               -> Netwave pcmcia from pcmcia 3.1.2 onward
                -> Wavelan IEEE pcmcia drivers
                -> Proxim RangeLan2/Symphony driver
                -> Patch your favourite driver
        Note : more recent kernels and drivers are likely to support
                more wireless extension features...
 
+Recommended versions :
+--------------------
+       This are the latest updates of the Wireless Extensions :
+       o Kernel (wireless extension definition) :
+               -> Kernel 2.2.14 onward
+               -> Kernel 2.3.24 onward
+       o Drivers with wireless extension support :
+               -> Wavelan isa from kernels above
+               -> Wavelan pcmcia from pcmcia 3.1.1 onward
+               -> Netwave pcmcia from pcmcia 3.1.2 onward
+               -> Wavelan IEEE pcmcia GPL driver (wvlan) 1.0.1 onward
+               -> Wavelan IEEE pcmcia binary driver (wavelan2) v4.00 onward
+               -> Proxim RangeLan2/Symphony driver 1.4.3 onward
+
 Compile wireless tools :
 ----------------------
-       In theory, a make should suffice.
-       In practice, there is big troubles with the headers. Depending
-on which version of the kernel headers (might be different from
-kernel) and library headers you have, you need to play with the
-options buried in iwcommon.h.
+       In theory, a "make" should suffice.
+       In practice, there is big troubles with the headers. If you
+have glibc and kernel 2.2.X headers, that should be all
+right. Depending on which version of the kernel headers (might be
+different from kernel) and library headers you have, you need to play
+with the options buried in iwcommon.h.
+       Note : as some internal data structures change from kernel to
+kernel, you are advised to not use the precompiled version but to
+recompile your own.
+       "xwireless" is not currently in a compilable state.
 
+Installation :
+------------
+       I advise to copy the executable (iwconfig, iwspy and iwpriv)
+in /usr/local/bin or /usr/local/sbin. The man pages (iwconfig.8,
+iwspy.8 and iwpriv.8) should be copied in /usr/local/man/man8 or
+/usr/man/man8.
 
-This package was originally created by:
-
-       Jean <jt@hpl.hp.com>
 
-And is now being maintained by:
-       Justin Seger <jseger@media.mit.edu>
+List of contributors and changelog is in iwcommon.h.
 
-It seem that I've been taking over !
        Jean <jt@hpl.hp.com>
index 4a706b4..290ca28 100644 (file)
@@ -3,29 +3,47 @@ the Wireless Extensions. The Wireless Extension is an interface
 allowing you to set Wireless LAN specific parameters and get the
 specific stats.
 
+INSTALL
+-------
+       Installation instruction and requirements.
+
+man pages (iwconfig.8, iwpriv.8, iwspy.8)
+---------
+       As far as I know, the man pages are the most complete, up to
+date and accurate documentation of the wireless tools, and you really
+should read them.
+       They can either be copied in a location where the command
+"man" will find them, or can be read with the command :
+               nroff -man xxx.8 | more
+
+web page
+--------
+       You'll find a lot of useful info on :
+               http://web.hpl.hp.com/personal/Jean_Tourrilhes/Linux/
+
 iwconfig.c
 ----------
-       The main wireless tool. Used for device configuration.
-       You need of course to compile it.
-       This also includes the functionality previously contained in iwpriv.c.
-       It allows you to access device specific extensions.
+       The main wireless tool. Used for device configuration and to see
+       the most common parameters.
 
 iwspy.c
 -------
        Mobile IP support test and allow get get stats per MAC address
-       (instead of globally).
+       (instead of globally). Also display available bit rates and
+       frequencies.
 
 iwpriv.c
 --------
-       Manipulate driver private ioctls.
+       Manipulate driver private ioctls (all that is not available in
+       iwconfig). These are device specific parameters.
 
 xwireless.c
 -----------
        Graphical tool for the Netwave created by Dag Brattli <dagb@cs.uit.no>
 
 
-       The man page should describe adequately the behaviour of the tools.
        The list of changes, credits and errata notes are in
-iwcommon.h. Compilation might be tricky.
+iwcommon.h. Compilation might be tricky, see iwcommon.h for header
+problems...
 
        Jean <jt@hpl.hp.com>
diff --git a/wireless_tools/compat.h b/wireless_tools/compat.h
deleted file mode 100644 (file)
index 224e048..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-/* This whole file is flaky */
-/* This is all we need to compile and can't find only in linux headers.
- * So, I did copy past here...
- */
-#define __u8   unsigned char
-#define __u16  unsigned short
-#define __u32  unsigned long           /* Hum, and on Alpha ? */
-#define __u64  unsigned long long      /* Unsure about this one */
-
-#define        IFNAMSIZ        16
-#define ARPHRD_ETHER   1               /* Ethernet 10Mbps              */
-#define ETH_ALEN       6               /* Octets in one ethernet addr   */
-
-/*
- * Interface request structure used for socket
- * ioctl's.  All interface ioctl's must have parameter
- * definitions which begin with ifr_name.  The
- * remainder may be interface specific.
- */
-struct ifreq 
-{
-#define IFHWADDRLEN    6
-#define        IFNAMSIZ        16
-       union
-       {
-               char    ifrn_name[IFNAMSIZ];            /* if name, e.g. "en0" */
-       } ifr_ifrn;
-       
-       union {
-               struct  sockaddr ifru_addr;
-               struct  sockaddr ifru_dstaddr;
-               struct  sockaddr ifru_broadaddr;
-               struct  sockaddr ifru_netmask;
-               struct  sockaddr ifru_hwaddr;
-               short   ifru_flags;
-               int     ifru_metric;
-               int     ifru_mtu;
-#if 0
-               struct  ifmap ifru_map;
-#endif
-               char    ifru_slave[IFNAMSIZ];   /* Just fits the size */
-               caddr_t ifru_data;
-       } ifr_ifru;
-};
-#define ifr_name       ifr_ifrn.ifrn_name      /* interface name       */
-#define ifr_hwaddr     ifr_ifru.ifru_hwaddr    /* MAC address          */
-#define        ifr_addr        ifr_ifru.ifru_addr      /* address              */
-
-/*
- * Structure used in SIOCGIFCONF request.
- * Used to retrieve interface configuration
- * for machine (useful for programs which
- * must know all networks accessible).
- */
-struct ifconf 
-{
-       int     ifc_len;                        /* size of buffer       */
-       union 
-       {
-               caddr_t ifcu_buf;
-               struct  ifreq *ifcu_req;
-       } ifc_ifcu;
-};
-#define        ifc_buf ifc_ifcu.ifcu_buf               /* buffer address       */
-#define        ifc_req ifc_ifcu.ifcu_req               /* array of structures  */
-
-/* Internet address. */
-struct in_addr {
-       __u32   s_addr;
-};
-
-/* Address to accept any incoming messages. */
-#define        INADDR_ANY              ((unsigned long int) 0x00000000)
-
-/* Structure describing an Internet (IP) socket address. */
-#define __SOCK_SIZE__  16              /* sizeof(struct sockaddr)      */
-struct sockaddr_in {
-  short int            sin_family;     /* Address family               */
-  unsigned short int   sin_port;       /* Port number                  */
-  struct in_addr       sin_addr;       /* Internet address             */
-
-  /* Pad to size of `struct sockaddr'. */
-  unsigned char                __pad[__SOCK_SIZE__ - sizeof(short int) -
-                       sizeof(unsigned short int) - sizeof(struct in_addr)];
-};
-
-#define ATF_COM                0x02            /* completed entry (ha valid)   */
-/* ARP ioctl request. */
-struct arpreq {
-  struct sockaddr      arp_pa;         /* protocol address             */
-  struct sockaddr      arp_ha;         /* hardware address             */
-  int                  arp_flags;      /* flags                        */
-  struct sockaddr       arp_netmask;    /* netmask (only for proxy arps) */
-  char                 arp_dev[16];
-};
-
index cfdea27..932ea4e 100644 (file)
  *     o I think I now got set/get char strings right in [iwpriv]
  *             (From Thomas Ekstrom <tomeck@thelogic.com>)
  *     o Fix a very obscure bug in [iwspy]
+ *
+ * wireless 20 :
+ * -----------
+ *             (From Jean Tourrilhes)
+ *     o Remove all #ifdef WIRELESS ugliness, but add a #error :
+ *             we require Wireless Extensions 9 or nothing !  [all]
+ *     o Switch to new 'nwid' definition (specific -> iw_param) [iwconfig]
+ *     o Rewriten totally the encryption support [iwconfig]
+ *             - Multiple keys, through key index
+ *             - Flexible/multiple key size, and remove 64bits upper limit
+ *             - Open/Restricted modes
+ *             - Enter keys as ASCII strings
+ *     o List key sizes supported and all keys in [iwspy]
+ *     o Mode of operation support (ad-hoc, managed...) [iwconfig]
+ *     o Use '=' to indicate fixed instead of ugly '(f)' [iwconfig]
+ *     o Ability to disable RTS & frag (off), now the right way [iwconfig]
+ *     o Auto as an input modifier for bitrate [iwconfig]
+ *     o Power Management support [iwconfig]
+ *             - set timeout or period and its value
+ *             - Reception mode (unicast/multicast/all)
+ *     o Updated man pages with all that ;-)
  */
 
 /* ----------------------------- TODO ----------------------------- */
  *
  * iwconfig :
  * --------
- *     Use new 802.11 parameters (rate, rts, frag)...
+ *     Make disable a per encryption key modifier if some hardware
+ *     requires it.
+ *     Should not mention "Access Point" but something different when
+ *     in ad-hoc mode.
  *
  * iwpriv :
  * ------
- *     ?
+ *     Remove 'port' and 'roam' cruft now that we have mode in iwconfig
  *
  * iwspy :
  * -----
  *
  * Doc & man pages :
  * ---------------
- *     ?
+ *     Update main doc.
+ *
+ * Other :
+ * -----
+ *     What about some graphical tools ?
  */
 
 /***************************** INCLUDES *****************************/
 /* This is our header selection. Try to hide the mess and the misery :-(
  * Please choose only one of the define...
  */
-#define KER2_2_HEADERS         /* Kernel 2.2.X + Glibc - ok for most people */
-#undef LINUX_HEADERS           /* Kernel 2.0.X + Glibc - Debian 2.0, RH5 */
-#undef LIBC5_HEADERS           /* Kernel 2.0.X + libc5 - old systems */
-#undef PRIVATE_HEADERS         /* Ugly last resort case */
+/* Kernel headers 2.0.X + Glibc 2.0 - Debian 2.0, RH5
+ * Kernel headers 2.2.X + Glibc 2.1 - Debian 2.2, RH6.1 */
+#define GLIBC_HEADERS
 
-#ifdef KER2_2_HEADERS
-#include <socketbits.h>
-#include <linux/if_arp.h>      /* For ARPHRD_ETHER */
-#include <linux/socket.h>      /* For AF_INET & struct sockaddr */
-#include <linux/in.h>          /* For struct sockaddr_in */
+/* Kernel headers 2.2.X + Glibc 2.0 - Debian 2.1 */
+#undef KLUDGE_HEADERS
 
-/* Wireless extensions */
-#include <linux/wireless.h>
+/* Kernel headers 2.0.X + libc5 - old systems */
+#undef LIBC5_HEADERS
 
-#endif /* KER2_2_HEADERS */
+#ifdef KLUDGE_HEADERS
+#include <socketbits.h>
+#endif /* KLUDGE_HEADERS */
 
-#ifdef LINUX_HEADERS
+#if defined(KLUDGE_HEADERS) || defined(GLIBC_HEADERS)
 #include <linux/if_arp.h>      /* For ARPHRD_ETHER */
 #include <linux/socket.h>      /* For AF_INET & struct sockaddr */
 #include <linux/in.h>          /* For struct sockaddr_in */
-
-/* Wireless extensions */
-#include <linux/wireless.h>
-
-#endif /* LINUX_HEADERS */
+#endif /* KLUDGE_HEADERS || GLIBC_HEADERS */
 
 #ifdef LIBC5_HEADERS
 #include <sys/socket.h>                /* For AF_INET & struct sockaddr & socket() */
 #include <linux/if_arp.h>      /* For ARPHRD_ETHER */
 #include <linux/in.h>          /* For struct sockaddr_in */
-
-/* Wireless extensions */
-#include <linux/wireless.h>
-
 #endif /* LIBC5_HEADERS */
 
-#ifdef PRIVATE_HEADERS
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <socketbits.h>
-#include "compat.h"            /* Don't ask ! */
-
 /* Wireless extensions */
-#include "wireless.h"
-
-#endif /* PRIVATE_HEADERS */
+#include <linux/wireless.h>
 
+#if WIRELESS_EXT < 8
+#error "Wireless Extension v9 or newer required :-(\n\
+Use Wireless Tools v19 or update your kernel headers"
+#endif
 
 /****************************** DEBUG ******************************/
 
 #define MEGA   1e6
 #define GIGA   1e9
 
-/* Some hack */
-#ifndef IW_ESSID_MAX_SIZE
-#define IW_ESSID_MAX_SIZE      32      /* Should be in wireless.h */
-#endif
-#ifndef IW_MAX_AP
-#define IW_MAX_AP              8       /* Should be in wireless.h */
-#endif
-
 /****************************** TYPES ******************************/
 
 /* Shortcuts */
 typedef struct iw_statistics   iwstats;
 typedef struct iw_range                iwrange;
+typedef struct iw_param                iwparam;
 typedef struct iw_freq         iwfreq;
 typedef struct iw_priv_args    iwprivargs;
 typedef struct sockaddr                sockaddr;
@@ -189,15 +196,15 @@ typedef struct wireless_info
 {
   char         name[IFNAMSIZ];         /* Wireless/protocol name */
   int          has_nwid;
-  int          nwid_on;
-  u_long       nwid;                   /* Network ID */
+  iwparam      nwid;                   /* Network ID */
   int          has_freq;
   float                freq;                   /* Frequency/channel */
   int          has_sens;
-  int          sens;                   /* sensitivity */
-  int          has_enc;
-  int          enc_method;             /* encoding method or off */
-  long long    enc_key;                /* key used */
+  iwparam      sens;                   /* sensitivity */
+  int          has_key;
+  unsigned char        key[IW_ENCODING_TOKEN_MAX];     /* Encoding key used */
+  int          key_size;               /* Number of bytes */
+  int          key_flags;              /* Various flags */
   int          has_essid;
   int          essid_on;
   char         essid[IW_ESSID_MAX_SIZE + 1];   /* ESSID (extended network) */
@@ -206,14 +213,15 @@ typedef struct wireless_info
   int          has_ap_addr;
   sockaddr     ap_addr;                /* Access point address */
   int          has_bitrate;
-  long         bitrate;                /* Bit rate in bps */
-  int          bitrate_fixed;          /* Fixed or auto */
+  iwparam      bitrate;                /* Bit rate in bps */
   int          has_rts;
-  long         rts;                    /* RTS threshold in bytes */
-  int          rts_fixed;              /* Fixed or auto */
+  iwparam      rts;                    /* RTS threshold in bytes */
   int          has_frag;
-  long         frag;                   /* Fragmentation threshold in bytes */
-  int          frag_fixed;             /* Fixed or auto */
+  iwparam      frag;                   /* Fragmentation threshold in bytes */
+  int          has_mode;
+  int          mode;                   /* Operation mode */
+  int          has_power;
+  iwparam      power;                  /* Power management parameters */
 
   /* Stats */
   iwstats      stats;
diff --git a/wireless_tools/iwconfig b/wireless_tools/iwconfig
deleted file mode 100644 (file)
index abc90a6..0000000
Binary files a/wireless_tools/iwconfig and /dev/null differ
index 24c1e50..3b0c5fd 100644 (file)
@@ -15,9 +15,11 @@ iwconfig \- configure a wireless network interface
 .br
 .BI "iwconfig " interface " [essid " X "] [nwid " N "] [freq " F "] [channel " C ]
 .br
-.BI "                   [sens " S "] [enc " E "] [ap " A "] [nick " NN ]
+.BI "                   [sens " S "] [mode " M "] [ap " A "] [nick " NN ]
 .br
 .BI "                   [rate " R "] [rts " RT "] [frag " FT ]
+.br
+.BI "                   [enc " E "] [key " K "] [power " P ]
 .\"
 .\" DESCRIPTION part
 .\"
@@ -51,8 +53,14 @@ As opposed to the NWID which defines a single cell, the ESSID defines
 a group of cell connected via repeaters or infrastructure, where the
 user may roam.  With some card, you may disable the ESSID checking
 (ESSID promiscuous) with
-.IR off " (and " on
+.IR off " or " any " (and " on
 to reenable it).
+.br
+.B Examples :
+.br
+.I "   iwconfig eth0 essid any"
+.br
+.I "   iwconfig eth0 essid ""My Network""
 .TP
 .BR nwid / domain
 Set the Network ID (in some products it is also called Domain ID). As
@@ -62,11 +70,17 @@ identify nodes belonguing to the same cell. With some card, you may
 disable the Network ID checking (NWID promiscuous) with
 .IR off " (and " on
 to reenable it).
+.br
+.B Examples :
+.br
+.I "   iwconfig eth0 nwid AB34
+.br
+.I "   iwconfig eth0 nwid off"
 .TP
 .BR freq / channel
 Set the operating frequency or channel in the device. Value below 1000
 are the channel number, value over this is the frequency in Hz. You
-must prepend the suffix k, M or G to the value (for example, "2.46G"
+must append the suffix k, M or G to the value (for example, "2.46G"
 for 2.46 GHz frequency), or add enough '0'.
 .br
 Channels are usually numbered starting at 1,
@@ -75,6 +89,12 @@ and you may use
 to get the total number of channels and list the available
 frequencies. Depending on regulations, some frequencies/channels may
 not be available.
+.br
+.B Examples :
+.br
+.I "   iwconfig eth0 freq 2.422G"
+.br
+.I "   iwconfig eth0 channel 3"
 .TP
 .B sens
 Set the sensitivity threshold. This is the lowest signal level for
@@ -88,40 +108,73 @@ With some hardware, this parameter also control the defer threshold
 (lowest signal level for which we consider the channel busy) and the
 handover threshold (lowest signal level where we stay associated with
 the current access point).
+.br
+.B Example :
+.br
+.I "   iwconfig eth0 sens -80"
 .TP
-.B enc
-Set the encryption or scrambing key (the syntax is
-.IR XXXX-XXXX-XXXX-XXXX " or " XXXXXXXX ).
-Used also to control the encryption feature
-.RI ( on / off ).
+.B mode
+Set the operating mode of the device, which depends on the network
+topology. The mode can be
+.I Ad-hoc
+(network composed of only one cell and without Access Point),
+.I Managed
+(network composed of many cells, with roaming or with an Access Point),
+.I Master
+(the node is the synchronisation master or act as an Access Point),
+.I Repeater
+(the node forward packets on the air),
+.I Secondary
+(the node act as a backup master/repeater) or
+.IR Auto .
+.br
+.B Example :
+.br
+.I "   iwconfig eth0 mode Managed"
 .TP
 .B ap
 Register to the Access Point given by the address, if it is
 possible. When the quality of the connection goes too low, the driver
 may revert back to automatic mode.
+.br
+.B Example :
+.br
+.I "   iwconfig eth0 ap 00:60:1D:01:23:45"
 .TP
-.BR nick [ name ]
+.BR nick [name]
 Set the nickname, or the station name. Most 802.11 products do define
 it, but this is not used as far as the protocols (MAC, IP, TCP) are
 concerned and completely accessory as far as configuration goes. In
 fact only some diagnostic tools may use it.
+.br
+.B Example :
+.br
+.I "   iwconfig eth0 nickname ""My Linux Node""
 .TP
-.BR rate / bit [ rate ]
+.BR rate / bit [rate]
 For cards supporting multiple bit rates, set the bit-rate in b/s. The
 bit-rate is the speed at which bits are transmitted over the medium,
 the user speed of the link is lower due to medium sharing and
 overhead.
 .br
-You must prepend the suffix k, M or G to the value (decimal multiplier
+You must append the suffix k, M or G to the value (decimal multiplier
 : 10^3, 10^6 and 10^9 b/s), or add enough '0'. Values below 1000 are
 card specific, usually an index in the bit-rate list. Use
 .I auto
 to select the automatic bit-rate mode (fallback to lower rate on noisy
 channels), which is the default for most cards, and
 .I fixed
-to revert back to fixed setting.
+to revert back to fixed setting. If you specify a bit-rate value and append
+.IR auto ,
+the driver will use all bit lower and equal than this value.
+.br
+.B Examples :
+.br
+.I "   iwconfig eth0 rate 11M"
+.br
+.I "   iwconfig eth0 rate auto"
 .TP
-.BR rts [ _threshold ]
+.BR rts [_threshold]
 RTS/CTS adds a handshake before each packet transmission to make sure
 that the channel is clear. This adds overhead, but increase
 performance in case of hidden nodes or large number of active
@@ -129,14 +182,89 @@ nodes. This parameters set the size of the smallest packet for which
 the node sends RTS, a value equal to the maximum packet size disable
 the scheme. You may also set this parameter to
 .IR auto ", " fixed " or " off .
+.br
+.B Examples :
+.br
+.I "   iwconfig eth0 rts 250"
+.br
+.I "   iwconfig eth0 rts off"
 .TP
-.BR frag [ mentation_threshold ]
+.BR frag [mentation_threshold]
 Fragmentation allow to split a IP packet in a burst of smaller
 fragments transmitted on the medium. In most cases this adds overhead,
 but in very noisy environment this reduce the error penalty. This
 parameter set the maximum fragment size, a value equal to the maximum
 packet size disable the scheme. You may also set this parameter to
 .IR auto ", " fixed " or " off .
+.br
+.B Examples :
+.br
+.I "   iwconfig eth0 frag 512"
+.br
+.I "   iwconfig eth0 frag off"
+.TP
+.BR key / enc [ryption]
+Used to manipulate encryption or scrambling keys and encryption mode.
+.br
+To set the current encryption key, just enter the key in hex digits as
+.IR XXXX-XXXX-XXXX-XXXX " or " XXXXXXXX .
+To set a key other than the current key, append
+.I [index]
+to the key itself. You can also enter the key as an ASCII string by
+using the
+.I s:
+prefix.
+.br
+To change which key is the current active key, just enter
+.I [index]
+(without entering any key value).
+.br
+.IR off " and " on
+disable and reenable encryption,
+.I open
+set the system in open mode (accept non-encrypted packets) and
+.I restricted
+discard non-encrypted packets.
+.br
+.B Examples :
+.br
+.I "   iwconfig eth0 key 0123-4567-89"
+.br
+.I "   iwconfig eth0 key s:password [2]"
+.br
+.I "   iwconfig eth0 key [2] open"
+.br
+.I "   iwconfig eth0 key off"
+.TP
+.BR power
+Used to manipulate power management scheme parameters and mode.
+.br
+To set the period between wake up, enter
+.IR "period `value'" .
+To set the timeout before going back to sleep, enter
+.IR "timeout `value'" .
+By defaults, those values are in seconds, append the suffix m or u to
+specify values un milliseconds or microseconds.
+.br
+.IR off " and " on
+disable and reenable power management. Finally, you may set the power
+management mode to
+.I all
+(receive all packets),
+.I unicast
+(receive unicast packets only, discard multicast and broadcast) and
+.I multicast
+(receive multicast and broadcast only, discard unicast packets).
+.br
+.B Examples :
+.br
+.I "   iwconfig eth0 power period 2"
+.br
+.I "   iwconfig eth0 power 500m unicast"
+.br
+.I "   iwconfig eth0 power timeout 300u all"
+.br
+.I "   iwconfig eth0 power off"
 .\"
 .\" DISPLAY part
 .\"
@@ -154,16 +282,27 @@ the
 (or channel), the
 .BR sensitivity ,
 the
+.B mode
+of operation, the
 .B Access Point
 address, the
 .B bit-rate
-(with
-.B (f)
-if fixed), the
+the
 .BR "RTS threshold" ", the " "fragmentation threshold" ,
-and the
+the
 .B encryption key
-(depending on availability). See above for explanations.
+and the
+.B power management
+settings (depending on availability).
+.br
+See above for explanations of what these parameters mean.
+.br
+If the label for bitrate is followed by
+.RB ` = ',
+it means that the parameter is fixed and forced to that value, if it
+is followed by
+.RB ` : '
+it is only the current value (device in normal auto mode).
 .PP
 If
 .I /proc/net/wireless
@@ -172,7 +311,8 @@ exists,
 will also display its content :
 .TP
 .B Link quality
-Quality of the link or the modulation (how good the received signal is).
+Quality of the link or the modulation (what is the level of contention
+or interference, or how good the received signal is).
 .TP
 .B Signal level
 Received signal strength (how strong the received signal is).
@@ -193,7 +333,7 @@ Other packets lost in relation with specific wireless operations.
 .\" AUTHOR part
 .\"
 .SH AUTHOR
-Jean Tourrilhes \- jt@hplb.hpl.hp.com
+Jean Tourrilhes \- jt@hpl.hp.com
 .\"
 .\" FILES part
 .\"
index 8cb9f0c..c65f92e 100644 (file)
 
 #include "iwcommon.h"          /* Header */
 
+/**************************** VARIABLES ****************************/
+char * operation_mode[] = { "Auto",
+                            "Ad-Hoc",
+                            "Managed",
+                            "Master",
+                            "Repeater",
+                            "Secondary" };
+
 /************************* MISC SUBROUTINES **************************/
 
 /*------------------------------------------------------------------*/
@@ -43,40 +51,59 @@ static int
 iw_getstats(char *     ifname,
            iwstats *   stats)
 {
-  FILE *f=fopen("/proc/net/wireless","r");
-  char buf[256];
-  char *bp;
+  FILE *       f=fopen("/proc/net/wireless","r");
+  char         buf[256];
+  char *       bp;
+  int          t;
   if(f==NULL)
-       return -1;
+    return -1;
+  /* Loop on all devices */
   while(fgets(buf,255,f))
-  {
-       bp=buf;
-       while(*bp&&isspace(*bp))
-               bp++;
-       if(strncmp(bp,ifname,strlen(ifname))==0 && bp[strlen(ifname)]==':')
+    {
+      bp=buf;
+      while(*bp&&isspace(*bp))
+       bp++;
+      /* Is it the good device ? */
+      if(strncmp(bp,ifname,strlen(ifname))==0 && bp[strlen(ifname)]==':')
        {
-               bp=strchr(bp,':');
-               bp++;
-               bp = strtok(bp, " .");
-               sscanf(bp, "%X", (unsigned int *)&stats->status);
-               bp = strtok(NULL, " .");
-               sscanf(bp, "%d", (unsigned int *)&stats->qual.qual);
-               bp = strtok(NULL, " .");
-               sscanf(bp, "%d", (unsigned int *)&stats->qual.level);
-               bp = strtok(NULL, " .");
-               sscanf(bp, "%d", (unsigned int *)&stats->qual.noise);
-               bp = strtok(NULL, " .");
-               sscanf(bp, "%d", &stats->discard.nwid);
-               bp = strtok(NULL, " .");
-               sscanf(bp, "%d", &stats->discard.code);
-               bp = strtok(NULL, " .");
-               sscanf(bp, "%d", &stats->discard.misc);
-               fclose(f);
-               return 0;
+         /* Skip ethX: */
+         bp=strchr(bp,':');
+         bp++;
+         /* -- status -- */
+         bp = strtok(bp, " ");
+         sscanf(bp, "%X", &t);
+         stats->status = (unsigned short) t;
+         /* -- link quality -- */
+         bp = strtok(NULL, " ");
+         if(strchr(bp,'.') != NULL)
+           stats->qual.updated |= 1;
+         sscanf(bp, "%d", &t);
+         stats->qual.qual = (unsigned char) t;
+         /* -- signal level -- */
+         bp = strtok(NULL, " ");
+         if(strchr(bp,'.') != NULL)
+           stats->qual.updated |= 2;
+         sscanf(bp, "%d", &t);
+         stats->qual.level = (unsigned char) t;
+         /* -- noise level -- */
+         bp = strtok(NULL, " ");
+         if(strchr(bp,'.') != NULL)
+           stats->qual.updated += 4;
+         sscanf(bp, "%d", &t);
+         stats->qual.noise = (unsigned char) t;
+         /* -- discarded packets -- */
+         bp = strtok(NULL, " ");
+         sscanf(bp, "%d", &stats->discard.nwid);
+         bp = strtok(NULL, " ");
+         sscanf(bp, "%d", &stats->discard.code);
+         bp = strtok(NULL, " ");
+         sscanf(bp, "%d", &stats->discard.misc);
+         fclose(f);
+         return 0;
        }
-  }
+    }
   fclose(f);
-  return 0;
+  return -1;
 }
 
 /*------------------------------------------------------------------*/
@@ -107,8 +134,7 @@ get_info(int                        skfd,
   if(ioctl(skfd, SIOCGIWNWID, &wrq) >= 0)
     {
       info->has_nwid = 1;
-      info->nwid_on = wrq.u.nwid.on;
-      info->nwid = wrq.u.nwid.nwid;
+      memcpy(&(info->nwid), &(wrq.u.nwid), sizeof(iwparam));
     }
 
   /* Get frequency / channel */
@@ -124,24 +150,26 @@ get_info(int                      skfd,
   if(ioctl(skfd, SIOCGIWSENS, &wrq) >= 0)
     {
       info->has_sens = 1;
-      info->sens = wrq.u.sensitivity;
+      memcpy(&(info->sens), &(wrq.u.sens), sizeof(iwparam));
     }
 
-   /* Get encryption information */
-   strcpy(wrq.ifr_name, ifname);
-   if(ioctl(skfd, SIOCGIWENCODE, &wrq) >= 0)
-     {
-       info->has_enc = 1;
-       info->enc_method = wrq.u.encoding.method;
-       info->enc_key = wrq.u.encoding.code;
-     }
-
-#if WIRELESS_EXT > 5
-  /* Get ESSID */
+  /* Get encryption information */
   strcpy(wrq.ifr_name, ifname);
-  wrq.u.data.pointer = (caddr_t) info->essid;
+  wrq.u.data.pointer = (caddr_t) info->key;
   wrq.u.data.length = 0;
   wrq.u.data.flags = 0;
+  if(ioctl(skfd, SIOCGIWENCODE, &wrq) >= 0)
+    {
+      info->has_key = 1;
+      info->key_size = wrq.u.data.length;
+      info->key_flags = wrq.u.data.flags;
+    }
+
+  /* Get ESSID */
+  strcpy(wrq.ifr_name, ifname);
+  wrq.u.essid.pointer = (caddr_t) info->essid;
+  wrq.u.essid.length = 0;
+  wrq.u.essid.flags = 0;
   if(ioctl(skfd, SIOCGIWESSID, &wrq) >= 0)
     {
       info->has_essid = 1;
@@ -155,14 +183,12 @@ get_info(int                      skfd,
       info->has_ap_addr = 1;
       memcpy(&(info->ap_addr), &(wrq.u.ap_addr), sizeof (sockaddr));
     }
-#endif /* WIRELESS_EXT > 5 */
 
-#if WIRELESS_EXT > 7
   /* Get NickName */
   strcpy(wrq.ifr_name, ifname);
-  wrq.u.data.pointer = (caddr_t) info->nickname;
-  wrq.u.data.length = 0;
-  wrq.u.data.flags = 0;
+  wrq.u.essid.pointer = (caddr_t) info->nickname;
+  wrq.u.essid.length = 0;
+  wrq.u.essid.flags = 0;
   if(ioctl(skfd, SIOCGIWNICKN, &wrq) >= 0)
     if(wrq.u.data.length > 1)
       info->has_nickname = 1;
@@ -172,8 +198,7 @@ get_info(int                        skfd,
   if(ioctl(skfd, SIOCGIWRATE, &wrq) >= 0)
     {
       info->has_bitrate = 1;
-      info->bitrate_fixed = wrq.u.bitrate.fixed;
-      info->bitrate = wrq.u.bitrate.value;
+      memcpy(&(info->bitrate), &(wrq.u.bitrate), sizeof(iwparam));
     }
 
   /* Get RTS threshold */
@@ -181,22 +206,36 @@ get_info(int                      skfd,
   if(ioctl(skfd, SIOCGIWRTS, &wrq) >= 0)
     {
       info->has_rts = 1;
-      info->rts_fixed = wrq.u.rts.fixed;
-      info->rts = wrq.u.rts.value;
+      memcpy(&(info->rts), &(wrq.u.rts), sizeof(iwparam));
     }
 
-  /* Get fragmentation thershold */
+  /* Get fragmentation threshold */
   strcpy(wrq.ifr_name, ifname);
   if(ioctl(skfd, SIOCGIWFRAG, &wrq) >= 0)
     {
       info->has_frag = 1;
-      info->frag_fixed = wrq.u.frag.fixed;
-      info->frag = wrq.u.frag.value;
+      memcpy(&(info->frag), &(wrq.u.frag), sizeof(iwparam));
+    }
+
+  /* Get operation mode */
+  strcpy(wrq.ifr_name, ifname);
+  if(ioctl(skfd, SIOCGIWMODE, &wrq) >= 0)
+    {
+      if((wrq.u.mode < 6) && (wrq.u.mode >= 0))
+       info->has_mode = 1;
+      info->mode = wrq.u.mode;
+    }
+
+  /* Get Power Management settings */
+  strcpy(wrq.ifr_name, ifname);
+  if(ioctl(skfd, SIOCGIWPOWER, &wrq) >= 0)
+    {
+      info->has_power = 1;
+      memcpy(&(info->power), &(wrq.u.power), sizeof(iwparam));
     }
-#endif /* WIRELESS_EXT > 7 */
 
   /* Get stats */
-  if(iw_getstats(ifname, &(info->stats)) == 0)
+  if(iw_getstats(ifname, &(info->stats)) >= 0)
     {
       info->has_stats = 1;
     }
@@ -242,10 +281,10 @@ display_info(struct wireless_info *       info,
     {
       /* Note : should display right number of digit according to info
        * in range structure */
-      if(info->nwid_on)
-       printf("NWID:%lX  ", info->nwid);
-      else
+      if(info->nwid.disabled)
        printf("NWID:off/any  ");
+      else
+       printf("NWID:%X  ", info->nwid.value);
     }
 
   /* Display frequency / channel */
@@ -270,14 +309,31 @@ display_info(struct wireless_info *       info,
   /* Display sensitivity */
   if(info->has_sens)
     {
+      /* Fixed ? */
+      if(info->sens.fixed)
+       printf("Sensitivity=");
+      else
+       printf("Sensitivity:");
+
       if(info->has_range)
        /* Display in dBm ? */
-       if(info->sens < 0)
-         printf("Sensitivity:%d dBm  ", info->sens);
+       if(info->sens.value < 0)
+         printf("%d dBm  ", info->sens.value);
        else
-         printf("Sensitivity:%d/%d  ", info->sens, info->range.sensitivity);
+         printf("%d/%d  ", info->sens.value, info->range.sensitivity);
       else
-       printf("Sensitivity:%d  ", info->sens);
+       printf("%d  ", info->sens.value);
+    }
+
+  /* Display the current mode of operation */
+  if(info->has_mode)
+    {
+      /* A bit of clever formatting */
+      if((info->has_nwid + 2*info->has_freq + 2*info->has_sens
+         + !info->has_essid) > 4)
+       printf("\n          ");
+
+      printf("Mode:%s  ", operation_mode[info->mode]);
     }
 
   /* Display the address of the current Access Point */
@@ -285,7 +341,7 @@ display_info(struct wireless_info * info,
     {
       /* A bit of clever formatting */
       if((info->has_nwid + 2*info->has_freq + 2*info->has_sens
-         + !info->has_essid) > 3)
+         + info->has_mode + !info->has_essid) > 3)
        printf("\n          ");
 
       printf("Access Point: %s", pr_ether(info->ap_addr.sa_data));
@@ -296,78 +352,148 @@ display_info(struct wireless_info *      info,
   /* Display the currently used/set bit-rate */
   if(info->has_bitrate)
     {
-      printf("Bit Rate:");
-      if(info->bitrate >= GIGA)
-       printf("%g Gb/s", info->bitrate / GIGA);
+      /* Fixed ? */
+      if(info->bitrate.fixed)
+       printf("Bit Rate=");
       else
-       if(info->bitrate >= MEGA)
-         printf("%g Mb/s", info->bitrate / MEGA);
-       else
-         printf("%g kb/s", info->bitrate / KILO);
+       printf("Bit Rate:");
 
-      /* Fixed ? */
-      if(info->bitrate_fixed)
-       printf(" (f)   ");
+      if(info->bitrate.value >= GIGA)
+       printf("%gGb/s", info->bitrate.value / GIGA);
       else
-       printf("   ");
+       if(info->bitrate.value >= MEGA)
+         printf("%gMb/s", info->bitrate.value / MEGA);
+       else
+         printf("%gkb/s", info->bitrate.value / KILO);
+      printf("   ");
     }
 
   /* Display the RTS threshold */
   if(info->has_rts)
     {
-      printf("RTS thr:%ld B", info->rts);
-
-      /* Fixed ? */
-      if(info->rts_fixed)
-       printf(" (f)   ");
+      /* Disabled ? */
+      if(info->rts.disabled)
+       printf("RTS thr:off   ");
       else
-       printf("   ");
+       {
+         /* Fixed ? */
+         if(info->rts.fixed)
+           printf("RTS thr=");
+         else
+           printf("RTS thr:");
+
+         printf("%d B   ", info->rts.value);
+       }
     }
 
   /* Display the fragmentation threshold */
-  if(info->has_bitrate)
+  if(info->has_frag)
     {
-      printf("Frag thr:%ld B", info->frag);
-
-      /* Fixed ? */
-      if(info->frag_fixed)
-       printf(" (f)   ");
+      /* Disabled ? */
+      if(info->frag.disabled)
+       printf("Fragment thr:off   ");
       else
-       printf("   ");
+       {
+         /* Fixed ? */
+         if(info->frag.fixed)
+           printf("Fragment thr=");
+         else
+           printf("Fragment thr:");
+
+         printf("%d B   ", info->frag.value);
+       }
     }
 
   /* Formating */
   if((info->has_bitrate) || (info->has_rts) || (info->has_bitrate))
     printf("\n          ");
 
-  if(info->has_enc)
+  /* Display encryption information */
+  /* Note : we display only the "current" key, use iwspy to list all keys */
+  if(info->has_key)
     {
       printf("Encryption key:");
-      if(info->enc_method)
+      if((info->key_flags & IW_ENCODE_DISABLED) || (info->key_size == 0))
+       printf("off\n          ");
+      else
        {
-         int           i = 0;
-         u_short       parts[4];
-         long long     key = info->enc_key;
+         int   i;
 
-         for(i = 3; i >= 0; i--)
+         printf("%.2X", info->key[0]);
+         for(i = 1; i < info->key_size; i++)
            {
-             parts[i] = key & 0xFFFF;
-             key >>= 16;
+             if((i & 0x1) == 0)
+               printf("-");
+             printf("%.2X", info->key[i]);
            }
 
-         i = 0;
-         while((parts[i] == 0) && (i < 3))
-           i++;
-         for(; i < 3; i++)
-           printf("%.4X-", parts[i]);
-         printf("%.4X", parts[3]);
-
-         if(info->enc_method > 1)
-           printf(" (%d)", info->enc_method);
+         /* Other 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");
+         if(info->key_flags & IW_ENCODE_OPEN)
+           printf("   Encryption mode:open");
          printf("\n          ");
        }
+    }
+
+  /* Display Power Management information */
+  /* Note : we display only one parameter, period or timeout. If a device
+   * (such as HiperLan) has both, we would need to be a bit more clever... */
+  if(info->has_power)  /* I hope the device has power ;-) */
+    { 
+      printf("Power Management");
+      /* Disabled ? */
+      if(info->power.disabled)
+       printf(":off\n          ");
       else
-       printf("off\n          ");
+       {
+         /* Let's check the value and its type */
+         if(info->power.flags & IW_POWER_TYPE)
+           {
+             /* Type */
+             if(info->power.flags & IW_POWER_TIMEOUT)
+               printf(" timeout:");
+             else
+               printf(" period:");
+
+             /* Display value with units */
+             if(info->power.value >= (int) MEGA)
+               printf("%gs  ", ((double) info->power.value) / MEGA);
+             else
+               if(info->power.value  >= (int) KILO)
+                 printf("%gms  ", ((double) info->power.value) / KILO);
+               else
+                 printf("%dus  ", info->power.value);
+           }
+
+         /* Let's check the mode */
+         switch(info->power.flags & IW_POWER_MODE)
+           {
+           case IW_POWER_UNICAST_R:
+             printf(" mode:Unicast received");
+             break;
+           case IW_POWER_MULTICAST_R:
+             printf(" mode:Multicast received");
+             break;
+           case IW_POWER_ALL_R:
+             printf(" mode:All packets received");
+             break;
+           case IW_POWER_FORCE_S:
+             printf(" mode:Force sending");
+             break;
+           case IW_POWER_REPEATER:
+             printf(" mode:Repeat multicasts");
+             break;
+           default:
+           }
+
+         /* Let's check if nothing (simply on) */
+         if(info->power.flags == IW_POWER_ON)
+           printf(":on");
+         printf("\n          ");
+       }
     }
 
   if(info->has_stats)
@@ -487,7 +613,7 @@ set_info(int                skfd,           /* The socket */
            iw_usage();
          if((!strcasecmp(args[i], "off")) ||
             (!strcasecmp(args[i], "any")))
-           wrq.u.nwid.on = 0;
+           wrq.u.nwid.disabled = 1;
          else
            if(!strcasecmp(args[i], "on"))
              {
@@ -498,14 +624,15 @@ set_info(int              skfd,           /* The socket */
                    return(-1);
                  }
                strcpy(wrq.ifr_name, ifname);
-               wrq.u.nwid.on = 1;
+               wrq.u.nwid.disabled = 0;
              }
            else
-             if(sscanf(args[i], "%lX", (unsigned long *) &(wrq.u.nwid.nwid))
+             if(sscanf(args[i], "%lX", (unsigned long *) &(wrq.u.nwid.value))
                 != 1)
                iw_usage();
              else
-               wrq.u.nwid.on = 1;
+               wrq.u.nwid.disabled = 0;
+         wrq.u.nwid.fixed = 1;
 
          if(ioctl(skfd, SIOCSIWNWID, &wrq) < 0)
            {
@@ -544,7 +671,7 @@ set_info(int                skfd,           /* The socket */
        {
          if(++i >= count)
            iw_usage();
-         if(sscanf(args[i], "%d", &(wrq.u.sensitivity)) != 1)
+         if(sscanf(args[i], "%d", &(wrq.u.sens.value)) != 1)
            iw_usage();
 
          if(ioctl(skfd, SIOCSIWSENS, &wrq) < 0)
@@ -556,51 +683,111 @@ set_info(int             skfd,           /* The socket */
        }
 
       /* ---------- Set encryption stuff ---------- */
-      if(!strncmp(args[i], "enc", 3 ))
+      if((!strncmp(args[i], "enc", 3)) ||
+        (!strcmp(args[i], "key")))
        {
-         unsigned long long    key = 0;
+         unsigned char key[IW_ENCODING_TOKEN_MAX];
 
          if(++i >= count)
            iw_usage();
 
-         if(!strcasecmp(args[i], "off"))
-           wrq.u.encoding.method = 0;
+         if(!strcasecmp(args[i], "on"))
+           {
+             /* Get old encryption information */
+             wrq.u.data.pointer = (caddr_t) key;
+             wrq.u.data.length = 0;
+             wrq.u.data.flags = 0;
+             if(ioctl(skfd, SIOCGIWENCODE, &wrq) < 0)
+               {
+                 fprintf(stderr, "SIOCGIWENCODE: %s\n", strerror(errno));
+                 return(-1);
+               }
+             strcpy(wrq.ifr_name, ifname);
+             wrq.u.data.flags &= ~IW_ENCODE_DISABLED;  /* Enable */
+           }
          else
            {
-             if(!strcasecmp(args[i], "on"))
+             char *    buff;
+             char *    p;
+             int               temp;
+             int               k = 0;
+             int               gotone = 1;
+
+             wrq.u.data.pointer = (caddr_t) NULL;
+             wrq.u.data.flags = 0;
+             wrq.u.data.length = 0;
+
+             /* -- Check for the key -- */
+             if(!strncmp(args[i], "s:", 2))
                {
-                 /* Get old encryption information */
-                 if(ioctl(skfd, SIOCGIWENCODE, &wrq) < 0)
-                   {
-                     fprintf(stderr, "SIOCGIWENCODE: %s\n", strerror(errno));
-                     return(-1);
-                   }
-                 strcpy(wrq.ifr_name, ifname);
+                 /* First case : as an ASCII string */
+                 wrq.u.data.length = strlen(args[i] + 2);
+                 if(wrq.u.data.length > IW_ENCODING_TOKEN_MAX)
+                   wrq.u.data.length = IW_ENCODING_TOKEN_MAX;
+                 strncpy(key, args[i] + 2, wrq.u.data.length);
+                 wrq.u.data.pointer = (caddr_t) key;
+                 ++i;
+                 gotone = 1;
                }
              else
                {
-                 char *        buff;
-                 char *        p;
-                 u_long        temp;
-
-                 p = buff = malloc(strlen(args[i] + 1));
+                 /* Second case : has hexadecimal digits */
+                 p = buff = malloc(strlen(args[i]) + 1);
                  strcpy(buff, args[i]);
 
-                 p = strtok(buff, "-:;.,*#");
+                 p = strtok(buff, "-:;.,");
                  while(p != (char *) NULL)
                    {
-                     key = key << 16;
-                     if(sscanf(p, "%lX", &temp) != 1)
-                       iw_usage();
-                     key += temp;
-                     p = strtok((char *) NULL, "-:;.,*#");
+                     if(sscanf(p, "%2X", &temp) != 1)
+                       {
+                         gotone = 0;
+                         break;
+                       }
+                     key[k++] = (unsigned char) (temp & 0xFF);
+                     if(strlen(p) > 2) /* Token not finished yet */
+                       p += 2;
+                     else
+                       p = strtok((char *) NULL, "-:;.,");
                    }
-
                  free(buff);
-                 wrq.u.encoding.code = key;
+
+                 if(gotone)
+                   {
+                     ++i;
+                     wrq.u.data.length = k;
+                     wrq.u.data.pointer = (caddr_t) key;
+                   }
                }
-             /* TODO : check for "(method)" in args list */
-             wrq.u.encoding.method = 1;
+
+             /* -- Check for token index -- */
+             if((i < count) &&
+                (sscanf(args[i], "[%d]", &temp) == 1) &&
+                (temp > 0) && (temp < IW_ENCODE_INDEX))
+               {
+                 wrq.u.encoding.flags |= temp;
+                 ++i;
+                 gotone = 1;
+               }
+
+             /* -- Check the various flags -- */
+             if(i < count)
+               {
+                 if(!strcasecmp(args[i], "off"))
+                   wrq.u.data.flags |= IW_ENCODE_DISABLED;
+                 if(!strcasecmp(args[i], "open"))
+                   wrq.u.data.flags |= IW_ENCODE_OPEN;
+                 if(!strncasecmp(args[i], "restricted", 5))
+                   wrq.u.data.flags |= IW_ENCODE_RESTRICTED;
+                 if(wrq.u.data.flags & IW_ENCODE_FLAGS)
+                   {
+                     ++i;
+                     gotone = 1;
+                   }
+               }
+
+             if(!gotone)
+               iw_usage();
+             --i;
            }
 
          if(ioctl(skfd, SIOCSIWENCODE, &wrq) < 0)
@@ -612,7 +799,6 @@ set_info(int                skfd,           /* The socket */
          continue;
        }
 
-#if WIRELESS_EXT > 5
       /* ---------- Set ESSID ---------- */
       if(!strcasecmp(args[i], "essid"))
        {
@@ -624,23 +810,23 @@ set_info(int              skfd,           /* The socket */
          if((!strcasecmp(args[i], "off")) ||
             (!strcasecmp(args[i], "any")))
            {
-             wrq.u.data.flags = 0;
+             wrq.u.essid.flags = 0;
              essid[0] = '\0';
            }
          else
            if(!strcasecmp(args[i], "on"))
              {
                /* Get old essid */
-               wrq.u.data.pointer = (caddr_t) essid;
-               wrq.u.data.length = 0;
-               wrq.u.data.flags = 0;
+               wrq.u.essid.pointer = (caddr_t) essid;
+               wrq.u.essid.length = 0;
+               wrq.u.essid.flags = 0;
                if(ioctl(skfd, SIOCGIWESSID, &wrq) < 0)
                  {
                    fprintf(stderr, "SIOCGIWESSID: %s\n", strerror(errno));
                    return(-1);
                  }
                strcpy(wrq.ifr_name, ifname);
-               wrq.u.data.flags = 1;
+               wrq.u.essid.flags = 1;
              }
            else
              if(strlen(args[i]) > IW_ESSID_MAX_SIZE)
@@ -651,12 +837,12 @@ set_info(int              skfd,           /* The socket */
                }
              else
                {
-                 wrq.u.data.flags = 1;
+                 wrq.u.essid.flags = 1;
                  strcpy(essid, args[i]);
                }
 
-         wrq.u.data.pointer = (caddr_t) essid;
-         wrq.u.data.length = strlen(essid) + 1;
+         wrq.u.essid.pointer = (caddr_t) essid;
+         wrq.u.essid.length = strlen(essid) + 1;
          if(ioctl(skfd, SIOCSIWESSID, &wrq) < 0)
            {
              fprintf(stderr, "SIOCSIWESSID: %s\n", strerror(errno));
@@ -689,9 +875,7 @@ set_info(int                skfd,           /* The socket */
            }
          continue;
        }
-#endif /* WIRELESS_EXT > 5 */
 
-#if WIRELESS_EXT > 7
       /* ---------- Set NickName ---------- */
       if(!strncmp(args[i], "nick", 4))
        {
@@ -705,8 +889,8 @@ set_info(int                skfd,           /* The socket */
              iw_usage();
            }
 
-         wrq.u.data.pointer = (caddr_t) args[i];
-         wrq.u.data.length = strlen(args[i]) + 1;
+         wrq.u.essid.pointer = (caddr_t) args[i];
+         wrq.u.essid.length = strlen(args[i]) + 1;
          if(ioctl(skfd, SIOCSIWNICKN, &wrq) < 0)
            {
              fprintf(stderr, "SIOCSIWNICKN: %s\n", strerror(errno));
@@ -719,8 +903,7 @@ set_info(int                skfd,           /* The socket */
       if((!strncmp(args[i], "bit", 3)) ||
         (!strcmp(args[i], "rate")))
        {
-         i++;
-         if(i >= count)
+         if(++i >= count)
            iw_usage();
          if(!strcasecmp(args[i], "auto"))
            {
@@ -738,6 +921,7 @@ set_info(int                skfd,           /* The socket */
                      return(-1);
                    }
                  strcpy(wrq.ifr_name, ifname);
+                 wrq.u.bitrate.fixed = 1;
                }
              else                      /* Should be a numeric value */
                {
@@ -749,8 +933,16 @@ set_info(int               skfd,           /* The socket */
                  if(index(args[i], 'M')) brate *= MEGA;
                  if(index(args[i], 'k')) brate *= KILO;
                  wrq.u.bitrate.value = (long) brate;
+                 wrq.u.bitrate.fixed = 1;
+
+                 /* Check for an additional argument */
+                 if(((i+1) < count) &&
+                    (!strcasecmp(args[i+1], "auto")))
+                   {
+                     wrq.u.bitrate.fixed = 0;
+                     ++i;
+                   }
                }
-             wrq.u.bitrate.fixed = 1;
            }
 
          if(ioctl(skfd, SIOCSIWRATE, &wrq) < 0)
@@ -762,37 +954,36 @@ set_info(int              skfd,           /* The socket */
        }
 
       /* ---------- Set RTS threshold ---------- */
-      if(!strncmp(args[i], "rts", 3))
+      if(!strncasecmp(args[i], "rts", 3))
        {
          i++;
          if(i >= count)
            iw_usage();
-         if(!strcasecmp(args[i], "auto"))
-           {
-             wrq.u.rts.value = -1;
-             wrq.u.rts.fixed = 0;
-           }
+         wrq.u.rts.value = -1;
+         wrq.u.rts.fixed = 1;
+         wrq.u.rts.disabled = 0;
+         if(!strcasecmp(args[i], "off"))
+           wrq.u.rts.disabled = 1;     /* i.e. max size */
          else
-           {
-             if(!strcasecmp(args[i], "fixed"))
-               {
-                 /* Get old RTS threshold */
-                 if(ioctl(skfd, SIOCGIWRTS, &wrq) < 0)
-                   {
-                     fprintf(stderr, "SIOCGIWRTS: %s\n", strerror(errno));
-                     return(-1);
-                   }
-                 strcpy(wrq.ifr_name, ifname);
-               }
-             else
-               if(!strcasecmp(args[i], "off"))
-                 wrq.u.rts.value = -1; /* i.e. max size */
+           if(!strcasecmp(args[i], "auto"))
+             wrq.u.rts.fixed = 0;
+           else
+             {
+               if(!strcasecmp(args[i], "fixed"))
+                 {
+                   /* Get old RTS threshold */
+                   if(ioctl(skfd, SIOCGIWRTS, &wrq) < 0)
+                     {
+                       fprintf(stderr, "SIOCGIWRTS: %s\n", strerror(errno));
+                       return(-1);
+                     }
+                   strcpy(wrq.ifr_name, ifname);
+                   wrq.u.rts.fixed = 1;
+                 }
                else                    /* Should be a numeric value */
                  if(sscanf(args[i], "%ld", (unsigned long *) &(wrq.u.rts.value))
                     != 1)
                    iw_usage();
-
-             wrq.u.rts.fixed = 1;
            }
 
          if(ioctl(skfd, SIOCSIWRTS, &wrq) < 0)
@@ -809,32 +1000,31 @@ set_info(int             skfd,           /* The socket */
          i++;
          if(i >= count)
            iw_usage();
-         if(!strcasecmp(args[i], "auto"))
-           {
-             wrq.u.frag.value = -1;
-             wrq.u.frag.fixed = 0;
-           }
+         wrq.u.frag.value = -1;
+         wrq.u.frag.fixed = 1;
+         wrq.u.frag.disabled = 0;
+         if(!strcasecmp(args[i], "off"))
+           wrq.u.frag.disabled = 1;    /* i.e. max size */
          else
-           {
-             if(!strcasecmp(args[i], "fixed"))
-               {
-                 /* Get old fragmentation threshold */
-                 if(ioctl(skfd, SIOCGIWFRAG, &wrq) < 0)
-                   {
-                     fprintf(stderr, "SIOCGIWFRAG: %s\n", strerror(errno));
-                     return(-1);
-                   }
-                 strcpy(wrq.ifr_name, ifname);
-               }
-             else
-               if(!strcasecmp(args[i], "off"))
-                 wrq.u.frag.value = -1;        /* i.e. max size */
+           if(!strcasecmp(args[i], "auto"))
+             wrq.u.frag.fixed = 0;
+           else
+             {
+               if(!strcasecmp(args[i], "fixed"))
+                 {
+                   /* Get old fragmentation threshold */
+                   if(ioctl(skfd, SIOCGIWFRAG, &wrq) < 0)
+                     {
+                       fprintf(stderr, "SIOCGIWFRAG: %s\n", strerror(errno));
+                       return(-1);
+                     }
+                   strcpy(wrq.ifr_name, ifname);
+                   wrq.u.frag.fixed = 1;
+                 }
                else                    /* Should be a numeric value */
                  if(sscanf(args[i], "%ld", (unsigned long *) &(wrq.u.frag.value))
                     != 1)
                    iw_usage();
-
-             wrq.u.frag.fixed = 1;
            }
 
          if(ioctl(skfd, SIOCSIWFRAG, &wrq) < 0)
@@ -844,8 +1034,124 @@ set_info(int             skfd,           /* The socket */
            }
          continue;
        }
-#endif /* WIRELESS_EXT > 7 */
 
+      /* ---------- Set operation mode ---------- */
+      if(!strcmp(args[i], "mode"))
+       {
+         int   k;
+
+         i++;
+         if(i >= count)
+           iw_usage();
+
+         if(sscanf(args[i], "%d", &k) != 1)
+           {
+             k = 0;
+             while(k < 6 && strncasecmp(args[i], operation_mode[k], 3))
+               k++;
+           }
+         if((k > 5) || (k < 0))
+           iw_usage();
+
+         wrq.u.mode = k;
+         if(ioctl(skfd, SIOCSIWMODE, &wrq) < 0)
+           {
+             fprintf(stderr, "SIOCSIWMODE: %s\n", strerror(errno));
+             return(-1);
+           }
+         continue;
+       }
+
+      /* ---------- Set Power Management ---------- */
+      if(!strncmp(args[i], "power", 3))
+       {
+         if(++i >= count)
+           iw_usage();
+
+         if(!strcasecmp(args[i], "off"))
+           wrq.u.power.disabled = 1;   /* i.e. max size */
+         else
+           if(!strcasecmp(args[i], "on"))
+             {
+               /* Get old Power info */
+               if(ioctl(skfd, SIOCGIWPOWER, &wrq) < 0)
+                 {
+                   fprintf(stderr, "SIOCGIWFRAG: %s\n", strerror(errno));
+                   return(-1);
+                 }
+               strcpy(wrq.ifr_name, ifname);
+               wrq.u.power.disabled = 0;
+             }
+           else
+             {
+               double          temp;
+               int             gotone = 0;
+               /* Default - nope */
+               wrq.u.power.flags = IW_POWER_ON;
+               wrq.u.power.disabled = 0;
+
+               /* Check value modifier */
+               if(!strcasecmp(args[i], "period"))
+                 {
+                   wrq.u.power.flags = IW_POWER_PERIOD;
+                   if(++i >= count)
+                     iw_usage();
+                 }
+               else
+                 if(!strcasecmp(args[i], "timeout"))
+                   {
+                     wrq.u.power.flags = IW_POWER_TIMEOUT;
+                     if(++i >= count)
+                       iw_usage();
+                   }
+
+               /* Is there any value to grab ? */
+               if(sscanf(args[i], "%lg", &(temp)) == 1)
+                 {
+                   temp *= MEGA;       /* default = s */
+                   if(index(args[i], 'u')) temp /= MEGA;
+                   if(index(args[i], 'm')) temp /= KILO;
+                   wrq.u.power.value = (long) temp;
+                   if(wrq.u.power.flags == IW_POWER_ON)
+                     wrq.u.power.flags = IW_POWER_PERIOD;
+                   ++i;
+                   gotone = 1;
+                 }
+
+               /* Now, check the mode */
+               if(i < count)
+                 {
+                   if(!strcasecmp(args[i], "all"))
+                     wrq.u.power.flags |= IW_POWER_ALL_R;
+                   if(!strncasecmp(args[i], "unicast", 4))
+                     wrq.u.power.flags |= IW_POWER_UNICAST_R;
+                   if(!strncasecmp(args[i], "multicast", 5))
+                     wrq.u.power.flags |= IW_POWER_MULTICAST_R;
+                   if(!strncasecmp(args[i], "force", 5))
+                     wrq.u.power.flags |= IW_POWER_FORCE_S;
+                   if(!strcasecmp(args[i], "repeat"))
+                     wrq.u.power.flags |= IW_POWER_REPEATER;
+                   if(wrq.u.power.flags & IW_POWER_MODE)
+                     {
+                       ++i;
+                       gotone = 1;
+                     }
+                 }
+               if(!gotone)
+                 iw_usage();
+               --i;
+             }
+
+         if(ioctl(skfd, SIOCSIWPOWER, &wrq) < 0)
+           {
+             fprintf(stderr, "SIOCSIWPOWER(%d): %s\n",
+                     errno, strerror(errno));
+             return(-1);
+           }
+         continue;
+       }
+
+      /* ---------- Other ---------- */
       /* Here we have an unrecognised arg... */
       fprintf(stderr, "Invalid argument : %s\n", args[i]);
       iw_usage();
diff --git a/wireless_tools/iwpriv b/wireless_tools/iwpriv
deleted file mode 100644 (file)
index 4657f67..0000000
Binary files a/wireless_tools/iwpriv and /dev/null differ
index 8acc2e8..9ed9b90 100644 (file)
@@ -18,7 +18,7 @@ network interface
 .br
 .BI "iwpriv " interface " roam " {on,off}
 .br
-.BI "iwpriv " interface " port " [ N ]
+.BI "iwpriv " interface " port " {ad-hoc,managed,N}
 .\"
 .\" DESCRIPTION part
 .\"
@@ -55,8 +55,8 @@ driver.
 .TP
 .B port
 Read or configure the port type. Call the private commands
-.IR gport_type " and " sport_type .
-Found in the
+.IR gport_type ", " sport_type ", " get_port " or " set_port
+found in the
 .IR wavelan2_cs " and " wvlan_cs " drivers."
 .TP
 .I private-command
index 3e22f4b..d1da985 100644 (file)
@@ -21,7 +21,7 @@ iw_usage(void)
 {
   fprintf(stderr, "Usage: iwpriv interface [private-command [private-arguments]]\n");
   fprintf(stderr, "              interface [roam {on|off}]\n");
-  fprintf(stderr, "              interface [port [n]]\n");
+  fprintf(stderr, "              interface [port {ad-hoc|managed|N}]\n");
   exit(1);
 }
 
@@ -386,6 +386,7 @@ port_type(int               skfd,           /* Socket */
   iwprivargs   priv[16];
   int          number;
   char         ptype = 0;
+  char *       modes[] = { "invalid", "managed (BSS)", "reserved", "ad-hoc" };
 
   /* Read the private ioctls */
   number = get_priv_info(skfd, ifname, priv);
@@ -403,7 +404,8 @@ port_type(int               skfd,           /* Socket */
     {
       /* So, we just want to see the current value... */
       k = -1;
-      while((++k < number) && strcmp(priv[k].name, "gport_type"));
+      while((++k < number) && strcmp(priv[k].name, "gport_type") &&
+            strcmp(priv[k].name, "get_port"));
       if(k == number)
        {
          fprintf(stderr, "This device doesn't support getting port type\n");
@@ -420,7 +422,8 @@ port_type(int               skfd,           /* Socket */
       ptype = *wrq.u.name;
 
       /* Display it */
-      printf("%-8.8s  Port type is %d.\n\n", ifname, ptype);
+      printf("%-8.8s  Current port mode is %s <port type is %d>.\n\n",
+            ifname, modes[(int) ptype], ptype);
 
       return(0);
     }
@@ -429,11 +432,20 @@ port_type(int             skfd,           /* Socket */
     iw_usage();
 
   /* Read it */
-  if(sscanf(args[i], "%d", (int *) &ptype) != 1)
-    iw_usage();
+  /* As a string... */
+  k = 0;
+  while((k < 4) && strncasecmp(args[i], modes[k], 2))
+    k++;
+  if(k < 4)
+    ptype = k;
+  else
+    /* ...or as an integer */
+    if(sscanf(args[i], "%d", (int *) &ptype) != 1)
+      iw_usage();
   
   k = -1;
-  while((++k < number) && strcmp(priv[k].name, "sport_type"));
+  while((++k < number) && strcmp(priv[k].name, "sport_type") &&
+       strcmp(priv[k].name, "set_port"));
   if(k == number)
     {
       fprintf(stderr, "This device doesn't support setting port type\n");
@@ -445,7 +457,7 @@ port_type(int               skfd,           /* Socket */
 
   if(ioctl(skfd, priv[k].cmd, &wrq) < 0)
     {
-      fprintf(stderr, "Invalid port type\n");
+      fprintf(stderr, "Invalid port type (or setting not allowed)\n");
       exit(0);
     }
 
diff --git a/wireless_tools/iwspy b/wireless_tools/iwspy
deleted file mode 100644 (file)
index f857716..0000000
Binary files a/wireless_tools/iwspy and /dev/null differ
index 0a4c243..d7af14c 100644 (file)
@@ -22,6 +22,8 @@ iwspy \- Get wireless statistics from specific nodes
 .BI "iwspy " interface " ap"
 .br
 .BI "iwspy " interface " rate"
+.br
+.BI "iwspy " interface " keys"
 .\"
 .\" DESCRIPTION part
 .\"
@@ -82,8 +84,12 @@ displayed and channel numbers.
 Give the list of Access Points in range, and optionally the quality of
 link to them.
 .TP
-.BR rate / bit [ rate ]
+.BR rate / bit [rate]
 List the bit-rates supported by the device.
+.TP
+.BR keys / enc [ryption]
+List the encryption key sizes supported and display all the encryption
+keys availables in the device.
 .\"
 .\" FILES part
 .\"
index dd2d604..1fa39d3 100644 (file)
@@ -150,11 +150,7 @@ print_freq_info(int                skfd,
          /* Print them all */
          for(k = 0; k < range.num_frequency; k++)
            {
-#if WIRELESS_EXT > 7
-               printf("\t  Channel %.2d : ", range.freq[k].i);
-#else
-               printf("\t  ");
-#endif
+             printf("\t  Channel %.2d : ", range.freq[k].i);
              freq = freq2float(&(range.freq[k]));
              if(freq >= GIGA)
                printf("%g GHz\n", freq / GIGA);
@@ -199,7 +195,6 @@ print_freq_devices(int              skfd)
     print_freq_info(skfd, ifr->ifr_name);
 }
 
-#if WIRELESS_EXT > 5
 /*------------------------------------------------------------------*/
 /*
  * Display the list of ap addresses and the associated stats
@@ -310,9 +305,7 @@ print_ap_devices(int                skfd)
   for(i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++)
     print_ap_info(skfd, ifr->ifr_name);
 }
-#endif /* WIRELESS_EXT > 5 */
 
-#if WIRELESS_EXT > 7
 /*------------------------------------------------------------------*/
 /*
  * Print the number of available bitrates for the device
@@ -385,7 +378,103 @@ print_bitrate_devices(int         skfd)
   for(i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++)
     print_bitrate_info(skfd, ifr->ifr_name);
 }
-#endif /* WIRELESS_EXT > 7 */
+
+/*------------------------------------------------------------------*/
+/*
+ * Print the number of available bitrates for the device
+ */
+static void
+print_keys_info(int            skfd,
+               char *          ifname)
+{
+  struct iwreq         wrq;
+  struct iw_range      range;
+  unsigned char                key[IW_ENCODING_TOKEN_MAX];
+  int                  k;
+
+  strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
+  wrq.u.data.pointer = (caddr_t) &range;
+  wrq.u.data.length = 0;
+  wrq.u.data.flags = 0;
+  if(ioctl(skfd, SIOCGIWRANGE, &wrq) < 0)
+      fprintf(stderr, "%-8.8s  no encryption keys information.\n\n",
+                     ifname);
+  else
+    {
+      printf("%-8.8s  ", ifname);
+      if((range.num_encoding_sizes > 0) &&
+        (range.num_encoding_sizes < IW_MAX_ENCODING_SIZES))
+       {
+         printf("%d key sizes : %d", range.num_encoding_sizes,
+                range.encoding_size[0] * 8);
+         /* Print them all */
+         for(k = 1; k < range.num_encoding_sizes; k++)
+           printf(", %d", range.encoding_size[k] * 8);
+         printf("bits\n          ");
+       }
+      printf("%d keys available :\n", range.max_encoding_tokens);
+      for(k = 1; k <= range.max_encoding_tokens; k++)
+       {
+         strcpy(wrq.ifr_name, ifname);
+         wrq.u.data.pointer = (caddr_t) key;
+         wrq.u.data.length = 0;
+         wrq.u.data.flags = k;
+         if(ioctl(skfd, SIOCGIWENCODE, &wrq) < 0)
+           {
+             fprintf(stderr, "SIOCGIWENCODE: %s\n", strerror(errno));
+             break;
+           }
+         if((wrq.u.data.flags & IW_ENCODE_DISABLED) ||
+            (wrq.u.data.length == 0))
+           printf("\t\t[%d]: off\n", k);
+         else
+           {
+             int       i;
+
+             printf("\t\t[%d]: %.2X", k, key[0]);
+             for(i = 1; i < wrq.u.data.length; i++)
+               {
+                 if((i & 0x1) == 0)
+                   printf("-");
+                 printf("%.2X", key[i]);
+               }
+
+             /* Other info... */
+             printf(" (%d bits)", wrq.u.data.length * 8);
+             printf("\n");
+           }
+       }
+
+      printf("\n\n");
+    }
+}
+
+/*------------------------------------------------------------------*/
+/*
+ * Get bit-rate info on all devices and print it on the screen
+ */
+static void
+print_keys_devices(int         skfd)
+{
+  char         buff[1024];
+  struct ifconf ifc;
+  struct ifreq *ifr;
+  int i;
+
+  /* Get list of active devices */
+  ifc.ifc_len = sizeof(buff);
+  ifc.ifc_buf = buff;
+  if(ioctl(skfd, SIOCGIFCONF, &ifc) < 0)
+    {
+      fprintf(stderr, "SIOCGIFCONF: %s\n", strerror(errno));
+      return;
+    }
+  ifr = ifc.ifc_req;
+
+  /* Print them */
+  for(i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++)
+    print_keys_info(skfd, ifr->ifr_name);
+}
 
 /************************* SETTING ROUTINES **************************/
 
@@ -528,7 +617,6 @@ main(int    argc,
       exit(0);
     }
 
-#if WIRELESS_EXT > 5
   /* Access Point list */
   if(!strcasecmp(argv[1], "ap"))
     {
@@ -536,9 +624,7 @@ main(int    argc,
       close(skfd);
       exit(0);
     }
-#endif /* WIRELESS_EXT > 5 */
 
-#if WIRELESS_EXT > 7
   /* Bit-rate list */
   if((!strncmp(argv[1], "bit", 3)) ||
      (!strcmp(argv[1], "rate")))
@@ -547,7 +633,15 @@ main(int   argc,
       close(skfd);
       exit(0);
     }
-#endif /* WIRELESS_EXT > 7 */
+
+  /* Encryption key list */
+  if((!strncmp(argv[1], "enc", 3)) ||
+     (!strncmp(argv[1], "key", 3)))
+    {
+      print_keys_devices(skfd);
+      close(skfd);
+      exit(0);
+    }
 
   /* The device name must be the first argument */
   /* Name only : show spy list for that device only */
@@ -568,7 +662,6 @@ main(int    argc,
       exit(0);
     }
 
-#if WIRELESS_EXT > 5
   /* Access Point  list */
   if(!strcasecmp(argv[2], "ap"))
     {
@@ -576,9 +669,7 @@ main(int    argc,
       close(skfd);
       exit(0);
     }
-#endif /* WIRELESS_EXT > 5 */
 
-#if WIRELESS_EXT > 7
   /* Access Point  list */
   if((!strncmp(argv[2], "bit", 3)) ||
      (!strcmp(argv[2], "rate")))
@@ -587,7 +678,15 @@ main(int   argc,
       close(skfd);
       exit(0);
     }
-#endif /* WIRELESS_EXT > 7 */
+
+  /* Access Point  list */
+  if((!strncmp(argv[2], "enc", 3)) ||
+     (!strncmp(argv[2], "key", 3)))
+    {
+      print_keys_info(skfd, argv[1]);
+      close(skfd);
+      exit(0);
+    }
 
   /* Otherwise, it's a list of address to set in the spy list */
   goterr = set_spy_info(skfd, argv + 2, argc - 2, argv[1]);
diff --git a/wireless_tools/sample_enc_cs.c b/wireless_tools/sample_enc_cs.c
new file mode 100644 (file)
index 0000000..47247b2
--- /dev/null
@@ -0,0 +1,105 @@
+#define MAX_KEY_SIZE   16
+#define        MAX_KEYS        8
+int    key_on = 0;
+int    key_open = 1;
+int    key_current = 0;
+char   key_table[MAX_KEYS][MAX_KEY_SIZE];
+int    key_size[MAX_KEYS];
+
+#if WIRELESS_EXT > 8
+     case SIOCSIWENCODE:
+       /* Basic checking... */
+       if(wrq->u.encoding.pointer != (caddr_t) 0)
+        {
+          int  index = (wrq->u.encoding.flags & IW_ENCODE_INDEX) - 1;
+
+          /* Check the size of the key */
+          if(wrq->u.encoding.length > MAX_KEY_SIZE)
+            {
+              ret = -EINVAL;
+              break;
+            }
+
+          /* Check the index */
+          if((index < 0) || (index >= MAX_KEYS))
+            index = key_current;
+
+          /* Copy the key in the driver */
+          if(copy_from_user(key_table[index], wrq->u.encoding.pointer,
+                            wrq->u.encoding.length))
+            {
+              key_size[index] = 0;
+              ret = -EFAULT;
+              break;
+            }
+          key_size[index] = wrq->u.encoding.length;
+          key_on = 1;
+        }
+       else
+        {
+          int  index = (wrq->u.encoding.flags & IW_ENCODE_INDEX) - 1;
+          /* Do we want to just set the current key ? */
+          if((index >= 0) && (index < MAX_KEYS))
+            {
+              if(key_size[index] > 0)
+                {
+                  key_current = index;
+                  key_on = 1;
+                }
+              else
+                ret = -EINVAL;
+            }
+        }
+
+       /* Read the flags */
+       if(wrq->u.encoding.flags & IW_ENCODE_DISABLED)
+        key_on = 0;    /* disable encryption */
+       if(wrq->u.encoding.flags & IW_ENCODE_RESTRICTED)
+        key_open = 0;  /* disable open mode */
+       if(wrq->u.encoding.flags & IW_ENCODE_OPEN)
+        key_open = 1;  /* enable open mode */
+
+       break;
+
+     case SIOCGIWENCODE:
+       /* only super-user can see encryption key */
+       if(!suser())
+        {
+          ret = -EPERM;
+          break;
+        }
+
+       /* Basic checking... */
+       if(wrq->u.encoding.pointer != (caddr_t) 0)
+        {
+          int  index = (wrq->u.encoding.flags & IW_ENCODE_INDEX) - 1;
+
+          /* Set the flags */
+          wrq->u.encoding.flags = 0;
+          if(key_on == 0)
+             wrq->u.encoding.flags |= IW_ENCODE_DISABLED;
+          if(key_open == 0)
+            wrq->u.encoding.flags |= IW_ENCODE_RESTRICTED;
+          else
+            wrq->u.encoding.flags |= IW_ENCODE_OPEN;
+
+          /* Which key do we want */
+          if((index < 0) || (index >= MAX_KEYS))
+            index = key_current;
+          wrq->u.encoding.flags |= index + 1;
+
+          /* Copy the key to the user buffer */
+          wrq->u.encoding.length = key_size[index];
+          if(copy_to_user(wrq->u.encoding.pointer, key_table[index],
+                          key_size[index]))
+            ret = -EFAULT;
+       }
+       break;
+#endif /* WIRELESS_EXT > 8 */
+
+#if WIRELESS_EXT > 8
+         range.encoding_size[0] = 8;   /* DES = 64 bits key */
+         range.encoding_size[1] = 16;
+         range.num_encoding_sizes = 2;
+         range.max_encoding_tokens = 8;
+#endif /* WIRELESS_EXT > 8 */
diff --git a/wireless_tools/wireless.h b/wireless_tools/wireless.h
deleted file mode 100644 (file)
index 0be1d51..0000000
+++ /dev/null
@@ -1,347 +0,0 @@
-/*
- * This file define a set of standard wireless extensions
- *
- * Version :   7       23.4.99
- *
- * Authors :   Jean Tourrilhes - HPLB - <jt@hplb.hpl.hp.com>
- */
-
-#ifndef _LINUX_WIRELESS_H
-#define _LINUX_WIRELESS_H
-
-/************************** DOCUMENTATION **************************/
-/*
- * Basically, the wireless extensions are for now a set of standard ioctl
- * call + /proc/net/wireless
- *
- * The entry /proc/net/wireless give statistics and information on the
- * driver.
- * This is better than having each driver having its entry because
- * its centralised and we may remove the driver module safely.
- *
- * Ioctl are used to configure the driver and issue commands.  This is
- * better than command line options of insmod because we may want to
- * change dynamically (while the driver is running) some parameters.
- *
- * The ioctl mechanimsm are copied from standard devices ioctl.
- * We have the list of command plus a structure descibing the
- * data exchanged...
- * Note that to add these ioctl, I was obliged to modify :
- *     net/core/dev.c (two place + add include)
- *     net/ipv4/af_inet.c (one place + add include)
- *
- * /proc/net/wireless is a copy of /proc/net/dev.
- * We have a structure for data passed from the driver to /proc/net/wireless
- * Too add this, I've modified :
- *     net/core/dev.c (two other places)
- *     include/linux/netdevice.h (one place)
- *     include/linux/proc_fs.h (one place)
- *
- * Do not add here things that are redundant with other mechanisms
- * (drivers init, ifconfig, /proc/net/dev, ...) and with are not
- * wireless specific.
- *
- * These wireless extensions are not magic : each driver has to provide
- * support for them...
- *
- * IMPORTANT NOTE : As everything in the kernel, this is very much a
- * work in progress. Contact me if you have ideas of improvements...
- */
-
-/***************************** INCLUDES *****************************/
-
-#if 0
-#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... */
-#endif
-
-/**************************** CONSTANTS ****************************/
-
-/* --------------------------- VERSION --------------------------- */
-/*
- * This constant is used to know the availability of the wireless
- * extensions and to know which version of wireless extensions it is
- * (there is some stuff that will be added in the future...)
- * I just plan to increment with each new version.
- */
-#define WIRELESS_EXT   6
-
-/*
- * 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
- */
-
-/* -------------------------- IOCTL LIST -------------------------- */
-
-/* Basic operations */
-#define SIOCSIWNAME    0x8B00          /* Unused ??? */
-#define SIOCGIWNAME    0x8B01          /* get name */
-#define SIOCSIWNWID    0x8B02          /* set network id */
-#define SIOCGIWNWID    0x8B03          /* get network id */
-#define SIOCSIWFREQ    0x8B04          /* set channel/frequency */
-#define SIOCGIWFREQ    0x8B05          /* get channel/frequency */
-#define SIOCSIWENCODE  0x8B06          /* set encoding info */
-#define SIOCGIWENCODE  0x8B07          /* get encoding info */
-#define SIOCSIWSENS    0x8B08          /* set sensitivity */
-#define SIOCGIWSENS    0x8B09          /* get sensitivity */
-
-/* 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 */
-
-/* Mobile IP support */
-#define SIOCSIWSPY     0x8B10          /* set spy addresses */
-#define SIOCGIWSPY     0x8B11          /* get spy info (quality of link) */
-
-/* Access Point manipulation */
-#define SIOCSIWAP      0x8B14          /* set access point hardware addresses */
-#define SIOCGIWAP      0x8B15          /* get access point hardware addresses */
-#define SIOCGIWAPLIST  0x8B17          /* get list of access point in range */
-
-/* 802.11 specific support */
-#define SIOCSIWESSID   0x8B1A          /* set ESSID (network name) */
-#define SIOCGIWESSID   0x8B1B          /* get ESSID */
-/* As the ESSID is a string up to 32 bytes long, it doesn't fit within the
- * 'iwreq' structure, so we need to use the 'data' member to point to a
- * string in user space, like it is done for RANGE...
- * The "flags" member indicate if the ESSID is active or not.
- */
-
-/* ------------------------- IOCTL STUFF ------------------------- */
-
-/* The first and the last (range) */
-#define SIOCIWFIRST    0x8B00
-#define SIOCIWLAST     0x8B1B
-
-/* Even : get (world access), odd : set (root access) */
-#define IW_IS_SET(cmd) (!((cmd) & 0x1))
-#define IW_IS_GET(cmd) ((cmd) & 0x1)
-
-/* ------------------------- PRIVATE INFO ------------------------- */
-/*
- * The following is used with SIOCGIWPRIV. It allow a driver to define
- * the interface (name, type of data) for its private ioctl.
- * Privates ioctl are SIOCDEVPRIVATE -> SIOCDEVPRIVATE + 0xF
- */
-
-#define IW_PRIV_TYPE_MASK      0x7000  /* Type of arguments */
-#define IW_PRIV_TYPE_NONE      0x0000
-#define IW_PRIV_TYPE_BYTE      0x1000  /* Char as number */
-#define IW_PRIV_TYPE_CHAR      0x2000  /* Char as character */
-#define IW_PRIV_TYPE_INT       0x4000  /* 32 bits int */
-#define IW_PRIV_TYPE_FLOAT     0x5000
-
-#define IW_PRIV_SIZE_FIXED     0x0800  /* Variable or fixed nuber of args */
-
-#define IW_PRIV_SIZE_MASK      0x07FF  /* Max number of those args */
-
-/*
- * Note : if the number of args is fixed and the size < 16 octets,
- * instead of passing a pointer we will put args in the iwreq struct...
- */
-
-/* ----------------------- OTHER CONSTANTS ----------------------- */
-
-/* Maximum frequencies in the range struct */
-#define IW_MAX_FREQUENCIES     16
-/* Note : if you have something like 80 frequencies,
- * don't increase this constant and don't fill the frequency list.
- * The user will be able to set by channel anyway... */
-
-/* Maximum of address that you may set with SPY */
-#define IW_MAX_SPY             8
-
-/* Maximum of address that you may get in the
-   list of access points in range */
-#define IW_MAX_AP              8
-
-/* Maximum size of the ESSID string */
-#define IW_ESSID_MAX_SIZE      32
-
-/****************************** TYPES ******************************/
-
-/* --------------------------- SUBTYPES --------------------------- */
-/*
- *     A frequency
- *     For numbers lower than 10^9, we encode the number in 'mant' and
- *     set 'exp' to 0
- *     For number greater than 10^9, we divide it by a power of 10.
- *     The power of 10 is in 'exp', the result is in 'mant'.
- */
-struct iw_freq
-{
-       __u32           m;              /* Mantissa */
-       __u16           e;              /* Exponent */
-};
-
-/*
- *     Quality of the link
- */
-struct iw_quality
-{
-       __u8            qual;           /* link quality (SNR or better...) */
-       __u8            level;          /* signal level */
-       __u8            noise;          /* noise level */
-       __u8            updated;        /* Flags to know if updated */
-};
-
-/*
- *     Packet discarded in the wireless adapter due to
- *     "wireless" specific problems...
- */
-struct iw_discarded
-{
-       __u32           nwid;           /* Wrong nwid */
-       __u32           code;           /* Unable to code/decode */
-       __u32           misc;           /* Others cases */
-};
-
-/*
- *     Encoding information (setting and so on)
- *     Encoding might be hardware encryption, scrambing or others
- */
-struct iw_encoding
-{
-  __u8 method;                 /* Algorithm number / key used */
-  __u64        code;                   /* Data/key used for algorithm */
-};
-
-
-/* ------------------------ WIRELESS STATS ------------------------ */
-/*
- * Wireless statistics (used for /proc/net/wireless)
- */
-struct iw_statistics
-{
-       __u8            status;         /* Status
-                                        * - device dependent for now */
-
-       struct iw_quality       qual;           /* Quality of the link
-                                                * (instant/mean/max) */
-       struct iw_discarded     discard;        /* Packet discarded counts */
-};
-
-/* ------------------------ IOCTL REQUEST ------------------------ */
-/*
- * The structure to exchange data for ioctl.
- * This structure is the same as 'struct ifreq', but (re)defined for
- * convenience...
- *
- * Note that it should fit on the same memory footprint !
- * You should check this when increasing the above structures (16 octets)
- * 16 octets = 128 bits. Warning, pointers might be 64 bits wide...
- */
-struct iwreq 
-{
-       union
-       {
-               char    ifrn_name[IFNAMSIZ];    /* if name, e.g. "en0" */
-       } ifr_ifrn;
-
-       /* Data part */
-       union
-       {
-               /* Config - generic */
-               char    name[IFNAMSIZ];
-               /* Name : used to verify the presence of  wireless extensions.
-                * Name of the protocol/provider... */
-
-               struct          /* network id (or domain) : used to to */
-               {               /* create logical channels on the air */
-                       __u32   nwid;           /* value */
-                       __u8    on;             /* active/unactive nwid */
-               }       nwid;
-
-               struct iw_freq  freq;   /* frequency or channel :
-                                        * 0-1000 = channel
-                                        * > 1000 = frequency in Hz */
-
-               struct iw_encoding      encoding;       /* Encoding stuff */
-
-               __u32   sensitivity;            /* signal level threshold */
-
-               struct sockaddr ap_addr;        /* Access point address */
-
-               struct          /* For all data bigger than 16 octets */
-               {
-                       caddr_t pointer;        /* Pointer to the data
-                                                * (in user space) */
-                       __u16   length;         /* fields or byte size */
-                       __u16   flags;          /* Optional params */
-               }       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... */
-
-       /* NWID (or domain id) */
-       __u32           min_nwid;       /* Minimal NWID we are able to set */
-       __u32           max_nwid;       /* Maximal NWID we are able to set */
-
-       /* Frequency */
-       __u16           num_channels;   /* Number of channels [0; num - 1] */
-       __u8            num_frequency;  /* Number of entry in the list */
-       struct iw_freq  freq[IW_MAX_FREQUENCIES];       /* list */
-       /* Note : this frequency list doesn't need to fit channel numbers */
-
-       /* signal level threshold range */
-       __u32   sensitivity;
-
-       /* Quality of link & SNR stuff */
-       struct iw_quality       max_qual;       /* Quality of the link */
-
-       /* Encoder stuff */
-       struct iw_encoding      max_encoding;   /* Encoding max range */
-};
-
-/*
- * Private ioctl interface information
- */
-struct iw_priv_args
-{
-       __u32           cmd;            /* Number of the ioctl to issue */
-       __u16           set_args;       /* Type and number of args */
-       __u16           get_args;       /* Type and number of args */
-       char            name[IFNAMSIZ]; /* Name of the extension */
-};
-
-#endif /* _LINUX_WIRELESS_H */