OSDN Git Service

v21
authorchris-kirby <chris.kirby@hpe.com>
Tue, 11 Oct 2016 20:54:07 +0000 (14:54 -0600)
committerchris-kirby <chris.kirby@hpe.com>
Tue, 11 Oct 2016 20:54:07 +0000 (14:54 -0600)
22 files changed:
wireless_tools/COPYING [new file with mode: 0644]
wireless_tools/INSTALL
wireless_tools/Makefile
wireless_tools/PCMCIA.txt [new file with mode: 0644]
wireless_tools/README
wireless_tools/iwcommon.c
wireless_tools/iwcommon.h
wireless_tools/iwconfig.8
wireless_tools/iwconfig.c
wireless_tools/iwgetid.c [new file with mode: 0644]
wireless_tools/iwlist.8 [new file with mode: 0644]
wireless_tools/iwlist.c [new file with mode: 0644]
wireless_tools/iwpriv.8
wireless_tools/iwpriv.c
wireless_tools/iwspy.8
wireless_tools/iwspy.c
wireless_tools/sample_enc_cs.c
wireless_tools/sample_pm_cs.c [new file with mode: 0644]
wireless_tools/wireless.10.h [new file with mode: 0644]
wireless_tools/wireless.h [new file with mode: 0644]
wireless_tools/xwireless.c [deleted file]
wireless_tools/xwireless.make [deleted file]

diff --git a/wireless_tools/COPYING b/wireless_tools/COPYING
new file mode 100644 (file)
index 0000000..d60c31a
--- /dev/null
@@ -0,0 +1,340 @@
+                   GNU GENERAL PUBLIC LICENSE
+                      Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                           Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+\f
+                   GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+\f
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+\f
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+\f
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                           NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                    END OF TERMS AND CONDITIONS
+\f
+           How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year  name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
index 7aa92c0..6093c2e 100644 (file)
@@ -5,9 +5,7 @@ Very important note :
        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.
        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 might have headers troubles and it doesn't compile, see below...
 
 You need :
 --------
 
 You need :
 --------
@@ -16,13 +14,17 @@ You need :
                -> from 2.2.14 onward
                -> from 2.3.24 onward
                Note : CONFIG_NET_RADIO must be enabled
                -> from 2.2.14 onward
                -> from 2.3.24 onward
                Note : CONFIG_NET_RADIO must be enabled
+       o (Optional) A Pcmcia package supporting Wireless Extension
        o A driver supporting wireless extensions
        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 isa
+               -> Wavelan pcmcia
+               -> Netwave pcmcia
                -> Wavelan IEEE pcmcia drivers
                -> Wavelan IEEE pcmcia drivers
+               -> Aironet MPL driver
                -> Proxim RangeLan2/Symphony driver
                -> Proxim RangeLan2/Symphony driver
-               -> Patch your favourite driver
+               -> Raylink/WegGear2.4 driver
+               -> Check my web page for latest list of drivers,
+                       otherwise patch your favourite driver...
        Note : more recent kernels and drivers are likely to support
                more wireless extension features...
 
        Note : more recent kernels and drivers are likely to support
                more wireless extension features...
 
@@ -32,35 +34,55 @@ Recommended versions :
        o Kernel (wireless extension definition) :
                -> Kernel 2.2.14 onward
                -> Kernel 2.3.24 onward
        o Kernel (wireless extension definition) :
                -> Kernel 2.2.14 onward
                -> Kernel 2.3.24 onward
+       o Pcmcia package :
+               -> Pcmcia 3.1.15 onward
        o Drivers with wireless extension support :
                -> Wavelan isa from kernels above
                -> Wavelan pcmcia from pcmcia 3.1.1 onward
                -> Netwave pcmcia from pcmcia 3.1.2 onward
        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
+               -> Wavelan IEEE pcmcia GPL driver (wvlan_cs) 1.0.5 onward
+               -> Aironet MPL driver (airo_cs.c) 1.4 onward
                -> Proxim RangeLan2/Symphony driver 1.4.3 onward
                -> Proxim RangeLan2/Symphony driver 1.4.3 onward
+               -> Raylink/WegGear2.4 driver 1.70 (note : read only)
 
 Compile wireless tools :
 ----------------------
 
 Compile wireless tools :
 ----------------------
-       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.
+       In theory, a "make" should suffice to create the tools.
+       In practice, there is big troubles with the kernel
+headers. See below for how to fix that.
        Note : as some internal data structures change from kernel to
        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.
+kernel, you are advised to not use the precompiled version of the
+tools but to recompile your own.
 
 Installation :
 ------------
 
 Installation :
 ------------
+       If I were you, I would not trust a "make install". If you feel
+courageous, just do "make install". It may even do the right thing.
        I advise to copy the executable (iwconfig, iwspy and iwpriv)
        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
+in /usr/local/sbin or /usr/sbin. The man pages (iwconfig.8, iwspy.8
+and iwpriv.8) should be copied in /usr/local/man/man8 or
 /usr/man/man8.
 /usr/man/man8.
+       In fact, if you want to use Pcmcia wireless.opts, this step is
+mandatory...
 
 
+Kernel headers (why it doesn't compile) :
+---------------------------------------
+       Some changes in the kernel headers and glibc headers are
+making my life difficult.
+       If you have glibc and kernel 2.2.X headers (or greater), that
+should be all right. This is the default for most modern distributions.
+       In the other cases, depending on which version of the kernel
+headers (might be different from kernel) and library headers you have,
+you need to play with the options at the top of the Makefile.
 
 
-List of contributors and changelog is in iwcommon.h.
+       The second issue is that some distributions install some
+independant kernel headers in /usr/include. If you upgrade your
+kernel, those headers become out of sync and you don't benefit from
+the latest Wireless Extensions. Even worse, it can sometimes prevent
+the tools from compiling.
+       The trick is to copy the file .../include/linux/wireless.h
+from the kernel to the /usr/include headers.
+       A similar procedure may be used to update Wireless Extensions
+in an older kernel...
 
        Jean <jt@hpl.hp.com>
 
        Jean <jt@hpl.hp.com>
index 9764187..b7f7550 100644 (file)
@@ -1,11 +1,47 @@
+#
+# Basic and crude Makefile...
+#
+
+# Targets to build
+PROGS= iwconfig iwlist iwpriv iwspy iwgetid
+
+# Installation directory. By default, go in local.
+# Distributions should probably use /usr/sbin, but they probably know better...
+INSTALL_DIR= /usr/local/sbin
+
+# This is our header selection. Try to hide the mess and the misery :-(
+# Please choose *only one* of the define...
+
+# Kernel headers 2.4.X + Glibc 2.2 - Mandrake 8.0 */
+#HEADERS= -DGLIBC22_HEADERS
+
+# Kernel headers 2.0.X + Glibc 2.0 - Debian 2.0, RH 5
+# Kernel headers 2.2.X + Glibc 2.1 - Debian 2.2, RH 6.1
+# Kernel headers 2.4.X + Glibc 2.1 - Debian 2.2 upgraded, RH 7.0
+HEADERS= -DGLIBC_HEADERS
+
+# Kernel headers 2.2.X + Glibc 2.0 - Debian 2.1
+#HEADERS= -DKLUDGE_HEADERS
+
+# Kernel headers 2.0.X + libc5 - old systems
+#HEADERS= -DLIBC5_HEADERS
+
+# Use private copy of Wireless Extension definition instead 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.
+#WE_HEADER= -DPRIVATE_WE_HEADER
+WE_HEADER=
+
+# ------------ End of config --------------
+
 CC = gcc
 RM = rm -f
 
 RM_CMD = $(RM) *.BAK *.bak *.o ,* *~ *.a
 
 CC = gcc
 RM = rm -f
 
 RM_CMD = $(RM) *.BAK *.bak *.o ,* *~ *.a
 
-CFLAGS=-O2 -Wall
+CFLAGS=-O2 -Wall $(HEADERS) $(WE_HEADER)
 
 
-PROGS=iwconfig iwpriv iwspy
 LIBS=-lm
 
 all:: $(PROGS)
 LIBS=-lm
 
 all:: $(PROGS)
@@ -14,17 +50,31 @@ all:: $(PROGS)
        $(CC) $(CFLAGS) -c $<
 
 iwconfig: iwconfig.o iwcommon.o
        $(CC) $(CFLAGS) -c $<
 
 iwconfig: iwconfig.o iwcommon.o
-       gcc -O2 -o $@ $^ $(LIBS)
+       $(CC) $(CFLAGS) -o $@ $^ $(LIBS)
+
+iwlist: iwlist.o iwcommon.o
+       $(CC) $(CFLAGS) -o $@ $^ $(LIBS)
 
 iwpriv: iwpriv.o iwcommon.o
 
 iwpriv: iwpriv.o iwcommon.o
-       gcc -O2 -o $@ $^ $(LIBS)
+       $(CC) $(CFLAGS) -o $@ $^ $(LIBS)
 
 iwspy: iwspy.o iwcommon.o
 
 iwspy: iwspy.o iwcommon.o
-       gcc -O2 -o $@ $^ $(LIBS)
+       $(CC) $(CFLAGS) -o $@ $^ $(LIBS)
+
+iwgetid: iwgetid.o
+       $(CC) $(CFLAGS) -o $@ $^
+
+# So crude but so effective ;-)
+install::
+       cp $(PROGS) $(INSTALL_DIR)
 
 clean::
        $(RM_CMD) 
 
 
 clean::
        $(RM_CMD) 
 
+realclean::
+       $(RM_CMD) 
+       $(RM) $(PROGS)
+
 depend::
        makedepend -s "# DO NOT DELETE" -- $(INCLUDES) -- $(SRCS)
 # DO NOT DELETE
 depend::
        makedepend -s "# DO NOT DELETE" -- $(INCLUDES) -- $(SRCS)
 # DO NOT DELETE
diff --git a/wireless_tools/PCMCIA.txt b/wireless_tools/PCMCIA.txt
new file mode 100644 (file)
index 0000000..0ac220d
--- /dev/null
@@ -0,0 +1,135 @@
+       One of the most exciting thing having happen after release 20
+is the addition of Wireless Extension support in the Pcmcia init
+scripts. Here is a quick intro on the subject...
+
+Pre-requisite :
+-------------
+       o Pcmcia package with Wireless Extension support : 3.1.15 onward
+       o A driver with Wireless Extension support
+       o The tools (iwconfig and co.) installed in the /usr/local/sbin
+               or /usr/sbin
+
+Raylink driver :
+--------------
+       The Raylink driver as of 1.70 doesn't support yet writable
+Wireless Extensions, so enabling wireless.opts on this driver will
+make thing worse.
+
+Pcmcia precompiled package :
+--------------------------
+       The Pcmcia package part of many distributions, especially
+those from Red-Hat, include some weird init scripts. Because of this,
+the present feature won't work.
+       On the other hand, the Pcmcia package in source form from the
+official Linux-Pcmcia web site will install the proper init scripts.
+
+Basic support :
+-------------
+       The file /etc/pcmcia/wireless.opts contain some templates for
+the most common drivers. Just fill in your card configuration in the
+template corresponding to your driver configuration.
+       Then, to activate it, you just need to remove or comment the 4
+lines at the top of wireless.opts and restart the Pcmcia package.
+
+       Things to take care of :
+       The options of wireless.opts will be used directly as
+arguments of iwconfig. So, you need iwconfig, and you need to check
+the man page of iwconfig to know how to format them.
+       A quick way to determine the correct options without
+restarting Pcmcia is to play a bit with iwconfig directly to see what
+is possible and what is the proper setup of the card and to copy that
+in wireless.opts.
+       At the end of wireless.opts, there is also a generic template
+containing all the possible options and explaining their meaning. Not
+all of them are supported by all cards (actually, most cards support a
+limited subset of it).
+       The current card templates are designed to match the MAC
+address of the card. Please check that this matches with your card.
+       Also, sample describe the most common/useful options available
+with the card, for more advance option, borrow options from the
+template. You can also remove some options, the card will usually
+initialise with a sane value.
+
+       Alternatively, you can also discard the current wireless.opts
+and replace it with a file looking like this :
+----------- wireless.opts ---------------------
+case "$ADDRESS" in
+*,*,*,*)
+    ESSID="MY_ESSID"
+    MODE="Managed"
+    ;;
+esac
+-----------------------------------------------
+
+
+Scheme support :
+--------------
+       The file wireless.opts fully support schemes. This allow you
+to define different configurations (home, work...) and to switch on
+the fly between them.
+       The best way to explain it is to show an example.
+       Let's say you have an infrastructured setup at work (MY_WORK)
+and an adhoc network at home (MY_HOME). Moreover, when a specific card
+is inserted, you want it to be in adhoc mode (TEST). The work setup
+will be the default...
+
+       Each Wireless LAN will have the following configuration :
+--------- wireless.opts --------------------
+# Lucent Wavelan IEEE - Ad-Hoc mode for test card
+*,*,*,00:60:1D:03:9F:2D)
+    ESSID="TEST"
+    MODE="Ad-Hoc"
+    FREQ="10"
+    RATE="1M"
+    ;;
+
+# Lucent Wavelan IEEE - Ad-Hoc mode at home
+home,*,*,00:60:1D:*|home,*,*,00:02:2D:*)
+    ESSID="MY_HOME"
+    MODE="Ad-Hoc"
+    FREQ="5"
+    ;;
+
+# Lucent Wavelan IEEE - infrastructured mode at work
+*,*,*,00:60:1D:*|*,*,*,00:02:2D:*)
+    ESSID="MY_WORK"
+    MODE="Managed"
+    KEY="s:verysecurekey"
+    ;;
+--------------------------------------------
+
+       Don't forget the IP configuration :
+--------- network.opts ---------------------
+# Wavelan IEEE : ad-hoc mode for test card
+*,*,*,00:60:1D:03:9F:2D)
+    DHCP="n"
+    IPADDR="10.0.0.1"
+    NETMASK="255.255.255.0"
+    NETWORK="10.0.0.0"
+    BROADCAST="10.0.0.255"
+    ;;
+
+# Wavelan IEEE : ad-hoc mode at home
+home,*,*,00:60:1D:*|home,*,*,00:02:2D:*)
+    DHCP="n"
+    IPADDR="10.0.1.19"
+    NETMASK="255.255.255.0"
+    NETWORK="10.0.1.0"
+    BROADCAST="10.0.1.255"
+    GATEWAY="15.0.1.1"
+    ;;
+
+# Wavelan IEEE : infrastructured mode at work
+*,*,*,00:60:1D:*|*,*,*,00:02:2D:*)
+    DHCP="y"
+    ;;
+--------------------------------------------
+
+       Now, when you are at work you do :
+> cardctl scheme default
+       And at home, you do :
+> cardctl scheme home
+
+       I guess you get the idea ;-)
+
+       Jean <jt@hpl.hp.com>
index 290ca28..7ac44ab 100644 (file)
@@ -1,45 +1,82 @@
+       Wireless Tools
+       --------------
+
        This package contain the Wireless tools, used to manipulate
 the Wireless Extensions. The Wireless Extension is an interface
 allowing you to set Wireless LAN specific parameters and get the
 specific stats.
 
        This package contain the Wireless tools, used to manipulate
 the Wireless Extensions. The Wireless Extension is an interface
 allowing you to set Wireless LAN specific parameters and get the
 specific stats.
 
+web page
+--------
+       You'll find a lot of useful info on :
+               http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html
+               http://web.hpl.hp.com/personal/Jean_Tourrilhes/Linux/
+
 INSTALL
 -------
 INSTALL
 -------
-       Installation instruction and requirements.
+       This file contains installation instruction and requirements.
 
 
-man pages (iwconfig.8, iwpriv.8, iwspy.8)
+PCMCIA.txt
+----------
+       This file describes how to use Pcmcia init script to configure
+Wireless Extensions and how to use Pcmcia schemes.
+
+man pages (iwconfig.8, iwlist.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
+       VERY IMPORTANT : I try to keep the man page up to date, so
+you'd better read them before asking questions.
+       ALSO IMPORTANT : Those man pages describe the capacity of the
+tools, no device implement the full range (and driver usually
+implement even less).
 
 
-web page
---------
-       You'll find a lot of useful info on :
-               http://web.hpl.hp.com/personal/Jean_Tourrilhes/Linux/
+       As far as I know, the man pages are the most complete, up to
+date and accurate documentation of the wireless tools. An update of
+the web page related to Wireless Extension is long overdue. Send
+feedback to me.
+       The man pages can either be copied in a location where the
+command "man" will find them, such as /usr/local/man/man8, or can be
+read locally with the command :
+               nroff -man xxx.8 | less
 
 iwconfig.c
 ----------
        The main wireless tool. Used for device configuration and to see
 
 iwconfig.c
 ----------
        The main wireless tool. Used for device configuration and to see
-       the most common parameters.
+the most common wireless parameters.
+
+iwlist.c
+--------
+       Display some large chunk of information not displayed by iwconfig.
+       For example, all bit rates, all frequencies, all keys...
 
 iwspy.c
 -------
        Mobile IP support test and allow get get stats per MAC address
 
 iwspy.c
 -------
        Mobile IP support test and allow get get stats per MAC address
-       (instead of globally). Also display available bit rates and
-       frequencies.
+(instead of globally). Also, for some driver/device, this is the only
+way to get stats in Ad-Hoc mode.
 
 iwpriv.c
 --------
 
 iwpriv.c
 --------
-       Manipulate driver private ioctls (all that is not available in
-       iwconfig). These are device specific parameters.
+       Manipulate driver private ioctls : all parameters that are
+specific to a driver or a device and therefore not part of iwconfig.
+
+iwgetid.c
+---------
+       Output the ESSID or NWID of the specified device.
+       Can also output it in a form that can be used as a Pcmcia Scheme.
+
+Changelog, contributions
+------------------------
+       See iwcommon.h
+
+wireless.h
+----------
+       Definition of the Wireless Extensions. You may drop this file
+in your kernel headers to update the Wireless Extensions.
 
 
-xwireless.c
+Other tools :
 -----------
 -----------
-       Graphical tool for the Netwave created by Dag Brattli <dagb@cs.uit.no>
+       My web page above list many other tools using Wireless
+Extensions that you may find useful...
 
 
        The list of changes, credits and errata notes are in
 
 
        The list of changes, credits and errata notes are in
index 43de184..0b2be07 100644 (file)
@@ -1,9 +1,11 @@
 /*
  *     Wireless Tools
  *
 /*
  *     Wireless Tools
  *
- *             Jean II - HPLB '99
+ *             Jean II - HPLB 97->99 - HPL 99->00
  *
  * Common subroutines to all the wireless tools...
  *
  * Common subroutines to all the wireless tools...
+ *
+ * This file is released under the GPL license.
  */
 
 #include "iwcommon.h"          /* Header */
  */
 
 #include "iwcommon.h"          /* Header */
@@ -56,14 +58,55 @@ get_range_info(int          skfd,
               iwrange *        range)
 {
   struct iwreq         wrq;
               iwrange *        range)
 {
   struct iwreq         wrq;
+  char                 buffer[sizeof(iwrange) * 2];    /* Large enough */
+
+  /* Cleanup */
+  memset(buffer, 0, sizeof(range));
 
   strcpy(wrq.ifr_name, ifname);
 
   strcpy(wrq.ifr_name, ifname);
-  wrq.u.data.pointer = (caddr_t) range;
+  wrq.u.data.pointer = (caddr_t) buffer;
   wrq.u.data.length = 0;
   wrq.u.data.flags = 0;
   if(ioctl(skfd, SIOCGIWRANGE, &wrq) < 0)
     return(-1);
 
   wrq.u.data.length = 0;
   wrq.u.data.flags = 0;
   if(ioctl(skfd, SIOCGIWRANGE, &wrq) < 0)
     return(-1);
 
+  /* Copy stuff at the right place, ignore extra */
+  memcpy((char *) range, buffer, sizeof(iwrange));
+
+  /* Lot's of people have driver and tools out of sync as far as Wireless
+   * Extensions are concerned. It's because /usr/include/linux/wireless.h
+   * and /usr/src/linux/include/linux/wireless.h are different.
+   * We try to catch this stuff here... */
+
+  /* For new versions, we can check the version directly, for old versions
+   * we use magic. 300 bytes is a also magic number, don't touch... */
+  if((WIRELESS_EXT > 10) && (wrq.u.data.length >= 300))
+    {
+#if WIRELESS_EXT > 10
+      /* Version verification - for new versions */
+      if(range->we_version_compiled != WIRELESS_EXT)
+       {
+         fprintf(stderr, "Warning : Device %s has been compiled with version %d\n", ifname, range->we_version_compiled);
+         fprintf(stderr, "of Wireless Extension, while we are using version %d.\n", WIRELESS_EXT);
+         fprintf(stderr, "Some things may be broken...\n\n");
+       }
+#endif /* WIRELESS_EXT > 10 */
+    }
+  else
+    {
+      /* Version verification - for old versions */
+      if(wrq.u.data.length != sizeof(iwrange))
+       {
+         fprintf(stderr, "Warning : Device %s has been compiled with a different version\n", ifname);
+         fprintf(stderr, "of Wireless Extension than ours (we are using version %d).\n", WIRELESS_EXT);
+         fprintf(stderr, "Some things may be broken...\n\n");
+       }
+    }
+
+  /* Note : we are only trying to catch compile difference, not source.
+   * If the driver source has not been updated to the latest, it doesn't
+   * matter because the new fields are set to zero */
+
   return(0);
 }
 
   return(0);
 }
 
@@ -126,6 +169,224 @@ freq2float(iwfreq *       in)
   return ((double) in->m) * pow(10,in->e);
 }
 
   return ((double) in->m) * pow(10,in->e);
 }
 
+/************************ POWER SUBROUTINES *************************/
+
+/*------------------------------------------------------------------*/
+/*
+ * Convert a value in dBm to a value in milliWatt.
+ */
+int
+dbm2mwatt(int  in)
+{
+  return((int) (floor(pow(10.0, (((double) in) / 10.0)))));
+}
+
+/*------------------------------------------------------------------*/
+/*
+ * Convert a value in milliWatt to a value in dBm.
+ */
+int
+mwatt2dbm(int  in)
+{
+  return((int) (ceil(10.0 * log10((double) in))));
+}
+
+/********************** STATISTICS SUBROUTINES **********************/
+
+/*------------------------------------------------------------------*/
+/*
+ * Output the link statistics, taking care of formating
+ */
+void
+print_stats(FILE *     stream,
+           iwqual *    qual,
+           iwrange *   range,
+           int         has_range)
+{
+  /* Just do it */
+  if(has_range && (qual->level != 0))
+    {
+      /* If the statistics are in dBm */
+      if(qual->level > range->max_qual.level)
+       {
+         /* Statistics are in dBm (absolute power measurement) */
+         fprintf(stream,
+                 "Quality:%d/%d  Signal level:%d dBm  Noise level:%d dBm%s\n",
+                 qual->qual, range->max_qual.qual,
+                 qual->level - 0x100, qual->noise - 0x100,
+                 (qual->updated & 0x7) ? " (updated)" : "");
+       }
+      else
+       {
+         /* Statistics are relative values (0 -> max) */
+         fprintf(stream,
+                 "Quality:%d/%d  Signal level:%d/%d  Noise level:%d/%d%s\n",
+                 qual->qual, range->max_qual.qual,
+                 qual->level, range->max_qual.level,
+                 qual->noise, range->max_qual.noise,
+                 (qual->updated & 0x7) ? " (updated)" : "");
+       }
+    }
+  else
+    {
+      /* We can't read the range, so we don't know... */
+      fprintf(stream, "Quality:%d  Signal level:%d  Noise level:%d%s\n",
+             qual->qual, qual->level, qual->noise,
+             (qual->updated & 0x7) ? " (updated)" : "");
+    }
+}
+
+/*********************** ENCODING SUBROUTINES ***********************/
+
+/*------------------------------------------------------------------*/
+/*
+ * Output the encoding key, with a nice formating
+ */
+void
+print_key(FILE *               stream,
+         unsigned char *       key,
+         int                   key_size,
+         int                   key_flags)
+{
+  int  i;
+
+  /* Is the key present ??? */
+  if(key_flags & IW_ENCODE_NOKEY)
+    {
+      /* Nope : print dummy */
+      printf("**");
+      for(i = 1; i < key_size; i++)
+       {
+         if((i & 0x1) == 0)
+           printf("-");
+         printf("**");
+       }
+    }
+  else
+    {
+      /* Yes : print the key */
+      printf("%.2X", key[0]);
+      for(i = 1; i < key_size; i++)
+       {
+         if((i & 0x1) == 0)
+           printf("-");
+         printf("%.2X", key[i]);
+       }
+    }
+}
+
+
+/******************* POWER MANAGEMENT SUBROUTINES *******************/
+
+/*------------------------------------------------------------------*/
+/*
+ * Output a power management value with all attributes...
+ */
+void
+print_pm_value(FILE *  stream,
+              int      value,
+              int      flags)
+{
+  /* Modifiers */
+  if(flags & IW_POWER_MIN)
+    fprintf(stream, " min");
+  if(flags & IW_POWER_MAX)
+    fprintf(stream, " max");
+
+  /* Type */
+  if(flags & IW_POWER_TIMEOUT)
+    fprintf(stream, " timeout:");
+  else
+    fprintf(stream, " period:");
+
+  /* Display value without units */
+  if(flags & IW_POWER_RELATIVE)
+    fprintf(stream, "%g  ", ((double) value) / MEGA);
+  else
+    {
+      /* Display value with units */
+      if(value >= (int) MEGA)
+       fprintf(stream, "%gs  ", ((double) value) / MEGA);
+      else
+       if(value >= (int) KILO)
+         fprintf(stream, "%gms  ", ((double) value) / KILO);
+       else
+         fprintf(stream, "%dus  ", value);
+    }
+}
+
+/*------------------------------------------------------------------*/
+/*
+ * Output a power management mode
+ */
+void
+print_pm_mode(FILE *   stream,
+             int       flags)
+{
+  /* Print the proper mode... */
+  switch(flags & IW_POWER_MODE)
+    {
+    case IW_POWER_UNICAST_R:
+      fprintf(stream, " mode:Unicast only received");
+      break;
+    case IW_POWER_MULTICAST_R:
+      fprintf(stream, " mode:Multicast only received");
+      break;
+    case IW_POWER_ALL_R:
+      fprintf(stream, " mode:All packets received");
+      break;
+    case IW_POWER_FORCE_S:
+      fprintf(stream, " mode:Force sending");
+      break;
+    case IW_POWER_REPEATER:
+      fprintf(stream, " mode:Repeat multicasts");
+      break;
+    default:
+    }
+}
+
+/***************** RETRY LIMIT/LIFETIME SUBROUTINES *****************/
+
+#if WIRELESS_EXT > 10
+/*------------------------------------------------------------------*/
+/*
+ * Output a retry value with all attributes...
+ */
+void
+print_retry_value(FILE *       stream,
+                 int           value,
+                 int           flags)
+{
+  /* Modifiers */
+  if(flags & IW_RETRY_MIN)
+    fprintf(stream, " min");
+  if(flags & IW_RETRY_MAX)
+    fprintf(stream, " max");
+
+  /* Type lifetime of limit */
+  if(flags & IW_RETRY_LIFETIME)
+    {
+      fprintf(stream, " lifetime:");
+
+      /* Display value without units */
+      if(flags & IW_POWER_RELATIVE)
+       fprintf(stream, "%g", ((double) value) / MEGA);
+      else
+       {
+         /* Display value with units */
+         if(value >= (int) MEGA)
+           fprintf(stream, "%gs", ((double) value) / MEGA);
+         else
+           if(value >= (int) KILO)
+             fprintf(stream, "%gms", ((double) value) / KILO);
+           else
+             fprintf(stream, "%dus", value);
+       }
+    }
+  else
+    fprintf(stream, " limit:%d", value);
+}
+#endif /* WIRELESS_EXT > 10 */
 
 /*********************** ADDRESS SUBROUTINES ************************/
 /*
 
 /*********************** ADDRESS SUBROUTINES ************************/
 /*
index 932ea4e..1c23c41 100644 (file)
@@ -1,9 +1,11 @@
 /*
  *     Wireless Tools
  *
 /*
  *     Wireless Tools
  *
- *             Jean II - HPLB '99
+ *             Jean II - HPLB 97->99 - HPL 99->00
  *
  * Common header for the wireless tools...
  *
  * Common header for the wireless tools...
+ *
+ * This file is released under the GPL license.
  */
 
 #ifndef IWCOMMON_H
  */
 
 #ifndef IWCOMMON_H
  *             - set timeout or period and its value
  *             - Reception mode (unicast/multicast/all)
  *     o Updated man pages with all that ;-)
  *             - set timeout or period and its value
  *             - Reception mode (unicast/multicast/all)
  *     o Updated man pages with all that ;-)
+ *
+ * wireless 21 :
+ * -----------
+ *             (from Alan McReynolds <alan_mcreynolds@hpl.hp.com>)
+ *     o Use proper macros for compilation directives [Makefile]
+ *             (From Jean Tourrilhes)
+ *     o Put licensing info everywhere (almost). Yes, it's GPL !
+ *     o Document the use of /etc/pcmcia/wireless.opts
+ *     o Add min/max modifiers to power management parameters [iwconfig]
+ *             -> requested by Lee Keyser-Allen for the Spectrum24 driver
+ *     o Optionally output a second power management parameter [iwconfig]
+ *     ---
+ *     o Common subroutines to display stats & power saving info [iwcommon]
+ *     o Display all power management info, capability and values [iwspy]
+ *     ---
+ *     o Optional index for ESSID (for Aironet driver) [iwcommon]
+ *     o IW_ENCODE_NOKEY for write only keys [iwconfig/iwspy]
+ *     o Common subrouting to print encoding keys [iwspy]
+ *     ---
+ *     o Transmit Power stuff (dBm + mW) [iwconfig/iwspy]
+ *     o Cleaner formatting algorithm when displaying params [iwconfig]
+ *     ---
+ *     o Fix get_range_info() and use it everywhere - Should fix core dumps.
+ *     o Catch WE version differences between tools and driver and
+ *       warn user. Thanks to Tobias Ringstrom for the tip... [iwcommon]
+ *     o Add Retry limit and lifetime support. [iwconfig/iwlist]
+ *     o Display "Cell:" instead of "Access Point:" in ad-hoc mode [iwconfig]
+ *     o Header fix for glibc2.2 by Ross G. Miller <Ross_Miller@baylor.edu>
+ *     o Move header selection flags in Makefile [iwcommon/Makefile]
+ *     o Spin-off iwlist.c from iwspy.c. iwspy is now much smaller
+ *       After moving this bit of code all over the place, from iwpriv
+ *       to iwconfig to iwspy, it now has a home of its own... [iwspy/iwlist]
+ *     o Wrote quick'n'dirty iwgetid.
+ *     o Remove output of second power management parameter [iwconfig]
+ *       Please use iwlist, I don't want to bloat iwconfig
+ *     ---
+ *     o Fix bug in display ints - "Allen Miu" <aklmiu@mit.edu> [iwpriv]
  */
 
 /* ----------------------------- TODO ----------------------------- */
  */
 
 /* ----------------------------- TODO ----------------------------- */
  * --------
  *     Make disable a per encryption key modifier if some hardware
  *     requires it.
  * --------
  *     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 :
  * ------
  *
  * iwpriv :
  * ------
  *
  * iwspy :
  * -----
  *
  * iwspy :
  * -----
- *     ?
+ *     -
  *
  * Doc & man pages :
  * ---------------
  *
  * Doc & man pages :
  * ---------------
 #include <netdb.h>             /* gethostbyname, getnetbyname */
 
 /* This is our header selection. Try to hide the mess and the misery :-(
 #include <netdb.h>             /* gethostbyname, getnetbyname */
 
 /* This is our header selection. Try to hide the mess and the misery :-(
- * Please choose only one of the define...
- */
-/* 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
-
-/* Kernel headers 2.2.X + Glibc 2.0 - Debian 2.1 */
-#undef KLUDGE_HEADERS
-
-/* Kernel headers 2.0.X + libc5 - old systems */
-#undef LIBC5_HEADERS
+ * The selection has been moved in the Makefile, here we have only
+ * the ugly part. Don't look, you would go blind ;-) */
 
 #ifdef KLUDGE_HEADERS
 #include <socketbits.h>
 
 #ifdef KLUDGE_HEADERS
 #include <socketbits.h>
 #include <linux/in.h>          /* For struct sockaddr_in */
 #endif /* KLUDGE_HEADERS || GLIBC_HEADERS */
 
 #include <linux/in.h>          /* For struct sockaddr_in */
 #endif /* KLUDGE_HEADERS || GLIBC_HEADERS */
 
+#ifdef GLIBC22_HEADERS 
+/* Added by Ross G. Miller <Ross_Miller@baylor.edu>, 3/28/01 */
+#include <linux/if_arp.h>      /* For ARPHRD_ETHER */
+#include <linux/socket.h>      /* For AF_INET & struct sockaddr */
+#include <sys/socket.h>
+#endif /* GLIBC22_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 */
 #endif /* LIBC5_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 */
 #endif /* LIBC5_HEADERS */
 
-/* Wireless extensions */
+#ifdef PRIVATE_WE_HEADER
+/* Private copy of Wireless extensions */
+#include "wireless.h"
+#else  /* PRIVATE_WE_HEADER */
+/* System wide Wireless extensions */
 #include <linux/wireless.h>
 #include <linux/wireless.h>
+#endif /* PRIVATE_WE_HEADER */
 
 
-#if WIRELESS_EXT < 8
-#error "Wireless Extension v9 or newer required :-(\n\
+#if WIRELESS_EXT < 9
+#error "Wireless Extension v9 or newer required :-(\
 Use Wireless Tools v19 or update your kernel headers"
 #endif
 Use Wireless Tools v19 or update your kernel headers"
 #endif
+#if WIRELESS_EXT < 11
+#warning "Wireless Extension v11 recommended...\
+You may update your kernel and/or system headers to get the new features..."
+#endif
 
 /****************************** DEBUG ******************************/
 
 
 /****************************** DEBUG ******************************/
 
@@ -181,6 +225,19 @@ Use Wireless Tools v19 or update your kernel headers"
 #define MEGA   1e6
 #define GIGA   1e9
 
 #define MEGA   1e6
 #define GIGA   1e9
 
+/* Backward compatibility for Wireless Extension 9 */
+#ifndef IW_POWER_MODIFIER
+#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 */
+#endif IW_POWER_MODIFIER
+
+#ifndef IW_ENCODE_NOKEY
+#define IW_ENCODE_NOKEY         0x0800  /* Key is write only, so not here */
+#define IW_ENCODE_MODE         0xF000  /* Modes defined below */
+#endif IW_ENCODE_NOKEY
+
 /****************************** TYPES ******************************/
 
 /* Shortcuts */
 /****************************** TYPES ******************************/
 
 /* Shortcuts */
@@ -188,6 +245,7 @@ typedef struct iw_statistics        iwstats;
 typedef struct iw_range                iwrange;
 typedef struct iw_param                iwparam;
 typedef struct iw_freq         iwfreq;
 typedef struct iw_range                iwrange;
 typedef struct iw_param                iwparam;
 typedef struct iw_freq         iwfreq;
+typedef struct iw_quality      iwqual;
 typedef struct iw_priv_args    iwprivargs;
 typedef struct sockaddr                sockaddr;
 
 typedef struct iw_priv_args    iwprivargs;
 typedef struct sockaddr                sockaddr;
 
@@ -222,6 +280,10 @@ typedef struct wireless_info
   int          mode;                   /* Operation mode */
   int          has_power;
   iwparam      power;                  /* Power management parameters */
   int          mode;                   /* Operation mode */
   int          has_power;
   iwparam      power;                  /* Power management parameters */
+  int          has_txpower;
+  iwparam      txpower;                /* Transmit Power in dBm */
+  int          has_retry;
+  iwparam      retry;                  /* Retry limit or lifetime */
 
   /* Stats */
   iwstats      stats;
 
   /* Stats */
   iwstats      stats;
@@ -252,6 +314,38 @@ void
                   iwfreq *     out);
 double
        freq2float(iwfreq *     in);
                   iwfreq *     out);
 double
        freq2float(iwfreq *     in);
+/* ---------------------- POWER SUBROUTINES ----------------------- */
+int
+       dbm2mwatt(int   in);
+int
+       mwatt2dbm(int   in);
+/* -------------------- STATISTICS SUBROUTINES -------------------- */
+void
+       print_stats(FILE *      stream,
+                   iwqual *    qual,
+                   iwrange *   range,
+                   int         has_range);
+/* --------------------- ENCODING SUBROUTINES --------------------- */
+void
+       print_key(FILE *                stream,
+                 unsigned char *       key,
+                 int                   key_size,
+                 int                   key_flags);
+/* ----------------- POWER MANAGEMENT SUBROUTINES ----------------- */
+void
+       print_pm_value(FILE *   stream,
+                      int      value,
+                      int      flags);
+void
+       print_pm_mode(FILE *    stream,
+                     int       flags);
+/* --------------- RETRY LIMIT/LIFETIME SUBROUTINES --------------- */
+#if WIRELESS_EXT > 10
+void
+       print_retry_value(FILE *        stream,
+                         int           value,
+                         int           flags);
+#endif
 /* --------------------- ADDRESS SUBROUTINES ---------------------- */
 int
        check_addr_type(int     skfd,
 /* --------------------- ADDRESS SUBROUTINES ---------------------- */
 int
        check_addr_type(int     skfd,
index 3b0c5fd..fbc3483 100644 (file)
@@ -17,9 +17,9 @@ iwconfig \- configure a wireless network interface
 .br
 .BI "                   [sens " S "] [mode " M "] [ap " A "] [nick " NN ]
 .br
 .br
 .BI "                   [sens " S "] [mode " M "] [ap " A "] [nick " NN ]
 .br
-.BI "                   [rate " R "] [rts " RT "] [frag " FT ]
+.BI "                   [rate " R "] [rts " RT "] [frag " FT "] [txpower " T ]
 .br
 .br
-.BI "                   [enc " E "] [key " K "] [power " P ]
+.BI "                   [enc " E "] [key " K "] [power " P "] [retry " R ]
 .\"
 .\" DESCRIPTION part
 .\"
 .\"
 .\" DESCRIPTION part
 .\"
@@ -243,8 +243,12 @@ To set the period between wake up, enter
 .IR "period `value'" .
 To set the timeout before going back to sleep, enter
 .IR "timeout `value'" .
 .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.
+You can also add the
+.IR min " and " max
+modifiers. By defaults, those values are in seconds, append the
+suffix m or u to specify values un milliseconds or
+microseconds. Sometimes, those values are without units (number of
+dwell or the like).
 .br
 .IR off " and " on
 disable and reenable power management. Finally, you may set the power
 .br
 .IR off " and " on
 disable and reenable power management. Finally, you may set the power
@@ -265,6 +269,61 @@ management mode to
 .I "   iwconfig eth0 power timeout 300u all"
 .br
 .I "   iwconfig eth0 power off"
 .I "   iwconfig eth0 power timeout 300u all"
 .br
 .I "   iwconfig eth0 power off"
+.br
+.I "   iwconfig eth0 power min period 2 power max period 4"
+.TP
+.BR txpower
+For cards supporting multiple transmit powers, set the transmit power in dBm. If 
+.I W
+is the power in Watt, the power in dBm is
+.IR "P = 30 + 10.log(W)" .
+If the value is postfixed by
+.IR mW ,
+it will be automatically converted to dBm.
+.br
+In addition, 
+.IR on " and " off
+enable and disable the radio, and
+.IR auto " and " fixed
+enable and disable power control (if those features are available).
+.br
+.B Examples :
+.br
+.I "   iwconfig eth0 txpower 15"
+.br
+.I "   iwconfig eth0 txpower 30mW"
+.br
+.I "   iwconfig eth0 txpower auto"
+.br
+.I "   iwconfig eth0 txpower off"
+.TP
+.BR retry
+Most cards have MAC retransmissions, and some allow to set the
+behaviour of the retry mechanism.
+.br
+To set the maximum number of retries, enter
+.IR "limit `value'" .
+This is an absolute value (without unit).
+The set the maximum length of time the MAC should retry, enter
+.IR "lifetime `value'" .
+By defaults, this value in in seconds, append the suffix m or u to
+specify values un milliseconds or microseconds.
+.br
+You can also add the
+.IR min " and " max
+modifiers. If the card support automatic mode, they define the bounds
+of the limit or lifetime. Some other cards define different values
+depending on packet size, for example in 802.11
+.I min limit
+is the short retry limit (non RTS/CTS packets).
+.br
+.B Examples :
+.br
+.I "   iwconfig eth0 retry 16"
+.br
+.I "   iwconfig eth0 retry lifetime 300m"
+.br
+.I "   iwconfig eth0 retry min limit 8"
 .\"
 .\" DISPLAY part
 .\"
 .\"
 .\" DISPLAY part
 .\"
@@ -345,7 +404,9 @@ Jean Tourrilhes \- jt@hpl.hp.com
 .SH SEE ALSO
 .BR ifconfig (8),
 .BR iwspy (8),
 .SH SEE ALSO
 .BR ifconfig (8),
 .BR iwspy (8),
+.BR iwlist (8),
 .BR iwpriv (8),
 .BR wavelan (4),
 .BR wavelan_cs (4),
 .BR iwpriv (8),
 .BR wavelan (4),
 .BR wavelan_cs (4),
-.BR xircnw_cs (4).
+.BR wvlan_cs (4),
+.BR netwave_cs (4).
index c65f92e..b70c049 100644 (file)
@@ -1,11 +1,13 @@
 /*
  *     Wireless Tools
  *
 /*
  *     Wireless Tools
  *
- *             Jean II - HPLB '99
+ *             Jean II - HPLB 97->99 - HPL 99->01
  *
  * Main code for "iwconfig". This is the generic tool for most
  * manipulations...
  * You need to link this code against "iwcommon.c" and "-lm".
  *
  * Main code for "iwconfig". This is the generic tool for most
  * manipulations...
  * You need to link this code against "iwcommon.c" and "-lm".
+ *
+ * This file is released under the GPL license.
  */
 
 #include "iwcommon.h"          /* Header */
  */
 
 #include "iwcommon.h"          /* Header */
@@ -37,6 +39,8 @@ iw_usage(void)
   fprintf(stderr, "                          [rts {N|auto|fixed|off}]\n");
   fprintf(stderr, "                          [frag {N|auto|fixed|off}]\n");
   fprintf(stderr, "                          [enc NNNN-NNNN]\n");
   fprintf(stderr, "                          [rts {N|auto|fixed|off}]\n");
   fprintf(stderr, "                          [frag {N|auto|fixed|off}]\n");
   fprintf(stderr, "                          [enc NNNN-NNNN]\n");
+  fprintf(stderr, "                          [power { period N|timeout N}]\n");
+  fprintf(stderr, "                          [txpower N {mW|dBm}]\n");
   exit(1);
 }
 
   exit(1);
 }
 
@@ -129,6 +133,10 @@ get_info(int                       skfd,
   else
     strcpy(info->name, wrq.u.name);
 
   else
     strcpy(info->name, wrq.u.name);
 
+  /* Get ranges */
+  if(get_range_info(skfd, ifname, &(info->range)) >= 0)
+    info->has_range = 1;
+
   /* Get network ID */
   strcpy(wrq.ifr_name, ifname);
   if(ioctl(skfd, SIOCGIWNWID, &wrq) >= 0)
   /* Get network ID */
   strcpy(wrq.ifr_name, ifname);
   if(ioctl(skfd, SIOCGIWNWID, &wrq) >= 0)
@@ -228,22 +236,39 @@ get_info(int                      skfd,
 
   /* Get Power Management settings */
   strcpy(wrq.ifr_name, ifname);
 
   /* Get Power Management settings */
   strcpy(wrq.ifr_name, ifname);
+  wrq.u.power.flags = 0;
   if(ioctl(skfd, SIOCGIWPOWER, &wrq) >= 0)
     {
       info->has_power = 1;
       memcpy(&(info->power), &(wrq.u.power), sizeof(iwparam));
     }
 
   if(ioctl(skfd, SIOCGIWPOWER, &wrq) >= 0)
     {
       info->has_power = 1;
       memcpy(&(info->power), &(wrq.u.power), sizeof(iwparam));
     }
 
+#if WIRELESS_EXT > 9
+  /* Get Transmit Power */
+  strcpy(wrq.ifr_name, ifname);
+  if(ioctl(skfd, SIOCGIWTXPOW, &wrq) >= 0)
+    {
+      info->has_txpower = 1;
+      memcpy(&(info->txpower), &(wrq.u.txpower), sizeof(iwparam));
+    }
+#endif
+
+#if WIRELESS_EXT > 10
+  /* Get retry limit/lifetime */
+  strcpy(wrq.ifr_name, ifname);
+  if(ioctl(skfd, SIOCGIWRETRY, &wrq) >= 0)
+    {
+      info->has_retry = 1;
+      memcpy(&(info->retry), &(wrq.u.retry), sizeof(iwparam));
+    }
+#endif /* WIRELESS_EXT > 10 */
+
   /* Get stats */
   if(iw_getstats(ifname, &(info->stats)) >= 0)
     {
       info->has_stats = 1;
     }
 
   /* Get stats */
   if(iw_getstats(ifname, &(info->stats)) >= 0)
     {
       info->has_stats = 1;
     }
 
-  /* Get ranges */
-  if(get_range_info(skfd, ifname, &(info->range)) >= 0)
-    info->has_range = 1;
-
   return(0);
 }
 
   return(0);
 }
 
@@ -256,6 +281,9 @@ static void
 display_info(struct wireless_info *    info,
             char *                     ifname)
 {
 display_info(struct wireless_info *    info,
             char *                     ifname)
 {
+  /* One token is more of less 5 character, 14 tokens per line */
+  int  tokens = 3;     /* For name */
+
   /* Display device name and wireless name (name of the protocol used) */
   printf("%-8.8s  %s  ", ifname, info->name);
 
   /* Display device name and wireless name (name of the protocol used) */
   printf("%-8.8s  %s  ", ifname, info->name);
 
@@ -263,7 +291,14 @@ display_info(struct wireless_info *        info,
   if(info->has_essid)
     {
       if(info->essid_on)
   if(info->has_essid)
     {
       if(info->essid_on)
-       printf("ESSID:\"%s\"  ", info->essid);
+       {
+         /* Does it have an ESSID index ? */
+         if((info->essid_on & IW_ENCODE_INDEX) > 1)
+           printf("ESSID:\"%s\" [%d]  ", info->essid,
+                  (info->essid_on & IW_ENCODE_INDEX));
+         else
+           printf("ESSID:\"%s\"  ", info->essid);
+       }
       else
        printf("ESSID:off  ");
     }
       else
        printf("ESSID:off  ");
     }
@@ -274,7 +309,10 @@ display_info(struct wireless_info *        info,
 
   /* Formatting */
   if(info->has_essid || info->has_nickname)
 
   /* Formatting */
   if(info->has_essid || info->has_nickname)
-    printf("\n          ");
+    {
+      printf("\n          ");
+      tokens = 0;
+    }
 
   /* Display Network ID */
   if(info->has_nwid)
 
   /* Display Network ID */
   if(info->has_nwid)
@@ -285,6 +323,14 @@ display_info(struct wireless_info *        info,
        printf("NWID:off/any  ");
       else
        printf("NWID:%X  ", info->nwid.value);
        printf("NWID:off/any  ");
       else
        printf("NWID:%X  ", info->nwid.value);
+      tokens +=2;
+    }
+
+  /* Display the current mode of operation */
+  if(info->has_mode)
+    {
+      printf("Mode:%s  ", operation_mode[info->mode]);
+      tokens +=3;
     }
 
   /* Display frequency / channel */
     }
 
   /* Display frequency / channel */
@@ -304,54 +350,39 @@ display_info(struct wireless_info *       info,
                printf("Frequency:%gkHz  ", info->freq / KILO);
            }
        }
                printf("Frequency:%gkHz  ", info->freq / KILO);
            }
        }
-    }
-
-  /* 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.value < 0)
-         printf("%d dBm  ", info->sens.value);
-       else
-         printf("%d/%d  ", info->sens.value, info->range.sensitivity);
-      else
-       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]);
+      tokens +=4;
     }
 
   /* Display the address of the current Access Point */
   if(info->has_ap_addr)
     {
       /* A bit of clever formatting */
     }
 
   /* Display the address of the current Access Point */
   if(info->has_ap_addr)
     {
       /* A bit of clever formatting */
-      if((info->has_nwid + 2*info->has_freq + 2*info->has_sens
-         + info->has_mode + !info->has_essid) > 3)
-       printf("\n          ");
+      if(tokens > 8)
+       {
+         printf("\n          ");
+         tokens = 0;
+       }
+      tokens +=6;
 
 
-      printf("Access Point: %s", pr_ether(info->ap_addr.sa_data));
+      /* Oups ! No Access Point in Ad-Hoc mode */
+      if((info->has_mode) && (info->mode == IW_MODE_ADHOC))
+       printf("Cell:");
+      else
+       printf("Access Point:");
+      printf(" %s", pr_ether(info->ap_addr.sa_data));
     }
 
     }
 
-  printf("\n          ");
-
   /* Display the currently used/set bit-rate */
   if(info->has_bitrate)
     {
   /* Display the currently used/set bit-rate */
   if(info->has_bitrate)
     {
+      /* A bit of clever formatting */
+      if(tokens > 11)
+       {
+         printf("\n          ");
+         tokens = 0;
+       }
+      tokens +=3;
+
       /* Fixed ? */
       if(info->bitrate.fixed)
        printf("Bit Rate=");
       /* Fixed ? */
       if(info->bitrate.fixed)
        printf("Bit Rate=");
@@ -368,6 +399,96 @@ display_info(struct wireless_info *        info,
       printf("   ");
     }
 
       printf("   ");
     }
 
+#if WIRELESS_EXT > 9
+  /* Display the Transmit Power */
+  if(info->has_txpower)
+    {
+      /* A bit of clever formatting */
+      if(tokens > 11)
+       {
+         printf("\n          ");
+         tokens = 0;
+       }
+      tokens +=3;
+
+      /* Disabled ? */
+      if(info->txpower.disabled)
+       printf("Tx-Power:off   ");
+      else
+       {
+         int           dbm;
+
+         /* Fixed ? */
+         if(info->txpower.fixed)
+           printf("Tx-Power=");
+         else
+           printf("Tx-Power:");
+
+         /* Convert everything to dBm */
+         if(info->txpower.flags & IW_TXPOW_MWATT)
+           dbm = mwatt2dbm(info->txpower.value);
+         else
+           dbm = info->txpower.value;
+
+         /* Display */
+         printf("%d dBm   ", dbm);
+       }
+    }
+#endif
+
+  /* Display sensitivity */
+  if(info->has_sens)
+    {
+      /* A bit of clever formatting */
+      if(tokens > 10)
+       {
+         printf("\n          ");
+         tokens = 0;
+       }
+      tokens +=4;
+
+      /* Fixed ? */
+      if(info->sens.fixed)
+       printf("Sensitivity=");
+      else
+       printf("Sensitivity:");
+
+      if(info->has_range)
+       /* Display in dBm ? */
+       if(info->sens.value < 0)
+         printf("%d dBm  ", info->sens.value);
+       else
+         printf("%d/%d  ", info->sens.value, info->range.sensitivity);
+      else
+       printf("%d  ", info->sens.value);
+    }
+
+  printf("\n          ");
+  tokens = 0;
+
+#if WIRELESS_EXT > 10
+  /* Display retry limit/lifetime information */
+  if(info->has_retry)
+    { 
+      printf("Retry");
+      /* Disabled ? */
+      if(info->retry.disabled)
+       printf(":off");
+      else
+       {
+         /* Let's check the value and its type */
+         if(info->retry.flags & IW_RETRY_TYPE)
+           print_retry_value(stdout, info->retry.value, info->retry.flags);
+
+         /* Let's check if nothing (simply on) */
+         if(info->retry.flags == IW_RETRY_ON)
+           printf(":on");
+       }
+      printf("   ");
+      tokens += 5;     /* Between 3 and 5, depend on flags */
+    }
+#endif /* WIRELESS_EXT > 10 */
+
   /* Display the RTS threshold */
   if(info->has_rts)
     {
   /* Display the RTS threshold */
   if(info->has_rts)
     {
@@ -384,14 +505,23 @@ display_info(struct wireless_info *       info,
 
          printf("%d B   ", info->rts.value);
        }
 
          printf("%d B   ", info->rts.value);
        }
+      tokens += 3;
     }
 
   /* Display the fragmentation threshold */
   if(info->has_frag)
     {
     }
 
   /* Display the fragmentation threshold */
   if(info->has_frag)
     {
+      /* A bit of clever formatting */
+      if(tokens > 10)
+       {
+         printf("\n          ");
+         tokens = 0;
+       }
+      tokens +=4;
+
       /* Disabled ? */
       if(info->frag.disabled)
       /* Disabled ? */
       if(info->frag.disabled)
-       printf("Fragment thr:off   ");
+       printf("Fragment thr:off");
       else
        {
          /* Fixed ? */
       else
        {
          /* Fixed ? */
@@ -405,11 +535,11 @@ display_info(struct wireless_info *       info,
     }
 
   /* Formating */
     }
 
   /* Formating */
-  if((info->has_bitrate) || (info->has_rts) || (info->has_bitrate))
+  if(tokens > 0)
     printf("\n          ");
 
   /* Display encryption information */
     printf("\n          ");
 
   /* Display encryption information */
-  /* Note : we display only the "current" key, use iwspy to list all keys */
+  /* Note : we display only the "current" key, use iwlist to list all keys */
   if(info->has_key)
     {
       printf("Encryption key:");
   if(info->has_key)
     {
       printf("Encryption key:");
@@ -417,15 +547,8 @@ display_info(struct wireless_info *        info,
        printf("off\n          ");
       else
        {
        printf("off\n          ");
       else
        {
-         int   i;
-
-         printf("%.2X", info->key[0]);
-         for(i = 1; i < info->key_size; i++)
-           {
-             if((i & 0x1) == 0)
-               printf("-");
-             printf("%.2X", info->key[i]);
-           }
+         /* Display the key */
+         print_key(stdout, info->key, info->key_size, info->key_flags);
 
          /* Other info... */
          if((info->key_flags & IW_ENCODE_INDEX) > 1)
 
          /* Other info... */
          if((info->key_flags & IW_ENCODE_INDEX) > 1)
@@ -440,7 +563,7 @@ display_info(struct wireless_info * info,
 
   /* Display Power Management information */
   /* Note : we display only one parameter, period or timeout. If a device
 
   /* 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... */
+   * (such as HiperLan) has both, the user need to use iwlist... */
   if(info->has_power)  /* I hope the device has power ;-) */
     { 
       printf("Power Management");
   if(info->has_power)  /* I hope the device has power ;-) */
     { 
       printf("Power Management");
@@ -451,43 +574,10 @@ display_info(struct wireless_info *       info,
        {
          /* Let's check the value and its type */
          if(info->power.flags & IW_POWER_TYPE)
        {
          /* 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);
-           }
+           print_pm_value(stdout, info->power.value, info->power.flags);
 
          /* Let's check the mode */
 
          /* 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:
-           }
+         print_pm_mode(stdout, info->power.flags);
 
          /* Let's check if nothing (simply on) */
          if(info->power.flags == IW_POWER_ON)
 
          /* Let's check if nothing (simply on) */
          if(info->power.flags == IW_POWER_ON)
@@ -496,27 +586,12 @@ display_info(struct wireless_info *       info,
        }
     }
 
        }
     }
 
+  /* Display statistics */
   if(info->has_stats)
     {
   if(info->has_stats)
     {
-      if(info->has_range && (info->stats.qual.level != 0))
-       /* If the statistics are in dBm */
-       if(info->stats.qual.level > info->range.max_qual.level)
-         printf("Link quality:%d/%d  Signal level:%d dBm  Noise level:%d dBm\n",
-                info->stats.qual.qual, info->range.max_qual.qual,
-                info->stats.qual.level - 0x100,
-                info->stats.qual.noise - 0x100);
-       else
-         /* Statistics are relative values (0 -> max) */
-         printf("Link quality:%d/%d  Signal level:%d/%d  Noise level:%d/%d\n",
-                info->stats.qual.qual, info->range.max_qual.qual,
-                info->stats.qual.level, info->range.max_qual.level,
-                info->stats.qual.noise, info->range.max_qual.noise);
-      else
-       /* We can't read the range, so we don't know... */
-       printf("Link quality:%d  Signal level:%d  Noise level:%d\n",
-              info->stats.qual.qual,
-              info->stats.qual.level,
-              info->stats.qual.noise);
+      info->stats.qual.updated = 0x0;  /* Not that reliable, disable */
+      printf("Link ");
+      print_stats(stdout, &info->stats.qual, &info->range, info->has_range);
 
       printf("          Rx invalid nwid:%d  invalid crypt:%d  invalid misc:%d\n",
             info->stats.discard.nwid,
 
       printf("          Rx invalid nwid:%d  invalid crypt:%d  invalid misc:%d\n",
             info->stats.discard.nwid,
@@ -837,8 +912,19 @@ set_info(int               skfd,           /* The socket */
                }
              else
                {
                }
              else
                {
+                 int           temp;
+
                  wrq.u.essid.flags = 1;
                  strcpy(essid, args[i]);
                  wrq.u.essid.flags = 1;
                  strcpy(essid, args[i]);
+
+                 /* 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;
+                   }
                }
 
          wrq.u.essid.pointer = (caddr_t) essid;
                }
 
          wrq.u.essid.pointer = (caddr_t) essid;
@@ -942,6 +1028,12 @@ set_info(int              skfd,           /* The socket */
                      wrq.u.bitrate.fixed = 0;
                      ++i;
                    }
                      wrq.u.bitrate.fixed = 0;
                      ++i;
                    }
+                 if(((i+1) < count) &&
+                    (!strcasecmp(args[i+1], "fixed")))
+                   {
+                     wrq.u.bitrate.fixed = 1;
+                     ++i;
+                   }
                }
            }
 
                }
            }
 
@@ -1076,7 +1168,7 @@ set_info(int              skfd,           /* The socket */
                /* Get old Power info */
                if(ioctl(skfd, SIOCGIWPOWER, &wrq) < 0)
                  {
                /* Get old Power info */
                if(ioctl(skfd, SIOCGIWPOWER, &wrq) < 0)
                  {
-                   fprintf(stderr, "SIOCGIWFRAG: %s\n", strerror(errno));
+                   fprintf(stderr, "SIOCGIWPOWER: %s\n", strerror(errno));
                    return(-1);
                  }
                strcpy(wrq.ifr_name, ifname);
                    return(-1);
                  }
                strcpy(wrq.ifr_name, ifname);
@@ -1091,16 +1183,31 @@ set_info(int            skfd,           /* The socket */
                wrq.u.power.disabled = 0;
 
                /* Check value modifier */
                wrq.u.power.disabled = 0;
 
                /* Check value modifier */
+               if(!strcasecmp(args[i], "min"))
+                 {
+                   wrq.u.power.flags |= IW_POWER_MIN;
+                   if(++i >= count)
+                     iw_usage();
+                 }
+               else
+                 if(!strcasecmp(args[i], "max"))
+                   {
+                     wrq.u.power.flags |= IW_POWER_MAX;
+                     if(++i >= count)
+                       iw_usage();
+                   }
+
+               /* Check value type */
                if(!strcasecmp(args[i], "period"))
                  {
                if(!strcasecmp(args[i], "period"))
                  {
-                   wrq.u.power.flags = IW_POWER_PERIOD;
+                   wrq.u.power.flags |= IW_POWER_PERIOD;
                    if(++i >= count)
                      iw_usage();
                  }
                else
                  if(!strcasecmp(args[i], "timeout"))
                    {
                    if(++i >= count)
                      iw_usage();
                  }
                else
                  if(!strcasecmp(args[i], "timeout"))
                    {
-                     wrq.u.power.flags = IW_POWER_TIMEOUT;
+                     wrq.u.power.flags |= IW_POWER_TIMEOUT;
                      if(++i >= count)
                        iw_usage();
                    }
                      if(++i >= count)
                        iw_usage();
                    }
@@ -1112,8 +1219,8 @@ set_info(int              skfd,           /* The socket */
                    if(index(args[i], 'u')) temp /= MEGA;
                    if(index(args[i], 'm')) temp /= KILO;
                    wrq.u.power.value = (long) temp;
                    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;
+                   if((wrq.u.power.flags & IW_POWER_TYPE) == 0)
+                     wrq.u.power.flags |= IW_POWER_PERIOD;
                    ++i;
                    gotone = 1;
                  }
                    ++i;
                    gotone = 1;
                  }
@@ -1151,6 +1258,166 @@ set_info(int            skfd,           /* The socket */
          continue;
        }
 
          continue;
        }
 
+#if WIRELESS_EXT > 9
+      /* ---------- Set Transmit-Power ---------- */
+      if(!strncmp(args[i], "txpower", 3))
+       {
+         struct iw_range       range;
+
+         if(++i >= count)
+           iw_usage();
+
+         /* Extract range info */
+         if(get_range_info(skfd, ifname, &range) < 0)
+           memset(&range, 0, sizeof(range));
+
+         /* Prepare the request */
+         strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
+         wrq.u.txpower.value = -1;
+         wrq.u.txpower.fixed = 1;
+         wrq.u.txpower.disabled = 0;
+         wrq.u.data.flags = IW_TXPOW_DBM;
+         if(!strcasecmp(args[i], "off"))
+           wrq.u.txpower.disabled = 1; /* i.e. turn radio off */
+         else
+           if(!strcasecmp(args[i], "auto"))
+             wrq.u.txpower.fixed = 0;  /* i.e. use power control */
+           else
+             {
+               if(!strcasecmp(args[i], "fixed"))
+                 {
+                   /* Get old tx-power */
+                   if(ioctl(skfd, SIOCGIWTXPOW, &wrq) < 0)
+                     {
+                       fprintf(stderr, "SIOCGIWTXPOW: %s\n", strerror(errno));
+                       return(-1);
+                     }
+                   strcpy(wrq.ifr_name, ifname);
+                   wrq.u.txpower.fixed = 1;
+                 }
+               else                    /* Should be a numeric value */
+                 {
+                   int         power;
+                   int         ismwatt = 0;
+
+                   /* Get the value */
+                   if(sscanf(args[i], "%ld",
+                             (unsigned long *) &(power)) != 1)
+                     iw_usage();
+
+                   /* Check if milliwatt */
+                   ismwatt = (index(args[i], 'm') != NULL);
+
+                   /* Convert */
+                   if(!ismwatt && (range.txpower_capa & IW_TXPOW_MWATT))
+                     {
+                       power = dbm2mwatt(power);
+                       wrq.u.data.flags = IW_TXPOW_MWATT;
+                     }
+                   if(ismwatt && !(range.txpower_capa & IW_TXPOW_MWATT))
+                     power = mwatt2dbm(power);
+                   wrq.u.bitrate.value = power;
+
+                   /* Check for an additional argument */
+                   if(((i+1) < count) &&
+                      (!strcasecmp(args[i+1], "auto")))
+                     {
+                       wrq.u.txpower.fixed = 0;
+                       ++i;
+                     }
+                   if(((i+1) < count) &&
+                      (!strcasecmp(args[i+1], "fixed")))
+                     {
+                       wrq.u.txpower.fixed = 1;
+                       ++i;
+                     }
+                 }
+             }
+
+         if(ioctl(skfd, SIOCSIWTXPOW, &wrq) < 0)
+           {
+             fprintf(stderr, "SIOCSIWTXPOW: %s\n", strerror(errno));
+             return(-1);
+           }
+         continue;
+       }
+#endif
+
+#if WIRELESS_EXT > 10
+      /* ---------- Set Power Management ---------- */
+      if(!strncmp(args[i], "retry", 3))
+       {
+         double                temp;
+         int           gotone = 0;
+
+         if(++i >= count)
+           iw_usage();
+
+         /* Default - nope */
+         wrq.u.retry.flags = IW_RETRY_LIMIT;
+         wrq.u.retry.disabled = 0;
+
+         /* Check value modifier */
+         if(!strcasecmp(args[i], "min"))
+           {
+             wrq.u.retry.flags |= IW_RETRY_MIN;
+             if(++i >= count)
+               iw_usage();
+           }
+         else
+           if(!strcasecmp(args[i], "max"))
+             {
+               wrq.u.retry.flags |= IW_RETRY_MAX;
+               if(++i >= count)
+                 iw_usage();
+             }
+
+         /* Check value type */
+         if(!strcasecmp(args[i], "limit"))
+           {
+             wrq.u.retry.flags |= IW_RETRY_LIMIT;
+             if(++i >= count)
+               iw_usage();
+           }
+         else
+           if(!strncasecmp(args[i], "lifetime", 4))
+             {
+               wrq.u.retry.flags |= IW_RETRY_LIFETIME;
+               if(++i >= count)
+                 iw_usage();
+             }
+
+         /* Is there any value to grab ? */
+         if(sscanf(args[i], "%lg", &(temp)) == 1)
+           {
+             /* Limit is absolute, on the other hand lifetime is seconds */
+             if(!(wrq.u.retry.flags & IW_RETRY_LIMIT))
+               {
+                 /* Normalise lifetime */
+                 temp *= MEGA; /* default = s */
+                 if(index(args[i], 'u')) temp /= MEGA;
+                 if(index(args[i], 'm')) temp /= KILO;
+               }
+             wrq.u.retry.value = (long) temp;
+             ++i;
+             gotone = 1;
+           }
+
+         if(!gotone)
+           iw_usage();
+         --i;
+
+         if(ioctl(skfd, SIOCSIWRETRY, &wrq) < 0)
+           {
+             fprintf(stderr, "SIOCSIWRETRY(%d): %s\n",
+                     errno, strerror(errno));
+             return(-1);
+           }
+         continue;
+       }
+
+#endif /* WIRELESS_EXT > 10 */
+
       /* ---------- Other ---------- */
       /* Here we have an unrecognised arg... */
       fprintf(stderr, "Invalid argument : %s\n", args[i]);
       /* ---------- Other ---------- */
       /* Here we have an unrecognised arg... */
       fprintf(stderr, "Invalid argument : %s\n", args[i]);
@@ -1213,5 +1480,3 @@ main(int  argc,
 
   return(goterr);
 }
 
   return(goterr);
 }
-
-
diff --git a/wireless_tools/iwgetid.c b/wireless_tools/iwgetid.c
new file mode 100644 (file)
index 0000000..ef3ea8d
--- /dev/null
@@ -0,0 +1,384 @@
+/*
+ *     Wireless Tools
+ *
+ *             Jean II - HPL '01
+ *
+ * Just print the ESSID or NWID...
+ *
+ * This file is released under the GPL license.
+ */
+
+#include "iwcommon.h"          /* Header */
+
+#define FORMAT_DEFAULT 0       /* Nice looking display for the user */
+#define FORMAT_SCHEME  1       /* To be used as a Pcmcia Scheme */
+
+/*
+ * Note on Pcmcia Schemes :
+ * ----------------------
+ *     The purpose of this tool is to use the ESSID discovery mechanism
+ * to select the appropriate Pcmcia Scheme. The card tell us which
+ * ESSID it has found, and we can then select the appropriate Pcmcia
+ * Scheme for this ESSID (Wireless config (encrypt keys) and IP config).
+ *     The way to do it is as follows :
+ *                     cardctl scheme "essidany"
+ *                     delay 100
+ *                     $scheme = iwgetid --scheme
+ *                     cardctl scheme $scheme
+ *     Of course, you need to add a scheme called "essidany" with the
+ * following setting :
+ *                     essidany,*,*,*)
+ *                             ESSID="any"
+ *                             IPADDR="10.0.0.1"
+ *
+ *     This can also be integrated int he Pcmcia scripts.
+ *     Some drivers don't activate the card up to "ifconfig up".
+ * Therefore, they wont scan ESSID up to this point, so we can't
+ * read it reliably in Pcmcia scripts.
+ *     I guess the proper way to write the network script is as follows :
+ *                     if($scheme == "iwgetid") {
+ *                             iwconfig $name essid any
+ *                             iwconfig $name nwid any
+ *                             ifconfig $name up
+ *                             delay 100
+ *                             $scheme = iwgetid $name --scheme
+ *                             ifconfig $name down
+ *                     }
+ *
+ *     This is pseudo code, but you get an idea...
+ *     The "ifconfig up" activate the card.
+ *     The "delay" is necessary to let time for the card scan the
+ * frequencies and associate with the AP.
+ *     The "ifconfig down" is necessary to allow the driver to optimise
+ * the wireless parameters setting (minimise number of card resets).
+ *
+ *     Another cute idea is to have a list of Pcmcia Schemes to try
+ * and to keep the first one that associate (AP address != 0). This
+ * would be necessary for closed networks and cards that can't
+ * discover essid...
+ *
+ * Jean II - 29/3/01
+ */
+
+/************************ DISPLAY ESSID/NWID ************************/
+
+/*------------------------------------------------------------------*/
+/*
+ * Display the ESSID if possible
+ */
+static int
+print_essid(int                skfd,
+           char *      ifname,
+           int         format)
+{
+  struct iwreq         wrq;
+  char                 essid[IW_ESSID_MAX_SIZE + 1];   /* ESSID */
+  char                 pessid[IW_ESSID_MAX_SIZE + 1];  /* Pcmcia format */
+  int          i;
+  int          j;
+
+  /* Get ESSID */
+  strcpy(wrq.ifr_name, ifname);
+  wrq.u.essid.pointer = (caddr_t) essid;
+  wrq.u.essid.length = 0;
+  wrq.u.essid.flags = 0;
+  if(ioctl(skfd, SIOCGIWESSID, &wrq) < 0)
+    return(-1);
+
+  switch(format)
+    {
+    case FORMAT_SCHEME:
+      /* Stip all white space and stuff */
+      j = 0;
+      for(i = 0; i < strlen(essid); i++)
+       if(isalnum(essid[i]))
+         pessid[j++] = essid[i];
+      pessid[j] = '\0';
+      if((j == 0) || (j > 32))
+       return(-2);
+      printf("%s\n", pessid);
+      fflush(stdout);
+      break;
+    default:
+      printf("%-8.8s  ESSID:\"%s\"\n", ifname, essid);
+      break;
+    }
+
+  return(0);
+}
+
+/*------------------------------------------------------------------*/
+/*
+ * Display the NWID if possible
+ */
+static int
+print_nwid(int         skfd,
+          char *       ifname,
+          int          format)
+{
+  struct iwreq         wrq;
+
+  /* Get network ID */
+  strcpy(wrq.ifr_name, ifname);
+  if(ioctl(skfd, SIOCGIWNWID, &wrq) < 0)
+    return(-1);
+
+  switch(format)
+    {
+    case FORMAT_SCHEME:
+      /* Prefix with nwid to avoid name space collisions */
+      printf("nwid%X\n", wrq.u.nwid.value);
+      fflush(stdout);
+      break;
+    default:
+      printf("%-8.8s  NWID:%X\n", ifname, wrq.u.nwid.value);
+      break;
+    }
+
+  return(0);
+}
+
+/*------------------------------------------------------------------*/
+/*
+ * Try the various devices until one return something we can use
+ */
+static int
+scan_devices(int               skfd,
+            int                format)
+{
+  char         buff[1024];
+  struct ifconf ifc;
+  struct ifreq *ifr;
+  int          i;
+  int          ret;
+
+  /* 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(-1);
+    }
+  ifr = ifc.ifc_req;
+
+  /* Print the first match */
+  for(i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++)
+    {
+      /* Try to print an ESSID */
+      ret = print_essid(skfd, ifr->ifr_name, format);
+      if(ret == 0)
+       return(0);      /* Success */
+
+      /* Try to print a nwid */
+      ret = print_nwid(skfd, ifr->ifr_name, format);
+      if(ret == 0)
+       return(0);      /* Success */
+    }
+  return(-1);
+}
+
+/*************************** SUBROUTINES ***************************/
+
+/*------------------------------------------------------------------*/
+/*
+ * Display an Ethernet address in readable format.
+ */
+char *
+pr_ether(unsigned char *ptr)
+{
+  static char buff[64];
+
+  sprintf(buff, "%02X:%02X:%02X:%02X:%02X:%02X",
+       (ptr[0] & 0xFF), (ptr[1] & 0xFF), (ptr[2] & 0xFF),
+       (ptr[3] & 0xFF), (ptr[4] & 0xFF), (ptr[5] & 0xFF)
+  );
+  return(buff);
+}
+
+/*------------------------------------------------------------------*/
+/*
+ * Open a socket.
+ * Depending on the protocol present, open the right socket. The socket
+ * will allow us to talk to the driver.
+ */
+int
+sockets_open(void)
+{
+       int ipx_sock = -1;              /* IPX socket                   */
+       int ax25_sock = -1;             /* AX.25 socket                 */
+       int inet_sock = -1;             /* INET socket                  */
+       int ddp_sock = -1;              /* Appletalk DDP socket         */
+
+       inet_sock=socket(AF_INET, SOCK_DGRAM, 0);
+       ipx_sock=socket(AF_IPX, SOCK_DGRAM, 0);
+       ax25_sock=socket(AF_AX25, SOCK_DGRAM, 0);
+       ddp_sock=socket(AF_APPLETALK, SOCK_DGRAM, 0);
+       /*
+        * Now pick any (exisiting) useful socket family for generic queries
+        */
+       if(inet_sock!=-1)
+               return inet_sock;
+       if(ipx_sock!=-1)
+               return ipx_sock;
+       if(ax25_sock!=-1)
+               return ax25_sock;
+       /*
+        * If this is -1 we have no known network layers and its time to jump.
+        */
+        
+       return ddp_sock;
+}
+
+/**************************** AP ADDRESS ****************************/
+
+/*------------------------------------------------------------------*/
+/*
+ * Display the NWID if possible
+ */
+static int
+print_ap(int           skfd,
+        char *         ifname,
+        int            format)
+{
+  struct iwreq         wrq;
+
+  /* Get network ID */
+  strcpy(wrq.ifr_name, ifname);
+  if(ioctl(skfd, SIOCGIWAP, &wrq) < 0)
+    return(-1);
+
+  /* Print */
+  printf("%-8.8s  Access Point: %s\n", ifname,
+        pr_ether(wrq.u.ap_addr.sa_data));
+
+  return(0);
+}
+
+/*------------------------------------------------------------------*/
+/*
+ * Try the various devices until one return something we can use
+ */
+static inline int
+scan_ap(int            skfd,
+       int             format)
+{
+  char         buff[1024];
+  struct ifconf ifc;
+  struct ifreq *ifr;
+  int          i;
+  int          ret;
+
+  /* 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(-1);
+    }
+  ifr = ifc.ifc_req;
+
+  /* Print the first match */
+  for(i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++)
+    {
+      /* Try to print an ESSID */
+      ret = print_ap(skfd, ifr->ifr_name, format);
+      if(ret == 0)
+       return(0);      /* Success */
+    }
+  return(-1);
+}
+
+/******************************* MAIN ********************************/
+
+/*------------------------------------------------------------------*/
+/*
+ * The main !
+ */
+int
+main(int       argc,
+     char **   argv)
+{
+  int  skfd = -1;              /* generic raw socket desc.     */
+  int  format = FORMAT_DEFAULT;
+  int  ret = -1;
+
+  /* Create a channel to the NET kernel. */
+  if((skfd = sockets_open()) < 0)
+    {
+      perror("socket");
+      return(-1);
+    }
+
+  /* No argument */
+  if(argc == 1)
+    {
+      /* Look on all devices */
+      ret = scan_devices(skfd, format);
+      close(skfd);
+      return(ret);
+    }
+
+  /* Only ask for first AP address */
+  if((!strcmp(argv[1], "--ap")) || (!strcmp(argv[1], "-a")))
+    {
+      /* Look on all devices */
+      ret = scan_ap(skfd, format);
+      close(skfd);
+      return(ret);
+    }
+
+  /* Only the format, no interface name */
+  if((!strncmp(argv[1], "--scheme", 4)) || (!strcmp(argv[1], "-s")))
+    {
+      /* Look on all devices */
+      format = FORMAT_SCHEME;
+      ret = scan_devices(skfd, format);
+      close(skfd);
+      return(ret);
+    }
+
+  /* Help */
+  if((argc > 3) ||
+     (!strncmp(argv[1], "-h", 9)) || (!strcmp(argv[1], "--help")))
+    {
+      fprintf(stderr, "Usage: iwgetid [interface]\n");
+      fprintf(stderr, "               [interface] --scheme\n");
+      return(-1);
+    }
+
+  /* If at least a device name */
+  if(argc > 1)
+    {
+      /* Check extra format argument */
+      if(argc > 2)
+       {
+         /* Only ask for first AP address */
+         if((!strcmp(argv[2], "--ap")) || (!strcmp(argv[2], "-a")))
+           {
+             ret = print_ap(skfd, argv[1], format);
+             close(skfd);
+             return(ret);
+           }
+
+         /* Want scheme format */
+         if((!strncmp(argv[2], "--scheme", 4)) || (!strcmp(argv[2], "-s")))
+           format = FORMAT_SCHEME;
+       }
+
+      /* Try to print an ESSID */
+      ret = print_essid(skfd, argv[1], format);
+
+      if(ret == -1)
+       {
+         /* Try to print a nwid */
+         ret = print_nwid(skfd, argv[1], format);
+       }
+    }
+
+  /* Close the socket. */
+  close(skfd);
+
+  return(ret);
+}
diff --git a/wireless_tools/iwlist.8 b/wireless_tools/iwlist.8
new file mode 100644 (file)
index 0000000..f362bae
--- /dev/null
@@ -0,0 +1,79 @@
+.\" Jean II - HPLB - 96
+.\" iwlist.8
+.\"
+.TH IWLIST 8 "31 October 1996" "net-tools" "Linux Programmer's Manual"
+.\"
+.\" NAME part
+.\"
+.SH NAME
+iwlist \- Get wireless statistics from specific nodes
+.\"
+.\" SYNOPSIS part
+.\"
+.SH SYNOPSIS
+.BI "iwlist " interface " freq"
+.br
+.BI "iwlist " interface " ap"
+.br
+.BI "iwlist " interface " rate"
+.br
+.BI "iwlist " interface " keys"
+.br
+.BI "iwlist " interface " power"
+.br
+.BI "iwlist " interface " txpower"
+.br
+.BI "iwlist " interface " retry"
+.\"
+.\" DESCRIPTION part
+.\"
+.SH DESCRIPTION
+.B Iwlist
+is used to display some large chunk of information from a wireless
+network interface that is not displayed by iwconfig. This is typically
+list of parameters.
+.\"
+.\" PARAMETER part
+.\"
+.SH PARAMETERS
+.TP
+.B freq
+Give the list of available frequencies in the device and the number of
+defined channels. Please note that usually the driver returns the
+total number of channels and only the frequencies available in the
+present locale, so there is no one to one mapping between frequencies
+displayed and channel numbers.
+.TP
+.B ap
+Give the list of Access Points in range, and optionally the quality of
+link to them.
+.TP
+.BR rate / bit [rate]
+List the bit-rates supported by the device.
+.TP
+.BR keys / enc [ryption]
+List the encryption key sizes supported and display all the encryption
+keys availables in the device.
+.TP
+.B power
+List the various Power Management attributes and modes of the device.
+.TP
+.B txpower
+List the various Transmit Power available on the device.
+.TP
+.B retry
+List the transmit retry limits and retry lifetime on the device.
+.\"
+.\" FILES part
+.\"
+.SH FILES
+.I /proc/net/wireless
+.\"
+.\" SEE ALSO part
+.\"
+.SH SEE ALSO
+.BR iwconfig (8),
+.BR ifconfig (8),
+.BR iwspy (8).
+.BR iwpriv (8).
+
diff --git a/wireless_tools/iwlist.c b/wireless_tools/iwlist.c
new file mode 100644 (file)
index 0000000..b8284af
--- /dev/null
@@ -0,0 +1,951 @@
+/*
+ *     Wireless Tools
+ *
+ *             Jean II - HPLB '99 - HPL 99->01
+ *
+ * This tool can access various piece of information on the card
+ * not part of iwconfig...
+ * You need to link this code against "iwcommon.c" and "-lm".
+ *
+ * This file is released under the GPL license.
+ */
+
+#include "iwcommon.h"          /* Header */
+
+/*********************** FREQUENCIES/CHANNELS ***********************/
+
+/*------------------------------------------------------------------*/
+/*
+ * Print the number of channels and available frequency for the device
+ */
+static void
+print_freq_info(int            skfd,
+               char *          ifname)
+{
+  float                        freq;
+  struct iw_range      range;
+  int                  k;
+
+  if(get_range_info(skfd, ifname, &range) < 0)
+      fprintf(stderr, "%-8.8s  no frequency information.\n\n",
+                     ifname);
+  else
+    {
+      if(range.num_frequency > 0)
+       {
+         printf("%-8.8s  %d channels in total; available frequencies :\n",
+                ifname, range.num_channels);
+         /* Print them all */
+         for(k = 0; k < range.num_frequency; k++)
+           {
+             printf("\t  Channel %.2d : ", range.freq[k].i);
+             freq = freq2float(&(range.freq[k]));
+             if(freq >= GIGA)
+               printf("%g GHz\n", freq / GIGA);
+             else
+               if(freq >= MEGA)
+                 printf("%g MHz\n", freq / MEGA);
+               else
+                 printf("%g kHz\n", freq / KILO);
+           }
+         printf("\n\n");
+       }
+      else
+       printf("%-8.8s  %d channels\n\n",
+              ifname, range.num_channels);
+    }
+}
+
+/*------------------------------------------------------------------*/
+/*
+ * Get frequency info on all devices and print it on the screen
+ */
+static void
+print_freq_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_freq_info(skfd, ifr->ifr_name);
+}
+
+/************************ ACCESS POINT LIST ************************/
+
+/*------------------------------------------------------------------*/
+/*
+ * Display the list of ap addresses and the associated stats
+ * Exacly the same as the spy list, only with different IOCTL and messages
+ */
+static void
+print_ap_info(int      skfd,
+              char *   ifname)
+{
+  struct iwreq         wrq;
+  char         buffer[(sizeof(struct iw_quality) +
+                       sizeof(struct sockaddr)) * IW_MAX_AP];
+  struct sockaddr *    hwa;
+  struct iw_quality *  qual;
+  iwrange      range;
+  int          has_range = 0;
+  int          has_qual = 0;
+  int          n;
+  int          i;
+
+  /* Collect stats */
+  strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
+  wrq.u.data.pointer = (caddr_t) buffer;
+  wrq.u.data.length = 0;
+  wrq.u.data.flags = 0;
+  if(ioctl(skfd, SIOCGIWAPLIST, &wrq) < 0)
+    {
+      fprintf(stderr, "%-8.8s  Interface doesn't have a list of Access Points\n\n", ifname);
+      return;
+    }
+
+  /* Number of addresses */
+  n = wrq.u.data.length;
+  has_qual = wrq.u.data.flags;
+
+  /* The two lists */
+  hwa = (struct sockaddr *) buffer;
+  qual = (struct iw_quality *) (buffer + (sizeof(struct sockaddr) * n));
+
+  /* Check if we have valid address types */
+  if(check_addr_type(skfd, ifname) < 0)
+    {
+      fprintf(stderr, "%-8.8s  Interface doesn't support MAC & IP addresses\n\n", ifname);
+      return;
+    }
+
+  /* Get range info if we can */
+  if(get_range_info(skfd, ifname, &(range)) >= 0)
+    has_range = 1;
+
+  /* Display it */
+  if(n == 0)
+    printf("%-8.8s  No Access Point in range\n", ifname);
+  else
+    printf("%-8.8s  Access Points in range:\n", ifname);
+  for(i = 0; i < n; i++)
+    {
+      if(has_qual)
+       {
+         /* Print stats for this address */
+         printf("    %s : ", pr_ether(hwa[i].sa_data));
+         print_stats(stdout, &qual[i], &range, has_range);
+       }
+      else
+       /* Only print the address */
+       printf("    %s\n", pr_ether(hwa[i].sa_data));
+    }
+  printf("\n");
+}
+
+/*------------------------------------------------------------------*/
+/*
+ * Get list of AP on all devices and print it on the screen
+ */
+static void
+print_ap_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_ap_info(skfd, ifr->ifr_name);
+}
+
+/***************************** BITRATES *****************************/
+
+/*------------------------------------------------------------------*/
+/*
+ * Print the number of available bitrates for the device
+ */
+static void
+print_bitrate_info(int         skfd,
+                  char *       ifname)
+{
+  float                        bitrate;
+  struct iw_range      range;
+  int                  k;
+
+  /* Extract range info */
+  if(get_range_info(skfd, ifname, &range) < 0)
+      fprintf(stderr, "%-8.8s  no bit-rate information.\n\n",
+                     ifname);
+  else
+    {
+      if((range.num_bitrates > 0) && (range.num_bitrates < IW_MAX_BITRATES))
+       {
+         printf("%-8.8s  %d available bit-rates :\n",
+                ifname, range.num_bitrates);
+         /* Print them all */
+         for(k = 0; k < range.num_bitrates; k++)
+           {
+             printf("\t  ");
+             bitrate = range.bitrate[k];
+             if(bitrate >= GIGA)
+               printf("%g Gb/s\n", bitrate / GIGA);
+             else
+               if(bitrate >= MEGA)
+                 printf("%g Mb/s\n", bitrate / MEGA);
+               else
+                 printf("%g kb/s\n", bitrate / KILO);
+           }
+         printf("\n\n");
+       }
+      else
+       printf("%-8.8s  No bit-rates ? Please update driver...\n\n", ifname);
+    }
+}
+
+/*------------------------------------------------------------------*/
+/*
+ * Get bit-rate info on all devices and print it on the screen
+ */
+static void
+print_bitrate_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_bitrate_info(skfd, ifr->ifr_name);
+}
+
+/************************* ENCRYPTION KEYS *************************/
+
+/*------------------------------------------------------------------*/
+/*
+ * Print the number of available encryption key 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;
+
+  /* Extract range info */
+  if(get_range_info(skfd, ifname, &range) < 0)
+      fprintf(stderr, "%-8.8s  no encryption keys information.\n\n",
+                     ifname);
+  else
+    {
+      printf("%-8.8s  ", ifname);
+      /* Print key sizes */
+      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          ");
+       }
+      /* Print the keys and associate mode */
+      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
+           {
+             /* Display the key */
+             printf("\t\t[%d]: ", k);
+             print_key(stdout, key, wrq.u.data.length, wrq.u.data.flags);
+
+             /* Other info... */
+             printf(" (%d bits)", wrq.u.data.length * 8);
+             printf("\n");
+           }
+       }
+      /* Print current key and mode */
+      strcpy(wrq.ifr_name, ifname);
+      wrq.u.data.pointer = (caddr_t) key;
+      wrq.u.data.length = 0;
+      wrq.u.data.flags = 0;    /* Set index to zero to get current */
+      if(ioctl(skfd, SIOCGIWENCODE, &wrq) < 0)
+       {
+         fprintf(stderr, "SIOCGIWENCODE: %s\n", strerror(errno));
+         return;
+       }
+      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");
+      if(wrq.u.data.flags & IW_ENCODE_OPEN)
+       printf("          Encryption mode:open\n");
+
+      printf("\n\n");
+    }
+}
+
+/*------------------------------------------------------------------*/
+/*
+ * Get encryption 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);
+}
+
+/************************* POWER MANAGEMENT *************************/
+
+/*------------------------------------------------------------------*/
+/*
+ * Print Power Management info for each device
+ */
+static inline int
+get_pm_value(int               skfd,
+            char *             ifname,
+            struct iwreq *     pwrq,
+            int                flags)
+{
+  /* Get Another Power Management value */
+  strcpy(pwrq->ifr_name, ifname);
+  pwrq->u.power.flags = flags;
+  if(ioctl(skfd, SIOCGIWPOWER, pwrq) >= 0)
+    {
+      /* Let's check the value and its type */
+      if(pwrq->u.power.flags & IW_POWER_TYPE)
+       {
+         printf("\n                 ");
+         print_pm_value(stdout, pwrq->u.power.value, pwrq->u.power.flags);
+       }
+    }
+  return(pwrq->u.power.flags);
+}
+
+/*------------------------------------------------------------------*/
+/*
+ * Print Power Management info for each device
+ */
+static void
+print_pm_info(int              skfd,
+             char *            ifname)
+{
+  struct iwreq         wrq;
+  struct iw_range      range;
+
+  /* Extract range info */
+  if(get_range_info(skfd, ifname, &range) < 0)
+      fprintf(stderr, "%-8.8s  no power management information.\n\n",
+                     ifname);
+  else
+    {
+      printf("%-8.8s  ", ifname);
+#if WIRELESS_EXT > 9
+      /* Display modes availables */
+      if(range.pm_capa & IW_POWER_MODE)
+       {
+         printf("Supported modes :\n          ");
+         if(range.pm_capa & (IW_POWER_UNICAST_R | IW_POWER_MULTICAST_R))
+           printf("\t\to Receive all packets (unicast & multicast)\n          ");
+         if(range.pm_capa & IW_POWER_UNICAST_R)
+           printf("\t\to Receive Unicast only (discard multicast)\n          ");
+         if(range.pm_capa & IW_POWER_MULTICAST_R)
+           printf("\t\to Receive Multicast only (discard unicast)\n          ");
+         if(range.pm_capa & IW_POWER_FORCE_S)
+           printf("\t\to Force sending using Power Management\n          ");
+         if(range.pm_capa & IW_POWER_REPEATER)
+           printf("\t\to Repeat multicast\n          ");
+       }
+      /* Display min/max period availables */
+      if(range.pmp_flags & IW_POWER_PERIOD)
+       {
+         int   flags = (range.pmp_flags & ~(IW_POWER_MIN | IW_POWER_MAX));
+         /* Display if auto or fixed */
+         if(range.pmp_flags & IW_POWER_MIN)
+           printf("Auto  period  ; ");
+         else
+           printf("Fixed period  ; ");
+         /* Print the range */
+         print_pm_value(stdout, range.min_pmp, flags | IW_POWER_MIN);
+         printf("\n                          ");
+         print_pm_value(stdout, range.max_pmp, flags | IW_POWER_MAX);
+         printf("\n          ");
+         
+       }
+      /* Display min/max timeout availables */
+      if(range.pmt_flags & IW_POWER_TIMEOUT)
+       {
+         int   flags = (range.pmt_flags & ~(IW_POWER_MIN | IW_POWER_MAX));
+         /* Display if auto or fixed */
+         if(range.pmt_flags & IW_POWER_MIN)
+           printf("Auto  timeout ; ");
+         else
+           printf("Fixed timeout ; ");
+         /* Print the range */
+         print_pm_value(stdout, range.min_pmt, flags | IW_POWER_MIN);
+         printf("\n                          ");
+         print_pm_value(stdout, range.max_pmt, flags | IW_POWER_MAX);
+         printf("\n          ");
+         
+       }
+#endif /* WIRELESS_EXT > 9 */
+
+      /* Get current Power Management settings */
+      strcpy(wrq.ifr_name, ifname);
+      wrq.u.power.flags = 0;
+      if(ioctl(skfd, SIOCGIWPOWER, &wrq) >= 0)
+       {
+         int   flags = wrq.u.power.flags;
+
+         /* Is it disabled ? */
+         if(wrq.u.power.disabled)
+           printf("Current mode:off\n          ");
+         else
+           {
+             int       pm_mask = 0;
+
+             /* Let's check the mode */
+             printf("Current");
+             print_pm_mode(stdout, flags);
+
+             /* Let's check if nothing (simply on) */
+             if((flags & IW_POWER_MODE) == IW_POWER_ON)
+               printf(" mode:on");
+             printf("\n                 ");
+
+             /* Let's check the value and its type */
+             if(wrq.u.power.flags & IW_POWER_TYPE)
+               print_pm_value(stdout, wrq.u.power.value, wrq.u.power.flags);
+
+             /* If we have been returned a MIN value, ask for the MAX */
+             if(flags & IW_POWER_MIN)
+               pm_mask = IW_POWER_MAX;
+             /* If we have been returned a MAX value, ask for the MIN */
+             if(flags & IW_POWER_MAX)
+               pm_mask = IW_POWER_MIN;
+             /* If we have something to ask for... */
+             if(pm_mask)
+               get_pm_value(skfd, ifname, &wrq, pm_mask);
+
+#if WIRELESS_EXT > 9
+             /* And if we have both a period and a timeout, ask the other */
+             pm_mask = (range.pm_capa & (~(wrq.u.power.flags) &
+                                         IW_POWER_TYPE));
+             if(pm_mask)
+               {
+                 int   base_mask = pm_mask;
+                 flags = get_pm_value(skfd, ifname, &wrq, pm_mask);
+                 pm_mask = 0;
+
+                 /* If we have been returned a MIN value, ask for the MAX */
+                 if(flags & IW_POWER_MIN)
+                   pm_mask = IW_POWER_MAX | base_mask;
+                 /* If we have been returned a MAX value, ask for the MIN */
+                 if(flags & IW_POWER_MAX)
+                   pm_mask = IW_POWER_MIN | base_mask;
+                 /* If we have something to ask for... */
+                 if(pm_mask)
+                   get_pm_value(skfd, ifname, &wrq, pm_mask);
+               }
+#endif /* WIRELESS_EXT > 9 */
+           }
+       }
+      printf("\n");
+    }
+}
+
+/*------------------------------------------------------------------*/
+/*
+ * Get Power Management info on all devices and print it on the screen
+ */
+static void
+print_pm_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_pm_info(skfd, ifr->ifr_name);
+}
+
+/************************** TRANSMIT POWER **************************/
+
+/*------------------------------------------------------------------*/
+/*
+ * Print the number of available transmit powers for the device
+ */
+static void
+print_txpower_info(int         skfd,
+                  char *       ifname)
+{
+  struct iw_range      range;
+  int                  dbm;
+  int                  mwatt;
+  int                  k;
+
+#if WIRELESS_EXT > 9
+  /* Extract range info */
+  if(get_range_info(skfd, ifname, &range) < 0)
+      fprintf(stderr, "%-8.8s  no transmit-power information.\n\n",
+                     ifname);
+  else
+    {
+      if((range.num_txpower > 0) && (range.num_txpower < IW_MAX_TXPOWER))
+       {
+         printf("%-8.8s  %d available transmit-powers :\n",
+                ifname, range.num_txpower);
+         /* Print them all */
+         for(k = 0; k < range.num_txpower; k++)
+           {
+             if(range.txpower_capa & IW_TXPOW_MWATT)
+               {
+                 dbm = mwatt2dbm(range.txpower[k]);
+                 mwatt = range.txpower[k];
+               }
+             else
+               {
+                 dbm = range.txpower[k];
+                 mwatt = dbm2mwatt(range.txpower[k]);
+               }
+             printf("\t  %d dBm  \t(%d mW)\n", dbm, mwatt);
+           }
+         printf("\n\n");
+       }
+      else
+       printf("%-8.8s  No transmit-powers ? Please update driver...\n\n", ifname);
+    }
+#endif /* WIRELESS_EXT > 9 */
+}
+
+/*------------------------------------------------------------------*/
+/*
+ * Get tx-power info on all devices and print it on the screen
+ */
+static void
+print_txpower_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_txpower_info(skfd, ifr->ifr_name);
+}
+
+/*********************** RETRY LIMIT/LIFETIME ***********************/
+
+#if WIRELESS_EXT > 10
+/*------------------------------------------------------------------*/
+/*
+ * Print one retry value
+ */
+static inline int
+get_retry_value(int            skfd,
+               char *          ifname,
+               struct iwreq *  pwrq,
+               int             flags)
+{
+  /* Get Another retry value */
+  strcpy(pwrq->ifr_name, ifname);
+  pwrq->u.retry.flags = flags;
+  if(ioctl(skfd, SIOCGIWRETRY, pwrq) >= 0)
+    {
+      /* Let's check the value and its type */
+      if(pwrq->u.retry.flags & IW_RETRY_TYPE)
+       {
+         printf("\n                 ");
+         print_retry_value(stdout, pwrq->u.retry.value, pwrq->u.retry.flags);
+       }
+    }
+  return(pwrq->u.retry.flags);
+}
+
+/*------------------------------------------------------------------*/
+/*
+ * Print Retry info for each device
+ */
+static void
+print_retry_info(int           skfd,
+             char *            ifname)
+{
+  struct iwreq         wrq;
+  struct iw_range      range;
+
+  /* Extract range info */
+  if(get_range_info(skfd, ifname, &range) < 0)
+      fprintf(stderr, "%-8.8s  no retry limit/lifetime information.\n\n",
+             ifname);
+  else
+    {
+      printf("%-8.8s  ", ifname);
+
+      /* Display min/max limit availables */
+      if(range.retry_flags & IW_RETRY_LIMIT)
+       {
+         int   flags = (range.retry_flags & ~(IW_RETRY_MIN | IW_RETRY_MAX));
+         /* Display if auto or fixed */
+         if(range.retry_flags & IW_RETRY_MIN)
+           printf("Auto  limit    ; ");
+         else
+           printf("Fixed limit    ; ");
+         /* Print the range */
+         print_retry_value(stdout, range.min_retry, flags | IW_RETRY_MIN);
+         printf("\n                           ");
+         print_retry_value(stdout, range.max_retry, flags | IW_RETRY_MAX);
+         printf("\n          ");
+         
+       }
+      /* Display min/max lifetime availables */
+      if(range.r_time_flags & IW_RETRY_LIFETIME)
+       {
+         int   flags = (range.r_time_flags & ~(IW_RETRY_MIN | IW_RETRY_MAX));
+         /* Display if auto or fixed */
+         if(range.r_time_flags & IW_RETRY_MIN)
+           printf("Auto  lifetime ; ");
+         else
+           printf("Fixed lifetime ; ");
+         /* Print the range */
+         print_retry_value(stdout, range.min_r_time, flags | IW_RETRY_MIN);
+         printf("\n                           ");
+         print_retry_value(stdout, range.max_r_time, flags | IW_RETRY_MAX);
+         printf("\n          ");
+         
+       }
+
+      /* Get current retry settings */
+      strcpy(wrq.ifr_name, ifname);
+      wrq.u.retry.flags = 0;
+      if(ioctl(skfd, SIOCGIWRETRY, &wrq) >= 0)
+       {
+         int   flags = wrq.u.retry.flags;
+
+         /* Is it disabled ? */
+         if(wrq.u.retry.disabled)
+           printf("Current mode:off\n          ");
+         else
+           {
+             int       retry_mask = 0;
+
+             /* Let's check the mode */
+             printf("Current mode:on\n                 ");
+
+             /* Let's check the value and its type */
+             if(wrq.u.retry.flags & IW_RETRY_TYPE)
+               print_retry_value(stdout, wrq.u.retry.value, wrq.u.retry.flags);
+
+             /* If we have been returned a MIN value, ask for the MAX */
+             if(flags & IW_RETRY_MIN)
+               retry_mask = IW_RETRY_MAX;
+             /* If we have been returned a MAX value, ask for the MIN */
+             if(flags & IW_RETRY_MAX)
+               retry_mask = IW_RETRY_MIN;
+             /* If we have something to ask for... */
+             if(retry_mask)
+               get_retry_value(skfd, ifname, &wrq, retry_mask);
+
+             /* And if we have both a period and a timeout, ask the other */
+             retry_mask = (range.retry_capa & (~(wrq.u.retry.flags) &
+                                         IW_RETRY_TYPE));
+             if(retry_mask)
+               {
+                 int   base_mask = retry_mask;
+                 flags = get_retry_value(skfd, ifname, &wrq, retry_mask);
+                 retry_mask = 0;
+
+                 /* If we have been returned a MIN value, ask for the MAX */
+                 if(flags & IW_RETRY_MIN)
+                   retry_mask = IW_RETRY_MAX | base_mask;
+                 /* If we have been returned a MAX value, ask for the MIN */
+                 if(flags & IW_RETRY_MAX)
+                   retry_mask = IW_RETRY_MIN | base_mask;
+                 /* If we have something to ask for... */
+                 if(retry_mask)
+                   get_retry_value(skfd, ifname, &wrq, retry_mask);
+               }
+           }
+       }
+      printf("\n");
+    }
+}
+
+/*------------------------------------------------------------------*/
+/*
+ * Get retry info on all devices and print it on the screen
+ */
+static void
+print_retry_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_retry_info(skfd, ifr->ifr_name);
+}
+#endif /* WIRELESS_EXT > 10 */
+
+/******************************* MAIN ********************************/
+
+/*------------------------------------------------------------------*/
+/*
+ * The main !
+ */
+int
+main(int       argc,
+     char **   argv)
+{
+  int skfd = -1;               /* generic raw socket desc.     */
+
+  /* Create a channel to the NET kernel. */
+  if((skfd = sockets_open()) < 0)
+    {
+      perror("socket");
+      exit(-1);
+    }
+
+  /* Help */
+  if((argc == 1) || (argc > 3) ||
+     (!strncmp(argv[1], "-h", 9)) || (!strcmp(argv[1], "--help")))
+    {
+      fprintf(stderr, "Usage: iwlist [interface] freq\n");
+      fprintf(stderr, "              [interface] ap\n");
+      fprintf(stderr, "              [interface] bitrate\n");
+      fprintf(stderr, "              [interface] keys\n");
+      fprintf(stderr, "              [interface] power\n");
+      fprintf(stderr, "              [interface] txpower\n");
+      fprintf(stderr, "              [interface] retries\n");
+      close(skfd);
+      exit(0);
+    }
+
+  /* Frequency list */
+  if((!strncmp(argv[1], "freq", 4)) ||
+     (!strncmp(argv[1], "channel", 7)))
+    {
+      print_freq_devices(skfd);
+      close(skfd);
+      exit(0);
+    }
+
+  /* Access Point list */
+  if(!strcasecmp(argv[1], "ap"))
+    {
+      print_ap_devices(skfd);
+      close(skfd);
+      exit(0);
+    }
+
+  /* Bit-rate list */
+  if((!strncmp(argv[1], "bit", 3)) ||
+     (!strcmp(argv[1], "rate")))
+    {
+      print_bitrate_devices(skfd);
+      close(skfd);
+      exit(0);
+    }
+
+  /* Encryption key list */
+  if((!strncmp(argv[1], "enc", 3)) ||
+     (!strncmp(argv[1], "key", 3)))
+    {
+      print_keys_devices(skfd);
+      close(skfd);
+      exit(0);
+    }
+
+  /* Power Management list */
+  if(!strncmp(argv[1], "power", 3))
+    {
+      print_pm_devices(skfd);
+      close(skfd);
+      exit(0);
+    }
+
+  /* Transmit Power list */
+  if(!strncmp(argv[1], "txpower", 3))
+    {
+      print_txpower_devices(skfd);
+      close(skfd);
+      exit(0);
+    }
+
+#if WIRELESS_EXT > 10
+  /* Retry limit/lifetime */
+  if(!strncmp(argv[1], "retry", 4))
+    {
+      print_retry_devices(skfd);
+      close(skfd);
+      exit(0);
+    }
+#endif
+
+  /* Special cases take two... */
+  /* Frequency list */
+  if((!strncmp(argv[2], "freq", 4)) ||
+     (!strncmp(argv[2], "channel", 7)))
+    {
+      print_freq_info(skfd, argv[1]);
+      close(skfd);
+      exit(0);
+    }
+
+  /* Access Point  list */
+  if(!strcasecmp(argv[2], "ap"))
+    {
+      print_ap_info(skfd, argv[1]);
+      close(skfd);
+      exit(0);
+    }
+
+  /* Bit-rate list */
+  if((!strncmp(argv[2], "bit", 3)) ||
+     (!strcmp(argv[2], "rate")))
+    {
+      print_bitrate_info(skfd, argv[1]);
+      close(skfd);
+      exit(0);
+    }
+
+  /* Encryption key list */
+  if((!strncmp(argv[2], "enc", 3)) ||
+     (!strncmp(argv[2], "key", 3)))
+    {
+      print_keys_info(skfd, argv[1]);
+      close(skfd);
+      exit(0);
+    }
+
+  /* Power Management list */
+  if(!strncmp(argv[2], "power", 3))
+    {
+      print_pm_info(skfd, argv[1]);
+      close(skfd);
+      exit(0);
+    }
+
+  /* Transmit Power list */
+  if(!strncmp(argv[2], "txpower", 3))
+    {
+      print_txpower_info(skfd, argv[1]);
+      close(skfd);
+      exit(0);
+    }
+
+#if WIRELESS_EXT > 10
+  /* Retry limit/lifetime */
+  if(!strncmp(argv[2], "retry", 4))
+    {
+      print_retry_info(skfd, argv[1]);
+      close(skfd);
+      exit(0);
+    }
+#endif
+
+  /* Close the socket. */
+  close(skfd);
+
+  return(1);
+}
index 9ed9b90..2f51651 100644 (file)
@@ -95,7 +95,7 @@ histogram of up to 16 values with the following commands :
 .\" AUTHOR part
 .\"
 .SH AUTHOR
 .\" AUTHOR part
 .\"
 .SH AUTHOR
-Jean Tourrilhes \- jt@hplb.hpl.hp.com
+Jean Tourrilhes \- jt@hpl.hp.com
 .\"
 .\" FILES part
 .\"
 .\"
 .\" FILES part
 .\"
@@ -107,7 +107,9 @@ Jean Tourrilhes \- jt@hplb.hpl.hp.com
 .SH SEE ALSO
 .BR ifconfig (8),
 .BR iwconfig (8),
 .SH SEE ALSO
 .BR ifconfig (8),
 .BR iwconfig (8),
+.BR iwlist (8),
 .BR iwspy (8),
 .BR wavelan (4),
 .BR wavelan_cs (4),
 .BR iwspy (8),
 .BR wavelan (4),
 .BR wavelan_cs (4),
-.BR xircnw_cs (4).
+.BR wvlan_cs (4),
+.BR netwave_cs (4).
index d1da985..de98613 100644 (file)
@@ -1,11 +1,13 @@
 /*
  *     Wireless Tools
  *
 /*
  *     Wireless Tools
  *
- *             Jean II - HPLB '99
+ *             Jean II - HPLB 97->99 - HPL 99->00
  *
  * Main code for "iwconfig". This is the generic tool for most
  * manipulations...
  * You need to link this code against "iwcommon.c" and "-lm".
  *
  * Main code for "iwconfig". This is the generic tool for most
  * manipulations...
  * You need to link this code against "iwcommon.c" and "-lm".
+ *
+ * This file is released under the GPL license.
  */
 
 #include "iwcommon.h"          /* Header */
  */
 
 #include "iwcommon.h"          /* Header */
@@ -253,7 +255,7 @@ set_private(int             skfd,           /* Socket */
        case IW_PRIV_TYPE_INT:
          /* Display args */
          for(j = 0; j < n; j++)
        case IW_PRIV_TYPE_INT:
          /* Display args */
          for(j = 0; j < n; j++)
-           printf("%d  ", ((u_int *) buffer)[i]);
+           printf("%d  ", ((u_int *) buffer)[j]);
          printf("\n");
          break;
 
          printf("\n");
          break;
 
index d7af14c..d550281 100644 (file)
@@ -16,14 +16,6 @@ iwspy \- Get wireless statistics from specific nodes
 .BI "iwspy " interface " [+] " IPADDR " | " HWADDR " [...]"
 .br
 .BI "iwspy " interface " off"
 .BI "iwspy " interface " [+] " IPADDR " | " HWADDR " [...]"
 .br
 .BI "iwspy " interface " off"
-.br
-.BI "iwspy " interface " freq"
-.br
-.BI "iwspy " interface " ap"
-.br
-.BI "iwspy " interface " rate"
-.br
-.BI "iwspy " interface " keys"
 .\"
 .\" DESCRIPTION part
 .\"
 .\"
 .\" DESCRIPTION part
 .\"
@@ -38,9 +30,8 @@ information is the same as the one available in
 This information is updated each time a new packet is received, so
 each address of the list add some overhead in the driver.
 .PP
 This information is updated each time a new packet is received, so
 each address of the list add some overhead in the driver.
 .PP
-.B Iwspy
-Can also display the list of frequencies available for the device or the
-list of Access Points in range.
+Note the this functionality work only for node part of the current
+wireless cells.
 .\"
 .\" PARAMETER part
 .\"
 .\"
 .\" PARAMETER part
 .\"
@@ -72,24 +63,6 @@ should use this option to avoid conflicts.
 .TP
 .B off
 Remove the current list of addresses and disable the spy functionality
 .TP
 .B off
 Remove the current list of addresses and disable the spy functionality
-.TP
-.B freq
-Give the list of available frequencies in the device and the number of
-defined channels. Please note that usually the driver returns the
-total number of channels and only the frequencies available in the
-present locale, so there is no one to one mapping between frequencies
-displayed and channel numbers.
-.TP
-.B ap
-Give the list of Access Points in range, and optionally the quality of
-link to them.
-.TP
-.BR rate / bit [rate]
-List the bit-rates supported by the device.
-.TP
-.BR keys / enc [ryption]
-List the encryption key sizes supported and display all the encryption
-keys availables in the device.
 .\"
 .\" FILES part
 .\"
 .\"
 .\" FILES part
 .\"
@@ -101,5 +74,6 @@ keys availables in the device.
 .SH SEE ALSO
 .BR iwconfig (8),
 .BR ifconfig (8),
 .SH SEE ALSO
 .BR iwconfig (8),
 .BR ifconfig (8),
+.BR iwlist (8).
 .BR iwpriv (8).
 
 .BR iwpriv (8).
 
index 1fa39d3..ead9a62 100644 (file)
@@ -3,9 +3,10 @@
  *
  *             Jean II - HPLB '99
  *
  *
  *             Jean II - HPLB '99
  *
- * Main code for "iwconfig". This is the generic tool for most
- * manipulations...
+ * This tool can manipulate the spy list : add addresses and display stat
  * You need to link this code against "iwcommon.c" and "-lm".
  * You need to link this code against "iwcommon.c" and "-lm".
+ *
+ * This file is released under the GPL license.
  */
 
 #include "iwcommon.h"          /* Header */
  */
 
 #include "iwcommon.h"          /* Header */
@@ -70,26 +71,9 @@ print_spy_info(int   skfd,
 
   for(i = 0; i < n; i++)
     {
 
   for(i = 0; i < n; i++)
     {
-      if(has_range && (qual[i].level != 0))
-       /* If the statistics are in dBm */
-       if(qual[i].level > range.max_qual.level)
-         printf("    %s : Quality %d/%d ; Signal %d dBm ; Noise %d dBm %s\n",
-                pr_ether(hwa[i].sa_data),
-                qual[i].qual, range.max_qual.qual,
-                qual[i].level - 0x100, qual[i].noise - 0x100,
-                qual[i].updated & 0x7 ? "(updated)" : "");
-       else
-         printf("    %s : Quality %d/%d ; Signal %d/%d ; Noise %d/%d %s\n",
-                pr_ether(hwa[i].sa_data),
-                qual[i].qual, range.max_qual.qual,
-                qual[i].level, range.max_qual.level,
-                qual[i].noise, range.max_qual.noise,
-                qual[i].updated & 0x7 ? "(updated)" : "");
-      else
-       printf("    %s : Quality %d ; Signal %d ; Noise %d %s\n",
-              pr_ether(hwa[i].sa_data),
-              qual[i].qual, qual[i].level, qual[i].noise,
-              qual[i].updated & 0x7 ? "(updated)" : "");
+      /* Print stats for each address */
+      printf("    %s : ", pr_ether(hwa[i].sa_data));
+      print_stats(stdout, &qual[i], &range, has_range);
     }
   printf("\n");
 }
     }
   printf("\n");
 }
@@ -121,361 +105,6 @@ print_spy_devices(int             skfd)
     print_spy_info(skfd, ifr->ifr_name);
 }
 
     print_spy_info(skfd, ifr->ifr_name);
 }
 
-/*------------------------------------------------------------------*/
-/*
- * Print the number of channels and available frequency for the device
- */
-static void
-print_freq_info(int            skfd,
-               char *          ifname)
-{
-  struct iwreq         wrq;
-  float                        freq;
-  struct iw_range      range;
-  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 frequency information.\n\n",
-                     ifname);
-  else
-    {
-      if(range.num_frequency > 0)
-       {
-         printf("%-8.8s  %d channels in total; available frequencies :\n",
-                ifname, range.num_channels);
-         /* Print them all */
-         for(k = 0; k < range.num_frequency; k++)
-           {
-             printf("\t  Channel %.2d : ", range.freq[k].i);
-             freq = freq2float(&(range.freq[k]));
-             if(freq >= GIGA)
-               printf("%g GHz\n", freq / GIGA);
-             else
-               if(freq >= MEGA)
-                 printf("%g MHz\n", freq / MEGA);
-               else
-                 printf("%g kHz\n", freq / KILO);
-           }
-         printf("\n\n");
-       }
-      else
-       printf("%-8.8s  %d channels\n\n",
-              ifname, range.num_channels);
-    }
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Get frequency info on all devices and print it on the screen
- */
-static void
-print_freq_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_freq_info(skfd, ifr->ifr_name);
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Display the list of ap addresses and the associated stats
- * Exacly the same as the spy list, only with different IOCTL and messages
- */
-static void
-print_ap_info(int      skfd,
-              char *   ifname)
-{
-  struct iwreq         wrq;
-  char         buffer[(sizeof(struct iw_quality) +
-                       sizeof(struct sockaddr)) * IW_MAX_AP];
-  struct sockaddr *    hwa;
-  struct iw_quality *  qual;
-  iwrange      range;
-  int          has_range = 0;
-  int          has_qual = 0;
-  int          n;
-  int          i;
-
-  /* Collect stats */
-  strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
-  wrq.u.data.pointer = (caddr_t) buffer;
-  wrq.u.data.length = 0;
-  wrq.u.data.flags = 0;
-  if(ioctl(skfd, SIOCGIWAPLIST, &wrq) < 0)
-    {
-      fprintf(stderr, "%-8.8s  Interface doesn't have a list of Access Points\n\n", ifname);
-      return;
-    }
-
-  /* Number of addresses */
-  n = wrq.u.data.length;
-  has_qual = wrq.u.data.flags;
-
-  /* The two lists */
-  hwa = (struct sockaddr *) buffer;
-  qual = (struct iw_quality *) (buffer + (sizeof(struct sockaddr) * n));
-
-  /* Check if we have valid address types */
-  if(check_addr_type(skfd, ifname) < 0)
-    {
-      fprintf(stderr, "%-8.8s  Interface doesn't support MAC & IP addresses\n\n", ifname);
-      return;
-    }
-
-  /* Get range info if we can */
-  if(get_range_info(skfd, ifname, &(range)) >= 0)
-    has_range = 1;
-
-  /* Display it */
-  if(n == 0)
-    printf("%-8.8s  No Access Point in range\n", ifname);
-  else
-    printf("%-8.8s  Access Points in range:\n", ifname);
-  for(i = 0; i < n; i++)
-    {
-      if(has_qual)
-       if(has_range)
-         /* If the statistics are in dBm */
-         if(qual[i].level > range.max_qual.level)
-           printf("    %s : Quality %d/%d ; Signal %d dBm ; Noise %d dBm %s\n",
-                  pr_ether(hwa[i].sa_data),
-                  qual[i].qual, range.max_qual.qual,
-                  qual[i].level - 0x100, qual[i].noise - 0x100,
-                  qual[i].updated & 0x7 ? "(updated)" : "");
-         else
-           printf("    %s : Quality %d/%d ; Signal %d/%d ; Noise %d/%d %s\n",
-                  pr_ether(hwa[i].sa_data),
-                  qual[i].qual, range.max_qual.qual,
-                  qual[i].level, range.max_qual.level,
-                  qual[i].noise, range.max_qual.noise,
-                  qual[i].updated & 0x7 ? "(updated)" : "");
-       else
-         printf("    %s : Quality %d ; Signal %d ; Noise %d %s\n",
-                pr_ether(hwa[i].sa_data),
-                qual[i].qual, qual[i].level, qual[i].noise,
-                qual[i].updated & 0x7 ? "(updated)" : "");
-      else
-       printf("    %s\n", pr_ether(hwa[i].sa_data));
-    }
-  printf("\n");
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Get list of AP on all devices and print it on the screen
- */
-static void
-print_ap_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_ap_info(skfd, ifr->ifr_name);
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Print the number of available bitrates for the device
- */
-static void
-print_bitrate_info(int         skfd,
-                  char *       ifname)
-{
-  struct iwreq         wrq;
-  float                        bitrate;
-  struct iw_range      range;
-  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 bit-rate information.\n\n",
-                     ifname);
-  else
-    {
-      if((range.num_bitrates > 0) && (range.num_bitrates < IW_MAX_BITRATES))
-       {
-         printf("%-8.8s  %d available bit-rates :\n",
-                ifname, range.num_bitrates);
-         /* Print them all */
-         for(k = 0; k < range.num_bitrates; k++)
-           {
-             printf("\t  ");
-             bitrate = range.bitrate[k];
-             if(bitrate >= GIGA)
-               printf("%g Gb/s\n", bitrate / GIGA);
-             else
-               if(bitrate >= MEGA)
-                 printf("%g Mb/s\n", bitrate / MEGA);
-               else
-                 printf("%g kb/s\n", bitrate / KILO);
-           }
-         printf("\n\n");
-       }
-      else
-       printf("%-8.8s  No bit-rates ? Please update driver...\n\n", ifname);
-    }
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Get bit-rate info on all devices and print it on the screen
- */
-static void
-print_bitrate_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_bitrate_info(skfd, ifr->ifr_name);
-}
-
-/*------------------------------------------------------------------*/
-/*
- * 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 **************************/
 
 /*------------------------------------------------------------------*/
 /************************* SETTING ROUTINES **************************/
 
 /*------------------------------------------------------------------*/
@@ -608,41 +237,6 @@ main(int   argc,
       exit(0);
     }
 
       exit(0);
     }
 
-  /* Frequency list */
-  if((!strncmp(argv[1], "freq", 4)) ||
-     (!strncmp(argv[1], "channel", 7)))
-    {
-      print_freq_devices(skfd);
-      close(skfd);
-      exit(0);
-    }
-
-  /* Access Point list */
-  if(!strcasecmp(argv[1], "ap"))
-    {
-      print_ap_devices(skfd);
-      close(skfd);
-      exit(0);
-    }
-
-  /* Bit-rate list */
-  if((!strncmp(argv[1], "bit", 3)) ||
-     (!strcmp(argv[1], "rate")))
-    {
-      print_bitrate_devices(skfd);
-      close(skfd);
-      exit(0);
-    }
-
-  /* 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 */
   if(argc == 2)
   /* The device name must be the first argument */
   /* Name only : show spy list for that device only */
   if(argc == 2)
@@ -652,42 +246,6 @@ main(int   argc,
       exit(0);
     }
 
       exit(0);
     }
 
-  /* Special cases take two... */
-  /* Frequency list */
-  if((!strncmp(argv[2], "freq", 4)) ||
-     (!strncmp(argv[2], "channel", 7)))
-    {
-      print_freq_info(skfd, argv[1]);
-      close(skfd);
-      exit(0);
-    }
-
-  /* Access Point  list */
-  if(!strcasecmp(argv[2], "ap"))
-    {
-      print_ap_info(skfd, argv[1]);
-      close(skfd);
-      exit(0);
-    }
-
-  /* Access Point  list */
-  if((!strncmp(argv[2], "bit", 3)) ||
-     (!strcmp(argv[2], "rate")))
-    {
-      print_bitrate_info(skfd, argv[1]);
-      close(skfd);
-      exit(0);
-    }
-
-  /* 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]);
 
   /* Otherwise, it's a list of address to set in the spy list */
   goterr = set_spy_info(skfd, argv + 2, argc - 2, argv[1]);
 
index 47247b2..f72ca2f 100644 (file)
@@ -1,3 +1,8 @@
+/* Note : this particular snipset of code is available under
+ * the LGPL, MPL or BSD license (at your choice).
+ * Jean II
+ */
+
 #define MAX_KEY_SIZE   16
 #define        MAX_KEYS        8
 int    key_on = 0;
 #define MAX_KEY_SIZE   16
 #define        MAX_KEYS        8
 int    key_on = 0;
diff --git a/wireless_tools/sample_pm_cs.c b/wireless_tools/sample_pm_cs.c
new file mode 100644 (file)
index 0000000..9cecad0
--- /dev/null
@@ -0,0 +1,146 @@
+/* Note : this particular snipset of code is available under
+ * the LGPL, MPL or BSD license (at your choice).
+ * Jean II
+ */
+
+/* Backward compatibility for Wireless Extension 9 */
+#ifndef IW_POWER_MODIFIER
+#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 */
+#endif IW_POWER_MODIFIER
+
+struct net_local {
+  int          pm_on;          // Power Management enabled
+  int          pm_multi;       // Receive multicasts
+  int          pm_period;      // Power Management period
+  int          pm_period_auto; // Power Management auto mode
+  int          pm_max_period;  // Power Management max period
+  int          pm_min_period;  // Power Management min period
+  int          pm_timeout;     // Power Management timeout
+};
+
+      /* Set the desired Power Management mode */
+    case SIOCSIWPOWER:
+      /* Disable it ? */
+      if(wrq->u.power.disabled)
+       {
+         local->pm_on = 0;
+         local->need_commit = 1;
+       }
+      else
+       {
+         /* Check mode */
+         switch(wrq->u.power.flags & IW_POWER_MODE)
+           {
+           case IW_POWER_UNICAST_R:
+             local->pm_multi = 0;
+             local->need_commit = 1;
+             break;
+           case IW_POWER_ALL_R:
+             local->pm_multi = 1;
+             local->need_commit = 1;
+             break;
+           case IW_POWER_ON:   /* None = ok */
+             break;
+           default:    /* Invalid */
+             rc = -EINVAL;
+           }
+         /* Set period */
+         if(wrq->u.power.flags & IW_POWER_PERIOD)
+           {
+             int       period = wrq->u.power.value/1000000;
+             /* Hum: check if within bounds... */
+
+             /* Activate PM */
+             local->pm_on = 1;
+             local->need_commit = 1;
+
+             /* Check min value */
+             if(wrq->u.power.flags & IW_POWER_MIN)
+               {
+                 local->pm_min_period = period;
+                 local->pm_period_auto = 1;
+               }
+             else
+               /* Check max value */
+               if(wrq->u.power.flags & IW_POWER_MAX)
+                 {
+                   local->pm_max_period = period;
+                   local->pm_period_auto = 1;
+                 }
+               else
+                 {
+                   /* Fixed value */
+                   local->pm_period = period;
+                   local->pm_period_auto = 0;
+                 }
+           }
+         /* Set timeout */
+         if(wrq->u.power.flags & IW_POWER_TIMEOUT)
+           {
+             /* Activate PM */
+             local->pm_on = 1;
+             local->need_commit = 1;
+             /* Fixed value in ms */
+             local->pm_timeout = wrq->u.power.value/1000;
+           }
+       }
+      break;
+
+      /* Get the power management settings */
+    case SIOCGIWPOWER:
+      wrq->u.power.disabled = !local->pm_on;
+      /* By default, display the period */
+      if(!(wrq->u.power.flags & IW_POWER_TIMEOUT))
+       {
+         int   inc_flags = wrq->u.power.flags;
+         wrq->u.power.flags = IW_POWER_PERIOD | IW_POWER_RELATIVE;
+         /* Check if auto */
+         if(local->pm_period_auto)
+           {
+             /* By default, the min */
+             if(!(inc_flags & IW_POWER_MAX))
+               {
+                 wrq->u.power.value = local->pm_min_period * 1000000;
+                 wrq->u.power.flags |= IW_POWER_MIN;
+               }
+             else
+               {
+                 wrq->u.power.value = local->pm_max_period * 1000000;
+                 wrq->u.power.flags |= IW_POWER_MAX;
+               }
+           }
+         else
+           {
+             /* Fixed value. Check the flags */
+             if(inc_flags & (IW_POWER_MIN | IW_POWER_MAX))
+               rc = -EINVAL;
+             else
+               wrq->u.power.value = local->pm_period * 1000000;
+           }
+       }
+      else
+       {
+         /* Deal with the timeout - always fixed */
+         wrq->u.power.flags = IW_POWER_TIMEOUT;
+         wrq->u.power.value = local->pm_timeout * 1000;
+       }
+      if(local->pm_multi)
+       wrq->u.power.flags |= IW_POWER_ALL_R;
+      else
+       wrq->u.power.flags |= IW_POWER_UNICAST_R;
+      break;
+#endif /* WIRELESS_EXT > 8 */
+
+#if WIRELESS_EXT > 9
+      range.min_pmp = 1000000; /* 1 units */
+      range.max_pmp = 12000000;        /* 12 units */
+      range.min_pmt = 1000;    /* 1 ms */
+      range.max_pmt = 1000000; /* 1 s */
+      range.pmp_flags = IW_POWER_PERIOD | IW_POWER_RELATIVE |
+        IW_POWER_MIN | IW_POWER_MAX;
+      range.pmt_flags = IW_POWER_TIMEOUT;
+      range.pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_UNICAST_R;
+#endif /* WIRELESS_EXT > 9 */
diff --git a/wireless_tools/wireless.10.h b/wireless_tools/wireless.10.h
new file mode 100644 (file)
index 0000000..c552ff2
--- /dev/null
@@ -0,0 +1,479 @@
+/*
+ * This file define a set of standard wireless extensions
+ *
+ * Version :   9       16.10.99
+ *
+ * Authors :   Jean Tourrilhes - HPL - <jt@hpl.hp.com>
+ */
+
+#ifndef _LINUX_WIRELESS_H
+#define _LINUX_WIRELESS_H
+
+/************************** DOCUMENTATION **************************/
+/*
+ * Basically, the wireless extensions are for now a set of standard ioctl
+ * call + /proc/net/wireless
+ *
+ * The entry /proc/net/wireless give statistics and information on the
+ * driver.
+ * This is better than having each driver having its entry because
+ * its centralised and we may remove the driver module safely.
+ *
+ * Ioctl are used to configure the driver and issue commands.  This is
+ * better than command line options of insmod because we may want to
+ * change dynamically (while the driver is running) some parameters.
+ *
+ * The ioctl mechanimsm are copied from standard devices ioctl.
+ * We have the list of command plus a structure descibing the
+ * data exchanged...
+ * Note that to add these ioctl, I was obliged to modify :
+ *     net/core/dev.c (two place + add include)
+ *     net/ipv4/af_inet.c (one place + add include)
+ *
+ * /proc/net/wireless is a copy of /proc/net/dev.
+ * We have a structure for data passed from the driver to /proc/net/wireless
+ * Too add this, I've modified :
+ *     net/core/dev.c (two other places)
+ *     include/linux/netdevice.h (one place)
+ *     include/linux/proc_fs.h (one place)
+ *
+ * Do not add here things that are redundant with other mechanisms
+ * (drivers init, ifconfig, /proc/net/dev, ...) and with are not
+ * wireless specific.
+ *
+ * These wireless extensions are not magic : each driver has to provide
+ * support for them...
+ *
+ * IMPORTANT NOTE : As everything in the kernel, this is very much a
+ * work in progress. Contact me if you have ideas of improvements...
+ */
+
+/***************************** INCLUDES *****************************/
+
+#include <linux/types.h>               /* for "caddr_t" et al          */
+#include <linux/socket.h>              /* for "struct sockaddr" et al  */
+#include <linux/if.h>                  /* for IFNAMSIZ and co... */
+
+/**************************** CONSTANTS ****************************/
+
+/* --------------------------- VERSION --------------------------- */
+/*
+ * This constant is used to know the availability of the wireless
+ * extensions and to know which version of wireless extensions it is
+ * (there is some stuff that will be added in the future...)
+ * I just plan to increment with each new version.
+ */
+#define WIRELESS_EXT   10
+
+/*
+ * 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)
+ */
+
+/* -------------------------- IOCTL LIST -------------------------- */
+
+/* Basic operations */
+#define SIOCSIWNAME    0x8B00          /* Unused */
+#define SIOCGIWNAME    0x8B01          /* get name == wireless protocol */
+#define SIOCSIWNWID    0x8B02          /* set network id (the cell) */
+#define SIOCGIWNWID    0x8B03          /* get network id */
+#define SIOCSIWFREQ    0x8B04          /* set channel/frequency (Hz) */
+#define SIOCGIWFREQ    0x8B05          /* get channel/frequency (Hz) */
+#define SIOCSIWMODE    0x8B06          /* set operation mode */
+#define SIOCGIWMODE    0x8B07          /* get operation mode */
+#define SIOCSIWSENS    0x8B08          /* set sensitivity (dBm) */
+#define SIOCGIWSENS    0x8B09          /* get sensitivity (dBm) */
+
+/* Informative stuff */
+#define SIOCSIWRANGE   0x8B0A          /* Unused */
+#define SIOCGIWRANGE   0x8B0B          /* Get range of parameters */
+#define SIOCSIWPRIV    0x8B0C          /* Unused */
+#define SIOCGIWPRIV    0x8B0D          /* get private ioctl interface info */
+
+/* Mobile IP support */
+#define SIOCSIWSPY     0x8B10          /* set spy addresses */
+#define SIOCGIWSPY     0x8B11          /* get spy info (quality of link) */
+
+/* Access Point manipulation */
+#define SIOCSIWAP      0x8B14          /* set access point MAC addresses */
+#define SIOCGIWAP      0x8B15          /* get access point MAC addresses */
+#define SIOCGIWAPLIST  0x8B17          /* get list of access point in range */
+
+/* 802.11 specific support */
+#define SIOCSIWESSID   0x8B1A          /* set ESSID (network name) */
+#define SIOCGIWESSID   0x8B1B          /* get ESSID */
+#define SIOCSIWNICKN   0x8B1C          /* set node name/nickname */
+#define SIOCGIWNICKN   0x8B1D          /* get node name/nickname */
+/* As the ESSID and NICKN are strings up to 32 bytes long, it doesn't fit
+ * within the 'iwreq' structure, so we need to use the 'data' member to
+ * point to a string in user space, like it is done for RANGE...
+ * The "flags" member indicate if the ESSID is active or not (promiscuous).
+ */
+
+/* Other parameters usefull 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) */
+
+/* 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 */
+
+/* ------------------------- IOCTL STUFF ------------------------- */
+
+/* The first and the last (range) */
+#define SIOCIWFIRST    0x8B00
+#define SIOCIWLAST     0x8B30
+
+/* 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 bit rates in the range struct */
+#define IW_MAX_BITRATES                8
+
+/* Maximum tx powers in the range struct */
+#define IW_MAX_TXPOWER         8
+
+/* Maximum of address that you may set with SPY */
+#define IW_MAX_SPY             8
+
+/* Maximum of address that you may get in the
+   list of access points in range */
+#define IW_MAX_AP              8
+
+/* Maximum size of the ESSID and NICKN strings */
+#define IW_ESSID_MAX_SIZE      32
+
+/* Modes of operation */
+#define IW_MODE_AUTO   0       /* Let the driver decides */
+#define IW_MODE_ADHOC  1       /* Single cell network */
+#define IW_MODE_INFRA  2       /* Multi cell network, roaming, ... */
+#define IW_MODE_MASTER 3       /* Synchronisation master or Access Point */
+#define IW_MODE_REPEAT 4       /* Wireless Repeater (forwarder) */
+#define IW_MODE_SECOND 5       /* Secondary master/repeater (backup) */
+
+/* Maximum number of size of encoding token available
+ * they are listed in the range structure */
+#define IW_MAX_ENCODING_SIZES  8
+
+/* Maximum size of the encoding token in bytes */
+#define IW_ENCODING_TOKEN_MAX  32      /* 256 bits (for now) */
+
+/* Flags for encoding (along with the token) */
+#define IW_ENCODE_INDEX                0x00FF  /* Token index (if needed) */
+#define IW_ENCODE_FLAGS                0xFF00  /* Flags defined below */
+#define IW_ENCODE_MODE         0xF000  /* Modes defined below */
+#define IW_ENCODE_DISABLED     0x8000  /* Encoding disabled */
+#define IW_ENCODE_ENABLED      0x0000  /* Encoding enabled */
+#define IW_ENCODE_RESTRICTED   0x4000  /* Refuse non-encoded packets */
+#define IW_ENCODE_OPEN         0x2000  /* Accept non-encoded packets */
+#define IW_ENCODE_NOKEY         0x0800  /* Key is write only, so not present */
+
+/* Power management flags available (along with the value, if any) */
+#define IW_POWER_ON            0x0000  /* No details... */
+#define IW_POWER_TYPE          0xF000  /* Type of parameter */
+#define IW_POWER_PERIOD                0x1000  /* Value is a period/duration of  */
+#define IW_POWER_TIMEOUT       0x2000  /* Value is a timeout (to go asleep) */
+#define IW_POWER_MODE          0x0F00  /* Power Management mode */
+#define IW_POWER_UNICAST_R     0x0100  /* Receive only unicast messages */
+#define IW_POWER_MULTICAST_R   0x0200  /* Receive only multicast messages */
+#define IW_POWER_ALL_R         0x0300  /* Receive all messages though PM */
+#define IW_POWER_FORCE_S       0x0400  /* Force PM procedure for sending unicast */
+#define IW_POWER_REPEATER      0x0800  /* Repeat broadcast messages in PM period */
+#define IW_POWER_MODIFIER      0x000F  /* Modify a parameter */
+#define IW_POWER_MIN           0x0001  /* Value is a minimum  */
+#define IW_POWER_MAX           0x0002  /* Value is a maximum */
+#define IW_POWER_RELATIVE      0x0004  /* Value is not in seconds/ms/us */
+
+/* Transmit Power flags available */
+#define IW_TXPOW_DBM           0x0000  /* Value is in dBm */
+#define IW_TXPOW_MWATT         0x0001  /* Value is in mW */
+
+/****************************** 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 alocated in user space.
+ */
+struct iw_point
+{
+  caddr_t      pointer;        /* Pointer to the data  (in user space) */
+  __u16                length;         /* number of fields or size in bytes */
+  __u16                flags;          /* Optional params */
+};
+
+/*
+ *     A frequency
+ *     For numbers lower than 10^9, we encode the number in 'm' and
+ *     set 'e' to 0
+ *     For number greater than 10^9, we divide it by the lowest power
+ *     of 10 to get 'm' lower than 10^9, with 'm'= f / (10^'e')...
+ *     The power of 10 is in 'e', the result of the division is in 'm'.
+ */
+struct iw_freq
+{
+       __u32           m;              /* Mantissa */
+       __u16           e;              /* Exponent */
+       __u8            i;              /* List index (when in range struct) */
+};
+
+/*
+ *     Quality of the link
+ */
+struct iw_quality
+{
+       __u8            qual;           /* link quality (%retries, SNR 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 */
+};
+
+/* ------------------------ 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 */
+};
+
+/* ------------------------ IOCTL REQUEST ------------------------ */
+/*
+ * The structure to exchange data for ioctl.
+ * This structure is the same as 'struct ifreq', but (re)defined for
+ * convenience...
+ *
+ * Note that it should fit on the same memory footprint !
+ * You should check this when increasing the above structures (16 octets)
+ * 16 octets = 128 bits. Warning, pointers might be 64 bits wide...
+ */
+struct iwreq 
+{
+       union
+       {
+               char    ifrn_name[IFNAMSIZ];    /* if name, e.g. "eth0" */
+       } ifr_ifrn;
+
+       /* Data part */
+       union
+       {
+               /* Config - generic */
+               char            name[IFNAMSIZ];
+               /* Name : used to verify the presence of  wireless extensions.
+                * Name of the protocol/provider... */
+
+               struct iw_point essid;  /* Extended network name */
+               struct iw_param nwid;   /* network id (or domain - the cell) */
+               struct iw_freq  freq;   /* frequency or channel :
+                                        * 0-1000 = channel
+                                        * > 1000 = frequency in Hz */
+
+               struct iw_param sens;           /* signal level threshold */
+               struct iw_param bitrate;        /* default bit rate */
+               struct iw_param txpower;        /* default transmit power */
+               struct iw_param rts;            /* RTS threshold threshold */
+               struct iw_param frag;           /* Fragmentation threshold */
+               __u32           mode;           /* Operation mode */
+
+               struct iw_point encoding;       /* Encoding stuff : tokens */
+               struct iw_param power;          /* PM duration/timeout */
+
+               struct sockaddr ap_addr;        /* Access point address */
+
+               struct iw_point data;           /* Other large parameters */
+       }       u;
+};
+
+/* -------------------------- IOCTL DATA -------------------------- */
+/*
+ *     For those ioctl which want to exchange mode data that what could
+ *     fit in the above structure...
+ */
+
+/*
+ *     Range of parameters
+ */
+
+struct iw_range
+{
+       /* Informative stuff (to choose between different interface) */
+       __u32           throughput;     /* To give an idea... */
+       /* In theory this value should be the maximum benchmarked
+        * TCP/IP throughput, because with most of these devices the
+        * bit rate is meaningless (overhead an co) to estimate how
+        * fast the connection will go and pick the fastest one.
+        * I suggest people to play with Netperf or any benchmark...
+        */
+
+       /* NWID (or domain id) */
+       __u32           min_nwid;       /* Minimal NWID we are able to set */
+       __u32           max_nwid;       /* Maximal NWID we are able to set */
+
+       /* Frequency */
+       __u16           num_channels;   /* Number of channels [0; num - 1] */
+       __u8            num_frequency;  /* Number of entry in the list */
+       struct iw_freq  freq[IW_MAX_FREQUENCIES];       /* list */
+       /* Note : this frequency list doesn't need to fit channel numbers */
+
+       /* signal level threshold range */
+       __s32   sensitivity;
+
+       /* Quality of link & SNR stuff */
+       struct iw_quality       max_qual;       /* Quality of the link */
+
+       /* Rates */
+       __u8            num_bitrates;   /* Number of entries in the list */
+       __s32           bitrate[IW_MAX_BITRATES];       /* list, in bps */
+
+       /* RTS threshold */
+       __s32           min_rts;        /* Minimal RTS threshold */
+       __s32           max_rts;        /* Maximal RTS threshold */
+
+       /* Frag threshold */
+       __s32           min_frag;       /* Minimal frag threshold */
+       __s32           max_frag;       /* Maximal frag threshold */
+
+       /* Power Management duration & timeout */
+       __s32           min_pmp;        /* Minimal PM period */
+       __s32           max_pmp;        /* Maximal PM period */
+       __s32           min_pmt;        /* Minimal PM timeout */
+       __s32           max_pmt;        /* Maximal PM timeout */
+       __u16           pmp_flags;      /* How to decode max/min PM period */
+       __u16           pmt_flags;      /* How to decode max/min PM timeout */
+       __u16           pm_capa;        /* What PM options are supported */
+
+       /* Encoder stuff */
+       __u16   encoding_size[IW_MAX_ENCODING_SIZES];   /* Different token sizes */
+       __u8    num_encoding_sizes;     /* Number of entry in the list */
+       __u8    max_encoding_tokens;    /* Max number of tokens */
+
+       /* Transmit power */
+       __u16           txpower_capa;   /* What options are supported */
+       __u8            num_txpower;    /* Number of entries in the list */
+       __s32           txpower[IW_MAX_TXPOWER];        /* list, in bps */
+};
+
+/*
+ * 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 */
diff --git a/wireless_tools/wireless.h b/wireless_tools/wireless.h
new file mode 100644 (file)
index 0000000..fe42409
--- /dev/null
@@ -0,0 +1,510 @@
+/*
+ * This file define a set of standard wireless extensions
+ *
+ * Version :   11      28.3.01
+ *
+ * Authors :   Jean Tourrilhes - HPL - <jt@hpl.hp.com>
+ */
+
+#ifndef _LINUX_WIRELESS_H
+#define _LINUX_WIRELESS_H
+
+/************************** DOCUMENTATION **************************/
+/*
+ * Basically, the wireless extensions are for now a set of standard ioctl
+ * call + /proc/net/wireless
+ *
+ * The entry /proc/net/wireless give statistics and information on the
+ * driver.
+ * This is better than having each driver having its entry because
+ * its centralised and we may remove the driver module safely.
+ *
+ * Ioctl are used to configure the driver and issue commands.  This is
+ * better than command line options of insmod because we may want to
+ * change dynamically (while the driver is running) some parameters.
+ *
+ * The ioctl mechanimsm are copied from standard devices ioctl.
+ * We have the list of command plus a structure descibing the
+ * data exchanged...
+ * Note that to add these ioctl, I was obliged to modify :
+ *     net/core/dev.c (two place + add include)
+ *     net/ipv4/af_inet.c (one place + add include)
+ *
+ * /proc/net/wireless is a copy of /proc/net/dev.
+ * We have a structure for data passed from the driver to /proc/net/wireless
+ * Too add this, I've modified :
+ *     net/core/dev.c (two other places)
+ *     include/linux/netdevice.h (one place)
+ *     include/linux/proc_fs.h (one place)
+ *
+ * Do not add here things that are redundant with other mechanisms
+ * (drivers init, ifconfig, /proc/net/dev, ...) and with are not
+ * wireless specific.
+ *
+ * These wireless extensions are not magic : each driver has to provide
+ * support for them...
+ *
+ * IMPORTANT NOTE : As everything in the kernel, this is very much a
+ * work in progress. Contact me if you have ideas of improvements...
+ */
+
+/***************************** INCLUDES *****************************/
+
+#include <linux/types.h>               /* for "caddr_t" et al          */
+#include <linux/socket.h>              /* for "struct sockaddr" et al  */
+#include <linux/if.h>                  /* for IFNAMSIZ and co... */
+
+/**************************** CONSTANTS ****************************/
+
+/* --------------------------- VERSION --------------------------- */
+/*
+ * This constant is used to know the availability of the wireless
+ * extensions and to know which version of wireless extensions it is
+ * (there is some stuff that will be added in the future...)
+ * I just plan to increment with each new version.
+ */
+#define WIRELESS_EXT   11
+
+/*
+ * 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)
+ */
+
+/* -------------------------- IOCTL LIST -------------------------- */
+
+/* Basic operations */
+#define SIOCSIWNAME    0x8B00          /* Unused */
+#define SIOCGIWNAME    0x8B01          /* get name == wireless protocol */
+#define SIOCSIWNWID    0x8B02          /* set network id (the cell) */
+#define SIOCGIWNWID    0x8B03          /* get network id */
+#define SIOCSIWFREQ    0x8B04          /* set channel/frequency (Hz) */
+#define SIOCGIWFREQ    0x8B05          /* get channel/frequency (Hz) */
+#define SIOCSIWMODE    0x8B06          /* set operation mode */
+#define SIOCGIWMODE    0x8B07          /* get operation mode */
+#define SIOCSIWSENS    0x8B08          /* set sensitivity (dBm) */
+#define SIOCGIWSENS    0x8B09          /* get sensitivity (dBm) */
+
+/* Informative stuff */
+#define SIOCSIWRANGE   0x8B0A          /* Unused */
+#define SIOCGIWRANGE   0x8B0B          /* Get range of parameters */
+#define SIOCSIWPRIV    0x8B0C          /* Unused */
+#define SIOCGIWPRIV    0x8B0D          /* get private ioctl interface info */
+
+/* Mobile IP support */
+#define SIOCSIWSPY     0x8B10          /* set spy addresses */
+#define SIOCGIWSPY     0x8B11          /* get spy info (quality of link) */
+
+/* Access Point manipulation */
+#define SIOCSIWAP      0x8B14          /* set access point MAC addresses */
+#define SIOCGIWAP      0x8B15          /* get access point MAC addresses */
+#define SIOCGIWAPLIST  0x8B17          /* get list of access point in range */
+
+/* 802.11 specific support */
+#define SIOCSIWESSID   0x8B1A          /* set ESSID (network name) */
+#define SIOCGIWESSID   0x8B1B          /* get ESSID */
+#define SIOCSIWNICKN   0x8B1C          /* set node name/nickname */
+#define SIOCGIWNICKN   0x8B1D          /* get node name/nickname */
+/* As the ESSID and NICKN are strings up to 32 bytes long, it doesn't fit
+ * within the 'iwreq' structure, so we need to use the 'data' member to
+ * point to a string in user space, like it is done for RANGE...
+ * The "flags" member indicate if the ESSID is active or not (promiscuous).
+ */
+
+/* Other parameters usefull 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 */
+
+/* ------------------------- IOCTL STUFF ------------------------- */
+
+/* The first and the last (range) */
+#define SIOCIWFIRST    0x8B00
+#define SIOCIWLAST     0x8B30
+
+/* 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 bit rates in the range struct */
+#define IW_MAX_BITRATES                8
+
+/* Maximum tx powers in the range struct */
+#define IW_MAX_TXPOWER         8
+
+/* Maximum of address that you may set with SPY */
+#define IW_MAX_SPY             8
+
+/* Maximum of address that you may get in the
+   list of access points in range */
+#define IW_MAX_AP              8
+
+/* Maximum size of the ESSID and NICKN strings */
+#define IW_ESSID_MAX_SIZE      32
+
+/* Modes of operation */
+#define IW_MODE_AUTO   0       /* Let the driver decides */
+#define IW_MODE_ADHOC  1       /* Single cell network */
+#define IW_MODE_INFRA  2       /* Multi cell network, roaming, ... */
+#define IW_MODE_MASTER 3       /* Synchronisation master or Access Point */
+#define IW_MODE_REPEAT 4       /* Wireless Repeater (forwarder) */
+#define IW_MODE_SECOND 5       /* Secondary master/repeater (backup) */
+
+/* Maximum number of size of encoding token available
+ * they are listed in the range structure */
+#define IW_MAX_ENCODING_SIZES  8
+
+/* Maximum size of the encoding token in bytes */
+#define IW_ENCODING_TOKEN_MAX  32      /* 256 bits (for now) */
+
+/* Flags for encoding (along with the token) */
+#define IW_ENCODE_INDEX                0x00FF  /* Token index (if needed) */
+#define IW_ENCODE_FLAGS                0xFF00  /* Flags defined below */
+#define IW_ENCODE_MODE         0xF000  /* Modes defined below */
+#define IW_ENCODE_DISABLED     0x8000  /* Encoding disabled */
+#define IW_ENCODE_ENABLED      0x0000  /* Encoding enabled */
+#define IW_ENCODE_RESTRICTED   0x4000  /* Refuse non-encoded packets */
+#define IW_ENCODE_OPEN         0x2000  /* Accept non-encoded packets */
+#define IW_ENCODE_NOKEY         0x0800  /* Key is write only, so not present */
+
+/* Power management flags available (along with the value, if any) */
+#define IW_POWER_ON            0x0000  /* No details... */
+#define IW_POWER_TYPE          0xF000  /* Type of parameter */
+#define IW_POWER_PERIOD                0x1000  /* Value is a period/duration of  */
+#define IW_POWER_TIMEOUT       0x2000  /* Value is a timeout (to go asleep) */
+#define IW_POWER_MODE          0x0F00  /* Power Management mode */
+#define IW_POWER_UNICAST_R     0x0100  /* Receive only unicast messages */
+#define IW_POWER_MULTICAST_R   0x0200  /* Receive only multicast messages */
+#define IW_POWER_ALL_R         0x0300  /* Receive all messages though PM */
+#define IW_POWER_FORCE_S       0x0400  /* Force PM procedure for sending unicast */
+#define IW_POWER_REPEATER      0x0800  /* Repeat broadcast messages in PM period */
+#define IW_POWER_MODIFIER      0x000F  /* Modify a parameter */
+#define IW_POWER_MIN           0x0001  /* Value is a minimum  */
+#define IW_POWER_MAX           0x0002  /* Value is a maximum */
+#define IW_POWER_RELATIVE      0x0004  /* Value is not in seconds/ms/us */
+
+/* Transmit Power flags available */
+#define IW_TXPOW_DBM           0x0000  /* Value is in dBm */
+#define IW_TXPOW_MWATT         0x0001  /* Value is in mW */
+
+/* Retry limits and lifetime flags available */
+#define IW_RETRY_ON            0x0000  /* No details... */
+#define IW_RETRY_TYPE          0xF000  /* Type of parameter */
+#define IW_RETRY_LIMIT         0x1000  /* Maximum number of retries*/
+#define IW_RETRY_LIFETIME      0x2000  /* Maximum duration of retries in us */
+#define IW_RETRY_MODIFIER      0x000F  /* Modify a parameter */
+#define IW_RETRY_MIN           0x0001  /* Value is a minimum  */
+#define IW_RETRY_MAX           0x0002  /* Value is a maximum */
+#define IW_RETRY_RELATIVE      0x0004  /* Value is not in seconds/ms/us */
+
+/****************************** TYPES ******************************/
+
+/* --------------------------- SUBTYPES --------------------------- */
+/*
+ *     Generic format for most parameters that fit in an int
+ */
+struct iw_param
+{
+  __s32                value;          /* The value of the parameter itself */
+  __u8         fixed;          /* Hardware should not use auto select */
+  __u8         disabled;       /* Disable the feature */
+  __u16                flags;          /* Various specifc flags (if any) */
+};
+
+/*
+ *     For all data larger than 16 octets, we need to use a
+ *     pointer to memory alocated in user space.
+ */
+struct iw_point
+{
+  caddr_t      pointer;        /* Pointer to the data  (in user space) */
+  __u16                length;         /* number of fields or size in bytes */
+  __u16                flags;          /* Optional params */
+};
+
+/*
+ *     A frequency
+ *     For numbers lower than 10^9, we encode the number in 'm' and
+ *     set 'e' to 0
+ *     For number greater than 10^9, we divide it by the lowest power
+ *     of 10 to get 'm' lower than 10^9, with 'm'= f / (10^'e')...
+ *     The power of 10 is in 'e', the result of the division is in 'm'.
+ */
+struct iw_freq
+{
+       __u32           m;              /* Mantissa */
+       __u16           e;              /* Exponent */
+       __u8            i;              /* List index (when in range struct) */
+};
+
+/*
+ *     Quality of the link
+ */
+struct iw_quality
+{
+       __u8            qual;           /* link quality (%retries, SNR 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 */
+};
+
+/* ------------------------ 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 */
+};
+
+/* ------------------------ IOCTL REQUEST ------------------------ */
+/*
+ * The structure to exchange data for ioctl.
+ * This structure is the same as 'struct ifreq', but (re)defined for
+ * convenience...
+ *
+ * Note that it should fit on the same memory footprint !
+ * You should check this when increasing the above structures (16 octets)
+ * 16 octets = 128 bits. Warning, pointers might be 64 bits wide...
+ */
+struct iwreq 
+{
+       union
+       {
+               char    ifrn_name[IFNAMSIZ];    /* if name, e.g. "eth0" */
+       } ifr_ifrn;
+
+       /* Data part */
+       union
+       {
+               /* Config - generic */
+               char            name[IFNAMSIZ];
+               /* Name : used to verify the presence of  wireless extensions.
+                * Name of the protocol/provider... */
+
+               struct iw_point essid;  /* Extended network name */
+               struct iw_param nwid;   /* network id (or domain - the cell) */
+               struct iw_freq  freq;   /* frequency or channel :
+                                        * 0-1000 = channel
+                                        * > 1000 = frequency in Hz */
+
+               struct iw_param sens;           /* signal level threshold */
+               struct iw_param bitrate;        /* default bit rate */
+               struct iw_param txpower;        /* default transmit power */
+               struct iw_param rts;            /* RTS threshold threshold */
+               struct iw_param frag;           /* Fragmentation threshold */
+               __u32           mode;           /* Operation mode */
+               struct iw_param retry;          /* Retry limits & lifetime */
+
+               struct iw_point encoding;       /* Encoding stuff : tokens */
+               struct iw_param power;          /* PM duration/timeout */
+
+               struct sockaddr ap_addr;        /* Access point address */
+
+               struct iw_point data;           /* Other large parameters */
+       }       u;
+};
+
+/* -------------------------- IOCTL DATA -------------------------- */
+/*
+ *     For those ioctl which want to exchange mode data that what could
+ *     fit in the above structure...
+ */
+
+/*
+ *     Range of parameters
+ */
+
+struct iw_range
+{
+       /* Informative stuff (to choose between different interface) */
+       __u32           throughput;     /* To give an idea... */
+       /* In theory this value should be the maximum benchmarked
+        * TCP/IP throughput, because with most of these devices the
+        * bit rate is meaningless (overhead an co) to estimate how
+        * fast the connection will go and pick the fastest one.
+        * I suggest people to play with Netperf or any benchmark...
+        */
+
+       /* NWID (or domain id) */
+       __u32           min_nwid;       /* Minimal NWID we are able to set */
+       __u32           max_nwid;       /* Maximal NWID we are able to set */
+
+       /* Frequency */
+       __u16           num_channels;   /* Number of channels [0; num - 1] */
+       __u8            num_frequency;  /* Number of entry in the list */
+       struct iw_freq  freq[IW_MAX_FREQUENCIES];       /* list */
+       /* Note : this frequency list doesn't need to fit channel numbers */
+
+       /* signal level threshold range */
+       __s32   sensitivity;
+
+       /* Quality of link & SNR stuff */
+       struct iw_quality       max_qual;       /* Quality of the link */
+
+       /* Rates */
+       __u8            num_bitrates;   /* Number of entries in the list */
+       __s32           bitrate[IW_MAX_BITRATES];       /* list, in bps */
+
+       /* RTS threshold */
+       __s32           min_rts;        /* Minimal RTS threshold */
+       __s32           max_rts;        /* Maximal RTS threshold */
+
+       /* Frag threshold */
+       __s32           min_frag;       /* Minimal frag threshold */
+       __s32           max_frag;       /* Maximal frag threshold */
+
+       /* Power Management duration & timeout */
+       __s32           min_pmp;        /* Minimal PM period */
+       __s32           max_pmp;        /* Maximal PM period */
+       __s32           min_pmt;        /* Minimal PM timeout */
+       __s32           max_pmt;        /* Maximal PM timeout */
+       __u16           pmp_flags;      /* How to decode max/min PM period */
+       __u16           pmt_flags;      /* How to decode max/min PM timeout */
+       __u16           pm_capa;        /* What PM options are supported */
+
+       /* Encoder stuff */
+       __u16   encoding_size[IW_MAX_ENCODING_SIZES];   /* Different token sizes */
+       __u8    num_encoding_sizes;     /* Number of entry in the list */
+       __u8    max_encoding_tokens;    /* Max number of tokens */
+
+       /* Transmit power */
+       __u16           txpower_capa;   /* What options are supported */
+       __u8            num_txpower;    /* Number of entries in the list */
+       __s32           txpower[IW_MAX_TXPOWER];        /* list, in bps */
+
+       /* Wireless Extension version info */
+       __u8            we_version_compiled;    /* Must be WIRELESS_EXT */
+       __u8            we_version_source;      /* Last update of source */
+
+       /* Retry limits and lifetime */
+       __u16           retry_capa;     /* What retry options are supported */
+       __u16           retry_flags;    /* How to decode max/min retry limit */
+       __u16           r_time_flags;   /* How to decode max/min retry life */
+       __s32           min_retry;      /* Minimal number of retries */
+       __s32           max_retry;      /* Maximal number of retries */
+       __s32           min_r_time;     /* Minimal retry lifetime */
+       __s32           max_r_time;     /* Maximal retry lifetime */
+};
+
+/*
+ * 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 */
diff --git a/wireless_tools/xwireless.c b/wireless_tools/xwireless.c
deleted file mode 100644 (file)
index dca0d48..0000000
+++ /dev/null
@@ -1,241 +0,0 @@
-/* Xwireless.c, status: experimental, do not distribute!! */
-#include <stdio.h>
-#include <getopt.h>
-#include <sys/types.h>
-
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <ctype.h>
-
-#include <X11/Intrinsic.h>
-#include <X11/StringDefs.h>
-#include <X11/cursorfont.h>
-#include <X11/Xaw/Form.h>
-#include <X11/Xaw/Label.h>
-#include <X11/Xaw/Scrollbar.h>
-
-#include <linux/wireless.h>
-
-char* status[] = { "Scanning","Registering","Best AP","Good AP",
-                         "Poor AP","Active Beacon Search","Static Load Balance",
-                         "Balance Search" };
-
-typedef struct privateData {
-       char    *ifname;
-       Pixel   currentColor;
-       Pixel   highColor;
-       Pixel   lowColor;
-       Pixel   criticalColor;
-       Pixel   foreground;
-       int     highValue;
-       int     lowValue;
-       int     delay;
-       String  geometry;
-       struct  iw_statistics stats;
-       struct  iw_range range;
-} privateData;
-
-static XtAppContext          app_context;
-static Widget                scrollbar;
-static Widget                topLevel;
-static Widget                label;
-static XtIntervalId          timerId;
-static privateData    priv;
-
-static int getstats(char *ifname, struct iw_statistics *stats)
-{
-       struct iwreq wrq;
-       FILE *f=fopen("/proc/net/wireless","r");
-       char buf[256];
-       char *bp;
-       if(f==NULL)
-               return -1;
-       while(fgets(buf,255,f))
-       {
-               bp=buf;
-               while(*bp&&isspace(*bp))
-                       bp++;
-               if( strncmp(bp,ifname,strlen(ifname))==0 && bp[strlen(ifname)]==':') {
-                       bp=strchr(bp,':');
-                       bp++;
-                       bp = strtok(bp, " .");
-                       sscanf(bp, "%X", &stats->status);
-                       bp = strtok(NULL, " .");
-                       sscanf(bp, "%d", &stats->qual.qual);
-                       bp = strtok(NULL, " .");
-                       sscanf(bp, "%d", &stats->qual.level);
-                       bp = strtok(NULL, " .");
-                       sscanf(bp, "%d", &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;
-               } else {
-                       stats->status = -1;
-                       stats->qual.qual = 0;
-                       stats->qual.level = 0;
-                       stats->qual.noise = 0;
-               }
-       }
-       fclose(f);
-
-       /*strcpy(wrq.ifr_name, ifname);
-       wrq.u.data.pointer = (caddr_t) &range;
-       wrq.u.data.length = 0;
-       wrq.u.data.flags = 0;
-       if(ioctl(skfd, SIOCGIWRANGE, &wrq) >= 0) {
-               info->has_range = 1;
-    }*/
-       
-       return 0;
-}
-
-static void update( XtPointer client_data, XtIntervalId *id )
-{
-       char       buf[128];
-       static int pixel           = -1;
-       static int lpixel          = -1;
-       static int bpixel          = -1;
-
-       getstats( priv.ifname, &(priv.stats));
-
-       if(status < 8)
-         sprintf( buf, "%s", status[priv.stats.status] );
-       else
-         sprintf( buf, "%s", "buggy" );
-       XtVaSetValues( label, XtNlabel, buf, NULL );
-
-       if (priv.stats.qual.qual <= priv.lowValue) {
-               if (pixel != priv.criticalColor)
-                       XtVaSetValues( scrollbar, XtNforeground,
-                                                  pixel = priv.criticalColor, NULL );
-               if (bpixel != priv.criticalColor)
-                       XtVaSetValues( scrollbar, XtNborderColor,
-                                                  bpixel = priv.criticalColor, NULL );
-       } else if (priv.stats.qual.qual <= priv.highValue) {
-               if (pixel != priv.lowColor)
-                       XtVaSetValues( scrollbar, 
-                                                  XtNforeground, pixel = priv.lowColor, NULL );
-               if (bpixel != priv.foreground)
-                       XtVaSetValues( scrollbar, XtNborderColor,
-                                                  bpixel = priv.foreground, NULL );
-       } else {
-               if (pixel != priv.highColor )
-                       XtVaSetValues( scrollbar, 
-                                                  XtNforeground, pixel = priv.highColor, NULL );
-       }
-       
-       XawScrollbarSetThumb( scrollbar, 0.0, priv.stats.qual.qual / 255.0 );
-       timerId = XtAppAddTimeOut( app_context, 1000 , update, app_context );
-}
-
-#define offset(field) XtOffsetOf( privateData, field )
-static XtResource resources[] = {
-       { "highColor", XtCForeground, XtRPixel, sizeof(Pixel),
-         offset(highColor), XtRString, "green" },
-       { "lowColor", XtCForeground, XtRPixel, sizeof(Pixel),
-         offset(lowColor), XtRString, "orange" },
-       { "criticalColor", XtCForeground, XtRPixel, sizeof(Pixel),
-         offset(criticalColor), XtRString, "red" },
-       { XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
-         offset(foreground), XtRString, XtDefaultForeground },
-       { "highValue", XtCValue, XtRInt, sizeof(int),
-         offset(highValue), XtRImmediate, (XtPointer)50 },
-       { "lowValue", XtCValue, XtRInt, sizeof(int),
-         offset(lowValue), XtRImmediate, (XtPointer)10 },
-       { "geometry", XtCString, XtRString, sizeof( String ),
-         offset(geometry), XtRString, (XtPointer)"10x100" },
-       { "delay", XtCValue, XtRInt, sizeof(int),
-         offset(delay), XtRImmediate, (XtPointer)1 },
-};
-
-int main( int argc, char **argv ) {
-       Cursor           cursor;
-       int              c;
-       Widget           form;
-       XFontStruct      *fs;
-       int              fontWidth, fontHeight;
-       int              width = 120;
-       
-       /* The device name must be the first argument */
-       if(argc < 2) {
-               printf("Hmm\n");                
-    }
-       priv.ifname = argv[1];
-
-       if( priv.ifname == (char *) NULL) {
-               printf("Usage: xwireless <interface>\n");
-               exit(-1);
-       }
-
-       topLevel = XtVaAppInitialize( &app_context, "Xwireless",
-                                                                 NULL, 0,
-                                                                 &argc, argv, NULL, NULL );
-
-       XtGetApplicationResources( topLevel,
-                                                          &priv,
-                                                          resources,
-                                                          XtNumber( resources ),
-                                                          NULL, 0 );
-       priv.lowValue = 85;
-       priv.highValue = 170;
-
-/*     printf( "highColor = %ld\n",     priv.highColor );
-       printf( "lowColor = %ld\n",      priv.lowColor );
-       printf( "criticalColor = %ld\n", priv.criticalColor );
-       printf( "foreground = %ld\n",    priv.foreground );
-       printf( "highValue = %d\n",      priv.highValue );
-       printf( "lowValue = %d\n",       priv.lowValue );
-       printf( "geometry = %s\n",       priv.geometry );*/
-
-       cursor = XCreateFontCursor( XtDisplay( topLevel ), XC_top_left_arrow );
-       
-       form = XtVaCreateManagedWidget( "form",
-                                                                       formWidgetClass, topLevel,
-                                                                       XtNorientation, XtorientHorizontal,
-                                                                       XtNborderWidth, 0,
-                                                                       XtNdefaultDistance, 2,
-                                                                       NULL );
-   
-    label = XtVaCreateManagedWidget( "label",
-                                                                        labelWidgetClass, form,
-                                                                        XtNleft, XtChainLeft,
-                                                                        XtNinternalHeight, 0,
-                                                                        XtNinternalWidth, 0,
-                                                                        XtNborderWidth, 0,
-                                                                        XtNlabel, "Status",
-                                                                        NULL );
-       
-       XtVaGetValues( label, XtNfont, &fs, NULL );
-       fontWidth  = fs->max_bounds.width;
-       fontHeight = fs->max_bounds.ascent + fs->max_bounds.descent;
-       XtVaSetValues( label, XtNwidth, fontWidth * 8, NULL );
-       
-       scrollbar = XtVaCreateManagedWidget( "scrollbar",
-                                                                                scrollbarWidgetClass, form,
-                                                                                XtNhorizDistance, 3,
-                                                                                XtNfromHoriz, label,
-                                                                                XtNorientation, XtorientHorizontal,
-                                                                                XtNscrollHCursor, cursor,
-                                                                                XtNthickness, fontHeight,
-                                                                                XtNlength, (width > fontWidth*4 - 6)
-                                                                                ? width - fontWidth * 4 - 6
-                                                                                : fontWidth * 4,
-                                                                                NULL );
-       
-       XawScrollbarSetThumb( scrollbar, 0.0, 0.0 );
-/*     XtVaSetValues( scrollbar,
-                                  XtNtranslations, XtParseTranslationTable( "" ), NULL );
-                                  */
-       XtRealizeWidget( topLevel );
-       timerId = XtAppAddTimeOut( app_context, 0, update, app_context );
-       XtAppMainLoop( app_context );
-       
-       return 0;
-}
diff --git a/wireless_tools/xwireless.make b/wireless_tools/xwireless.make
deleted file mode 100644 (file)
index 758d827..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-# Makefile for Xwireless
-CC = gcc
-RM = rm -f
-
-RM_CMD = $(RM) *.BAK *.bak *.o ,* *~ *.a
-
-INCLUDES =     $(SYS_INCLUDES) $(LOCAL_INCLUDES)
-LIBRARIES =    $(LOCAL_LIBRARIES) $(SYS_LIBRARIES)
-LIBPATH = $(SYS_LIBPATH) $(LOCAL_LIBPATH)
-
-#
-# System stuff
-#
-SYS_INCLUDES = -I/usr/include  -I/usr/X11R6/include
-SYS_LIBRARIES = -lXaw -lXmu -lXt -lXext  -lSM -lICE -lX11      
-SYS_LIBPATH = -L/usr/lib -L/usr/local/lib -L/usr/X11R6/lib
-
-#
-# Local stuff
-#
-LOCAL_INCLUDES = 
-LOCAL_LIBRARIES        = 
-LOCAL_LIBPATH = 
-
-XTRACFLAGS=-Wall -pipe -I.
-
-# Uncomment these lines for a production compile
-#CFLAGS=-O3 -m486 -fomit-frame-pointer
-#LDFLAGS=-s
-CFLAGS=-g
-
-#
-# Files to make
-#
-PROGS=xwireless
-
-SRCS = $(PROGS).c
-OBJS = $(PROGS).o
-
-all:: $(PROGS)
-
-xwireless: $(OBJS)
-       $(CC) $(CFLAGS) -o $@ $(OBJS) $(INCLUDES) $(LIBPATH) $(LIBRARIES) 
-
-.c.o:
-       $(CC) $(CFLAGS) $(XTRACFLAGS) -c $(INCLUDES) -DNARROWPROTO $<
-
-clean::
-       $(RM_CMD) 
-
-depend::
-       makedepend -s "# DO NOT DELETE" -- $(INCLUDES) -- $(SRCS)
-# DO NOT DELETE