• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

external/wireless-tools


Commit MetaInfo

Revisión9d82610feb36dcd56d621e7831cbf5eec3f51104 (tree)
Tiempo2016-10-12 06:10:33
Autorchris-kirby <chris.kirby@hpe....>
Commiterchris-kirby

Log Message

v27

Cambiar Resumen

Diferencia incremental

--- a/wireless_tools/CHANGELOG.h
+++ b/wireless_tools/CHANGELOG.h
@@ -1,7 +1,7 @@
11 /*
22 * Wireless Tools
33 *
4- * Jean II - HPLB 97->99 - HPL 99->02
4+ * Jean II - HPLB 97->99 - HPL 99->04
55 *
66 * The changelog...
77 *
@@ -367,6 +367,171 @@
367367 * o Don't cast "int power" to unsigned long in sscanf [iwconfig]
368368 * (From Pavel Roskin <proski@gnu.org>)
369369 * o Add $(LDFLAGS) for final linking [Makefile]
370+ *
371+ * wireless 27 :
372+ * -----------
373+ * o Add 'sed' magic to automatically get WT/WE versions [Makefile]
374+ * o Change soname of iwlib to libiwWE.so.WT [Makefile]
375+ * Now dynamicaly linked versioned install can work
376+ * o Default to dynamic build, don't build static lib [Makefile]
377+ * o Update installation instructions [INSTALL]
378+ * o fflush(stdout), so that redirect to file/pipe works [iwevent]
379+ * (From Pavel Roskin <proski@gnu.org>)
380+ * o Display properly interface name larger than 8 char [all]
381+ * ---
382+ * o Implement auto/fixed frequencies [iwconfig]
383+ * (From Pavel Roskin <proski@gnu.org>)
384+ * o Don't fail is ldconfig fails [Makefile]
385+ * ---
386+ * o Fix one forgotten strcpy(ifname) -> strncpy change [iwconfig]
387+ * o Fix all dangerous sprintf, replace with snprintf [iwlib]
388+ * o Change iw_print_xxx() API to take buffer length [iwlib]
389+ * ---
390+ * o "iwspy ethX +" did not work, fix wrq.u.data.length [iwspy]
391+ * o Fix stupid bug in displaying link/ap/cell stats [iwspy]
392+ * o Fix display of fixed length char private args [iwpriv]
393+ * o Add raw output for shell scripts, options -r [iwgetid]
394+ * o Tweak scheme output for freq and mode [iwgetid]
395+ * (From Andreas Mohr)
396+ * o Spelling fixes in README and man page
397+ * ---
398+ * o Add definitions for older version of W-Ext [iwlib]
399+ * o Always force compile with latest local version of wext [Makefile]
400+ * o Change soname of iwlib back to libiw.so.WT [Makefile]
401+ * o Get rid of redirector and "make vinstall" [Makefile/iwredir]
402+ * o Convert any struct iw_range to latest version [iwlib]
403+ * o Change run-time version warning to reflect new reality [iwlib]
404+ * o Remove compile-time version warning [iwlib]
405+ * o Add iw_get_kernel_we_version() to guess kernel WE version [iwlib]
406+ * o Remove all #ifdef WIRELESS_EXT, use dynamic iwrange version [all]
407+ * o Get/display wireless stats based on iwrange version [iwlib]
408+ * o Get power and retry settings based on iwrange version [iwconfig]
409+ * o Display power and retry settings based on iwrange version [iwlist]
410+ * o Optimise use of iwrange : read on demand [iwevent]
411+ * ---
412+ * o #include <wireless.h>, instead of using a #define [iwlib.h]
413+ * o Copy latest wireless.XX.h as wireless.h and install it [Makefile]
414+ * ---
415+ * o Fix various iwlist retry display bugs [iwlist]
416+ * o Fix dynamic link to libiw back to be libiw.so (doh !) [Makefile]
417+ * ---
418+ * o Trivial cleanups and docs updates
419+ * ---
420+ * o Implement "iwconfig XXX txpower on" and fix "fixed" [iwconfig]
421+ * o Always properly initialise sanlen before recvfrom() [iwevent]
422+ * o Zero buffer so we don't print garbage after essid [iwgetid]
423+ * o Document that 00:00:00:00:00:00 == no association [iwconfig.8]
424+ * (From Guus Sliepen <guus@sliepen.eu.org>)
425+ * o Fix doc typo : ad_hoc => ad-hoc [wireless.7/DISTRIBUTIONS.txt]
426+ * ---
427+ * (From vda <vda@port.imtp.ilyichevsk.odessa.ua>)
428+ * o Accept arbitrary number of private definitions [iwlib/iwpriv]
429+ * ---
430+ * o Added Hotplug documentation [HOTPLUG.txt]
431+ * o Add dependancies (gcc way), remove makedepend [Makefile]
432+ * (From Maxime Charpenne <maxime.charpenne@free.fr>)
433+ * o Traduction en francais des pages manuel [fr/*]
434+ * o Fix some incorrect/ambiguous sentences [iwconfig.8/iwevent.8]
435+ * (From Joshua Kwan <joshk@triplehelix.org>)
436+ * o Add 'const' qualifier to iwlib API [iwlib.c/iwlib.h]
437+ * (From Joey Hess <joey@dragon.kitenet.net>)
438+ * o Add Debian schemes scripts [debian/ifscheme*]
439+ * ---
440+ * o Add 'ifrename', complete rewrite of nameif [ifrename]
441+ * o Update documentation about ifrename [HOTPLUG.txt]
442+ * (From Joshua Kwan <joshk@triplehelix.org>)
443+ * o Fix disabling of key/enc with iw_set_basic_config() & WE<13 [iwlib.c]
444+ * ---
445+ * o Various bug fixes and improvements [ifrename]
446+ * ---
447+ * o Man pages for ifrename [ifrename.8/iftab.5]
448+ * o Update hotplug/ifrename documentation [HOTPLUG.txt]
449+ * ---
450+ * o Read configuration from stdin [ifrename]
451+ * (From Thomas Hood <jdthood@yahoo.co.uk>)
452+ * o Spell check and updated man page [wireless.7]
453+ * (From Pavel Roskin <proski@gnu.org>)
454+ * o Update and spellcheck documentation [HOTPLUG.txt]
455+ * ---
456+ * o Spin-off 'ifscheme' in a separate package to please Guus Sliepen
457+ * o Update documentation on 'ifscheme' [DISTRIBUTIONS.txt/README]
458+ * (From dann frazier <dannf@debian.org>)
459+ * o Spell check and updated man page [iwlist.8]
460+ * ---
461+ * o Cache interface static data (ifname/iwrange) [iwevent.c]
462+ * ---
463+ * o Change the policy to delete entry from cache [iwevent.c]
464+ * o If no TxPower in iwrange, still print current TxPower [iwlist.c]
465+ * o Use iw_get_basic_config() in iwconfig, bloat-- [iwconfig.c/iwlib.h]
466+ * ---
467+ * (From Pavel Roskin <proski@gnu.org>)
468+ * o Fix mode boundary checking in iw_get_basic_config() [iwlib.c]
469+ * ---
470+ * o Improved priv documentation [iwpriv.c]
471+ * (From Pavel Roskin <proski@gnu.org>)
472+ * o Fix token index bug : allow zero args [iwpriv.c]
473+ * o Grammar fixes in priv documentation [iwpriv.c]
474+ * ---
475+ * o Make iw_protocol_compare() smarter [iwlib.c]
476+ * o Display freq->channel conversion in scan results [iwlist]
477+ * o Display freq->channel conversion in events [iwevent]
478+ * o Interface name takeover support [ifrename]
479+ * o Update docu for Debian Sarge, various improvements [HOTPLUG.txt]
480+ * o Set wireless parameters in the proper order [iwlib]
481+ * ---
482+ * (Suggested by Pavel Roskin <proski@gnu.org>)
483+ * o Be less dramatic is driver doesn't export txpower info [iwlist]
484+ * o Be less dramatic is driver doesn't export bitrate info [iwlist]
485+ * o Use 'updated' bits to disable printing some qual [iwlib]
486+ * o Change the way we show 'updated' bits -> '=' vs. ':' [iwlib]
487+ * o Cosmetic update to channel display [iwlist/iwevent]
488+ * ---
489+ * o Easy scanning API (blocking & non-blocking) [iwlib]
490+ * o Add channel only support to iwgetid [iwgetid]
491+ * o Compile iwgetid with iwlib for above [Makefile/iwgetid]
492+ * (From Loic Minier <lool@dooz.org> via Guus Sliepen)
493+ * o Fix french man pages to not use special 'oe' char [fr/*.8]
494+ * (From Thomas Hood <jdthood@yahoo.co.uk>)
495+ * o Use hyphens instead of underscores in Debian docs [*.txt/*.7]
496+ * ---
497+ * o Update for WE-17 (wrq.u.freq.flags, IW_QUAL_*) [all]
498+ * o Use iw_get_ext() instead of ioctl() [iwgetid]
499+ * o Retry getting scan results with larger buffer [iwlist/iwlib]
500+ * o Display wireless event capabilities [iwlist]
501+ * o Add support for relative TxPower (yick !) [iwconfig/iwlist]
502+ * o Create iw_print_txpower() [iwlib]
503+ * o Add "Set" prefix for all SET wireless events [iwevent]
504+ * (Suggested by Pavel Roskin <proski@gnu.org>)
505+ * o Add support for get_freq and get_essid events [iwevent]
506+ * ---
507+ * o Reorganise iw_print_freq() => create iw_print_freq_value() [iwlib]
508+ * o Create iw_channel_to_freq() and use it [iwlib/iwconfig/iwevent]
509+ * o Fixup for WE-18 : Set scan takes an iw_point [iwlist/iwlib]
510+ * o Fixup for WE-19 : Take care of IW_EV_POINT_OFF [iwlib]
511+ * ---
512+ * o Introduces iw_sockets_close() [all]
513+ * o Set proper size on SIOCGIWSTATS requests [iwlib]
514+ * o Use iw_print_freq_value() in iwlist [iwlist]
515+ * o Optimise iw_print_bitrate() [iwlib]
516+ * o Fix wrq.u.data.flags => wrq.u.txpower.flags [iwconfig]
517+ * (From Denis Ovsienko <pilot@altlinux.ru>)
518+ * o Add dry-run support (only print name changes) [ifrename]
519+ * ---
520+ * o Move WE_VERSION/WT_VERSION to iwlib.h [iwlib/Makefile]
521+ * o Add support for new selector pcmciaslot [ifrename]
522+ * o Improve/cleanup DEBUG/verbose output [ifrename]
523+ * o Minor documentation updates [HOTPLUG.txt/DISTRIBUTIONS.txt]
524+ * (From Francesco Potorti` <pot@potorti.it>)
525+ * o Allow iwgetid to accept '-c' options [iwgetid]
526+ * (From Ian Gulliver <ian@penguinhosting.net>)
527+ * o Transform #define DEBUG into verbose command line switch [ifrename]
528+ * ---
529+ * (From Dan Williams <dcbw@redhat.com>)
530+ * o Fix buffer memory leak in scanning [iwlib/iwlist]
531+ * ---
532+ * o Make sure gcc inline stuff properly [iwlib.h]
533+ * o Update Hotplug documentation [HOTPLUG.txt]
534+ * o Add support for new selector firmware [ifrename]
370535 */
371536
372537 /* ----------------------------- TODO ----------------------------- */
@@ -391,9 +556,10 @@
391556 * Add scanning command line modifiers
392557 * More scan types support
393558 *
394- * iwevent :
395- * -------
396- * Make it non root-only
559+ * ifrename :
560+ * --------
561+ * Link Type should use readable form instead of numeric value
562+ * Support non MAC/Eth addresses ?
397563 *
398564 * Doc & man pages :
399565 * ---------------
--- a/wireless_tools/DISTRIBUTIONS.txt
+++ b/wireless_tools/DISTRIBUTIONS.txt
@@ -103,7 +103,7 @@ You can now add extra statements to the iface sections of the files in
103103 /etc/network/interfaces that are specific for wireless interfaces. They
104104 are of the form:
105105
106- wireless_<function> <value>
106+ wireless-<function> <value>
107107
108108 Before the interface is brought up, such a statement will result in the
109109 execution of the following command:
@@ -117,8 +117,8 @@ iface eth0 inet static
117117 network 192.168.1.0
118118 netmask 255.255.255.0
119119 broadcast 192.168.1.255
120- wireless_essid Home
121- wireless_mode ad_hoc
120+ wireless-essid Home
121+ wireless-mode ad-hoc
122122
123123 The current Debian script support all arguments present in
124124 wireless.opts apart from Nickname. You can check this in the script
@@ -135,19 +135,19 @@ do everything pcmcia schemes can do, and more. Here is part of mine:
135135
136136 auto wlan0
137137 mapping wlan0
138- script /usr/local/bin/ifscheme
138+ script /usr/local/bin/ifscheme-mapping
139139
140140 iface wlan0-home inet static
141141 address 192.168.1.5
142142 gateway 192.168.1.1
143143 netmask 255.255.255.0
144- wireless_mode ad_hoc
145- wireless_essid wortroot
146- wireless_nick dragon
147- wireless_channel 1
144+ wireless-mode ad-hoc
145+ wireless-essid wortroot
146+ wireless-nick dragon
147+ wireless-channel 1
148148
149149 iface wlan0-away inet dhcp
150- wireless_mode managed
150+ wireless-mode managed
151151
152152 Now I can type 'ifscheme -s away' when I leave home, rather like
153153 cardctl scheme.
@@ -171,8 +171,23 @@ ifupdown.
171171
172172 -----
173173
174- You may also want to check ifupdown-roaming :
174+ (Contributed by Jean Tourrilhes <jt@hpl.hp.com>)
175+ The 'ifscheme' scripts mentionned above are now available in
176+Debian Sarge, in the 'ifscheme' package.
177+ The MAC address based mapping mentioned above is deprecated,
178+you should use 'ifrename' to assign a consistent interface name to
179+each of your network interface. This is documented in
180+HOTPLUG.txt. This enable the combination of MAC address identification
181+of interfaces with scheme multi-configuration.
182+
183+ -----
184+
185+ If you need automatic wireless configuration, you can look at
186+the following packages :
187+ o ifupdown-roaming :
175188 http://panopticon.csustan.edu/thood/ifupdown-roaming.html
189+ o waproamd
190+ http://0pointer.de/lennart/projects/waproamd/
176191
177192 ---------------------------------------------------------------------
178193
@@ -339,13 +354,21 @@ eth0, eth1, ...).
339354 all of them. The script doing the configuration and where you can
340355 check the details is :
341356 /etc/network/network-scripts/ifup-wireless
342- You will of course need the Wireless Extension package :
357+ You will of course need the Wireless Tools package :
343358 rpm -Uvh wireless-tools-XX-Xmdk.XXX.rpm
344359
345360 Mandrake can also have wireless setting added to its
346361 Auto-Install procedure :
347362 http://members.shaw.ca/mandrake/drakx/8.2/HTML/section4-13.html
348363
364+ -----
365+
366+ (in e-mail from Thierry Vignaud <tvignaud@mandrakesoft.com>)
367+ You may use the following tool :
368+ o drakconnect
369+ You may read the following documentation :
370+ o ifcfg
371+
349372 ---------------------------------------------------------------------
350373
351374
--- /dev/null
+++ b/wireless_tools/HOTPLUG.txt
@@ -0,0 +1,990 @@
1+ Sane Hotplug network interface management
2+ -----------------------------------------
3+
4+INTRODUCTION
5+------------
6+ In the old day, all Wireless cards were managed by the
7+excellent Pcmcia subsystem and its rich configuration scripts, and
8+life was happy. Then came the wireless PCI cards, then the wireless
9+USB dongles. Some unification was needed, and rather than adapt the
10+Pcmcia subsystem for PCI and USB, it was decided to create the much
11+simpler Hotplug systems.
12+ The USB subsystem already use Hotplug, and the Pcmcia
13+subsystem is migrating to it, CardBus cards (32 bits) already use
14+Hotplug, whereas Pcmcia cards (16 bits) still use the old Pcmcia
15+scripts.
16+ The Hotplug system is still in its infancy, but already show
17+some good promises. Most users are disapointed at first by its
18+apparent lack of features compared to the Pcmcia scripts. In this
19+document, we will show how to fully exploit the Hotplug system and try
20+to implement the equivalent of all the functionality of the Pcmcia
21+scripts.
22+
23+ASSUMPTIONS
24+-----------
25+ The target audience of this document is mostly power users and
26+distribution maintainers, but it should give enough clues to help
27+newbies. You should have read and understood DISTRIBUTIONS.txt. The
28+procedures described here are more advanced than the simple
29+configuration described in DISTRIBUTIONS.txt.
30+ The main focus is of course removable wireless interfaces, but
31+we will try to keep things generic and talk of the whole network
32+interface management, so this should apply also to built-in Ethernet
33+cards.
34+
35+PROBLEM STATEMENT
36+-----------------
37+ Let assume a Linux system and two or more network devices,
38+Device A and Device B. Those devices may be built-in or removable,
39+they may be present or absent from the system at any time, and
40+activated in any particular order.
41+ The user wants to assign Configuration A to Device A and
42+Configuration B to Device B, without the possibility that Device A get
43+assigned Configuration B.
44+ Different users may have different definition of what is
45+Device A. For some, it's a specific instance of a specific hardware,
46+for others any hardware that meet some criteria (a wireless card, an
47+Ethernet card).
48+ The user may also want to have multiple configurations
49+depending on various factors (like the old Pcmcia schemes). Device A
50+may get Configuration A1 or Configuration A2 depending on those
51+factors.
52+ By default, all network interfaces are created using a default
53+interface name (starting at "eth0" and going up). I call that problem
54+"all my cards are eth0". And by default, "eth0" point to a single
55+fixed configuration in the configuration database. Clearly, this won't
56+satisfy our requirements.
57+
58+EXAMPLE SYSTEM
59+--------------
60+ The distribution I use is Debian 3.0, and some parts will be
61+specific to it. However, it should be easy to translate to other
62+distributions and I welcome additions to this document.
63+
64+ The example system is as follows :
65+ o Linux 2.6.X SMP kernel with hotplug support
66+ o Fully modular system (all network drivers as modules)
67+ o PCI Ethernet card : AMD PCnet LANCE (pcnet32 - eth4)
68+ o PCI Ethernet card : HP 100VG J2585B (hp100 - eth2)
69+ o ISA Wireless card : Old AT&T Wavelan (wavelan - eth3)
70+ o ISA-Pcmcia bridge : VADEM VG-469 (i82365 - slot 0)
71+ o PCI-CardBus bridge : Ricoh RL5c475 (yenta_socket - slot 2)
72+ o Pcmcia 802.11 card : Aironet 350 (airo_cs - eth0)
73+ o Pcmcia 802.11 card : Lucent Orinoco (orinoco_cs - eth0)
74+ o CardBus 802.11 card : SMC 2835W (prism54 - prism0)
75+
76+ This system just happen to be my Linux development box, and
77+has enough interfaces to make it interesting. All the example I quote
78+in this document are extracted from this fully working system.
79+
80+BASIC CONCEPTS
81+--------------
82+ Most of the concept and tricks presented here are not really
83+new, the main contribution is to integrate them together and make them
84+work.
85+
86+ 1) Removable network interfaces are managed by Hotplug
87+(Pcmcia, CardBus, USB...). We can't assume that those interfaces are
88+always present in this system and available at boot time (Pcmcia cards
89+are not made to be soldered in the Pcmcia slot), therefore Hotplug is
90+the only way to go.
91+ 2) Built-in PCI and ISA cards are managed by the init scripts,
92+like they have always been. The ISA subsystem will never have Hotplug
93+support, and hotplug is not necessary for PCI cards.
94+ 3) Built-in devices that are disable most of the time should
95+be enabled manually.
96+ 4) (1), (2) and (3) must be compatible on the same system and
97+play nice with each other.
98+
99+ 5) A well defined and consistent network interface name is
100+assigned to each network hardware interface using 'ifrename'. Device A
101+is always named 'ethA' (or whatever name you like such as
102+'mynetworkcard').
103+ 6) No interface is called 'eth0' (or 'wlan0'). Any unknown
104+device would be 'eth0', thefore known device should avoid using it
105+because it might be already taken.
106+ 7) Multiple configurations for a single interface (schemes)
107+are managed by the ifup/ifdown subsystem.
108+
109+CONFIGURATION FROM INIT SCRIPTS
110+-------------------------------
111+ It may seems paradoxal, but before setting up Hotplug, we need
112+to make sure that the initialisation of network cards via init
113+scripts is done properly and doesn't get in our way.
114+ The configuration of network cards via init scripts is the
115+traditional way network is initialised in Linux. The advantage of this
116+method is that it's very well documented and understood, and has not
117+changed much over the years. Unfortunately, it doesn't support
118+properly removable cards.
119+ The init scripts perform the following 3 functions in that
120+order :
121+ 1) load necessary driver modules
122+ 2) rename interface to name chosen by the user
123+ 3) configure those interfaces
124+
125+ 1) Applicability
126+ ----------------
127+ Configuration from init scripts is applicable to any built-in
128+network interface (ISA, PCI...), i.e. interfaces availalble at boot
129+time and that will never be removed from the system.
130+ The Hotplug subsystem has also the ability to configure some
131+of the built-in network interfaces, such as PCI cards. However, there
132+is a class of devices that will never have Hotplug support, such as
133+ISA and EISA cards, and for those Hotplug won't work.
134+ The advantage of using the init script method is that you are
135+probably already familiar with it and you have the ability to select
136+which interfaces should be configured at boot and which interface
137+should only be enabled manually (whereas Hotplug just configures
138+everything).
139+
140+ 2) Loading driver modules (if/as needed)
141+ ----------------------------------------
142+ Most distributions build the kernel drivers as modules. This
143+modular setup allow to minimise the amount of memory used by the
144+system and the flexible loading/unloading of drivers.
145+ You can also compile your kernel with static drivers
146+(non-modular). In that case, the driver will always be available in
147+your kernel, you don't need to configure the module subsystem, so you
148+can skip directly to the next section.
149+
150+ There are 3 alternatives to manage device drivers as
151+modules. Some distribution have explicit list of modules that are
152+loaded at boot time, if you want to use that feature you need to check
153+your distribution. Some system, such as hotplug or kudzu, can scan the
154+various buses of the PC and load the appropriate drivers, and this is
155+mostly configuration-free, but may not support all devices. The module
156+subsystem also allow to load modules 'on-demand'.
157+
158+ I personally prefer to use the 'on-demand' feature of the
159+module subsystem has, as it allows you to not have to specify the list
160+of modules that need to be loaded, and only modules really necessary
161+are loaded which save kernel memory. You can also choose which module
162+to load when there are multiple altenate modules valid for your
163+hardware (which happens quite often).
164+
165+ With kernel 2.6.X, the module subsystem is configured in
166+/etc/modprobe.conf. To configure 'on-demand' module loading, I need to
167+add to this file the following lines :
168+
169+--------- /etc/modprobe.conf ----------------
170+# HP 100VG J2585B PCI card
171+alias eth2 hp100
172+
173+# AMD AMD PCnet LANCE PCI card
174+alias eth4 pcnet32
175+
176+# Old AT&T Wavelan ISA card
177+alias eth3 wavelan
178+options wavelan io=0x390 irq=15
179+---------------------------------------------
180+
181+ Your distribution may already have lines for your interfaces,
182+either replace them or make sure they are correct (some distro are
183+notorious for picking the wrong driver name). This file also contains
184+configuration for lot of other subsystems, obviously you don't want to
185+touch that.
186+ In this file, you put the name you would like the interface to
187+have (we'll fix that in a minute). You note that for modern PCI cards,
188+this is much more straightforward than for old ISA cards.
189+
190+ 3) Installing 'ifrename'
191+ ------------------------
192+ You will need to install ifrename on your system. 'ifrename'
193+is part of the Wireless Tools package (version 27 and later) and is a
194+complete rewrite of the now obsolete 'nameif'.
195+ Some distributions, such as Debian Sarge, offer a specific
196+package for 'ifrename', and in this case you should just install this
197+package. Other distributions may include ifrename as part of their
198+'wireless tools' package (this should be the case for Geentoo and
199+Mandrake). Other distributions, such as Debian 3.0, don't include
200+ifrename at all, and you should compile yourself a recent version of
201+Wireless Tools (v27 or later) and install it.
202+
203+ In any case, you should verify if 'ifrename' is properly
204+installed, and what is the path to call it.
205+--------------------------
206+> which ifrename
207+/sbin/ifrename
208+--------------------------
209+ Most distributions will install 'ifrename' in '/sbin', while if
210+you compile your own wireless tools, it will be in '/usr/local/sbin'.
211+
212+ 4) Making the boot scripts call 'ifrename'
213+ ------------------------------------------
214+ You need to make sure 'ifrename' is run at boot time. Most
215+distributions don't do that yet by default.
216+ This is a part that is distribution specific, so you will need
217+to look into your init files. It will need to run just before the call
218+to 'ifup' or 'ifconfig' command.
219+
220+ In Debian 3.0, it needs to be run from /etc/init.d/networking,
221+which is not the default. The necessary patch is below :
222+
223+----------------------------------------------------------------
224+--- networking-orig Wed Feb 18 13:56:23 2004
225++++ networking Fri Feb 20 14:51:06 2004
226+@@ -120,6 +120,15 @@ case "$1" in
227+ doopt syncookies no
228+ doopt ip_forward no
229+
230++ # Optionally remap interface names based on MAC address.
231++ # '/sbin/ifrename' is part of wireless-tools package.
232++ # /etc/iftab is currently not created by default. Jean II
233++ if [ -x /sbin/ifrename ] && [ -r /etc/iftab ]; then
234++ echo -n "Remapping network interfaces name: "
235++ ifrename -p
236++ echo "done."
237++ fi
238++
239+ echo -n "Configuring network interfaces: "
240+ ifup -a
241+ echo "done."
242+----------------------------------------------------------------
243+ Don't forget to set the appropriate path to call ifrename (see
244+step (3) above).
245+
246+ You may want to also set the proper options for ifrename
247+(check the man page).
248+ The option '-p' enable module autoloading compatibility.
249+ The default version of 'ifrename' also includes some specific
250+Debian support : using "ifrename -p -d", only the proper modules are
251+loaded. If you are using Debian, you should use this option.
252+
253+ 5) Renaming interfaces
254+ ----------------------
255+ As stated above, we use 'ifrename' to assign names to
256+interfaces.
257+
258+ First, you need to get the MAC address of each of you
259+interface. You can read it on the label on the card or display it
260+using the 'ifconfig' command. Remember that the interface won't load
261+yet with the proper name, so you may need to do a bit looking around :
262+
263+-----------------------------
264+> modprobe pcnet32
265+> ifconfig eth0
266+eth0 Link encap:Ethernet HWaddr 00:10:83:34:BA:E5
267+[...]
268+-----------------------------
269+
270+ The configuration of 'ifrename' is simple, you just specify
271+which name should be used for each MAC address in the file
272+/etc/iftab :
273+
274+--------- /etc/iftab ------------------------
275+# HP 100VG J2585B PCI card
276+eth2 mac 08:00:09:*
277+
278+# Old AT&T Wavelan ISA card
279+eth3 mac 08:00:0E:*
280+
281+# AMD AMD PCnet LANCE PCI card
282+eth4 mac 00:10:83:*
283+---------------------------------------------
284+
285+ The '*' in the MAC address is a wildcard and allow me to
286+replicate my configuration between multiple identical computers. If
287+you have to manage large number of computers (like a rack of server or
288+clusters), you may want to look at other selectors offered by
289+'ifrename', such as the ability to base interface name on Bus
290+Information.
291+
292+ To test that ifrename works, do the following :
293+ o load all your drivers, see section (2)
294+ o check /proc/net/dev to see which interface exist
295+ o bring all interfaces down : ifconfig ethX down
296+ o run ifrename
297+ o check each interface with ifconfig
298+
299+ 6) Configuring interfaces
300+ -------------------------
301+ Most likely, your distribution is already doing this part
302+properly. Just assign the proper IP and wireless configuration to each
303+of the interface name you have chosen.
304+ This part is distribution specific, and I already document it
305+in the file DISTRIBUTIONS.txt.
306+
307+ In Debian, you would need to modify the file
308+/etc/network/interfaces like this :
309+
310+--------- /etc/network/interfaces -----------
311+# AMD AMD PCnet LANCE PCI card
312+auto eth4
313+iface eth4 inet dhcp
314+
315+# HP 100VG J2585B PCI card
316+auto eth2
317+iface eth2 inet static
318+ address 10.0.0.2
319+ network 10.0.0.0
320+ netmask 255.255.255.0
321+ broadcast 10.0.0.255
322+ gateway 10.0.0.1
323+---------------------------------------------
324+
325+ This was the last part. Now, at your next boot, all your
326+interfaces should be assigned the proper name and proper
327+configuration.
328+
329+CONFIGURATION VIA HOTPLUG
330+-------------------------
331+ Dealing with removable interfaces is similar to built-in
332+interfaces, the only difference is that we will use the Hotplug
333+scripts instead of the init scripts. Another difference is that it
334+will require more work on your part because most distributions are not
335+fully ready for it.
336+
337+ 1) Applicability
338+ ----------------
339+ The Hotplug configuration method is the best choice for any
340+removable network interface, such as :
341+ o Pcmcia (16 bits) network cards
342+ o CardBus (32 bits) network cards
343+ o USB network dongles
344+ o Hot-PCI network cards
345+ It may also be used to manage other types of network
346+interfaces, although it may not be the best choice for them.
347+
348+ 2) How Hotplug works
349+ --------------------
350+ Conceptually, Hotplug is very simple. When something
351+interesting happens, the Linux kernel generates an Hotplug event. This
352+run the proper script from the /etc/hotplug directory.
353+ There is 3 types of Hotplug events we care about :
354+ o PCI event : a CardBus device is added or removed
355+from the system. The script /etc/hotplug/pci.agent is run.
356+ o USB event : a USB device is added or removed
357+from the system. The script /etc/hotplug/usb.agent is run.
358+ o Network event : a network interface is added or
359+removed from the system. The script /etc/hotplug/net.agent is run.
360+
361+ If we insert a CardBus network card in the system, the
362+following happens :
363+ 1) Kernel detects new CardBus device
364+ 2) Kernel generates PCI Hotplug event
365+ 3) /etc/hotplug/pci.agent runs, find proper driver module
366+ 4) /etc/hotplug/pci.agent loads driver module
367+ 5) Driver module initialises, creates new network device
368+ 6) Kernel detects new network device
369+ 7) Kernel generates Network Hotplug event
370+ 8) /etc/hotplug/net.agent runs, configure network device
371+ The sequence of events is similar for removals and USB devices.
372+
373+ 3) Make ifup reentrant
374+ ----------------------
375+ <Most people should ignore this part>
376+ The first problem is that we need to make sure the command
377+'ifup' is fully reentrant. If the system has built-in interfaces, the
378+'ifup' may reenter itself at boot time :
379+ 1) Init scripts start running
380+ 2) Init script calls 'ifup -a' to initialise built-in network
381+ interfaces
382+ 3) 'ifup' auto-loads driver module for built-in network
383+ interface 'eth4'
384+ 4) Driver module initialises, creates new network device
385+ 5) Kernel generates Network hotplug event
386+ 6) /etc/hotplug/net.agent runs, call 'ifup eth4'
387+ You can produce the same reentrancy if want to manually load
388+module with the ifup command.
389+
390+ The default version of 'ifup' for Debian 3.0 is not reentrant and
391+may deadlock during boot or if you use it manually. The patch to make
392+'ifup' properly reentrant is available here :
393+ http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=231197
394+ Later version of Debian (Sarge and later) have some workaround
395+that prevent deadlock in most case (but not fully eliminate them), so
396+for normal use the default 'ifup' should work fine.
397+
398+ Other distributions have very different version of ifup, and I
399+have not tried those (tell me about it).
400+
401+ 4) Installing Hotplug for Debian Sarge (testing/unstable)
402+ ---------------------------------------------------------
403+ Thanks to the great work of many people, Debian Sarge has all
404+the necessary packages and hotplug support, and will work mostly 'out
405+of the box'.
406+ You will need to install the following packages :
407+ o hotplug
408+ o ifrename
409+
410+ While the installation of Hotplug is simple, its configuration
411+may seem complex. The current network Hotplug script has 3 modes,
412+'all', 'auto' and 'hotplug', however for our purpose they all produce
413+the same results when configured. This is controlled by the variable
414+NET_AGENT_POLICY in /etc/default/hotplug.
415+
416+ In the mode "all", all interfaces are processed by
417+'ifup'. This will work without further configuration.
418+
419+ In the mode "auto", only interfaces listed in a auto statement
420+in /etc/network/interfaces will be processed by 'ifup'. If you choose
421+this mode, you need to put in /etc/network/interfaces a statement auto
422+with the complete list of all interfaces.
423+--------- /etc/network/interfaces -----------
424+# Enable Hotplug support for "auto" mode (Sarge and later)
425+auto eth0 eth1 eth2 eth3 eth4 wlan0 wlan1 prism0 prism1 airo0 airo1
426+---------------------------------------------
427+ Unfortunately, this will make 'ifup' complain at boot time
428+that it can't find those interfaces. This is why I don't recommend
429+this mode.
430+
431+ In the mode "hotplug", hotplug network events are ignored by
432+ifup by default. To enable them, therefore making this mode equal to
433+"all", you will need to add the following lines to
434+/etc/network/interfaces :
435+--------- /etc/network/interfaces -----------
436+# Enable Hotplug support for "hotplug" mode (Sarge and later)
437+mapping hotplug
438+ script echo
439+---------------------------------------------
440+
441+ 5) Installing Hotplug for Debian 3.0
442+ ------------------------------------
443+ Debian 3.0 doesn't come by default with hotplug, but the
444+hotplug package is available as regular Debian package (on the CD or
445+downloadable via apt-get), so you can just install that.
446+
447+ Unfortunately, this version of hotplug is not fully compatible
448+with kernel 2.6.X. You will need to do the following modifications to
449+the file /etc/hotplug/net.agent.
450+
451+------- /etc/hotplug/net.agent ------------------
452+--- net.agent-d1 Fri Feb 20 18:18:05 2004
453++++ net.agent Fri Feb 20 18:22:50 2004
454+@@ -26,7 +26,7 @@ if [ "$INTERFACE" = "" ]; then
455+ fi
456+
457+ case $ACTION in
458+-register)
459++add|register)
460+
461+ case $INTERFACE in
462+ # interfaces that are registered after being "up" (?)
463+@@ -52,7 +52,7 @@ register)
464+ mesg $1 $ACTION event not handled
465+ ;;
466+
467+-unregister)
468++remove|unregister)
469+ # Assume that we want to run ifdown no matter what,
470+ # because it is not going to remove the data from the
471+ # ifstate database otherwise.
472+-------------------------------------------------
473+
474+ Compared to the version in Sarge, this older version of
475+hotplug is much more basic, and doesn't have any scanning at boot time
476+and doesn't need to be enabled in /etc/network/interfaces.
477+
478+ 6) Installing hotplug, other cases
479+ ----------------------------------
480+ The canonical version of hotplug is available at :
481+ http://linux-hotplug.sourceforge.net/
482+
483+ Most distributions have various version of hotplug with
484+various modifications on top of the canonical version, and chances are
485+that the canonical version won't completely work on your system.
486+ All these various changing versions make it difficult for me
487+to tell what exactly need to be changed in the hotplug scripts to make
488+them work.
489+
490+ Some version of hotplug will do scan at boot time, see section
491+(4) for my comments on this.
492+
493+ My guess is that in a few release, all these problems will
494+sort themselves out. Just be patient.
495+
496+ 7) Dealing with 'init' hotplug
497+ ------------------------------
498+ In addition to the standard kernel Hotplug events, modern
499+versions of the Hotplug scripts add init scripts that scan the system
500+buses and generate pseudo Hotplug events. For the PCI buses, the
501+script /etc/hotplug/pci.rc is run after the boot, for the USB bus,
502+/etc/hotplug/usb.rc is run.
503+ The end result is that the Hotplug subsystem will also attempt
504+to configure built-in devices :
505+ 1) Kernel boots
506+ 2) Init runs, start to initialise the OS
507+ 3) /etc/hotplug/pci.rc runs, generate pseudo Hotplug event
508+ 4) /etc/hotplug/pci.agent loads driver module
509+ 5) Driver module initialises, creates new network device
510+ 6) Kernel generates Network Hotplug event
511+ 7) /etc/hotplug/net.agent runs, configure network device
512+
513+ At this point, you realise that at initialisation, both
514+Hotplug and the regular init scripts (see "CONFIGURATION FROM INIT
515+SCRIPTS") are trying to configure the same devices in parallel. This
516+may create problem, and it is totally redundant.
517+ Another reason I don't like this mechanism is that it blindly
518+attempt to load drivers for all hardware present on the system, and
519+don't use the configuration in /etc/modules.conf to select the proper
520+driver. It's fairly common to have multiple driver for some hardware,
521+and because of Murphy's law, Hotplug will usually load the wrong
522+one. It's also fairly common to have hardware on the system that
523+doesn't need enabling (for example, the IDE controller on my SCSI
524+machine), not loading the driver makes your kernel smaller and boot
525+faster.
526+ Unfortunately, Hotplug did not provide a simple way to disable
527+such a feature. More importantly, there is no way to selectively
528+disable it (let say, disabled for network, enabled for sound).
529+
530+ One way to disable this functionality is to delete or rename
531+the files /etc/hotplug/pci.rc and /etc/hotplug/usb.rc.
532+
533+ 8) Making hotplug scripts call ifrename
534+ ---------------------------------------
535+ The last hotplug step is to make sure that 'ifrename' is run
536+by the hotplug subsystem at the right time. As before, we want to run
537+it just before calling 'ifup'.
538+ The latest version of the hotplug scripts have this
539+integrated. However, you need to check that the path they use for
540+calling 'ifrename' is the proper one on your system. And, for older
541+versions of hotplug scripts, you will need to add this support
542+yourself.
543+
544+ Check the path for ifrename :
545+--------------------------
546+> which ifrename
547+/sbin/ifrename
548+--------------------------
549+
550+ The patch to add 'ifrename' to hotplug looks like :
551+
552+------- /etc/hotplug/net.agent ------------------
553+--- net.agent-s2 Fri Feb 20 17:18:46 2004
554++++ net.agent Fri Feb 20 17:32:43 2004
555+@@ -40,6 +40,21 @@ add|register)
556+ # we can't do much here without distro-specific knowledge
557+ # such as whether/how to invoke DHCP, set up bridging, etc.
558+
559++ # Run ifrename as needed - Jean II
560++ # Remap interface names based on MAC address. This workaround
561++ # the dreaded configuration problem "all my cards are 'eth0'"...
562++ # This needs to be done before ifup otherwise ifup will get
563++ # confused by the name changed and because iface need to be
564++ # down to change its name.
565++ if [ -x /sbin/ifrename ] && [ -r /etc/iftab ]; then
566++ debug_mesg invoke ifrename for $INTERFACE
567++ NEWNAME=`/sbin/ifrename -i $INTERFACE`
568++ if [ -n "$NEWNAME" ]; then
569++ debug_mesg iface $INTERFACE is remapped to $NEWNAME
570++ INTERFACE=$NEWNAME
571++ fi;
572++ fi
573++
574+ # RedHat and similar
575+ export IN_HOTPLUG=1
576+ if [ -x /sbin/ifup ]; then
577+-------------------------------------------------
578+
579+ If your hotplug scrips already include ifrename support, you
580+should find a section in /etc/hotplug/net.agent looking like the patch
581+above. Otherwise, just cut'n'paste the patch above in the right place.
582+ The path for 'ifrename' is used twice above, so don't forget
583+to modify both occurences...
584+
585+
586+ 9) Loading driver modules
587+ -------------------------
588+ Wow ! The most difficult part is done.
589+ In theory, you don't need to do any specific configuration for
590+the driver modules to be loaded. The 'pci.agent' and 'usb.agent'
591+should load the right driver module for you.
592+ Also, you don't need to define aliases in /etc/modprobe.conf,
593+it's useless (and may be counter productive).
594+
595+ If you use driver compiled statically in the kernel, you also
596+have nothing to do.
597+
598+ 10) Renaming interfaces
599+ -----------------------
600+ We still use ifrename to assign names to interfaces. The
601+configuration of 'ifrename' is the same. To keep the possibility of
602+having multiple wireless cards (one in each CardBus slot), we use
603+wildcards in both the MAC address and the name :
604+
605+--------- /etc/iftab -----------------------
606+# SMC 2835W wireless CardBus card
607+prism* mac 00:30:B4:*
608+---------------------------------------------
609+
610+ If you insert two cards, they would be named prism0 and
611+prism1. Note that 'name wildcarding' is a feature only available in
612+2.6.X, so if you use 2.4.X you will need to be explicit and list each
613+card separatly :
614+
615+--------- /etc/iftab -----------------------
616+# SMC 2835W wireless CardBus card
617+prism0 mac 00:30:B4:64:27:8B
618+prism1 mac 00:30:B4:64:27:8D
619+---------------------------------------------
620+
621+ 11) Configuring interfaces
622+ -------------------------
623+ At this point, configuration of Hotplug interfaces is done
624+just like their built-in counterparts. This part is still distribution
625+specific, and still already document in the file DISTRIBUTIONS.txt..
626+
627+ In Debian, you would need to modify the file
628+/etc/network/interfaces like this :
629+
630+--------- /etc/network/interfaces -----------
631+# Enable Hotplug support (Sarge and later)
632+mapping hotplug
633+ script echo
634+
635+# SMC 2835W wireless CardBus card
636+iface prism0 inet static
637+ address 10.0.1.2
638+ network 10.0.1.0
639+ netmask 255.255.255.0
640+ broadcast 10.0.1.255
641+ wireless-essid THE_ESSID
642+ wireless-mode ad-hoc
643+ wireless-channel 5
644+---------------------------------------------
645+
646+ Now, just cross your finger and plug the card in the slot...
647+
648+PCMCIA INTERFACES (16 bits)
649+---------------------------
650+ The Pcmcia subsystem has quite some legacy, and can use
651+various configuration procedure. The Pcmcia subsystem fully use
652+hotplug for 32 bits card (if you are using the kernel Pcmcia modules,
653+which is the only option for 2.6.X). For 16 bits cards, we can't make
654+them fully hotplug yet and need the cardmgr and /etc/pcmcia directory,
655+however we can make their network configuration use hotplug.
656+
657+ To use Hotplug network configuration with 16 bits Pcmcia
658+cards, first make sure the Pcmcia subsystem is properly configured and
659+that cardmgr load the right module (in most case, it should). Then,
660+make sure that you don't have any configuration entries in
661+/etc/pcmcia/network.opts and /etc/pcmcia/wireless.opts. Make sure that
662+none of entries in your system network configuration use 'eth0' or
663+'wlan0' (in /etc/network/interfaces for Debian users).
664+ Then, just follow the procedure described above for
665+"Configuration Using Hotplug" to configure your network cards.
666+
667+ You might want a little bit of explanation on why this magic
668+will work (which would help in case it doesn't work).
669+ There is two types of Pcmcia network configuration scripts,
670+available as /etc/pcmcia/network. The original Pcmcia script configure
671+network cards using options found in /etc/pcmcia/network.opts and
672+/etc/pcmcia/wireless.opts. Most distributions replace it with a script
673+calling 'ifup'. By making sure that network.opts and wireless.opts are
674+"empty", we neutralise the first set of scripts. By making sure no
675+system configuration uses 'eth0' or 'wlan0', we neutralise the second
676+set of scripts, the script would call 'ifup' with the default
677+interface name, which is usually 'eth0', ifup would not find a
678+configuration for it and would just ignores it.
679+ The card would still be configured because hotplug network
680+events are generated for every interfaces, not only for devices
681+managed by hotplug. So, net.agent would receive an event and perform
682+the necessary steps to configure it.
683+
684+ Personally, I'm still using the original Pcmcia scripts for my
685+Pcmcia cards as described in the file PCMCIA.txt, because I will
686+migrate my complex configurations over time.
687+ You can also decide to not use Hotplug for Pcmcia cards and
688+modify the distribution Pcmcia scripts in /etc/pcmcia/* to handle
689+Pcmcia cards properly. You would need to modify /etc/pcmcia/network to
690+add 'ifrename' before 'ifup' the same way it was done for
691+/etc/hotplug/net.agent. But, as in the long term Pcmcia will migrate
692+to Hotplug, I would not bother...
693+
694+MANUAL LOADING, DOCKING STATIONS
695+--------------------------------
696+ Manual loading is used for built-in network interfaces that
697+are only use at specific time, and that you want disabled the rest of
698+the time. We assume that you still use modules so that when the
699+interface is not used you can remove the driver from the kernel.
700+
701+ First, you need to set the configuration for those interfaces,
702+the same way it's done for other network interfaces. The main
703+difference is that you need to specify that those interfaces should
704+not be enabled at boot time. It's also a good idea to disable Hotplug
705+init scripts.
706+ With Debian, you just need to make sure that the 'auto"
707+keyword doesn't apply to this interface.
708+--------- /etc/network/interfaces -----------
709+# AMD AMD PCnet LANCE PCI card
710+iface eth4 inet dhcp
711+---------------------------------------------
712+
713+ If you use driver statically built in the kernel, you can just
714+enable and disable those interfaces with 'ifup ethX' and 'ifdown ethX'.
715+
716+ If you use both a modular system and 'ifrename', you will need
717+to change your habits when enabling those devices. The classical 'ifup
718+ethX' won't work.
719+ If you don't use Hotplug, you need to do :
720+-----------------------------------
721+modprobe eth4
722+ifrename
723+ifup eth4
724+-----------------------------------
725+ If you use hotplug, you only need to do :
726+-----------------------------------
727+modprobe eth4
728+-----------------------------------
729+
730+ On the other hand, disabling the interface has not changed :
731+-----------------------------------
732+ifdown eth4
733+modprobe -r eth4
734+-----------------------------------
735+ Using "modprobe -r" make sure that if the driver is composed
736+of multiple module all the modules are unloaded.
737+
738+ Docking stations for laptops may contain built-in
739+interfaces. My previous laptop had one, and Linux had no support for
740+it. To be able to simply manage my docking station, I had created two
741+little scripts to enable and disable my network interface.
742+ After docking, you would run :
743+-------- /sbin/dock ----------------------------
744+#!/bin/sh
745+modprobe eth4
746+ifrename
747+ifup eth4
748+------------------------------------------------
749+ And prior to undocking, you would run :
750+-------- /sbin/undock ----------------------------
751+#!/bin/sh
752+ifdown eth4
753+modprobe -r eth4
754+------------------------------------------------
755+ Thanks to 'ifrename', the network interface in your dock will
756+always be properly configured regardless of if you have a Pcmcia
757+network card in the Pcmcia slot or not.
758+
759+SCHEMES (MULTI-CONFIG)
760+----------------------
761+ Most Ethernet cards will only connect to a single network, or
762+can use DHCP to be auto-configured. With Wireless Cards, it's much
763+more likely that you will need multiple configurations, for example at
764+work, at home and on-the-go.
765+
766+ Most distributions have various level of support for such
767+schemes. Some distributions offer simple network schemes, while other
768+offer "overall" schemes changing the whole configuration. I document
769+the support for schemes in various distributions in the file
770+DISTRIBUTIONS.txt.
771+
772+ You can also use tools such as IfPlugd, WapRoamd or
773+Wlandetect. Those tools are a kind of "wireless-DHCP", they attempt to
774+automatically detect the proper wireless configuration and apply
775+it. Most will also attempt to detect network changes.
776+ The main limitation of those tools is that they offer very
777+little manual control. If two valid alternatives are possible, you
778+can't switch between them. If a configuration can't be detected, they
779+usually fail.
780+ That's the same concept as using DHCP versus Static IP
781+addresses. Some people are very happy with DHCP, my style is Static IP
782+addresses.
783+
784+ If you use Debian and want to use simple manual schemes, these
785+are the things you need to do.
786+ 1) Make sure that 'ifscheme' and 'ifscheme-mapping' are
787+installed on the system. You may find them in a separate tar file on
788+my web site.
789+ 2) Check the path for 'ifscheme-mapping' (using whereis).
790+ 3) Modify you /etc/network/interface to add proper mapping and
791+configuration.
792+
793+------- /etc/network/interfaces ----------------------
794+# Enable Hotplug support (Sarge and later)
795+mapping hotplug
796+ script echo
797+
798+# SMC 2835W wireless CardBus card
799+mapping prism0
800+ script /sbin/ifscheme-mapping
801+
802+iface prism0-any inet dhcp
803+ wireless-essid any
804+ wireless-mode managed
805+
806+iface prism0-adhoc inet static
807+ address 10.0.1.2
808+ network 10.0.1.0
809+ netmask 255.255.255.0
810+ broadcast 10.0.1.255
811+ wireless-essid THE_ESSID
812+ wireless-mode ad-hoc
813+ wireless-channel 5
814+
815+iface prism0-other inet static
816+ address 10.10.10.2
817+ network 10.10.10.0
818+ netmask 255.255.255.0
819+ broadcast 10.10.10.255
820+ wireless-essid ANOTHER_ESSID
821+ wireless-mode ad-hoc
822+ wireless-key "s:secure"
823+------------------------------------------------------
824+
825+FIRMWARE LOADING
826+----------------
827+ A lot of modern wireless card don't have built in firmware and
828+need firmware loading. Recent kernel (2.6.X) have a firmware
829+loader. These are a few notes on how to use it.
830+
831+ First, read the documentation coming with your driver, because
832+each driver has specificities (like the name of the firmware file it
833+requires).
834+
835+ You need to compile your kernel with firmware loading
836+(CONFIG_FW_LOADER in "Generic Driver Options"). If your driver was
837+built from the kernel, chances are that it enabled this feature
838+already. Make sure you boot from this new kernel.
839+
840+ The 'sysfs' file system must be mounted. The easiest is to
841+mount it at boot time, add a line for it in /etc/fstab :
842+
843+-------- /etc/fstab ------------------------------
844+sysfs /sys sysfs defaults 0 0
845+--------------------------------------------------
846+
847+ Then, you add the firmware file in the directory where it's
848+expected, which is /usr/lib/hotplug/firmware/ in most cases.
849+
850+ Most distributions nowadays have a version of the Hotplug
851+scripts that knows how to deal with firmware. If it is not the case,
852+just grab the 'firmware.agent' file from an alternate source and copy
853+it into your /etc/hotplug directory (make sure it's executable).
854+ You can try the canonical version :
855+ http://linux-hotplug.sourceforge.net/
856+ Or Debian's version :
857+ http://packages.debian.org/unstable/admin/hotplug
858+
859+ Note that firmware loading will usually only work with
860+interfaces that are fully managed by Hotplug. This is the only way to
861+ensure the that proper sequence of action is happening in the right
862+order every time. Firmware loading will usually not work properly for
863+interfaces configured in the init scripts.
864+ This means that if you have a built-in interface that require
865+firmware loading, you should just use manage those interfaces like
866+removable interfaces (see section above). However, interface
867+configuration need to be explicitely triggered at boot time.
868+
869+ One possibility is to set-up Hotplug to be run from the init
870+script at boot time. This is usually an option for recent
871+distributions (it's not the case for Hotplug in Debian 3.0). But, we
872+have seen that this has some issues.
873+ The other possibility is to use an hybrid between the init
874+script method and the hotplug method. First, you need to add an alias
875+for the driver in /etc/modprobe.conf. Then, you need to specify a
876+mapping for this interface in /etc/iftab, and specify a configuration
877+for this interface and that that it is enabled at boot time. Lastly,
878+you make sure that the network init scripts run 'ifrename
879+-p'. 'Ifrename' will trigger the module to load, and all the Hotplug
880+events will be generated properly to configure the interface.
881+
882+DEVICES WITH MULTIPLE NAMES
883+---------------------------
884+ Some wireless drivers offer multiple network interfaces for
885+the same device. A classical example is the Aironet driver that
886+creates a 'ethX' and 'wifiY' for each card.
887+
888+ 'ifrename' allow you a finer selection of interfaces than
889+'nameif'. For example, to only rename the pseudo-Ethernet network
890+interface name of the Aironet driver, you would do :
891+
892+--------- /etc/iftab -----------------------
893+# Cisco Aironet 350 wireless Pcmcia card
894+airo* mac 00:07:0E:* arp 1
895+---------------------------------------------
896+
897+ After that, your device would be available through 'eth0' and
898+'wifi0'.
899+
900+ You can rename both interfaces. You just need to remember that
901+'ifrename' start matching from the last line of the file, so you would
902+do :
903+--------- /etc/iftab -----------------------
904+# Cisco Aironet 350 wireless Pcmcia card
905+wifi* mac 00:07:0E:*
906+airo* mac 00:07:0E:* arp 1
907+---------------------------------------------
908+
909+ The current version of 'ifrename' support only the most useful
910+selectors, and is architectured such as adding selectors is relatively
911+trivial. If you find a case that 'ifrename' can't handle, you should
912+just extend it.
913+
914+DEVICES WITHOUT MAC ADDRESSES
915+-----------------------------
916+ Most Ethernet and Wireless devices have a fixed and unique MAC
917+address, and it is therefore advised to name them based on this
918+criteria. However, there is also network interfaces that don't have a
919+fixed and unique MAC address, for example Ethernet over USB, IP over
920+FireWire, PPP and tunnel interfaces.
921+ The driver for those devices create the interface with a name
922+specific to the driver, such as ppp* for PPP interfaces and usb* for
923+Ethernet over USB, and therefore they are easy to identify and
924+configure, and few users feel the need to rename them. Moreover, some
925+of them, such as PPP, have their own configuration scripts and
926+methodology addressing their unique needs.
927+
928+ There is a few cases where you might want to rename interfaces
929+withour MAC addresses. One example is two Ethernet over USB
930+dongles. The way to do this is to use alternate ifrename
931+selectors. Choosing the right selector depend on what you want to
932+achieve.
933+ A quick theoretical example to illustrate :
934+--------- /etc/iftab -----------------------
935+# All other usbnet devices
936+usb* driver usbnet
937+# Specific usbnet devices
938+usb-p firmware "Prolific PL-2301/PL-2302"
939+usb-4 bus-info usb-00:02.0-1.4
940+---------------------------------------------
941+
942+TROUBLESHOOTING
943+---------------
944+ If your interface doesn't show up as expected with ifconfig,
945+you will need to find out why. First, you need to be familiar with the
946+sequence of actions in the system and find which one did not happen.
947+
948+ You need to check if the driver module(s) was loaded using
949+'lsmod'.
950+
951+ You need to check if the interface was properly renamed with
952+'ifrename'. You can use 'ifrename -D -V' to debug your /etc/iftab.
953+ Get the the list of interfaces on your system with 'cat
954+/proc/net/dev', and check if an interface is using the name you
955+assigned or 'eth0'. Check any suspicious interfaces with 'ifconfig
956+eth0', and check its MAC address. Note that some rare drivers don't
957+have a proper MAC address before brought up, which fools ifrename.
958+ Verify that no line in /etc/iftab matches the all-zero MAC
959+address. The all-zero MAC address matches the loopback interface 'lo'
960+and various pseudo network devices, renaming the loopback interface is
961+highly discouraged.
962+
963+ You need to check which configuration was given to the
964+interface using 'ifconfig' and 'iwconfig'.
965+
966+ The Hotplug subsystem has also good debugging facilities.
967+ To enable Hotplug debugging, just make sure the variable DEBUG
968+is defined in /sbin/hotplug :
969+--------- /sbin/hotplug ------------------------------
970+--- /sbin/hotplug-old Tue Mar 26 09:00:20 2002
971++++ /sbin/hotplug Fri Feb 20 18:40:38 2004
972+@@ -22,7 +22,7 @@
973+ cd /etc/hotplug
974+ . hotplug.functions
975+
976+-# DEBUG=yes export DEBUG
977++DEBUG=yes export DEBUG
978+
979+ if [ "$DEBUG" != "" ]; then
980+ mesg "arguments ($*) env (`env`)"
981+------------------------------------------------------
982+ Then, you can check your message logs for Hotplug events with
983+'tail -f /var/log/messages'. Verify that the various Hotplug events
984+happen as expected (pci, firmware, net...), and verify the log
985+messages from 'net.agent'.
986+
987+
988+ Have fun...
989+
990+ Jean
--- a/wireless_tools/INSTALL
+++ b/wireless_tools/INSTALL
@@ -1,96 +1,89 @@
11 Very important note :
22 -------------------
3- This release of the Wireless Tools is not compatible with Wireless
4- Extensions earlier than 9.
5- Kernels that support this version of the Wireless Tools are listed
6- below. For all kernels before that, please use the version v19 of
7- the Wireless Tools.
8- You might have headers troubles and it doesn't compile, see below...
3+ This release of the Wireless Tools is not compatible with
4+Wireless Extensions earlier than 9. Version 9 and 10 should work fine
5+but are not recommended. Version 8 and earlier will not work.
6+ Kernels that support this version of the Wireless Tools are
7+listed below. For all kernels before that, see at the end.
98
109 You need :
1110 --------
1211 o Compiler and development environment
13- o A kernel supporting wireless extensions version 9 or higher
14- -> from 2.2.14 onward
15- -> from 2.3.24 onward
12+ o A kernel supporting wireless extensions version 11 or higher
13+ -> from 2.4.4 onward (including 2.6.X)
1614 Note : CONFIG_NET_RADIO must be enabled
1715 o (Optional) A Pcmcia package supporting Wireless Extension
1816 o A driver supporting wireless extensions
19- -> Check my web pages for latest list of drivers,
20- otherwise patch your favourite driver...
17+ -> Check my web pages for status of various drivers.
2118 Note : more recent kernels and drivers are likely to support
2219 more wireless extension features...
2320
2421 Compile wireless tools :
2522 ----------------------
2623 In theory, a "make" should suffice to create the tools.
27- In practice, there is big troubles with the kernel
28-headers. See below for how to fix that.
29- Note : as some internal data structures change from kernel to
30-kernel, you are advised to not use the precompiled version of the
31-tools but to recompile your own.
3224
3325 Installation :
3426 ------------
35- If I were you, I would not trust a "make install". If you feel
36-courageous, just do "make install". It may even do the right
37-thing. Actually, with the various bugfixes that happened over the
38-time, it nowadays tend to do the right thing.
39- I advise to copy the executable (iwconfig, iwspy and iwpriv)
40-in /usr/local/sbin or /usr/sbin. The man pages (iwconfig.8, iwspy.8
41-and iwpriv.8) should be copied in /usr/local/man/man8 or
42-/usr/man/man8.
43- In fact, if you want to use Pcmcia wireless.opts, this step is
44-mandatory...
27+ "make install" should do the right thing for you, and install
28+the tools, their library and the man pages. You can also uninstall the
29+tools via "make uninstall".
30+ Note that the default installation is in the directory
31+'/usr/local/sbin'. This may not be in your path. Also, other version
32+of the tools may exist on the system, so double check which version is
33+the default and adjust your path as necessary.
4534
46-Kernel headers (why it doesn't compile) :
47----------------------------------------
48- Some changes in the kernel headers and glibc headers are
49-making my life difficult. We now have a mechanism to automatically
50-select the proper header based on various bits of information (libc
51-version & kernel version), but it may fail to do the right thing.
52- You may also see the message :
53- "Your kernel/libc combination is not supported"
54- If this happens to you, you will need to hack the rules at the
55-top of iwlib.h and send me the patch.
56-
57- The second issue is that some distributions install some
58-independant kernel headers in /usr/include. If you upgrade your
59-kernel, those headers become out of sync and you don't benefit from
60-the latest Wireless Extensions. Even worse, it can sometimes prevent
61-the tools from compiling.
62- The trick is to copy the file .../include/linux/wireless.h
63-from the kernel to the /usr/include headers.
64-
65-Multi-kernel installation (expert only) :
66----------------------------------------
67- People who run different kernel on the same system may have
68-problems due to the fact that those kernel have different version of
69-Wireless Extensions and the Wireless Tools need to match the version
70-of Wireless Extension used.
35+Create a local copy of the tools :
36+--------------------------------
37+ By default, the package is built with iwlib as a dynamic
38+library, and the tool will expect to use the default version of libiw
39+on the system.
40+ If you just want to experiment with a "local" version of the
41+tools, you may want to pass the BUILD_STATIC flag to Makefile. It will
42+create a self contained version of the tools.
43+-------------
44+make clean
45+make BUILD_STATIC='y'
46+-------------
47+ The resulting binary can be used in the compilation directory
48+or installed in any place you like.
7149
72- It is now possible to install multiple versions of the
73-Wireless Tools on a system and get the proper version used based on
74-the kernel running, using a redirector. However, this support is still
75-experimental and for expert users only.
76- The redirector will work properly only with kernel using
77-Wireless Extensions version 16 and higher. Earlier version of Wireless
78-Extensions will be detected as either v15 (v12, v13, v14 and v15) or
79-as v11 (v11 and earlier).
50+Wireless headers (past history) :
51+-------------------------------
52+ Previous version of the Wireless Tools had to be compiled with
53+the same version of Wireless Extension that the kernel was using, and
54+that was a major source of troubles.
55+ Starting with version 27, Wireless Tools include all the ugly
56+code to deal with any version of Wireless Extensions, so now you can
57+compile a single "generic" version of the tools for any kernel.
58+ Well, there are some limits, Wireless Extensions earlier than
59+v11 are not supported (v9 and v10 should work fine), and versions
60+later than the latest definition in the package are not
61+supported. Once compile, the command "iwconfig --version" should tell
62+you that.
63+ Note that the previous option to make versioned installed of
64+the tools no longer make sense and therefore is gone.
8065
81- The installation looks typically like :
82-------------------------------------
83-make clean
84-make FORCE_WEXT_VERSION=11
85-make vinstall FORCE_WEXT_VERSION=11
86-make clean
87-make FORCE_WEXT_VERSION=15
88-make vinstall FORCE_WEXT_VERSION=15
89-make clean
90-make FORCE_WEXT_VERSION=16
91-make vinstall FORCE_WEXT_VERSION=16
92-[...]
93-------------------------------------
66+Other useful Makefile options :
67+-----------------------------
68+ PREFIX : where the tools will be installed (default : /usr/local)
69+ BUILD_STATIC : build tools with a static version of the wireless lib
70+ BUILD_NOLIBM : build tools without mathematical lib (slower)
71+ Note that you should pass the same command line options for
72+all invocations of make ("make" and "make install").
9473
74+Old kernel with older Wireless Extensions :
75+-----------------------------------------
76+ Kernel prior to 2.2.14 : Those kernels include Wireless
77+Extensions v8 or earlier. Those versions don't have proper support for
78+802.11b, so are not very useful. You may want to consider upgrading.
79+ Kernel 2.2.19 to 2.2.25 : Those kernels include Wireless
80+Extensions v10. The tools should mostly work with it, but many drivers
81+won't. You can upgrade those kernel to WE v15 with a patch on my web
82+page.
83+ Kernel 2.2.14 to 2.2.18 : Those kernels include Wireless
84+Extensions v9. Same as above, you may want to upgrade to a later 2.2.X
85+kernel and then apply the patch.
86+ Kernel 2.0.X : Those kernels include very old version of
87+Wireless Extensions. Same deal as old 2.2.X kernels.
9588
9689 Jean <jt@hpl.hp.com>
--- a/wireless_tools/Makefile
+++ b/wireless_tools/Makefile
@@ -3,51 +3,58 @@
33 ##
44
55 ## Installation directory. By default, go in /usr/local
6-## Distributions should probably use /usr, but they probably know better...
6+## Distributions should probably use /, but they probably know better...
77 ifndef PREFIX
88 PREFIX = /usr/local
99 endif
1010
11-## Compiler to use
11+## Compiler to use (modify this for cross compile)
1212 CC = gcc
13+## Other tools you need to modify for cross compile (static lib only)
14+AR = ar
15+RANLIB = ranlib
1316
14-## Uncomment this to build against this kernel
15-# KERNEL_SRC = /usr/src/linux
16-
17-## Uncomment this to force a particular version of wireless extensions.
18-## This would use private copy of Wireless Extension definition instead
19-## of the system wide one in /usr/include/linux. Use with care.
20-## Can be used to create multiple versions of the tools on the same system
21-## for multiple kernels or get around broken distributions.
22-# FORCE_WEXT_VERSION = 16
23-
24-## Uncomment this to build tools using dynamic version of the library
25-# BUILD_SHARED = y
17+## Uncomment this to build tools using static version of the library
18+## Mostly useful for embedded platforms without ldd, or to create
19+## a local version (non-root).
20+# BUILD_STATIC = y
2621
2722 ## Uncomment this to build without using libm (less efficient)
28-## This is mostly useful for embedded platforms
23+## This is mostly useful for embedded platforms without maths.
2924 # BUILD_NOLIBM = y
3025
3126 # ***************************************************************************
3227 # ***** Most users should not need to change anything beyond this point *****
3328 # ***************************************************************************
3429
30+# Version of the Wireless Tools
31+WT_VERSION := $(shell sed -ne "/WT_VERSION/{s:\([^0-9]*\)::;p;q;}" < iwlib.h )
32+
33+# Version of Wireless Extensions.
34+WE_VERSION := $(shell sed -ne "/WE_VERSION/{s:\([^0-9]*\)::;p;q;}" < iwlib.h )
35+
36+# Always use local header for wireless extensions
37+WEXT_HEADER = wireless.$(WE_VERSION).h
38+
3539 # Targets to build
3640 STATIC=libiw.a
37-DYNAMIC=libiw.so.26
38-PROGS= iwconfig iwlist iwpriv iwspy iwgetid iwevent
39-MANPAGES8=iwconfig.8 iwlist.8 iwpriv.8 iwspy.8 iwgetid.8 iwevent.8
41+DYNAMIC=libiw.so.$(WT_VERSION)
42+PROGS= iwconfig iwlist iwpriv iwspy iwgetid iwevent ifrename
43+MANPAGES8=iwconfig.8 iwlist.8 iwpriv.8 iwspy.8 iwgetid.8 iwevent.8 ifrename.8
4044 MANPAGES7=wireless.7
41-EXTRAPROGS= macaddr iwredir
45+MANPAGES5=iftab.5
46+EXTRAPROGS= macaddr
4247
4348 # Composition of the library :
4449 OBJS = iwlib.o
4550
46-# Select library to link tool with
47-ifdef BUILD_SHARED
48- IWLIB=$(DYNAMIC)
49-else
51+# Select which library to build and to link tool with
52+ifdef BUILD_STATIC
5053 IWLIB=$(STATIC)
54+ IWLIB_INSTALL=install-static
55+else
56+ IWLIB=$(DYNAMIC)
57+ IWLIB_INSTALL=install-dynamic
5158 endif
5259
5360 # Standard name for dynamic library so that the dynamic linker can pick it.
@@ -60,21 +67,10 @@ INSTALL_LIB= $(PREFIX)/lib/
6067 INSTALL_INC= $(PREFIX)/include/
6168 INSTALL_MAN= $(PREFIX)/man/
6269
63-# Use local header if the version of wireless extensions is specified
64-ifdef FORCE_WEXT_VERSION
65- WEXT_FLAG = -DWEXT_HEADER=\"wireless.$(FORCE_WEXT_VERSION).h\"
66-endif
67-
70+# Various commands
6871 RM = rm -f
69-
70-RM_CMD = $(RM) *.BAK *.bak *.o *.so ,* *~ *.a *.orig *.rej
71-
72-ifdef KERNEL_SRC
73- ifeq ($(wildcard $(KERNEL_SRC)/include/linux/wireless.h),)
74- $(error Kernel source is missing or incomplete)
75- endif
76- KERNEL_INCLUDES = -I $(KERNEL_SRC)/include
77-endif
72+RM_CMD = $(RM) *.BAK *.bak *.d *.o *.so ,* *~ *.a *.orig *.rej *.out
73+LDCONFIG = ldconfig
7874
7975 # Do we want to build with or without libm ?
8076 ifdef BUILD_NOLIBM
@@ -84,18 +80,22 @@ else
8480 LIBS= -lm
8581 endif
8682
87-#CFLAGS=-O2 -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Werror
88-CFLAGS=-O2 -W -Wall -Wstrict-prototypes
89-XCFLAGS=$(CFLAGS) $(WARN) $(HEADERS) $(WEXT_FLAG) $(WELIB_FLAG) $(KERNEL_INCLUDES)
83+# Other flags
84+CFLAGS=-Os -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wshadow \
85+ -Wpointer-arith -Wcast-qual -Winline -I.
86+#CFLAGS=-O2 -W -Wall -Wstrict-prototypes -I.
87+DEPFLAGS=-MMD
88+XCFLAGS=$(CFLAGS) $(DEPFLAGS) $(WARN) $(HEADERS) $(WELIB_FLAG)
9089 PICFLAG=-fPIC
9190
92-all:: $(STATIC) $(DYNAMIC) $(PROGS)
91+# Standard compilation targets
92+all:: $(IWLIB) $(PROGS)
9393
9494 %: %.o
9595 $(CC) $(LDFLAGS) $(XCFLAGS) -o $@ $^ $(LIBS)
96-%.o: %.c
96+%.o: %.c wireless.h
9797 $(CC) $(XCFLAGS) -c $<
98-%.so: %.c
98+%.so: %.c wireless.h
9999 $(CC) $(XCFLAGS) $(PICFLAG) -c -o $@ $<
100100
101101 iwconfig: iwconfig.o $(IWLIB)
@@ -106,14 +106,18 @@ iwpriv: iwpriv.o $(IWLIB)
106106
107107 iwspy: iwspy.o $(IWLIB)
108108
109-iwgetid: iwgetid.o
109+iwgetid: iwgetid.o $(IWLIB)
110110
111111 iwevent: iwevent.o $(IWLIB)
112112
113-iwredir: iwredir.o
113+ifrename: ifrename.o $(IWLIB)
114114
115115 macaddr: macaddr.o $(IWLIB)
116116
117+# It's a kind of magic...
118+wireless.h:
119+ cp $(WEXT_HEADER) wireless.h
120+
117121 # Compilation of the dynamic library
118122 $(DYNAMIC): $(OBJS:.o=.so)
119123 $(CC) -shared -o $@ -Wl,-soname,$@ $(LIBS) -lc $^
@@ -121,32 +125,43 @@ $(DYNAMIC): $(OBJS:.o=.so)
121125 # Compilation of the static library
122126 $(STATIC): $(OBJS)
123127 $(RM) $@
124- ar cru $@ $^
125- ranlib $@
128+ $(AR) cru $@ $^
129+ $(RANLIB) $@
126130
127131 # So crude but so effective ;-)
128132 # Less crude thanks to many contributions ;-)
129-install:: all
133+install:: all $(IWLIB_INSTALL)
130134 install -m 755 -d $(INSTALL_DIR)
131135 install -m 755 $(PROGS) $(INSTALL_DIR)
132- install -m 755 -d $(INSTALL_LIB)
133- install -m 644 $(STATIC) $(INSTALL_LIB)
134- install -m 755 $(DYNAMIC) $(INSTALL_LIB)
135- ln -sfn $(DYNAMIC) $(INSTALL_LIB)/$(DYNAMIC_LINK)
136- echo "Don't forget to add $(INSTALL_LIB) to /etc/ld.so.conf, and run ldconfig."
137136 install -m 755 -d $(INSTALL_INC)
138137 install -m 644 iwlib.h $(INSTALL_INC)
138+ install -m 644 wireless.h $(INSTALL_INC)
139139 install -m 755 -d $(INSTALL_MAN)/man8/
140140 install -m 644 $(MANPAGES8) $(INSTALL_MAN)/man8/
141141 install -m 755 -d $(INSTALL_MAN)/man7/
142142 install -m 644 $(MANPAGES7) $(INSTALL_MAN)/man7/
143+ install -m 755 -d $(INSTALL_MAN)/man5/
144+ install -m 644 $(MANPAGES5) $(INSTALL_MAN)/man5/
145+
146+# Install the dynamic library
147+install-dynamic:: $(DYNAMIC)
148+ install -m 755 -d $(INSTALL_LIB)
149+ install -m 755 $(DYNAMIC) $(INSTALL_LIB)
150+ ln -sfn $(DYNAMIC) $(INSTALL_LIB)/$(DYNAMIC_LINK)
151+ @echo "*** Don't forget to add $(INSTALL_LIB) to /etc/ld.so.conf, and run ldconfig as root. ***"
152+ @$(LDCONFIG) || echo "*** Could not run ldconfig ! ***"
153+
154+# Install the static library
155+install-static:: $(STATIC)
156+ install -m 755 -d $(INSTALL_LIB)
157+ install -m 644 $(STATIC) $(INSTALL_LIB)
143158
144159 clean::
145160 $(RM_CMD)
146161
147162 realclean::
148163 $(RM_CMD)
149- $(RM) $(STATIC) $(DYNAMIC) $(PROGS) $(EXTRAPROGS)
164+ $(RM) $(STATIC) $(DYNAMIC) $(PROGS) $(EXTRAPROGS) libiw* wireless.h
150165
151166 uninstall::
152167 for f in $(PROGS); do \
@@ -156,41 +171,16 @@ uninstall::
156171 $(RM) $(INSTALL_LIB)/$(DYNAMIC)
157172 $(RM) $(INSTALL_LIB)/$(DYNAMIC_LINK)
158173 $(RM) $(INSTALL_INC)/iwlib.h
174+ $(RM) $(INSTALL_INC)/wireless.h
159175 for f in $(MANPAGES8); do \
160176 $(RM) $(INSTALL_MAN)/man8/$$f; \
161177 done
162178 for f in $(MANPAGES7); do \
163179 $(RM) $(INSTALL_MAN)/man7/$$f; \
164180 done
181+ for f in $(MANPAGES5); do \
182+ $(RM) $(INSTALL_MAN)/man5/$$f; \
183+ done
165184
166-# Versioned install...
167-# We rename each of the tool with a suffix corresponding to the version
168-# of WE it was compiled with. We use "iwredir" for the redirection...
169-
170-vinstall:: iwredir install
171- @wev=$(FORCE_WEXT_VERSION) ; \
172- if [ "$$wev" == "" ] ; then \
173- wev=`./iwredir -wev`; \
174- else :; fi ; \
175- echo "Installing tools for WE-$$wev..." ; \
176- for f in $(PROGS); do \
177- mv $(INSTALL_DIR)/$$f $(INSTALL_DIR)/$$f$$wev; \
178- done;
179- install -m 755 iwredir $(INSTALL_DIR)
180- for f in $(PROGS); do \
181- ln $(INSTALL_DIR)/iwredir $(INSTALL_DIR)/$$f; \
182- done;
183-
184-vuninstall:: uninstall
185- @wev=$(FORCE_WEXT_VERSION) ; \
186- if [ "$$wev" == "" ] ; then \
187- wev=`./iwredir -wev`; \
188- else :; fi ; \
189- for f in $(PROGS); do \
190- rm $(INSTALL_DIR)/$$f$$wev; \
191- done;
192- $(RM) $(INSTALL_DIR)/iwredir;
193-
194-depend::
195- makedepend -s "# DO NOT DELETE" -- $(INCLUDES) -- $(SRCS)
196-# DO NOT DELETE
185+# Include dependancies
186+-include *.d
--- a/wireless_tools/README
+++ b/wireless_tools/README
@@ -1,21 +1,28 @@
11 Wireless Tools
22 --------------
33
4- This package contain the Wireless tools, used to manipulate
5-the Wireless Extensions. The Wireless Extension is an interface
4+ This package contains the Wireless tools, used to manipulate
5+the Wireless Extensions. The Wireless Extensions is an interface
66 allowing you to set Wireless LAN specific parameters and get the
77 specific stats.
88
9-web page
9+web page :
1010 --------
1111 You'll find a lot of useful info on :
1212 http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html
1313 http://web.hpl.hp.com/personal/Jean_Tourrilhes/Linux/
1414
15+Precompiled version :
16+-------------------
17+ Most Linux distributions offer precompiled package containing
18+these tools. And many of them preinstall them by default. On the other
19+hand, installation of this package is (now) easy and allow you to get
20+a more up-to-date version.
21+
1522 INSTALL
1623 -------
17- This file contains installation instruction and requirements.
18- A *must* read.
24+ This file contains installation instructions and requirements.
25+ A *must*-read.
1926
2027 DISTRIBUTION.txt
2128 ----------------
@@ -26,28 +33,45 @@ Extensions). Please read it carefully before asking questions.
2633 Extensions integration in the most common Linux distributions. I need
2734 your help to complete this file.
2835
36+HOTPLUG.txt
37+-----------
38+ This file document how to manage and configure removable
39+wireless cards using Hotplug. This is more advanced than the simple
40+procedures of DISTRIBUTION.txt. This is currently mostly Debian
41+specific, but I hope you will contribute for other distributions.
42+
2943 PCMCIA.txt
3044 ----------
31- This file describes how to use Pcmcia init script to configure
32-Wireless Extensions and how to use Pcmcia schemes.
45+ This file describes how to use PCMCIA init script to configure
46+Wireless Extensions and how to use PCMCIA schemes.
3347
3448 man pages (iwconfig.8, iwlist.8, iwpriv.8, iwspy.8)
3549 ---------
36- VERY IMPORTANT : I try to keep the man page up to date, so
50+ VERY IMPORTANT : I try to keep the man pages up to date, so
3751 you'd better read them before asking questions.
38- ALSO IMPORTANT : Those man pages describe the capacity of the
39-tools, no device implement the full range (and drivers usually
52+ ALSO IMPORTANT : Those man pages describe the capacities of
53+the tools, no device implements the full range (and drivers usually
4054 implement even less).
4155
4256 As far as I know, the man pages are the most complete, up to
4357 date and accurate documentation of the wireless tools. An update of
44-the web page related to Wireless Extension is long overdue. Send
58+the web page related to Wireless Extensions is long overdue. Send
4559 feedback to me.
46- The man pages can either be copied in a location where the
60+ The man pages can either be copied into a location where the
4761 command "man" will find them, such as /usr/local/man/man8, or can be
4862 read locally with the command :
4963 nroff -man xxx.8 | less
5064
65+localised man pages (fr/*)
66+-------------------
67+ Localised man pages are not made by me, therefore the only
68+localisations available are those sent to me by courageous volonteers
69+and are expect those man pages to 'lag' compared to the english
70+version (i.e. not have all the latest updates). Translating man pages
71+is not a very gratifying task, especially due to my broken english,
72+and many technical terms don't translate well to other languages, so
73+refer to the english version when in doubt.
74+
5175 iwconfig.c
5276 ----------
5377 The main wireless tool. Used for device configuration and to see
@@ -60,9 +84,9 @@ iwlist.c
6084
6185 iwspy.c
6286 -------
63- Mobile IP support test and allow get get stats per MAC address
64-(instead of globally). Also, for some driver/device, this is the only
65-way to get stats in Ad-Hoc mode.
87+ Mobile IP support test and allows get get stats per MAC
88+address (instead of globally). Also, for some drivers/devices, this is
89+the only way to get stats in Ad-Hoc mode.
6690
6791 iwpriv.c
6892 --------
@@ -72,19 +96,23 @@ specific to a driver or a device and therefore not part of iwconfig.
7296 iwgetid.c
7397 ---------
7498 Output the ESSID or NWID of the specified device.
75- Can also output it in a form that can be used as a Pcmcia Scheme.
99+ Can also output it in a form that can be used as a PCMCIA Scheme.
76100
77101 iwevent.c
78102 ---------
79103 Display Wireless Events. This is new, so there is not much support
80104 in drivers for it yet...
81105
106+ifrename.c :
107+----------
108+ Rename network interfaces based on various selectors.
109+
82110 iwlib.c
83111 -------
84- The Wireless Tools helper library. May be usefull if you want
112+ The Wireless Tools helper library. May be useful if you want
85113 to create your own applications using Wireless Extensions.
86114
87-Changelog, contributions
115+Changelog, contributions :
88116 ------------------------
89117 See CHANGELOG.h
90118
@@ -94,29 +122,29 @@ wireless.h
94122 definition used by the drivers and the tools must match, otherwise
95123 funny things may happen. The tools try to check for that.
96124 Since Wireless Extensions v12, you can no longer drop this
97-file in your kernel headers to update the Wireless Extensions, you
125+file into your kernel headers to update the Wireless Extensions, you
98126 need to use the full patches available on my web page. So, the use is
99127 more if you plan to do some cross compile or something similar.
100- Just for your enjoyement, there is various release of it. If
128+ Just for your enjoyment, there are various releases of it. If
101129 your kernel/drivers are old, you may want to try the older releases...
102130
103131 sample_xxx.c :
104132 ------------
105133 Various samples of code showing how to implement some of the
106134 more tricky feature of Wireless Extensions in your driver.
107- Note that there is no guarantee that this code compile, let
108-alone work, but it should point you in the proper direction.
135+ Note that there is no guarantee that this code compiles, let
136+alone works, but it should point you in the proper direction.
109137 Also, have a look at existing drivers in the Linux kernel.
110138
111139 Other tools :
112140 -----------
113- My web page list many other tools using Wireless
141+ My web page lists many other tools using Wireless
114142 Extensions that you may find useful...
115143 http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html#links
116144
117145 Other questions :
118146 ---------------
119- You have the source, and it is documented. In 99% of the case,
147+ You have the source, and it is documented. In 99% of cases,
120148 you will find your answer there.
121149
122150 Good luck...
--- /dev/null
+++ b/wireless_tools/README.fr
@@ -0,0 +1,162 @@
1+ Wireless Tools
2+ --------------
3+
4+ Ce paquetage contient les Wireless Tools (Outils Wireless), utilisé pour
5+manipuler les Wireless Extensions. Les Wireless Extensions sont une interface
6+vous permettant de manier les paramètres spécifiques aux Wireless LAN (réseaux
7+sans fil) et d'obtenir les statistiques spécifiques.
8+
9+page web :
10+--------
11+ Vous trouverez beaucoup d'informations utiles sur :
12+ http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html
13+ http://web.hpl.hp.com/personal/Jean_Tourrilhes/Linux/
14+
15+version pré compilée
16+--------------------
17+ La plupart des distributions Linux fournit un paquetage pré compilé
18+contenant ces outils. Et beaucoup d'entre elles les pré installent par défaut.
19+Par ailleurs, l'installation de ce paquetage est (maintenant) facile et vous
20+permet d'obtenir une version plus à jour.
21+
22+INSTALL
23+-------
24+ Ce fichier contient les instructions et les requis pour l'installation.
25+ *Doit* être lu.
26+
27+DISTRIBUTION.txt
28+----------------
29+ Ce fichier documente la manière de configurer les cartes wireless au
30+démarrage avec différentes distributions Linux (en utilisant les Wireless
31+Extensions). Veuillez le lire attentivement avant de poser des questions.
32+ Dans ce fichier, j'essaye de rassembler toutes les spécificités de
33+l'intégration des Wireless Extensions dans les ditributions Linux les plus
34+courantes. J'ai besoin de votre aide pour compléter ce fichier.
35+
36+HOTPLUG.txt
37+-----------
38+ Ce fichier documente la manière de gérer et configurer les cartes
39+wireless éjectables utilisant Hotplug. Il est plus avancé que les simples
40+procédures de DISTRIBUTIONS.txt. Pour l'instant, il est principalement orienté
41+Debian, mais j'espère que vous contribuerez pour d'autres distributions.
42+
43+PCMCIA.txt
44+----------
45+ Ce fichier décrit comment utiliser le script init PCMCIA pour configurer
46+les Wireless Extensions et comment utiliser les schemes PCMCIA (NDT : procédures
47+automatiques).
48+
49+pages man (iwconfig.8, iwlist.8, iwpriv.8, iwspy.8)
50+---------
51+ TRÈS IMPORTANT : J'essaye de garder les pages man à jour, ainsi vous
52+devriez les lire avant de poser des questions.
53+ TRÈS IMPORTANT : Ces pages man décrivent les fonctionnalités des outils,
54+pas un périphérique n'en implémente toute l'étendue (et les pilotes en
55+implémentent souvent encore moins).
56+
57+ Pour autant que je sache, les pages man constituent la plus complète, la
58+plus à jour et la plus précise des documentations des Wireless Tools. Une mise
59+à jour de la page web concernant les Wireless Extensions a été faite il y a fort
60+longtemps. Envoyez-moi vos retours.
61+
62+ Les pages man peuvent aussi bien être copiées dans un endroit où la
63+commande « man » les trouvera, comme /usr/local/man/man8, ou peut être lue
64+localement avec la commande :
65+ nroff -man xxx.8 | less
66+(NDT : ou plus simplement avec « man ./xxx.8 »)
67+
68+pages man localisées (fr/*)
69+--------------------
70+ Les pages de man localisées ne sont pas écrites par moi (NDT\ : ainsi
71+que ce document), par conséquent les seules disponibles sont celles qui me sont
72+envoyées par de courageux volontaires et il faut s'attendre à ce que ces pages
73+man soient en décalage par rapport à la version anglaise (c.-à-d. qu'elles
74+n'aient pas toutes les mises à jour). La traduction des pages man n'est pas une
75+tâche très gratifiante, sans compter mon anglais bancal et un certain nombre
76+de termes techniques difficilement traduisibles vers d'autres langues, donc
77+référez-vous à la version anglaise en cas de doute.
78+
79+iwconfig.c
80+----------
81+ L'outil wireless principal. Utilisé pour la configuration du matériel et
82+pour voir les paramètres wireless les plus communs.
83+
84+iwlist.c
85+--------
86+ Affiche une grosse quantité d'information qui ne l'est pas par iwconfig.
87+ Par exemple, tous les débits, toutes les fréquences, toutes les clefs...
88+
89+iwspy.c
90+-------
91+ Test de support Mobile IP et autorise la récupération de statistiques
92+par adresse MAC (au lieu des stats globales). Aussi, pour certains
93+pilotes/périphériques, c'est la seule manière d'obtenir des stats en mode
94+Ad-Hoc.
95+
96+iwpriv.c
97+--------
98+ Manipule les ioctls privées des pilotes (« driver private ioctls ») :
99+tous les paramètres qui sont spécifiques à un pilote ou à un périphérique et
100+qui, par conséquent, ne font pas partie de iwconfig.
101+
102+iwgetid.c
103+---------
104+ Affiche l'ESSID ou le NWID du périphérique spécifié.
105+ Peut aussi l'afficher dans un format pouvant être utilisé comme un
106+« PCMCIA Scheme ».
107+
108+iwevent.c
109+---------
110+ Affiche les « Wireless Events » (Événements Wireless). Cela est
111+nouveau, il n'y a donc pas encore beaucoup de pilotes qui le supportent...
112+
113+ifrename.c :
114+----------
115+ Renomme les interfaces réseau basées sur différents attributs.
116+
117+iwlib.c
118+-------
119+ Les librairies « helper » Wireless Tools. Peuvent être utiles si vous
120+voulez créer votre propre application en utilisant les Wireless Extensions.
121+
122+Changelog, contributions :
123+------------------------
124+ Voir CHANGELOG.h
125+
126+wireless.h
127+----------
128+ Définition des Wireless Extensions. Gardez à l'esprit que la définition
129+utilisée par les pilotes et les outils (Wireless Tools) doivent correspondre,
130+sinon de drôles de choses peuvent arriver. Les outils essayent de le vérifier.
131+ Depuis les Wireless Extensions v12, vous ne pouvez plus mettre ce
132+fichier dans les entêtes de votre noyau pour mettre à jour les Wireless
133+Extensions, vous avez besoin d'utiliser les patches complets disponibles sur ma
134+page web. Donc, son utilité est plus pour le cas où vous prévoyez de faire de
135+la compilation transverse (if you plan to do some « cross compile ») ou quelque
136+chose de similaire.
137+Juste pour votre plaisir, il y en a différentes versions. Si vos noyau/pilotes
138+sont anciens, vous voudrez peut-être essayer les anciennes versions...
139+
140+sample_xxx.c :
141+------------
142+ Différents échantillons de code montrant comment implémenter quelques
143+unes des caractéristiques les plus intéressantes des Wireless Extensions dans
144+votre pilote.
145+ Notez qu'il n'y a pas d'assurance que ce code compile, laissez-le tel
146+quel, mais cela devrait vous orienter dans la bonne direction.
147+ Aussi, jetez un ½il aux pilotes existant dans le noyau Linux.
148+
149+Autres outils :
150+-------------
151+ Ma page web liste bien d'autres outils utilisant les Wireless
152+Extensions que vous pourriez trouver utiles...
153+ http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html#links
154+
155+Autres questions :
156+----------------
157+ Vous avez le source, et il est documenté. Dans 99% des cas, vous y
158+trouverez votre réponse.
159+
160+ Bonne chance...
161+
162+ Jean <jt@hpl.hp.com>
--- /dev/null
+++ b/wireless_tools/fr/ifrename.8
@@ -0,0 +1,147 @@
1+.\" Jean II - HPL - 2004
2+.\" ifrename.8
3+.\"
4+.\" Traduction 2004/08/25 Maxime CHARPENNE (voir
5+.\" http://www.delafond.org/traducmanfr/)
6+.\" 1ère traduction : version 27-pre25
7+.TH IFRENAME 8 "01 mars 2004" "wireless-tools" "Manuel du programmeur Linux"
8+.\"
9+.\" NAME part
10+.\"
11+.SH NOM
12+ifrename \- renomme les interfaces réseau basées sur différents critères
13+statiques
14+.\"
15+.\" SYNOPSIS part
16+.\"
17+.SH SYNOPSIS
18+.B "ifrename [-c configfile] [-p] [-d]"
19+.br
20+.B "ifrename [-c configfile] [-i interface] [-n newname]"
21+.\"
22+.\" DESCRIPTION part
23+.\"
24+.SH DESCRIPTION
25+.B Ifrename
26+est un outil vous permettant d'assigner un nom cohérent à chacune de vos
27+interfaces réseau.
28+.PP
29+Par défaut, les noms d'interface sont dynamiques, et à chaque interface réseau
30+est assigné le premier nom disponible
31+.RI ( eth0 ", " eth1 "...)."
32+L'ordre dans lequel les interfaces réseau sont créées peut varier. Pour les
33+interfaces fixes («\ built-in interfaces\ »), l'énumération du noyau au
34+démarrage peut varier. Pour les interfaces débranchables, l'utilisateur peut les
35+brancher dans n'importe quel ordre.
36+.PP
37+.B Ifrename
38+permet à l'utilisateur de décider quel nom une interface réseau aura.
39+.B Ifrename
40+peut utiliser différents sélecteurs
41+.RI "(«\ " selectors "\ »)"
42+pour spécifier comment les noms d'interface correspondent aux interfaces réseau
43+du système, le plus commun des sélecteurs étant
44+.RI "l'" "adresse MAC"
45+de l'interface.
46+.PP
47+.B Ifrename
48+doit être lancé avant que les interfaces ne soient démarrées, raison pour
49+laquelle il est surtout utile dans divers scripts (init, hotplug), mais il est
50+rarement utilisé directement par l'utilisateur. Par défaut,
51+.B ifrename
52+renomme toutes les interfaces système présentes en utilisant les correspondances
53+définies dans
54+.IR /etc/iftab .
55+.\"
56+.\" PARAMETER part
57+.\"
58+.SH PARAMÈTRES
59+.TP
60+.BI "-c " configfile
61+Fixe le fichier de configuration à utiliser (par défaut
62+.IR /etc/iftab ).
63+Le fichier de configuration définit la correspondance entre les sélecteurs et
64+les noms d'interface, et il est décrit dans
65+.IR iftab (5).
66+.br
67+Si
68+.I configfile
69+est «\ -\ », la configuration est lue depuis stdin.
70+.TP
71+.B -p
72+Sonde (charge) les modules noyau avant de renommer les interfaces. Par
73+défaut,
74+.B ifrename
75+vérifie seulement les interfaces déjà chargées, et ne charge pas
76+automatiquement les modules noyau requis. Cette option autorise une intégration
77+en douceur dans les systèmes qui ne chargent pas les modules avant d'appeler
78+.BR ifrename .
79+.TP
80+.B -d
81+Active divers bidouillages spécifiques à la
82+.BR Debian .
83+Combiné avec
84+.BR -p ,
85+seuls les modules pour les interfaces spécifiées dans
86+.I /etc/network/interface
87+sont chargés.
88+.TP
89+.BI "-i " interface
90+Renomme seulement
91+.RI "l'" interface
92+spécifiée, par opposition à toutes les interfaces présentes sur le système. Le
93+nouveau nom de l'interface est affiché.
94+.TP
95+.BI "-n " newname
96+Si utilisé avec
97+.IR -i ,
98+spécifie le nouveau nom de l'interface. La liste des correspondances depuis le
99+fichier de configuration est ignorée. Le nouveau nom peut être un joker
100+(«\ wildcard\ ») qui contient une seule '*'.
101+.TP
102+.B -t
103+Active l'absorption («\ takover\ ») de nom. Cela permet d'échanger un nom
104+d'interface entre deux interfaces ou plus.
105+.br
106+L'absorption permet à une interface de «\ voler\ » le nom d'une autre
107+interface. Cela fonctionne seulement avec le noyau 2.6.X et si l'autre
108+interface est désactivée. En conséquence, ce n'est pas compatible avec Hotplug.
109+L'autre interface se voit assigner un nom aléatoire, mais peut être renommée
110+plus tard avec 'ifrename'.
111+.br
112+Le nombre d'absorptions est limité pour éviter les boucles circulaires, et donc
113+certaines situations d'échanges de noms complexes ne seront pas complètement
114+traitées.
115+.br
116+Dans tous les cas, l'échange de noms et l'utilisation de cette caractéristique
117+sont découragés, et vous êtes invités à choisir des noms uniques et sans
118+ambiguïté pour vos interfaces...
119+.\"
120+.\" AUTHOR part
121+.\"
122+.SH AUTEUR
123+Jean Tourrilhes \- jt@hpl.hp.com
124+.\"
125+.\" TRADUCTION part
126+.\"
127+.SH TRADUCTION
128+Maxime CHARPENNE, août 2004 (wireless_tools.27-pre25).
129+.\"
130+.\" AVERTISSEMENT part
131+.\"
132+.SH AVERTISSEMENT SUR LA TRADUCTION
133+Il est possible que cette traduction soit imparfaite ou périmée. En cas de
134+doute, veuillez vous reporter au document original en langue anglaise fourni
135+avec le programme.
136+.\"
137+.\" FILES part
138+.\"
139+.SH FICHIERS
140+.I /etc/iftab
141+.\"
142+.\" SEE ALSO part
143+.\"
144+.SH VOIR AUSSI
145+.BR ifconfig (8),
146+.BR ip (8),
147+.BR iftab (5).
--- /dev/null
+++ b/wireless_tools/fr/iftab.5
@@ -0,0 +1,196 @@
1+.\" Jean II - HPL - 2004
2+.\" iftab.5
3+.\"
4+.\" Traduction 2004/08/25 Maxime CHARPENNE (voir
5+.\" http://www.delafond.org/traducmanfr/)
6+.\" 1ère traduction : version 27-pre25
7+.\"
8+.TH IFTAB 5 "01 mars 2004" "wireless-tools" "Manuel du Programmeur Linux"
9+.\"
10+.\" NAME part
11+.\"
12+.SH NOM
13+iftab \- informations statiques sur les interfaces réseau
14+.\"
15+.\" DESCRIPTION part
16+.\"
17+.SH DESCRIPTION
18+Le fichier
19+.B /etc/iftab
20+contient de l'information descriptive à propos des diverses interfaces réseau.
21+.B iftab
22+n'est utilisé que par le programme
23+.IR ifrename (8)
24+pour assigner un nom d'interface réseau cohérent à chaque interface réseau.
25+.PP
26+.B /etc/iftab
27+définit un ensemble de
28+.RI "correspondances («\ " mappings "\ »)."
29+Chaque correspondance contient un nom d'interface et un ensemble de sélecteurs
30+(«\ selectors\ »). Les sélecteurs permettent à
31+.B ifrename
32+d'identifier chaque interface réseau du système. Si une interface réseau
33+correspond à tous les descripteurs d'une correspondance,
34+.B ifrename
35+essaye de changer le nom de l'interface par le nom de l'interface donné dans la
36+correspondance.
37+.\"
38+.\" MAPPINGS part
39+.\"
40+.SH CORRESPONDANCES («\ MAPPINGS\ »)
41+Chaque correspondance est décrite sur une ligne distincte, elle commence avec
42+.IR "interface name" " (nom d'interface),"
43+et contient un ensemble de
44+.RI "descripteurs («\ " descriptors "\ »),"
45+séparés par des espaces ou des tabulations.
46+.PP
47+La relation entre les descripteurs d'une correspondance est un
48+.IR "et logique" .
49+Une correspondance s'applique à une interface réseau seulement si tous les
50+descripteurs s'appliquent. Si une interface réseau ne supporte pas un
51+descripteur particulier, elle ne s'appliquera à aucune correspondance qui
52+utilise ce descripteur.
53+.PP
54+Si vous voulez utiliser des descripteurs alternatifs pour un nom d'interface
55+(ou logique), spécifiez deux correspondances différentes avec le même nom
56+d'interface (une par ligne).
57+.B Ifrename
58+utilise toujours la première correspondance en commençant par la
59+.I fin
60+de
61+.BR iftab ,
62+donc les correspondances les plus restrictives devraient être définies en
63+dernier.
64+.\"
65+.\" INTERFACE NAME part
66+.\"
67+.SH NOM D'INTERFACE
68+La première partie de chaque correspondance est un nom d'interface. Si une
69+interface réseau correspond à tous les descripteurs d'une correspondance,
70+.B ifrename
71+essaye de changer le nom de l'interface par le nom de l'interface donné dans la
72+correspondance.
73+.PP
74+Le nom de l'interface d'une correspondance est soit un nom d'interface complet
75+(comme
76+.IR eth2 " ou " wlan0 )
77+ou un motif de nom d'interface contenant un seul caractère joker (comme
78+.IR eth* " ou " wlan* ).
79+Dans le cas d'un caractère joker («\ wildcard\ »), le noyau remplace le
80+caractère '*' par le plus petit entier disponible faisant un nom d'interface
81+unique.
82+.\"
83+.\" DESCRIPTORS part
84+.\"
85+.SH DESCRIPTEURS («\ DESCRIPTORS\ »)
86+Chaque descripteur est composé d'un nom de descripteur et d'une valeur de
87+descripteur. Les descripteurs définissent un attribut statique d'une interface
88+réseau, le but étant d'identifier de manière unique chaque périphérique.
89+.PP
90+La plupart des utilisateurs n'utiliseront que le sélecteur
91+.BR mac ,
92+les autres sélecteurs étant pour une configuration plus spécialisée.
93+.TP
94+.BI mac " adresse mac"
95+Correspond à l'Adresse MAC de l'interface avec l'adresse MAC spécifiée.
96+L'adresse MAC de l'interface peut être montrée en utilisant
97+.IR ifconfig (8)
98+ou
99+.IR ip (8).
100+L'adresse MAC spécifiée peut contenir une '*' pour la correspondance joker
101+(«\ wildcard matching\ »).
102+.br
103+C'est le plus commun des sélecteurs, vu que chaque interface possède une
104+adresse MAC unique, ce qui permet de les identifier sans ambiguïté.
105+.TP
106+.BI arp " arp type"
107+Fait correspondre le Type ARP («\ ARP Type\ ») (aussi appelé «\ Link Type\ »)
108+de l'interface avec le type ARP spécifié. Le Type ARP de l'interface peut être
109+montré en utilisant
110+.IR ifconfig (8)
111+ou
112+.IR ip (8).
113+.br
114+Ce sélecteur est utile quand un pilote crée plusieurs interfaces réseau pour
115+une seule carte réseau.
116+.TP
117+.BI driver " driver name"
118+Fait correspondre le Nom de Pilote («\ Driver Name\ ») de l'interface avec le
119+nom de pilote spécifié. Le Nom de Pilote de l'interface peut être montré en
120+utilisant
121+.IR "ethtool -i" (8).
122+.TP
123+.BI businfo " bus information"
124+Fait correspondre l'Information de Bus («\ Bus Information\ ») de l'interface
125+avec l'information de bus spécifiée. L'Information de Bus de l'interface peut
126+être montrée en utilisant
127+.IR "ethtool -i" (8).
128+.TP
129+.BI baseaddress " base address"
130+Fait correspondre l'Adresse de Base («\ Base Address\ ») de l'interface avec
131+l'adresse de base spécifiée. L'Adresse de Base de l'interface peut être montrée
132+en utilisant
133+.IR ifconfig (8).
134+.br
135+Ce sélecteur n'est utile que pour les cartes ISA et EISA car la plupart des
136+cartes utilisent l'allocation dynamique pour l'Adresse de Base.
137+.TP
138+.BI irq " irq line"
139+Fait correspondre la Ligne IRQ (interruption) de l'interface avec la ligne IRQ
140+spécifiée. La Ligne IRQ de l'interface peut être montrée en utilisant
141+.IR ifconfig (8).
142+.br
143+Ce sélecteur n'est habituellement pas suffisant pour identifier de manière
144+unique une interface, car les Lignes IRQ peuvent être partagées.
145+.TP
146+.BI iwproto " wireless protocol"
147+Fait correspondre le Protocole Wireless de l'interface avec le protocole
148+wireless spécifié. Le Protocole Wireless de l'interface peut être montré
149+en utilisant
150+.IR iwconfig (8).
151+.br
152+Ce sélecteur n'est valable que pour les interfaces wireless et n'est pas
153+suffisant pour en identifier une de manière unique.
154+.\"
155+.\" EXAMPLE part
156+.\"
157+.SH EXEMPLE
158+# Ceci est un commentaire
159+.br
160+eth2 mac 08:00:09:DE:82:0E
161+.br
162+eth3 driver wavelan interrupt 15 baseaddress 0x390
163+.br
164+eth4 driver pcnet32 businfo 0000:02:05.0
165+.br
166+air* mac 00:07:0E:* arp 1
167+.\"
168+.\" AUTHOR part
169+.\"
170+.SH AUTEUR
171+Jean Tourrilhes \- jt@hpl.hp.com
172+.\"
173+.\" TRADUCTION part
174+.\"
175+.SH TRADUCTION
176+Maxime CHARPENNE, août 2004 (wireless_tools.27-pre25).
177+.\"
178+.\" AVERTISSEMENT part
179+.\"
180+.SH AVERTISSEMENT SUR LA TRADUCTION
181+Il est possible que cette traduction soit imparfaite ou périmée. En cas de
182+doute, veuillez vous reporter au document original en langue anglaise fourni
183+avec le programme.
184+.\"
185+.\" FILES part
186+.\"
187+.SH FICHIERS
188+.I /etc/iftab
189+.\"
190+.\" SEE ALSO part
191+.\"
192+.SH VOIR AUSSI
193+.BR ifrename (8),
194+.BR ifconfig (8),
195+.BR ip (8),
196+.BR iwconfig (8).
--- /dev/null
+++ b/wireless_tools/fr/iwconfig.8
@@ -0,0 +1,569 @@
1+.\" Jean II - HPLB - 1996 => HPL - 2004
2+.\" iwconfig.8
3+.\"
4+.\" Traduction 2003/07/15 Maxime CHARPENNE (voir
5+.\" http://www.delafond.org/traducmanfr/)
6+.\" 1ère traduction : version 26
7+.\" Mise à jour 2004/01/28 : version 27-pre9 (beta)
8+.\" Mise à jour 2004/02/26 : version 27-pre11 (alpha)
9+.\" Mise à jour 2004/08/23 : version 27-pre25
10+.\"
11+.TH IWCONFIG 8 "22 juin 2004" "wireless-tools" "Manuel du programmeur Linux"
12+.\"
13+.\" NAME part
14+.\"
15+.SH NOM
16+iwconfig \- configure une interface réseau sans-fil (wireless)
17+.\"
18+.\" SYNOPSIS part
19+.\"
20+.SH SYNOPSIS
21+.BI "iwconfig [" interface ]
22+.br
23+.BI "iwconfig " interface " [essid " X "] [nwid " N "] [freq " F "] [channel " C ]
24+.br
25+.BI " [sens " S "] [mode " M "] [ap " A "] [nick " NN ]
26+.br
27+.BI " [rate " R "] [rts " RT "] [frag " FT "] [txpower " T ]
28+.br
29+.BI " [enc " E "] [key " K "] [power " P "] [retry " R ]
30+.br
31+.BI " [commit]
32+.br
33+.BI "iwconfig --help"
34+.br
35+.BI "iwconfig --version"
36+.\"
37+.\" DESCRIPTION part
38+.\"
39+.SH DESCRIPTION
40+.B Iwconfig
41+est similaire à
42+.IR ifconfig (8),
43+mais est dédié aux interfaces wireless. Il est utilisé pour manier les
44+paramètres des interfaces réseaux qui sont spécifiques aux opérations wireless
45+(par exemple\ : la fréquence).
46+.B Iwconfig
47+peut aussi être utilisé pour afficher ces paramètres, et les statistiques
48+concernant le sans fil (extraites de
49+.IR /proc/net/wireless ).
50+.PP
51+Tous ces paramètres et statistiques dépendent du matériel. Chaque pilote ne
52+fournira que quelques uns d'entre eux en fonction du support matériel, et
53+l'étendue des valeurs peut changer. Veuillez vous référer aux pages man de
54+chaque matériel pour plus de détails.
55+.\"
56+.\" PARAMETER part
57+.\"
58+.SH PARAMÈTRES
59+.TP
60+.B essid
61+Positionne le ESSID ( ou Network Name - pour certains produits, il peut aussi
62+être désigné comme Domain ID). L'ESSID est utilisé pour identifier les cellules
63+qui font partie du même réseau virtuel.
64+.br
65+Par opposition à l'adresse de l'AP ou au NWID qui définissent une seule cellule,
66+l'ESSID définit un groupe de cellules connectées via des répéteurs ou via
67+l'infrastructure, où l'utilisateur peut «\ roamer\ » ou errer de manière
68+transprente (c.-à-d. changer de cellule sans perdre sa connexion).
69+.br
70+Avec certaines cartes, vous pouvez désactiver le contrôle du ESSID (ESSID
71+promiscuous) avec
72+.IR off " ou " any " (et " on
73+pour le réactiver).
74+.br
75+.B Exemples :
76+.br
77+.I " iwconfig eth0 essid any"
78+.br
79+.I " iwconfig eth0 essid ""Mon Reseau""
80+.TP
81+.BR nwid / domain
82+Positionne le Network ID (pour certains produits, il peut aussi être appelé
83+Domain ID). Comme tous les réseaux sans fil adjacents partagent le même médium,
84+ce paramètre est utilisé pour les différencier (créer des réseaux logiques
85+colocalisés) et pour identifier des noeuds appartenant à la même cellule.
86+.br
87+Ce paramètre est seulement utilisé par les matériels antérieurs à 802.11, la
88+norme 802.11 se servant du ESSID et de l'adresse de l'AP pour cette fonction.
89+.br
90+Avec certaines cartes, vous pouvez désactiver le contrôle du Network ID (NWID
91+promiscuous) avec
92+.IR off " (et " on
93+pour le réactiver).
94+.br
95+.B Exemples :
96+.br
97+.I " iwconfig eth0 nwid AB34
98+.br
99+.I " iwconfig eth0 nwid off"
100+.TP
101+.BR freq / channel
102+Positionne la fréquence d'exploitation ou canal du périphérique. Une valeur
103+inférieure à 1\ 000 indique un numéro de canal, une valeur supérieure à 1\ 000
104+est une fréquence en Hz. Vous pouvez ajouter le suffixe k, M ou G à la valeur
105+(par exemple, «\ 2.46G\ » pour la fréquence 2,46\ GHz), ou ajouter suffisamment
106+de «\ 0\ ».
107+.br
108+Les canaux sont habituellement numérotés à partir de 1, et vous pouvez utiliser
109+.IR iwlist (8)
110+pour obtenir le nombre total de canaux, lister les fréquences disponibles, et
111+afficher le fréquence courante comme un canal.
112+Suivants les réglementations, certaines fréquences/canaux peuvent ne pas
113+être disponibles.
114+.br
115+.B Exemples :
116+.br
117+.I " iwconfig eth0 freq 2422000000"
118+.br
119+.I " iwconfig eth0 freq 2.422G"
120+.br
121+.I " iwconfig eth0 channel 3"
122+.TP
123+.B sens
124+Positionne le seuil de sensibilité. C'est le niveau de signal le plus bas pour
125+lequel le matériel essaye de réceptionner un paquet, les signaux plus bas sont
126+ignorés. Ceci est utilisé pour éviter de recevoir le bruit de fond, donc vous
127+devriez le positionner en fonction du niveau de bruit moyen. Les valeurs
128+positives sont supposées être les valeurs brutes utilisées par le matériel ou
129+un pourcentage, les valeurs négatives sont supposées être des dBm.
130+.br
131+Avec certains matériels, ce paramètre contrôle aussi le seuil de report
132+(defer threshold) (signal le plus faible pour lequel le matériel considère le
133+canal occupé) et le seuil de cession (handover threshold) (niveau de signal pour
134+lequel le matériel commence à chercher un nouveau Point d'Accès).
135+.br
136+.B Exemple :
137+.br
138+.I " iwconfig eth0 sens -80"
139+.TP
140+.B mode
141+Positionne le mode de fonctionnement du matériel, qui dépend de la topologie du
142+réseau. Le mode peut être
143+.I Ad-Hoc
144+(réseau composé d'une seule cellule et sans Point d'Accès),
145+.I Managed
146+(un noeud se connecte à un réseau composé de plusieurs Points d'Accès, avec
147+roaming ou errance),
148+.I Master
149+(le noeud est le maître qui synchronise ou agit comme un Point d'Accès),
150+.I Repeater
151+(le noeud transmet les paquets entre les autres n½uds wireless),
152+.I Secondary
153+(le noeud agit comme un maître/répéteur supplémentaire),
154+.I Monitor
155+(le noeud agit comme un moniteur passif et ne fait que recevoir des paquets) ou
156+.IR Auto .
157+.br
158+.B Exemple :
159+.br
160+.I " iwconfig eth0 mode Managed"
161+.br
162+.I " iwconfig eth0 mode Ad-Hoc"
163+.TP
164+.B ap
165+Force la carte à s'enregistrer auprès du Point d'Accès donné par l'adresse,
166+si c'est possible. Quand la qualité de la connexion devient trop mauvaise,
167+le pilote peut revenir en mode automatique (la carte sélectionne le meilleur
168+Point d'Accès à portée).
169+.br
170+Vous pouvez aussi utiliser
171+.I off
172+pour réactiver le mode automatique sans changer le Point d'Accès courant,
173+ou vous pouvez utiliser
174+.I any
175+ou
176+.I auto
177+pour forcer la carte à se ré associer avec le meilleur Point d'Accès courant.
178+.br
179+.B Exemple :
180+.br
181+.I " iwconfig eth0 ap 00:60:1D:01:23:45"
182+.br
183+.I " iwconfig eth0 ap any"
184+.br
185+.I " iwconfig eth0 ap off"
186+.TP
187+.BR nick [name]
188+Positionne le surnom (nickname), ou nom de station. Quelques produits
189+802.11 le définissent, mais il n'est pas utilisé dans la mesure où les
190+protocoles les plus usités (MAC, IP, TCP) ne s'en servent pas en l'état.
191+Seuls quelques outils de diagnostic peuvent l'utiliser.
192+.br
193+.B Exemple :
194+.br
195+.I " iwconfig eth0 nickname ""My Linux Node""
196+.TP
197+.BR rate / bit [rate]
198+Pour les cartes supportant plusieurs débits, positionne le débit en b/s. Le
199+débit est la vitesse à laquelle les bits sont transmis sur le médium, la
200+vitesse du lien pour l'utilisateur est inférieure à cause du partage du médium
201+et des diverses entêtes.
202+.br
203+Vous pouvez ajouter le suffixe k, M ou G à la valeur (multiplicateur décimal\ :
204+10^3, 10^6 et 10^9\ b/s), ou ajouter suffisamment de «\ 0\ ». Les valeurs
205+en-dessous de 1000 sont spécifiques à la carte, habituellement un index de la
206+liste des débit supportés. Utilisez
207+.I auto
208+pour sélectionner le mode débit automatique (repli à un débit moindre pour
209+les canaux bruités), ce qui est le mode par défaut pour la plupart des cartes,
210+et
211+.I fixed
212+pour revenir à des paramètres fixes. Si vous spécifiez une valeur de débit
213+et ajoutez
214+.IR auto ,
215+le driver utilisera tous les débits inférieurs et égaux à cette valeur.
216+.br
217+.B Exemples :
218+.br
219+.I " iwconfig eth0 rate 11M"
220+.br
221+.I " iwconfig eth0 rate auto"
222+.br
223+.I " iwconfig eth0 rate 5.5M auto"
224+.TP
225+.BR rts [_threshold]
226+RTS/CTS ajoute une «\ poignée de main\ » avant chaque transmission de paquet
227+pour être sûr que le canal est libre. Cela ajoute des entêtes (NDT\ : données de
228+gestion), mais augmente les performances en cas de n½uds cachés ou
229+d'un grand nombre de noeuds actifs. Ce paramètre fixe la taille du plus petit
230+paquet pour lequel le noeud envoie un RTS\ ; une valeur égale à la taille
231+maximale des paquets inhibe ce mécanisme. Vous pouvez aussi positionner
232+ce paramètre sur
233+.IR auto ", " fixed " ou " off .
234+.br
235+.B Exemples :
236+.br
237+.I " iwconfig eth0 rts 250"
238+.br
239+.I " iwconfig eth0 rts off"
240+.TP
241+.BR frag [mentation_threshold]
242+La fragmentation permet de découper un paquet IP en une série de plus petits
243+fragments transmis par le médium. Dans la plupart des cas, cela ajoute des
244+entêtes, mais dans un environnement très bruité, cela réduit les coûts de
245+transmission dus aux erreurs et permet aux paquets d'être acheminés malgré
246+des séries d'interférences. Ce paramètre fixe la taille de fragment maximale\ ;
247+une valeur égale à la taille maximale de paquet désactive ce procédé. Vous
248+pouvez aussi mettre ce paramètre à
249+.IR auto ", " fixed " ou " off .
250+.br
251+.B Exemples :
252+.br
253+.I " iwconfig eth0 frag 512"
254+.br
255+.I " iwconfig eth0 frag off"
256+.TP
257+.BR key / enc [ryption]
258+Utilisé pour manipuler les clefs de cryptage ou brouillage et le mode de
259+sécurité.
260+.br
261+Pour mettre la clef courante de cryptage, il suffit d'entrer la clef
262+en hexadécimal telle que
263+.IR XXXX-XXXX-XXXX-XXXX " ou " XXXXXXXX .
264+Pour entrer une autre clef que la clef courante, ajoutez (au début ou à la
265+fin)
266+.I [index]
267+à la clef elle-même (cela ne changera pas la clef active). Vous pouvez aussi
268+entrer la clef comme une chaîne ASCII en utilisant le préfixe
269+.IR s: .
270+Les phrases en tant que mot de passe ne sont actuellement pas supportées.
271+.br
272+Pour changer la clef active parmi les clefs déjà entrées, il suffit d'entrer
273+.RI l' "[index]"
274+(sans entrer de valeur de clef).
275+.br
276+.IR off " et " on
277+désactive et réactive le cryptage.
278+.br
279+Le mode de sécurité peut être
280+.I open
281+ou
282+.IR restricted ,
283+et sa signification dépend de la carte utilisée. Avec la plupart des cartes,
284+le mode
285+.I open
286+n'utilise pas d'authentification et la carte accepte des sessions non cryptées,
287+alors que le mode
288+.I restricted
289+n'accepte que des sessions cryptées et la carte utilisera l'authentification
290+si disponible.
291+.br
292+Si vous avez besoin de mettre plusieurs clefs, ou de mettre une clef et de
293+changer la clef active, vous avez besoin d'utiliser des instructions à clefs
294+.RB ( "key" )
295+multiples. Les arguments peuvent être mis dans n'importe quel ordre, le
296+dernier sera prioritaire.
297+.br
298+.B Exemples :
299+.br
300+.I " iwconfig eth0 key 0123-4567-89"
301+.br
302+.I " iwconfig eth0 key [3] 0123-4567-89"
303+.br
304+.I " iwconfig eth0 key s:password [2]"
305+.br
306+.I " iwconfig eth0 key [2]"
307+.br
308+.I " iwconfig eth0 key open"
309+.br
310+.I " iwconfig eth0 key off"
311+.br
312+.I " iwconfig eth0 key restricted [3] 0123456789"
313+.br
314+.I " iwconfig eth0 key 01-23 key 45-67 [4] key [4]"
315+.TP
316+.BR power
317+Utilisé pour manipuler les paramètres et le mode du procédé de gestion
318+d'énergie.
319+.br
320+Pour fixer la période entre les éveils, entrez la
321+.IR "period `valeur'" .
322+Pour fixer la temporisation avant le retour en veille, entrez la
323+.IR "timeout `valeur'" .
324+Vous pouvez aussi ajouter les modificateurs
325+.IR min " et " max ".
326+Par défaut, ces valeurs sont exprimées en secondes, ajoutez le suffixe m ou u
327+pour spécifier les valeurs en millisecondes ou microsecondes. Parfois, ces
328+valeurs sont sans unité (nombre de périodes de beacon, dwell ou similaire).
329+.br
330+.IR off " et " on
331+désactive et réactive la gestion d'énergie. Enfin, vous pouvez mettre la
332+gestion d'énergie en mode
333+.I all
334+(reçoit tous les paquets),
335+.I unicast
336+(reçoit seulement les paquets unicast, ignore les paquets multicast et de
337+broadcast) et
338+.I multicast
339+(reçoit seulement les paquets multicast et de broadcast, ignore l'unicast).
340+.br
341+.B Exemples :
342+.br
343+.I " iwconfig eth0 power period 2"
344+.br
345+.I " iwconfig eth0 power 500m unicast"
346+.br
347+.I " iwconfig eth0 power timeout 300u all"
348+.br
349+.I " iwconfig eth0 power off"
350+.br
351+.I " iwconfig eth0 power min period 2 power max period 4"
352+.TP
353+.BR txpower
354+Pour les cartes supportant plusieurs puissances de transmission, règle la
355+puissance de transmission en dBm. Si
356+.I W
357+est la puissance en Watt, la puissance en dBm est
358+.IR "P\ =\ 30\ +\ 10.log(W)" .
359+Si la valeur est post fixée par
360+.IR mW ,
361+elle sera automatiquement convertie en dBm.
362+.br
363+De plus,
364+.IR on " et " off
365+active et désactive la radio, et
366+.IR auto " et " fixed
367+active et désactive le contrôle de puissance (si ces fonctions sont
368+disponibles).
369+.br
370+.B Exemples :
371+.br
372+.I " iwconfig eth0 txpower 15"
373+.br
374+.I " iwconfig eth0 txpower 30mW"
375+.br
376+.I " iwconfig eth0 txpower auto"
377+.br
378+.I " iwconfig eth0 txpower off"
379+.TP
380+.BR retry
381+La plupart des cartes supportent les retransmissions MAC (contrôle d'accès
382+au médium), et certaines permettent le paramétrage du mécanisme des tentatives
383+(en cas d'échec).
384+.br
385+Pour fixer le nombre maximum d'essais, entrez
386+.IR "limit `valeur'" .
387+C'est une valeur absolue (sans unité).
388+Pour fixer le temps maximum autorisé au mécanisme MAC pour ses tentatives,
389+entrez
390+.IR "lifetime `valeur'" .
391+Par défaut, cette valeur est en secondes, ajouter le suffixe m ou u pour
392+spécifier les valeurs en millisecondes ou microsecondes.
393+.br
394+Vous pouvez aussi ajouter les modificateurs
395+.IR min " et " max ".
396+Si la carte supporte le mode automatique, ils définissent les limites du
397+lifetime, ou les limites inférieure et supérieure (NDT\ : de l'intervalle
398+temporel dans lequel le mécanisme MAC est autorisé à réitérer ses tentatives).
399+D'autres cartes définissent des valeurs différentes en fonction de la taille
400+des paquets, par exemple la norme 802.11 définit une
401+.I min limit
402+qui est la limite inférieure d'essai (paquets non RTS/CTS).
403+.br
404+.B Exemples :
405+.br
406+.I " iwconfig eth0 retry 16"
407+.br
408+.I " iwconfig eth0 retry lifetime 300m"
409+.br
410+.I " iwconfig eth0 retry min limit 8"
411+.TP
412+.BR commit
413+Certaines cartes peuvent ne pas appliquer immédiatement les changements
414+effectués par les Wireless Extensions (elles peuvent attendre pour prendre en
415+compte les changements ou les appliquer seulement quand la carte est montée via
416+ifconfig). Cette commande (si disponible) force la carte à appliquer les
417+changements en suspens.
418+.br
419+Cela n'est normalement pas nécessaire, car la carte appliquera éventuellement
420+les changements, mais peut être utile pour débuggage.
421+.\"
422+.\" DISPLAY part
423+.\"
424+.SH AFFICHAGE
425+Pour chaque matériel qui supporte les extensions wireless,
426+.I iwconfig
427+affiche le nom du
428+.B protocole MAC
429+utilisé (nom du matériel pour les protocoles propriétaires),
430+.RB l' ESSID
431+(Network Name), le
432+.BR NWID ,
433+la
434+.B fréquence
435+(ou canal), la
436+.BR sensibilité ,
437+le
438+.B mode
439+d'exploitation, l'adresse du
440+.BR "Point d'Accès",
441+le
442+.BR débit ,
443+le
444+.BR "seuil RTS" " (" "RTS threshold" "), le "
445+.BR "seuil de fragmentation" " (" "fragmentation threshold" "), la
446+.B clef de cryptage
447+et les paramètres de
448+.BR "gestion de l'énergie" " (" "power management" ")"
449+(en fonction de la disponibilité).
450+.PP
451+Les paramètres affichés ont la même signification et la même valeur que ceux
452+que vous pouvez régler, veuillez vous reporter à la précédente partie pour
453+leur explication détaillée.
454+.br
455+Quelques paramètres sont affichés seulement dans une forme abrégée (comme le
456+cryptage). Vous devez utiliser
457+.IR iwlist (8)
458+pour avoir tous les détails.
459+.br
460+Certains paramètres ont deux modes (comme le débit). Si la valeur est préfixée
461+par
462+.RB «\ =\ »,
463+cela veut dire que le paramètre est fixé et forcé à cette valeur, s'il est
464+préfixé par
465+.RB «\ :\ »,
466+le paramètre est en mode automatique et la valeur courante est montrée (et peut
467+changer).
468+.TP
469+.BR "Access Point" / Cell
470+Une adresse égale à 00:00:00:00:00:00 signifie que la carte n'a pas réussi à
471+s'associer avec un Point d'Accès (le plus souvent une question de
472+configuration).
473+Le paramètre
474+.B Access Point
475+sera montré comme une cellule
476+.RB ( Cell )
477+en mode ad hoc (pour des raisons évidentes), mais il fonctionne néanmoins
478+de la même manière.
479+.PP
480+Si
481+.I /proc/net/wireless
482+existe,
483+.I iwconfig
484+affichera aussi son contenu. Il faut noter que ces valeurs dépendent des
485+spécifications du pilote et de la carte, vous devrez donc vous référez à la
486+documentation du pilote pour une interprétation correcte de ces valeurs.
487+.TP
488+.B Link quality
489+Qualité globale du lien. Peut être basé sur le niveau de contention ou des
490+interférences, le taux d'erreur de trame ou de bit, la qualité du signal reçu,
491+des synchronisations temporelles, ou autre métrique matérielle. C'est une valeur
492+agrégat, et dépend totalement du pilote et du matériel.
493+.TP
494+.B Signal level
495+Force du signal reçu (RSSI - force du signal reçu). Cela peut être des unités
496+arbitraires ou des dBm,
497+.I iwconfig
498+utilise des méta-informations du pilote pour interpréter les valeurs
499+brutes données par
500+.I /proc/net/wireless
501+et affiche l'unité ou la valeur maximale correspondante (utilise l'arithmétique
502+8 bits). En mode
503+.I Ad-Hoc
504+cela peut être indéfini et vous devriez utiliser
505+.IR iwspy .
506+.TP
507+.B Noise level
508+Niveau du bruit de fond (quand aucun paquet n'est transmis). Commentaires
509+similaires à ceux de
510+.BR "Signal level" .
511+.TP
512+.B Rx invalid nwid
513+Nombre de paquets reçus avec un NWID ou ESSID différent. Utilisé pour détecter
514+des problèmes de configuration ou l'existence de réseau adjacent (sur la même
515+fréquence).
516+.TP
517+.B Rx invalid crypt
518+Nombre de paquets que le matériel a été incapable de décrypter. Cela peut être
519+utilisé pour détecter des mauvais paramètres de cryptage.
520+.TP
521+.B Rx invalid frag
522+Nombre de paquets pour lesquels le matériel a été incapable de ré-assembler
523+correctement les fragments de la couche liaison (le plus souvent, il en manque
524+un).
525+.TP
526+.B Tx excessive retries
527+Nombre de paquets que la carte n'a pas réussi à envoyer. La plupart des
528+protocoles MAC réessaient un certain nombre de fois avant d'abandonner.
529+.TP
530+.B invalid misc
531+Autres paquets perdus en relation avec les opérations spécifiques au sans fil.
532+.TP
533+.B Missed beacon
534+Nombre de beacons périodiques émis par la Cellule ou le Point d'Accès que nous
535+avons manqué. Les beacons sont envoyés à intervalles réguliers pour maintenir la
536+coordination de la cellule, l'impossibilité de les recevoir indiquant souvent
537+que la carte est hors de portée.
538+.\"
539+.\" AUTHOR part
540+.\"
541+.SH AUTEUR
542+Jean Tourrilhes \- jt@hpl.hp.com
543+.\"
544+.\" TRADUCTION part
545+.\"
546+.SH TRADUCTION
547+Maxime CHARPENNE, août 2004 (wireless_tools.27-pre25).
548+.\"
549+.\" AVERTISSEMENT part
550+.\"
551+.SH AVERTISSEMENT SUR LA TRADUCTION
552+Il est possible que cette traduction soit imparfaite ou périmée. En cas de
553+doute, veuillez vous reporter au document original en langue anglaise fourni
554+avec le programme.
555+.\"
556+.\" FILES part
557+.\"
558+.SH FICHIERS
559+.I /proc/net/wireless
560+.\"
561+.\" SEE ALSO part
562+.\"
563+.SH VOIR AUSSI
564+.BR ifconfig (8),
565+.BR iwspy (8),
566+.BR iwlist (8),
567+.BR iwevent (8),
568+.BR iwpriv (8),
569+.BR wireless (7).
--- /dev/null
+++ b/wireless_tools/fr/iwevent.8
@@ -0,0 +1,131 @@
1+.\" Jean Tourrilhes - HPL - 2002 - 2004
2+.\" iwevent.8
3+.\"
4+.\" Traduction 2003/08/17 Maxime CHARPENNE (voir
5+.\" http://www.delafond.org/traducmanfr/)
6+.\" 1ère traduction : version 26
7+.\" Manuel identique pour la version 27-pre9 (beta)
8+.\" Mise à jour 2004/02/26 : version 27-pre11 (alpha)
9+.\" Mise à jour 2004/08/23 : version 27-pre25
10+.\"
11+.TH IWEVENT 8 "23 juin 2004" "net-tools" "Manuel du Programmeur Linux"
12+.\"
13+.\" NAME part
14+.\"
15+.SH NOM
16+iwevent \- Affiche les Événements Wireless (Wireless Events) générés par les
17+pilotes et les changements de paramètres.
18+.\"
19+.\" SYNOPSIS part
20+.\"
21+.SH SYNOPSIS
22+.BI "iwevent "
23+.br
24+.\"
25+.\" DESCRIPTION part
26+.\"
27+.SH DESCRIPTION
28+.B iwevent
29+affiche les «\ Wireless Events\ » (événements du système Wireless) reçu par le
30+socket RTNetlink. Chaque ligne affiche le Wireless Event spécifique qui décrit
31+ce qui s'est passé sur l'interface sans fil spécifiée.
32+.br
33+Cette commande ne prend aucun argument.
34+.\"
35+.\" DISPLAY part
36+.\"
37+.SH AFFICHAGE
38+Il y a deux classes de Wireless Events.
39+.PP
40+La première classe regroupe les événements relatifs à un changement des
41+paramètres du sans fil sur l'interface (typiquement fait par
42+.B iwconfig
43+ou un script appelant
44+.BR iwconfig ).
45+Seuls les paramètres qui peuvent entraîner une perturbation de la connectivité
46+sont rapportés. Les événements actuellement rapportés changent un des paramètres
47+suivants\ :
48+.br
49+.I " Network ID"
50+.br
51+.I " ESSID"
52+.br
53+.I " Frequency"
54+.br
55+.I " Mode"
56+.br
57+.I " Encryption"
58+.br
59+Tous ces événements seront générer sur toutes les interfaces sans fil par le
60+sous-système «\ wireless\ » du noyau (mais seulement si le pilote a été converti
61+àl'API du nouveau pilote).
62+.PP
63+La deuxième classe d'événements concerne ceux générés par le matériel, lorsque
64+quelque chose arrive ou qu'une tâche s'est terminée. Ces événements incluent\ :
65+.TP
66+.B New Access Point/Cell address
67+L'interface a joint un nouveau point d'accès ou cellule ad hoc, ou perdu son
68+association avec. Il s'agit de la même adresse MAC affiché par
69+.BR iwconfig .
70+.TP
71+.B Scan request completed
72+Une requête de balayage (scanning) a été achevée, les résultats du «\ scan\ »
73+sont disponibles (voir
74+.BR iwlist ).
75+.TP
76+.B Tx packet dropped
77+Un paquet à destination de cette adresse a été rejeté car l'interface croit que
78+ce noeud ne répond plus (habituellement, le seuil maximum des émissions de la
79+couche MAC est atteint). C'est habituellement la première indication pouvant
80+révéler que le noeud a quitté la cellule ou est hors de portée, mais cela peut
81+être due à une atténuation ou une contention excessive.
82+.TP
83+.B Custom driver event
84+Événement spécifique au pilote. Veuillez consulter la documentation du pilote.
85+.TP
86+.B Registered node
87+L'interface a réussi à enregistrer un nouveau client/paire sans fil. Sera
88+généré la plupart du temps quand l'interface agit comme un point d'accès (mode
89+master).
90+.TP
91+.B Expired node
92+L'enregistrement d'un client/paire sur cette interface a expiré. Sera généré la
93+plupart du temps quand l'interface agit comme un point d'accès (mode master).
94+.TP
95+.B Spy threshold crossed
96+La force du signal pour une des adresses de la «\ spy list\ » (NDT\ : voir
97+iwspy(8)) est passé en-dessous du seuil bas, ou est passé au-dessus du seuil
98+haut.
99+.PP
100+La plupart des pilotes wireless génèrent seulement un sous-ensemble de ces
101+événements, pas tous, la liste exacte dépendant de la combinaison spécifique
102+matériel/pilote. Veuillez consulter la documentation du pilote pour les détails
103+de ce qui les génèrent, et utilisez
104+.IR iwlist (8)
105+pour vérifier ce que le pilote supporte.
106+.\"
107+.\" AUTHOR part
108+.\"
109+.SH AUTEUR
110+Jean Tourrilhes \- jt@hpl.hp.com
111+.\"
112+.\" TRADUCTION part
113+.\"
114+.SH TRADUCTION
115+Maxime CHARPENNE, août 2004 (wireless_tools.27-pre25).
116+.\"
117+\" AVERTISSEMENT part
118+.\"
119+.SH AVERTISSEMENT SUR LA TRADUCTION
120+Il est possible que cette traduction soit imparfaite ou périmée. En cas de
121+doute, veuillez vous reporter au document original en langue anglaise fourni
122+avec le programme.
123+.\"
124+.\" SEE ALSO part
125+.\"
126+.SH VOIR AUSSI
127+.BR iwconfig (8),
128+.BR iwlist (8),
129+.BR iwspy (8),
130+.BR iwpriv (8),
131+.BR wireless (7).
--- /dev/null
+++ b/wireless_tools/fr/iwgetid.8
@@ -0,0 +1,136 @@
1+.\" Guus Sliepen - 2001
2+.\" Completed and fixed up by Jean Tourrilhes - 2002-2003
3+.\" iwgetid.8
4+.\"
5+.\" Traduction 2003/08/17 Maxime CHARPENNE (voir
6+.\" http://www.delafond.org/traducmanfr/)
7+.\" 1ère traduction : version 26
8+.\" Mise à jour 2004/01/29 : version 27-pre9 (beta)
9+.\" Manuel identique pour la version 27-pre11 (alpha)
10+.\" Mise à jour 2004/08/23 : version 27-pre25
11+.\"
12+.TH IWGETID 8 "02 décembre 2003" "wireless-tools" "Manuel du Programmeur Linux"
13+.\"
14+.\" NAME part
15+.\"
16+.SH NOM
17+iwgetid \- Rapporte le ESSID, NWID ou l'Adresse de l'AP/Cell (Point d'Accès/\
18+Cellule) du réseau sans fil.
19+.\"
20+.\" SYNOPSIS part
21+.\"
22+.SH SYNOPSIS
23+.BI "iwgetid " [interface] " [--raw] [--scheme] [--ap] [--freq]"
24+.br
25+.BI " [--mode] [--protocol] [--channel]
26+.br
27+.\"
28+.\" DESCRIPTION part
29+.\"
30+.SH DESCRIPTION
31+.B iwgetid
32+est utilisé pour trouver le NWID, ESSID ou l'adresse de l'AP ou cellule du
33+réseau sans fil utilisé présentement. L'information rapportée est la même
34+que celle montrée par
35+.BR iwconfig ", mais " iwgetid
36+est plus facile à intégrer dans les scripts.
37+.br
38+Par défaut,
39+.B iwgetid
40+affichera
41+.RI l' ESSID
42+de la carte, et si la carte n'a pas d'ESSID, il affichera son
43+.IR NWID .
44+.br
45+Le formatage par défaut de la sortie est embelli.
46+.\"
47+.\" OPTIONS part
48+.\"
49+.SH OPTIONS
50+.TP
51+.B --raw
52+Cette option désactive l'embellissement de l'affichage de l'information. Cette
53+option est orthogonale aux autres options (sauf
54+.BR --scheme ),
55+donc, avec la combinaison appropriée des options, il est possible d'afficher
56+en brut l'ESSID, l'Adresse de l'AP ou le Mode.
57+.br
58+Ce format est idéal quand on stocke le résultat de iwgetid comme une variable
59+dans les scripts
60+.I Shell
61+ou
62+.IR Perl ,
63+ou pour passer le résultat comme argument sur la ligne de commande de
64+.BR iwconfig .
65+.TP
66+.B --scheme
67+Cette option est similaire à la précédente, elle désactive l'embellissement de
68+l'affichage des données et supprime tous les caractères non alphanumériques
69+(comme les caractères d'espacement, la ponctuation et les caractères de
70+contrôle).
71+.br
72+La sortie résultante est un identifiant Pcmcia valide («\ Pcmcia scheme
73+identifer\ ») (qui peut être utilisé comme argument de la commande
74+.BR "cardctl scheme" ).
75+Ce format est aussi idéal quand on utilise le résultat de iwgetid comme un
76+sélecteur («\ selector\ ») dans les scripts
77+.I Shell
78+ou
79+.IR Perl ,
80+ou comme un nom de fichier.
81+.TP
82+.B --ap
83+Affiche l'adresse MAC du
84+.I Point d'Access
85+ou de la
86+.I Cellule
87+sans fil.
88+.TP
89+.B --freq
90+Affiche la
91+.I fréquence
92+ou le
93+.I canal
94+courant utilisé par l'interface.
95+.TP
96+.B --channel
97+Affiche le canal
98+.RI ( channel )
99+courant utilisé par l'interface. Le canal est déterminé en utilisant la
100+fréquence courante et la liste de fréquence fournie par l'interface.
101+.TP
102+.B --mode
103+Affiche le
104+.I mode
105+courant de l'interface.
106+.TP
107+.B --protocol
108+Affiche le
109+.I nom de protocole
110+de l'interface. Il permet d'identifer toutes les cartes qui sont compatibles
111+entre elles et qui acceptent le même type de configuration.
112+.br
113+Cela peut aussi être utilisé pour
114+.I vérifier la compatibilité de Wireless Extension
115+sur l'interface, car c'est le seul attribut que tous les pilotes supportant
116+Wireless Extension doivent avoir.
117+.\"
118+.\" TRADUCTION part
119+.\"
120+.SH TRADUCTION
121+Maxime CHARPENNE, août 2004 (wireless_tools.27-pre25).
122+.\"
123+\" AVERTISSEMENT part
124+.\"
125+.SH AVERTISSEMENT SUR LA TRADUCTION
126+Il est possible que cette traduction soit imparfaite ou périmée. En cas de
127+doute, veuillez vous reporter au document original en langue anglaise fourni
128+avec le programme.
129+.\"
130+.\" SEE ALSO part
131+.\"
132+.SH VOIR AUSSI
133+.BR iwconfig (8),
134+.BR ifconfig (8),
135+.BR iwspy (8),
136+.BR iwpriv (8).
--- /dev/null
+++ b/wireless_tools/fr/iwlist.8
@@ -0,0 +1,145 @@
1+.\" Jean II - HPLB - 96
2+.\" iwlist.8
3+.\"
4+.\" Traduction 2003/08/17 Maxime CHARPENNE (voir
5+.\" http://www.delafond.org/traducmanfr/)
6+.\" 1ère traduction : version 26
7+.\" Mise à jour 2004/01/29 : version 27-pre9 (beta)
8+.\" Manuel identique pour la version 27-pre11 (alpha)
9+.\" Mise à jour 2004/08/23 : version 27-pre25
10+.\"
11+.TH IWLIST 8 "23 juin 2004" "wireless-tools" "Manuel du Programmeur Linux"
12+.\"
13+.\" NAME part
14+.\"
15+.SH NOM
16+iwlist \- Obtient plus d'informations wireless détaillées depuis une interface wireless
17+.\"
18+.\" SYNOPSIS part
19+.\"
20+.SH SYNOPSIS
21+.BI "iwlist " interface " scanning"
22+.br
23+.BI "iwlist " interface " frequency"
24+.br
25+.BI "iwlist " interface " rate"
26+.br
27+.BI "iwlist " interface " key"
28+.br
29+.BI "iwlist " interface " power"
30+.br
31+.BI "iwlist " interface " txpower"
32+.br
33+.BI "iwlist " interface " retry"
34+.br
35+.BI "iwlist " interface " event"
36+.br
37+.BI "iwlist --help"
38+.br
39+.BI "iwlist --version"
40+.\"
41+.\" DESCRIPTION part
42+.\"
43+.SH DESCRIPTION
44+.B Iwlist
45+est utilisé pour afficher de l'information additionnelle d'une interface réseau
46+wireless qui n'est pas affichée par
47+.IR iwconfig (8)
48+L'argument principal est utilisé pour sélectionner une catégorie d'information,
49+.B iwlist
50+affiche dans une forme détaillée toute information relative à cette catégorie,
51+y compris les informations déjà montrées par
52+.IR iwconfig (8).
53+.\"
54+.\" PARAMETER part
55+.\"
56+.SH PARAMÈTRES
57+.TP
58+.BR scan [ning]
59+Donne la liste des Points d'Accès et des cellules Ad-Hoc à portée, et
60+optionnellement plein d'autres informations à leur propos (ESSID, Quality,
61+Frequency, Mode...). Le type d'information retourné dépend de ce que la carte
62+supporte.
63+.br
64+Le «\ Triggering scanning\ » est une opération nécessitant les privilèges
65+de
66+.I root
67+et les utilisateurs normaux peuvent juste lire les résultats («\ letf-over scan
68+results\ »). Par défaut, les paramètres courants du pilote auront une grande
69+incidence sur la manière dont le scan est réalisé (la boucle du scan). Aussi,
70+cette commande est supposée prendre des arguments supplémentaires pour contrôler
71+le comportement du scan, mais cela n'est actuellement pas implémenté.
72+.TP
73+.BR freq [uency]/ channel
74+Donne la liste des fréquences disponibles du périphérique et le nombre de canaux
75+définis. Veuillez noter que, habituellement, le pilote retourne le nombre total
76+de canaux et seulement les fréquences disponibles dans la région considérée,
77+donc il n'y a pas correspondance entre le nombre de fréquences affichées et le
78+nombre de canaux.
79+.TP
80+.BR rate / bit [rate]
81+Liste les débits supportés par le périphérique (en b/s).
82+.TP
83+.BR key / enc [ryption]
84+Liste les tailles des clefs de cryptage supportées et affiche toutes
85+les clefs de cryptage disponibles dans le périphérique.
86+.TP
87+.B power
88+Liste les divers attributs et modes d'économie d'énergie («\ Power
89+Management\ ») du périphérique.
90+.TP
91+.B txpower
92+Liste les différentes puissances d'émission («\ Transmit Powers\ »)
93+disponibles dans le périphérique.
94+.TP
95+.B retry
96+Liste les limites des tentatives de transmissions («\ transmit retry limits\ »)
97+et la durée de vie des tentatives («\ retry lifetime\ ») du périphériques
98+(NDT\ : voir la section
99+.B retry
100+de iwconfig(8)).
101+.TP
102+.BR ap / accesspoint / peers
103+Donne la liste des Points d'Accès à portée, et optionnellement la qualié de leur
104+lien. Cette option est
105+.B obsolète
106+et est maintenant dépréciée en faveur du support scan (voir ci-dessus), et la
107+plupart des pilotes ne le supporte pas.
108+.br
109+Quelques pilotes peuvent utiliser cette commande pour retourner une
110+liste spécifique de Paires («\ Peers\ ») ou de Points d'Accès, telle que la
111+liste des Paires associés/enregistrés avec la carte. Voir la documentation du
112+pilote pour plus de détails.
113+.TP
114+.B event
115+Liste les événements wireless supportés par le périphérique.
116+.TP
117+.B --version
118+Affiche la version des outils, ainsi que la version courante et recommandée des
119+Wireless Extensions pour l'outil et les diverses interfaces sans fil.
120+.\"
121+.\" TRADUCTION part
122+.\"
123+.SH TRADUCTION
124+Maxime CHARPENNE, août 2004 (wireless_tools.27-pre25).
125+.\"
126+\" AVERTISSEMENT part
127+.\"
128+.SH AVERTISSEMENT SUR LA TRADUCTION
129+Il est possible que cette traduction soit imparfaite ou périmée. En cas de
130+doute, veuillez vous reporter au document original en langue anglaise fourni
131+avec le programme.
132+.\"
133+.\" FILES part
134+.\"
135+.SH FICHIERS
136+.I /proc/net/wireless
137+.\"
138+.\" SEE ALSO part
139+.\"
140+.SH VOIR AUSSI
141+.BR iwconfig (8),
142+.BR iwspy (8).
143+.BR iwevent (8),
144+.BR iwpriv (8),
145+.BR wireless (7).
--- /dev/null
+++ b/wireless_tools/fr/iwpriv.8
@@ -0,0 +1,156 @@
1+.\" Jean II - HPLB - 96
2+.\" iwpriv.8
3+.\"
4+.\" Traduction 2003/08/17 Maxime CHARPENNE (voir
5+.\" http://www.delafond.org/traducmanfr/)
6+.\" 1ère traduction : version 26
7+.\" Manuel identique pour version 27-pre9 (beta)
8+.\" Manuel identique pour version 27-pre11 (alpha)
9+.\"
10+.TH IWPRIV 8 "31 octobre 1996" "net-tools" "Manuel du programmeur Linux"
11+.\"
12+.\" NAME part
13+.\"
14+.SH NOM
15+iwpriv \- configure les paramètres optionnels (privés) d'une interface réseau
16+sans fil
17+.\"
18+.\" SYNOPSIS part
19+.\"
20+.SH SYNOPSIS
21+.BI "iwpriv [" interface ]
22+.br
23+.BI "iwpriv " "interface private-command " "[" private-parameters ]
24+.br
25+.BI "iwpriv " "interface private-command [I] " "[" private-parameters ]
26+.br
27+.BI "iwpriv " interface " --all"
28+.br
29+.BI "iwpriv " interface " roam " {on,off}
30+.br
31+.BI "iwpriv " interface " port " {ad-hoc,managed,N}
32+.\"
33+.\" DESCRIPTION part
34+.\"
35+.SH DESCRIPTION
36+.B Iwpriv
37+est l'outil à utiliser avec
38+.IR iwconfig (8).
39+.B Iwpriv
40+traite les paramètres et attributs spécifiques à chaque pilote (contrairement
41
42+.I iwconfig
43+qui ne s'occupe que des génériques).
44+.PP
45+Sans argument,
46+.B iwpriv
47+liste les commandes privées disponibles sur chaque interface, ainsi que les
48+paramètres qu'elles requièrent. En utilisant ces informations, l'utilisateur
49+peut appliquer ces commandes particulières sur les interfaces spécifiées.
50+.PP
51+En théorie, la documentation de chaque pilote devrait indiquer comment utiliser
52+ces commandes spécifiques et leurs effets.
53+.\"
54+.\" PARAMETER part
55+.\"
56+.SH PARAMÈTRES
57+.TP
58+.IR private-command " [" private-parameters ]
59+Exécute la
60+.I private-command
61+(commande privée) spécifiée sur l'interface.
62+.br
63+La commande peut éventuellement prendre ou nécessiter des arguments, et peut
64+afficher de l'information. En conséquent, les paramètres de la ligne de
65+commande peuvent ou peuvent ne pas être nécessaires et doivent correspondre
66+aux besoins de la commande. La liste des commandes que
67+.B iwpriv
68+affiche (quand il est appelé sans paramètre) doit vous donner des indications
69+sur ces paramètres.
70+.br
71+Cependant, vous devriez vous reporter à la documentation du pilote du
72+périphérique pour utiliser les commandes correctement, ainsi que connaître
73+leurs effets.
74+.TP
75+.I "private-command [I]" "[" private-parameters ]
76+Idem, sauf que
77+.I I
78+(un entier) est passé à la commande en tant que
79+.I "Token Index"
80+(indication d'index). Seules quelques commandes utiliseront ce «\ Token
81+Index\ » (la plupart l'ignoreront), et la documentation du pilote devrait
82+préciser quand il est nécessaire.
83+.TP
84+.BR -a / --all
85+Exécute et affiche toutes les commandes privées qui ne prennent aucun argument
86+(c.-à-d. en lecture seule).
87+.TP
88+.B roam
89+Active ou désactive le «\ roaming\ », s'il est supporté. Appelle la commande
90+privée
91+.IR setroam .
92+Trouvé dans le pilote
93+.I wavelan_cs
94+.TP
95+.B port
96+Lit ou configure le type de port. Appelle les commandes privées
97+.IR gport_type ", " sport_type ", " get_port " ou " set_port
98+trouvées dans les pilotes
99+.IR wavelan2_cs " et " wvlan_cs .
100+.\"
101+.\" DISPLAY part
102+.\"
103+.SH AFFICHAGE
104+Pour chaque matériel qui supporte les commandes privées,
105+.I iwpriv
106+affichera la liste des commandes privées disponibles.
107+.PP
108+Cela inclut le nom de la commande privée, le nombre d'arguments qui peuvent
109+être entrés et leur type, ainsi que le nombre d'arguments qui peuvent être
110+affichés et leur type.
111+.PP
112+Par exemple, vous pouvez avoir l'affichage suivant\ :
113+.br
114+.B "eth0 Available private ioctl :"
115+.br
116+.B " setqualthr (89F0) : set 1 byte & get 0"
117+.br
118+.B " gethisto (89F7) : set 0 & get 16 int"
119+.PP
120+Cela veut dire que vous pouvez fixer le seuil de qualité et afficher un
121+histogramme jusqu'à 16 valeurs avec les commandes suivantes\ :
122+.br
123+.I " iwpriv eth0 setqualthr 20"
124+.br
125+.I " iwpriv eth0 gethisto"
126+.\"
127+.\" AUTHOR part
128+.\"
129+.SH AUTHOR
130+Jean Tourrilhes \- jt@hpl.hp.com
131+.\"
132+.\" TRADUCTION part
133+.\"
134+.SH TRADUCTION
135+Maxime CHARPENNE, août 2003.
136+.\"
137+\" AVERTISSEMENT part
138+.\"
139+.SH AVERTISSEMENT SUR LA TRADUCTION
140+Il est possible que cette traduction soit imparfaite ou périmée. En cas de
141+doute, veuillez vous reporter au document original en langue anglaise fourni
142+avec le programme.
143+.\"
144+.\" FILES part
145+.\"
146+.SH FILES
147+.I /proc/net/wireless
148+.\"
149+.\" SEE ALSO part
150+.\"
151+.SH SEE ALSO
152+.BR iwconfig (8),
153+.BR iwlist (8),
154+.BR iwevent (8),
155+.BR iwspy (8),
156+.BR wireless (7).
--- /dev/null
+++ b/wireless_tools/fr/iwspy.8
@@ -0,0 +1,116 @@
1+.\" Jean II - HPLB - 96
2+.\" iwspy.8
3+.\"
4+.\" Traduction 2003/08/18 Maxime CHARPENNE (voir
5+.\" http://www.delafond.org/traducmanfr/)
6+.\" 1ère traduction : version 26
7+.\" Manuel identique pour la version 27-pre9 (beta)
8+.\" Manuel identique pour la version 27-pre11 (alpha)
9+.\"
10+.TH IWSPY 8 "31 octobre 1996" "net-tools" "Manuel du Programmeur Linux"
11+.\"
12+.\" NAME part
13+.\"
14+.SH NOM
15+iwspy \- Obtenir des statistiques wireless depuis des n½uds donnés
16+.\"
17+.\" SYNOPSIS part
18+.\"
19+.SH SYNOPSIS
20+.BI "iwspy " interface
21+.br
22+.BI "iwspy " interface " [+] " DNSNAME " | " IPADDR " | " HWADDR " [...]"
23+.br
24+.BI "iwspy " interface " off"
25+.br
26+.BI "iwspy " interface " setthr " "low high"
27+.br
28+.BI "iwspy " interface " getthr"
29+.\"
30+.\" DESCRIPTION part
31+.\"
32+.SH DESCRIPTION
33+.B Iwspy
34+est utilisé pour fixer une liste d'adresses sur une interface réseau sans fil,
35+et obtenir des informations sur la qualité du lien pour chacune d'elles. Ces
36+informations sont les mêmes que celles disponibles dans
37+.IR /proc/net/wireless "\ :"
38+qualité du lien, force du signal et niveau du bruit.
39+.PP
40+Ces informations sont mises à jour à chaque fois qu'un nouveau paquet est reçu,
41+donc chaque adresse de la liste ajoute quelques précisions en plus.
42+.PP
43+Remarquez que cette fonctionnalité ne marche que pour les n½uds faisant partie
44+des cellules sans fil courantes.
45+.\"
46+.\" PARAMETER part
47+.\"
48+.SH PARAMÈTRES
49+Vous pouvez fixer jusqu'à 8 adresses.
50+.TP
51+.BR DNSNAME " | " IPADDR
52+Paramètre une adresse IP, ou dans certains cas un nom DNS (en utilisant le
53+«\ resolver\ » de nom). Comme le matériel fonctionne avec des adresses
54+matérielles,
55+.B iwspy
56+traduira les adresses IP grâce à
57+.IR ARP .
58+Dans certains cas, cette adresse peut ne pas être dans le cache ARP et
59+.B iwspy
60+échouera. Dans cette situation, exécuter
61+.IR ping (8)
62+vers ces noms/adresses et réessayer.
63+.TP
64+.B HWADDR
65+Paramètre une adresse matérielle (MAC) (cette adresse n'est pas traduite et
66+vérifer comme le sont les adresses IP). L'adresse doit contenir deux-points
67+.RB ( : )
68+pour être reconnue comme une adresse matérielle.
69+.TP
70+.B +
71+Ajoute un nouveau jeu d'adresses à la fin de la liste courante au lieu de la
72+remplacer. La liste d'adresses est unique pour chaque carte, donc chaque
73+utilisateur devrait utiliser cette option pour éviter les conflits.
74+.TP
75+.B off
76+Enlève la liste d'adresses courante et désactive la fonctionnalité de
77+scrutation.
78+.TP
79+.B setthr
80+Fixe les seuils de force de signal
81+.IR low " (bas) et " high " (haut)"
82+pour les événements iwspy (pour les pilotes qui le supportent).
83+.br
84+Chaque fois que la force du signal, pour une des adresses contrôlées avec
85+iwspy, passe au-dessous du seuil bas ou au-dessus du seuil haut, un Wireless
86+Event est généré.
87+.br
88+Ceci peut être utilisé pour surveiller la qualité du lien sans avoir à lancer
89+iwspy périodiquement.
90+.TP
91+.B getthr
92+Récupère les seuils
93+.IR low " (bas) et " high " (haut)"
94+de la force du signal pour l'événement iwspy.
95+.\"
96+\" AVERTISSEMENT part
97+.\"
98+.SH AVERTISSEMENT SUR LA TRADUCTION
99+Il est possible que cette traduction soit imparfaite ou périmée. En cas de
100+doute, veuillez vous reporter au document original en langue anglaise fourni
101+avec le programme.
102+\"
103+.\" FILES part
104+.\"
105+.SH FICHIERS
106+.I /proc/net/wireless
107+.\"
108+.\" SEE ALSO part
109+.\"
110+.SH VOIR AUSSI
111+.BR iwconfig (8),
112+.BR iwlist (8),
113+.BR iwevent (8),
114+.BR iwpriv (8),
115+.BR wireless (7).
116+
--- /dev/null
+++ b/wireless_tools/fr/wireless.7
@@ -0,0 +1,145 @@
1+.\" Jean Tourrilhes - HPL - 2002 - 2004
2+.\" wireless.7
3+.\"
4+.\" Traduction 2004/02/26 Maxime CHARPENNE (voir
5+.\" http://www.delafond.org/traducmanfr/)
6+.\" 1ère traduction : version 27-pre11 (alpha)
7+.\" Mise à jour 2004/08/24 : version 27-pre25
8+.TH WIRELESS 7 "04 mars 2004" "wireless-tools" "Manuel du Programmeur Linux"
9+.\"
10+.\" NAME part
11+.\"
12+.SH NOM
13+wireless \- Wireless Tools et Wireless Extensions
14+.\"
15+.\" SYNOPSIS part
16+.\"
17+.SH SYNOPSIS
18+.B iwconfig
19+.br
20+.B iwpriv \-a
21+.br
22+.\"
23+.\" DESCRIPTION part
24+.\"
25+.SH DESCRIPTION
26+Les
27+.B Wireless Extensions
28+sont une API vous permettant de manipuler les interfaces réseaux Wireless LAN.
29+Ils sont composés d'une gamme d'outils et de fichiers de configuration. Ils sont
30+plus amplement détaillés dans le Linux Wireless LAN Howto.
31+.br
32+Les
33+.B Wireless Tools
34+sont utilisés pour changer la configuration des interfaces réseau LAN wireless
35+à la volée, pour obtenir leur configuration courante, pour avoir des
36+statistiques et pour les diagnostiquer. Ils sont décrits dans leur propre page
37+man, voir ci-dessous pour les références.
38+.br
39+La
40+.B configuration Wireless
41+est propre à chaque distribution Linux. Cette page man contiendra à l'avenir
42+la procédure de configuration pour quelques distributions les plus communes.
43+(quand j'en ai les informations nécessaires). Pour le moment, consultez le
44+fichier DISTRIBUTIONS.txt inclus avec le paquetage Wireless Tools.
45+.\"
46+.\" DEBIAN 3.0 part
47+.\"
48+.SH DEBIAN 3.0
49+Dans la Debian 3.0 (et suivante) vous pouvez configurer les périphériques
50+réseaux LAN wireless en utilisant l'outil de configuration réseau
51+.BR ifupdown (8).
52+.TP
53+.B Fichier :
54+.I /etc/network/interfaces
55+.TP
56+.B Format :
57+.RI wireless\- "<fonction> <valeur>"
58+.br
59+wireless\-essid Maison
60+.br
61+wireless\-mode Ad\-Hoc
62+.TP
63+.B Voir aussi :
64+.I /etc/network/if\-pre\-up.d/wireless\-tools
65+.br
66+.I /usr/share/doc/wireless\-tools/README.Debian
67+.\"
68+.\" SuSE 8.0 part
69+.\"
70+.SH SuSE 8.0
71+La SuSE 8.0 (et suivante) a intégré la configuration wireless dans ses
72+scripts réseaux.
73+.TP
74+.B Outils :
75+.B Yast2
76+.TP
77+.B Fichiers :
78+.I /etc/sysconfig/network/wireless
79+.br
80+.I /etc/sysconfig/network/ifcfg\-*
81+.TP
82+.B Format :
83+.RI WIRELESS_ "<fonction>" = "<valeur>"
84+.br
85+WIRELESS_ESSID="Maison"
86+.br
87+WIRELESS_MODE=Ad\-Hoc
88+.TP
89+.B Voir aussi :
90+man ifup
91+.br
92+info scpm
93+.\"
94+.\" PCMCIA part
95+.\"
96+.SH SCRIPTS ORIGINAUX PCMCIA
97+Si vous utilisez les scripts originaux de configuration du paquetage Pcmcia,
98+vous pouvez utiliser cette méthode.
99+.TP
100+.B Fichier :
101+.I /etc/pcmcia/wireless.opts
102+.TP
103+.B Format :
104+*,*,*,*)
105+.br
106+ ESSID="Maison"
107+.br
108+ MODE="Ad-Hoc"
109+.br
110+ ;;
111+.TP
112+.B Voir aussi :
113+.I /etc/pcmcia/wireless
114+.br
115+Le fichier
116+.I PCMCIA.txt
117+qui fait partie du paquetage Wireless Tools.
118+.\"
119+.\" AUTHOR part
120+.\"
121+.SH AUTEUR
122+Jean Tourrilhes \- jt@hpl.hp.com
123+.br
124+.I http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/
125+.\"
126+.\" TRADUCTION part
127+.\"
128+.SH TRADUCTION
129+Maxime CHARPENNE, août 2004 (wireless-tools.27-pre25).
130+.\"
131+.\" AVERTISSEMENT part
132+.\"
133+.SH AVERTISSEMENT SUR LA TRADUCTION
134+Il est possible que cette traduction soit imparfaite ou périmée. En cas de
135+doute, veuillez vous reporter au document original en langue anglaise fourni
136+avec le programme.
137+.\"
138+.\" SEE ALSO part
139+.\"
140+.SH VOIR AUSSI
141+.BR iwconfig (8),
142+.BR iwlist (8),
143+.BR iwspy (8),
144+.BR iwpriv (8),
145+.BR iwevent (8).
--- /dev/null
+++ b/wireless_tools/ifrename.8
@@ -0,0 +1,142 @@
1+.\" Jean II - HPL - 2004
2+.\" ifrename.8
3+.\"
4+.TH IFRENAME 8 "01 March 2004" "wireless-tools" "Linux Programmer's Manual"
5+.\"
6+.\" NAME part
7+.\"
8+.SH NAME
9+ifrename \- rename network interfaces based on various static criteria
10+.\"
11+.\" SYNOPSIS part
12+.\"
13+.SH SYNOPSIS
14+.B "ifrename [-c configfile] [-p] [-d] [-v] [-V] [-D]"
15+.br
16+.B "ifrename [-c configfile] [-i interface] [-n newname]"
17+.\"
18+.\" DESCRIPTION part
19+.\"
20+.SH DESCRIPTION
21+.B Ifrename
22+is a tool allowing you to assign a consistent name to each of your
23+network interface.
24+.PP
25+By default, interface names are dynamic, and each network interface is
26+assigned the first available name
27+.RI ( eth0 ", " eth1 "...)."
28+The order network interfaces are created may vary. For built-in
29+interfaces, the kernel boot time enumeration may vary. For removable
30+interface, the user may plug them in any order.
31+.PP
32+.B Ifrename
33+allow the user to decide what name a network interface will have.
34+.B Ifrename
35+can use a variety of
36+.I selectors
37+to specify how interface names match the network interfaces on the
38+system, the most common selector is the interface
39+.IR "MAC address" .
40+.PP
41+.B Ifrename
42+must be run before interfaces are brought up, which is why it's mostly
43+useful in various scripts (init, hotplug) but is seldom used directly
44+by the user. By default,
45+.B ifrename
46+renames all present system interfaces using mappings defined in
47+.IR /etc/iftab .
48+.\"
49+.\" PARAMETER part
50+.\"
51+.SH PARAMETERS
52+.TP
53+.BI "-c " configfile
54+Set the configuration file to be used (by default
55+.IR /etc/iftab ).
56+The configuration file define the mapping between selectors and
57+interface names, and is described in
58+.IR iftab (5).
59+.br
60+If
61+.I configfile
62+is "-", the configuration is read from stdin.
63+.TP
64+.B -p
65+Probe (load) kernel modules before renaming interfaces. By default
66+.B ifrename
67+only check interfaces already loaded, and doesn't auto-load the
68+required kernel modules. This option enables smooth integration with
69+system not loading modules before calling
70+.BR ifrename .
71+.TP
72+.B -d
73+Enable various
74+.B Debian
75+specific hacks. Combined with
76+.BR -p ,
77+only modules for interfaces specified in
78+.I /etc/network/interface
79+are loaded.
80+.TP
81+.BI "-i " interface
82+Only rename the specified
83+.I interface
84+as opposed to all interfaces on the system. The new interface name is
85+printed.
86+.TP
87+.BI "-n " newname
88+When used with
89+.IR -i ,
90+specify the new name of the interface. The list of mappings from the
91+configuration file is bypassed. The new name may be a wildcard
92+containing a single '*'.
93+.TP
94+.B -t
95+Enable name takeover support. This allow interface name swapping
96+between two or more interfaces.
97+.br
98+Takeover enable an interface to 'steal' the name of another
99+interface. This works only with kernel 2.6.X and if the other
100+interface is down. Consequently, this is not compatible with
101+Hotplug. The other interface is assigned a random name, but may be
102+renamed later with 'ifrename'.
103+.br
104+The number of takeovers is limited to avoid circular loops, and
105+therefore some complex multi-way name swapping situations may not be
106+fully processed.
107+.br
108+In any case, name swapping and the use of this feature is discouraged,
109+and you are invited to choose unique and unambiguous names for your
110+interfaces...
111+.TP
112+.B -D
113+Dry-run mode. Ifrename won't change any interface, it will only print
114+new interface name, if applicable, and return.
115+.br
116+In dry-run mode, interface name wildcards are not resolved. New
117+interface name is printed, even if it is the same as the old name.
118+.TP
119+.B -V
120+Verbose mode. Ifrename will display internal results of parsing its
121+configuration file and querying the interfaces selectors. Combined
122+with the
123+.I dry-run
124+option, this is a good way to debug complex configurations or trivial
125+problems.
126+.\"
127+.\" AUTHOR part
128+.\"
129+.SH AUTHOR
130+Jean Tourrilhes \- jt@hpl.hp.com
131+.\"
132+.\" FILES part
133+.\"
134+.SH FILES
135+.I /etc/iftab
136+.\"
137+.\" SEE ALSO part
138+.\"
139+.SH SEE ALSO
140+.BR ifconfig (8),
141+.BR ip (8),
142+.BR iftab (5).
--- /dev/null
+++ b/wireless_tools/ifrename.c
@@ -0,0 +1,2054 @@
1+/*
2+ * Wireless Tools
3+ *
4+ * Jean II - HPL 04
5+ *
6+ * Main code for "ifrename". This is tool allows to rename network
7+ * interfaces based on various criteria (not only wireless).
8+ * You need to link this code against "iwlib.c" and "-lm".
9+ *
10+ * This file is released under the GPL license.
11+ * Copyright (c) 2004 Jean Tourrilhes <jt@hpl.hp.com>
12+ */
13+
14+/*
15+ * The changelog for ifrename is in the file CHANGELOG.h ;-)
16+ *
17+ * This work is a nearly complete rewrite of 'nameif.c'.
18+ * Original CopyRight of version of 'nameif' I used is :
19+ * -------------------------------------------------------
20+ * Name Interfaces based on MAC address.
21+ * Writen 2000 by Andi Kleen.
22+ * Subject to the Gnu Public License, version 2.
23+ * TODO: make it support token ring etc.
24+ * $Id: nameif.c,v 1.3 2003/03/06 23:26:52 ecki Exp $
25+ * Add hotplug compatibility : ifname -i eth0. Jean II - 03.12.03
26+ * Add MAC address wildcard : 01:23:45:*. Jean II - 03.12.03
27+ * Add interface name wildcard : wlan*. Jean II - 03.12.03
28+ * Add interface name probing for modular systems. Jean II - 18.02.03
29+ * -------------------------------------------------------
30+ *
31+ * The last 4 patches never made it into the regular version of
32+ * 'nameif', and had some 'issues', which is the reason of this rewrite.
33+ * Difference with standard 'nameif' :
34+ * o 'nameif' has only a single selector, the interface MAC address.
35+ * o Modular selector architecture, easily add new selectors.
36+ * o hotplug invocation support.
37+ * o module loading support.
38+ * o MAC address wildcard.
39+ * o Interface name wildcard ('eth*' or 'wlan*').
40+ */
41+
42+/***************************** INCLUDES *****************************/
43+
44+/* This is needed to enable GNU extensions such as getline & FNM_CASEFOLD */
45+#ifndef _GNU_SOURCE
46+#define _GNU_SOURCE
47+#endif
48+
49+#include <getopt.h> /* getopt_long() */
50+#include <linux/sockios.h> /* SIOCSIFNAME */
51+#include <fnmatch.h> /* fnmatch() */
52+//#include <sys/syslog.h>
53+
54+#include "iwlib.h" /* Wireless Tools library */
55+
56+// This would be cool, unfortunately...
57+//#include <linux/ethtool.h> /* Ethtool stuff -> struct ethtool_drvinfo */
58+
59+/************************ CONSTANTS & MACROS ************************/
60+
61+/* Our default configuration file */
62+const char DEFAULT_CONF[] = "/etc/iftab";
63+
64+/* Debian stuff */
65+const char DEBIAN_CONFIG_FILE[] = "/etc/network/interfaces";
66+
67+/* Backward compatibility */
68+#ifndef ifr_newname
69+#define ifr_newname ifr_ifru.ifru_slave
70+#endif
71+
72+/* Types of selector we support. Must match selector_list */
73+const int SELECT_MAC = 0; /* Select by MAC address */
74+const int SELECT_ETHADDR = 1; /* Select by MAC address */
75+const int SELECT_ARP = 2; /* Select by ARP type */
76+const int SELECT_LINKTYPE = 3; /* Select by ARP type */
77+const int SELECT_DRIVER = 4; /* Select by Driver name */
78+const int SELECT_BUSINFO = 5; /* Select by Bus-Info */
79+const int SELECT_FIRMWARE = 6; /* Select by Firmware revision */
80+const int SELECT_BASEADDR = 7; /* Select by HW Base Address */
81+const int SELECT_IRQ = 8; /* Select by HW Irq line */
82+const int SELECT_INTERRUPT = 9; /* Select by HW Irq line */
83+const int SELECT_IWPROTO = 10; /* Select by Wireless Protocol */
84+const int SELECT_PCMCIASLOT = 11; /* Select by Wireless Protocol */
85+#define SELECT_NUM 12
86+
87+#define HAS_MAC_EXACT 1
88+#define HAS_MAC_FILTER 2
89+
90+const struct ether_addr zero_mac = {{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
91+
92+const struct option long_opt[] =
93+{
94+ {"config-file", 1, NULL, 'c' },
95+ {"debian", 0, NULL, 'd' },
96+ {"dry-run", 0, NULL, 'D' },
97+ {"help", 0, NULL, '?' },
98+ {"interface", 1, NULL, 'i' },
99+ {"newname", 1, NULL, 'n' },
100+ {"takeover", 0, NULL, 't' },
101+ {"version", 0, NULL, 'v' },
102+ {"verbose", 0, NULL, 'V' },
103+ {NULL, 0, NULL, '\0' },
104+};
105+
106+/* Pcmcia stab files */
107+#define PCMCIA_STAB1 "/var/lib/pcmcia/stab"
108+#define PCMCIA_STAB2 "/var/run/stab"
109+
110+/****************************** TYPES ******************************/
111+
112+/* Cut'n'paste from ethtool.h */
113+#define ETHTOOL_BUSINFO_LEN 32
114+/* these strings are set to whatever the driver author decides... */
115+struct ethtool_drvinfo {
116+ __u32 cmd;
117+ char driver[32]; /* driver short name, "tulip", "eepro100" */
118+ char version[32]; /* driver version string */
119+ char fw_version[32]; /* firmware version string, if applicable */
120+ char bus_info[ETHTOOL_BUSINFO_LEN]; /* Bus info for this IF. */
121+ /* For PCI devices, use pci_dev->slot_name. */
122+ char reserved1[32];
123+ char reserved2[16];
124+ __u32 n_stats; /* number of u64's from ETHTOOL_GSTATS */
125+ __u32 testinfo_len;
126+ __u32 eedump_len; /* Size of data from ETHTOOL_GEEPROM (bytes) */
127+ __u32 regdump_len; /* Size of data from ETHTOOL_GREGS (bytes) */
128+};
129+#define ETHTOOL_GDRVINFO 0x00000003 /* Get driver info. */
130+
131+/* Description of an interface mapping */
132+typedef struct if_mapping
133+{
134+ /* Linked list */
135+ struct if_mapping * next;
136+
137+ /* Name of this interface */
138+ char ifname[IFNAMSIZ+1];
139+
140+ /* Selectors for this interface */
141+ int active[SELECT_NUM]; /* Selectors active */
142+
143+ /* Selector data */
144+ struct ether_addr mac; /* Exact MAC address, hex */
145+ char mac_filter[6*3 + 1]; /* WildCard, ascii */
146+ unsigned short hw_type; /* Link/ARP type */
147+ char driver[32]; /* driver short name */
148+ char bus_info[ETHTOOL_BUSINFO_LEN]; /* Bus info for this IF. */
149+ char fw_version[32]; /* Firmware revision */
150+ unsigned short base_addr; /* HW Base I/O address */
151+ unsigned char irq; /* HW irq line */
152+ char iwproto[IFNAMSIZ + 1]; /* Wireless/protocol name */
153+ int pcmcia_slot; /* Pcmcia slot */
154+} if_mapping;
155+
156+/* Prototype for adding a selector to a mapping. Return -1 if invalid value. */
157+typedef int (*mapping_add)(struct if_mapping * ifnode,
158+ int * active,
159+ char * pos,
160+ size_t len,
161+ int linenum);
162+
163+/* Prototype for comparing the selector of two mapping. Return 0 if matches. */
164+typedef int (*mapping_cmp)(struct if_mapping * ifnode,
165+ struct if_mapping * target);
166+/* Prototype for extracting selector value from live interface */
167+typedef int (*mapping_get)(int skfd,
168+ const char * ifname,
169+ struct if_mapping * target,
170+ int flag);
171+
172+/* How to handle a selector */
173+typedef struct mapping_selector
174+{
175+ char * name;
176+ mapping_add add_fn;
177+ mapping_cmp cmp_fn;
178+ mapping_get get_fn;
179+} mapping_selector;
180+
181+/**************************** PROTOTYPES ****************************/
182+
183+static int
184+ mapping_addmac(struct if_mapping * ifnode,
185+ int * active,
186+ char * pos,
187+ size_t len,
188+ int linenum);
189+static int
190+ mapping_cmpmac(struct if_mapping * ifnode,
191+ struct if_mapping * target);
192+static int
193+ mapping_getmac(int skfd,
194+ const char * ifname,
195+ struct if_mapping * target,
196+ int flag);
197+static int
198+ mapping_addarp(struct if_mapping * ifnode,
199+ int * active,
200+ char * pos,
201+ size_t len,
202+ int linenum);
203+static int
204+ mapping_cmparp(struct if_mapping * ifnode,
205+ struct if_mapping * target);
206+static int
207+ mapping_getarp(int skfd,
208+ const char * ifname,
209+ struct if_mapping * target,
210+ int flag);
211+static int
212+ mapping_adddriver(struct if_mapping * ifnode,
213+ int * active,
214+ char * pos,
215+ size_t len,
216+ int linenum);
217+static int
218+ mapping_cmpdriver(struct if_mapping * ifnode,
219+ struct if_mapping * target);
220+static int
221+ mapping_addbusinfo(struct if_mapping * ifnode,
222+ int * active,
223+ char * pos,
224+ size_t len,
225+ int linenum);
226+static int
227+ mapping_cmpbusinfo(struct if_mapping * ifnode,
228+ struct if_mapping * target);
229+static int
230+ mapping_addfirmware(struct if_mapping * ifnode,
231+ int * active,
232+ char * pos,
233+ size_t len,
234+ int linenum);
235+static int
236+ mapping_cmpfirmware(struct if_mapping * ifnode,
237+ struct if_mapping * target);
238+static int
239+ mapping_getdriverbusinfo(int skfd,
240+ const char * ifname,
241+ struct if_mapping * target,
242+ int flag);
243+static int
244+ mapping_addbaseaddr(struct if_mapping * ifnode,
245+ int * active,
246+ char * pos,
247+ size_t len,
248+ int linenum);
249+static int
250+ mapping_cmpbaseaddr(struct if_mapping * ifnode,
251+ struct if_mapping * target);
252+static int
253+ mapping_addirq(struct if_mapping * ifnode,
254+ int * active,
255+ char * pos,
256+ size_t len,
257+ int linenum);
258+static int
259+ mapping_cmpirq(struct if_mapping * ifnode,
260+ struct if_mapping * target);
261+static int
262+ mapping_getbaseaddrirq(int skfd,
263+ const char * ifname,
264+ struct if_mapping * target,
265+ int flag);
266+static int
267+ mapping_addiwproto(struct if_mapping * ifnode,
268+ int * active,
269+ char * pos,
270+ size_t len,
271+ int linenum);
272+static int
273+ mapping_cmpiwproto(struct if_mapping * ifnode,
274+ struct if_mapping * target);
275+static int
276+ mapping_getiwproto(int skfd,
277+ const char * ifname,
278+ struct if_mapping * target,
279+ int flag);
280+static int
281+ mapping_addpcmciaslot(struct if_mapping * ifnode,
282+ int * active,
283+ char * pos,
284+ size_t len,
285+ int linenum);
286+static int
287+ mapping_cmppcmciaslot(struct if_mapping * ifnode,
288+ struct if_mapping * target);
289+static int
290+ mapping_getpcmciaslot(int skfd,
291+ const char * ifname,
292+ struct if_mapping * target,
293+ int flag);
294+
295+/**************************** VARIABLES ****************************/
296+
297+/* List of mapping read for config file */
298+struct if_mapping * mapping_list = NULL;
299+
300+/* List of selectors we can handle */
301+const struct mapping_selector selector_list[] =
302+{
303+ /* MAC address and ARP/Link type from ifconfig */
304+ { "mac", &mapping_addmac, &mapping_cmpmac, &mapping_getmac },
305+ { "ethaddr", &mapping_addmac, &mapping_cmpmac, &mapping_getmac },
306+ { "arp", &mapping_addarp, &mapping_cmparp, &mapping_getarp },
307+ { "linktype", &mapping_addarp, &mapping_cmparp, &mapping_getarp },
308+ /* Driver name, Bus-Info and firmware rev from ethtool -i */
309+ { "driver", &mapping_adddriver, &mapping_cmpdriver,
310+ &mapping_getdriverbusinfo },
311+ { "businfo", &mapping_addbusinfo, &mapping_cmpbusinfo,
312+ &mapping_getdriverbusinfo },
313+ { "firmware", &mapping_addfirmware, &mapping_cmpfirmware,
314+ &mapping_getdriverbusinfo },
315+ /* Base Address and IRQ from ifconfig */
316+ { "baseaddress", &mapping_addbaseaddr, &mapping_cmpbaseaddr,
317+ &mapping_getbaseaddrirq },
318+ { "irq", &mapping_addirq, &mapping_cmpirq, &mapping_getbaseaddrirq },
319+ { "interrupt", &mapping_addirq, &mapping_cmpirq, &mapping_getbaseaddrirq },
320+ /* Wireless Protocol from iwconfig */
321+ { "iwproto", &mapping_addiwproto, &mapping_cmpiwproto, &mapping_getiwproto },
322+ /* Pcmcia slot from cardmgr */
323+ { "pcmciaslot", &mapping_addpcmciaslot, &mapping_cmppcmciaslot, &mapping_getpcmciaslot },
324+ /* The Terminator */
325+ { NULL, NULL, NULL, NULL },
326+};
327+const int selector_num = sizeof(selector_list)/sizeof(selector_list[0]);
328+
329+/* List of active selectors */
330+int selector_active[SELECT_NUM]; /* Selectors active */
331+
332+/* Takeover support */
333+int force_takeover = 0; /* Takeover name from other interface */
334+int num_takeover = 0; /* Number of takeover done */
335+
336+/* Dry-run support */
337+int dry_run = 0; /* Just print new name, don't rename */
338+
339+/* Verbose support (i.e. debugging) */
340+int verbose = 0;
341+
342+/******************** INTERFACE NAME MANAGEMENT ********************/
343+/*
344+ * Bunch of low level function for managing interface names.
345+ */
346+
347+/*------------------------------------------------------------------*/
348+/*
349+ * Compare two interface names, with wildcards.
350+ * We can't use fnmatch() because we don't want expansion of '[...]'
351+ * expressions, '\' sequences and matching of '.'.
352+ * We only want to match a single '*' (converted to a %d at that point)
353+ * to a numerical value (no ascii).
354+ * Return 0 is matches.
355+ */
356+static int
357+if_match_ifname(const char * pattern,
358+ const char * value)
359+{
360+ const char * p;
361+ const char * v;
362+ int n;
363+ int ret;
364+
365+ /* Check for a wildcard (converted from '*' to '%d' in mapping_create()) */
366+ p = strstr(pattern, "%d");
367+
368+ /* No wildcard, simple comparison */
369+ if(p == NULL)
370+ return(strcmp(pattern, value));
371+
372+ /* Check is prefixes match */
373+ n = (p - pattern);
374+ ret = strncmp(pattern, value, n);
375+ if(ret)
376+ return(ret);
377+
378+ /* Check that value has some digits at this point */
379+ v = value + n;
380+ if(!isdigit(*v))
381+ return(-1);
382+
383+ /* Skip digits to go to value suffix */
384+ do
385+ v++;
386+ while(isdigit(*v));
387+
388+ /* Pattern suffix */
389+ p += 2;
390+
391+ /* Compare suffixes */
392+ return(strcmp(p, v));
393+}
394+
395+/*------------------------------------------------------------------*/
396+/*
397+ * Steal interface name from another interface. This enable interface
398+ * name swapping.
399+ * This will work :
400+ * 1) with kernel 2.6.X
401+ * 2) if other interface is down
402+ * Because of (2), it won't work with hotplug, but we don't need it
403+ * with hotplug, only with static ifaces...
404+ */
405+static int
406+if_takeover_name(int skfd,
407+ const char * victimname)
408+{
409+ char autoname[IFNAMSIZ+1];
410+ int len;
411+ struct ifreq ifr;
412+ int ret;
413+
414+ /* Compute name for victim interface */
415+ len = strlen(victimname);
416+ memcpy(autoname, victimname, len + 1);
417+ if(len > (IFNAMSIZ - 2))
418+ len = IFNAMSIZ - 2; /* Make sure we have at least two char */
419+ len--; /* Convert to index */
420+ while(isdigit(autoname[len]))
421+ len--; /* Scrap all trailing digits */
422+ strcpy(autoname + len + 1, "%d");
423+
424+ if(verbose)
425+ fprintf(stderr, "Takeover : moving interface `%s' to `%s'.\n",
426+ victimname, autoname);
427+
428+ /* Prepare request */
429+ bzero(&ifr, sizeof(struct ifreq));
430+ strncpy(ifr.ifr_name, victimname, IFNAMSIZ);
431+ strncpy(ifr.ifr_newname, autoname, IFNAMSIZ);
432+
433+ /* Rename victim interface */
434+ ret = ioctl(skfd, SIOCSIFNAME, &ifr);
435+
436+ if(!ret)
437+ num_takeover++;
438+
439+ return(ret);
440+}
441+
442+/*------------------------------------------------------------------*/
443+/*
444+ * Ask the kernel to change the name of an interface.
445+ * That's what we want to do. All the rest is to make sure we call this
446+ * appropriately.
447+ */
448+static int
449+if_set_name(int skfd,
450+ const char * oldname,
451+ const char * newname,
452+ char * retname)
453+{
454+ struct ifreq ifr;
455+ int ret;
456+
457+ /* The kernel doesn't check is the interface already has the correct
458+ * name and may return an error, so check ourselves.
459+ * In the case of wildcard, the result can be weird : if oldname='eth0'
460+ * and newname='eth*', retname would be 'eth1'.
461+ * So, if the oldname value matches the newname pattern, just return
462+ * success. */
463+ if(!if_match_ifname(newname, oldname))
464+ {
465+ if(verbose)
466+ fprintf(stderr, "Setting : Interface `%s' already matches `%s'.\n",
467+ oldname, newname);
468+
469+ strcpy(retname, oldname);
470+ return(0);
471+ }
472+
473+ /* Prepare request */
474+ bzero(&ifr, sizeof(struct ifreq));
475+ strncpy(ifr.ifr_name, oldname, IFNAMSIZ);
476+ strncpy(ifr.ifr_newname, newname, IFNAMSIZ);
477+
478+ /* Do it */
479+ ret = ioctl(skfd, SIOCSIFNAME, &ifr);
480+
481+ /* Takeover support : grab interface name from another interface */
482+ if(ret && (errno == EEXIST) && force_takeover)
483+ {
484+ /* Push things around */
485+ ret = if_takeover_name(skfd, newname);
486+ if(!ret)
487+ /* Second try */
488+ ret = ioctl(skfd, SIOCSIFNAME, &ifr);
489+ }
490+
491+ if(!ret)
492+ {
493+ /* Get the real new name (in case newname is a wildcard) */
494+ strcpy(retname, ifr.ifr_newname);
495+
496+ if(verbose)
497+ fprintf(stderr, "Setting : Interface `%s' renamed to `%s'.\n",
498+ oldname, retname);
499+ }
500+
501+ return(ret);
502+}
503+
504+/************************ SELECTOR HANDLING ************************/
505+/*
506+ * Handle the various selector we support
507+ */
508+
509+/*------------------------------------------------------------------*/
510+/*
511+ * Add a MAC address selector to a mapping
512+ */
513+static int
514+mapping_addmac(struct if_mapping * ifnode,
515+ int * active,
516+ char * string,
517+ size_t len,
518+ int linenum)
519+{
520+ size_t n;
521+
522+ /* Verify validity of string */
523+ if(len >= sizeof(ifnode->mac_filter))
524+ {
525+ fprintf(stderr, "MAC address too long at line %d\n", linenum);
526+ return(-1);
527+ }
528+ n = strspn(string, "0123456789ABCDEFabcdef:*");
529+ if(n < len)
530+ {
531+ fprintf(stderr, "Error: Invalid MAC address `%s' at line %d\n",
532+ string, linenum);
533+ return(-1);
534+ }
535+
536+ /* Copy as filter in all cases */
537+ memcpy(ifnode->mac_filter, string, len + 1);
538+
539+ /* Check the type of MAC address */
540+ if (strchr(ifnode->mac_filter, '*') != NULL)
541+ {
542+ /* This is a wilcard. Usual format : "01:23:45:*"
543+ * Unfortunately, we can't do proper parsing. */
544+ ifnode->active[SELECT_MAC] = HAS_MAC_FILTER;
545+ active[SELECT_MAC] = HAS_MAC_FILTER;
546+ }
547+ else
548+ {
549+ /* Not a wildcard : "01:23:45:67:89:AB" */
550+ if(iw_ether_aton(ifnode->mac_filter, &ifnode->mac) != 1)
551+ {
552+ fprintf(stderr, "Error: Invalid MAC address `%s' at line %d\n",
553+ ifnode->mac_filter, linenum);
554+ return(-1);
555+ }
556+
557+ /* Check that it's not NULL */
558+ if(!memcmp(&ifnode->mac, &zero_mac, 6))
559+ {
560+ fprintf(stderr,
561+ "Warning: MAC address is null at line %d, this is dangerous...\n",
562+ linenum);
563+ }
564+
565+ ifnode->active[SELECT_MAC] = HAS_MAC_EXACT;
566+ if(active[SELECT_MAC] == 0)
567+ active[SELECT_MAC] = HAS_MAC_EXACT;
568+ }
569+
570+ if(verbose)
571+ fprintf(stderr,
572+ "Parsing : Added %s MAC address `%s' from line %d.\n",
573+ ifnode->active[SELECT_MAC] == HAS_MAC_FILTER ? "filter" : "exact",
574+ ifnode->mac_filter, linenum);
575+
576+ return(0);
577+}
578+
579+/*------------------------------------------------------------------*/
580+/*
581+ * Compare the mac address of two mappings
582+ */
583+static int
584+mapping_cmpmac(struct if_mapping * ifnode,
585+ struct if_mapping * target)
586+{
587+ /* Check for wildcard matching */
588+ if(ifnode->active[SELECT_MAC] == HAS_MAC_FILTER)
589+ /* Do wildcard matching, case insensitive */
590+ return(fnmatch(ifnode->mac_filter, target->mac_filter, FNM_CASEFOLD));
591+ else
592+ /* Exact matching, in hex */
593+ return(memcmp(&ifnode->mac.ether_addr_octet, &target->mac.ether_addr_octet,
594+ 6));
595+}
596+
597+/*------------------------------------------------------------------*/
598+/*
599+ * Extract the MAC address and Link Type of an interface
600+ */
601+static int
602+mapping_getmac(int skfd,
603+ const char * ifname,
604+ struct if_mapping * target,
605+ int flag)
606+{
607+ int ret;
608+
609+ /* Extract MAC address */
610+ ret = iw_get_mac_addr(skfd, ifname, &target->mac, &target->hw_type);
611+ if(ret < 0)
612+ {
613+ fprintf(stderr, "Error: Can't read MAC address on interface `%s' : %s\n",
614+ ifname, strerror(errno));
615+ return(-1);
616+ }
617+
618+ /* Check the type of comparison */
619+ if((flag == HAS_MAC_FILTER) || verbose)
620+ {
621+ /* Convert to ASCII */
622+ iw_ether_ntop(&target->mac, target->mac_filter);
623+ }
624+
625+ target->active[SELECT_MAC] = flag;
626+ target->active[SELECT_ARP] = 1;
627+
628+ if(verbose)
629+ fprintf(stderr,
630+ "Querying %s : Got MAC address `%s' and ARP/Link Type `%d'.\n",
631+ ifname, target->mac_filter, target->hw_type);
632+
633+ return(0);
634+}
635+
636+/*------------------------------------------------------------------*/
637+/*
638+ * Add a ARP/Link type selector to a mapping
639+ */
640+static int
641+mapping_addarp(struct if_mapping * ifnode,
642+ int * active,
643+ char * string,
644+ size_t len,
645+ int linenum)
646+{
647+ size_t n;
648+ unsigned int type;
649+
650+ /* Verify validity of string, convert to int */
651+ n = strspn(string, "0123456789");
652+ if((n < len) || (sscanf(string, "%d", &type) != 1))
653+ {
654+ fprintf(stderr, "Error: Invalid ARP/Link Type `%s' at line %d\n",
655+ string, linenum);
656+ return(-1);
657+ }
658+
659+ ifnode->hw_type = (unsigned short) type;
660+ ifnode->active[SELECT_ARP] = 1;
661+ active[SELECT_ARP] = 1;
662+
663+ if(verbose)
664+ fprintf(stderr, "Parsing : Added ARP/Link Type `%d' from line %d.\n",
665+ ifnode->hw_type, linenum);
666+
667+ return(0);
668+}
669+
670+/*------------------------------------------------------------------*/
671+/*
672+ * Compare the ARP/Link type of two mappings
673+ */
674+static int
675+mapping_cmparp(struct if_mapping * ifnode,
676+ struct if_mapping * target)
677+{
678+ return(!(ifnode->hw_type == target->hw_type));
679+}
680+
681+/*------------------------------------------------------------------*/
682+/*
683+ * Extract the ARP/Link type of an interface
684+ */
685+static int
686+mapping_getarp(int skfd,
687+ const char * ifname,
688+ struct if_mapping * target,
689+ int flag)
690+{
691+ /* We may have already extracted the MAC address */
692+ if(target->active[SELECT_MAC])
693+ return(0);
694+
695+ /* Otherwise just do it */
696+ return(mapping_getmac(skfd, ifname, target, flag));
697+}
698+
699+/*------------------------------------------------------------------*/
700+/*
701+ * Add a Driver name selector to a mapping
702+ */
703+static int
704+mapping_adddriver(struct if_mapping * ifnode,
705+ int * active,
706+ char * string,
707+ size_t len,
708+ int linenum)
709+{
710+ /* Plain string, minimal verification */
711+ if(len >= sizeof(ifnode->driver))
712+ {
713+ fprintf(stderr, "Driver name too long at line %d\n", linenum);
714+ return(-1);
715+ }
716+
717+ /* Copy */
718+ memcpy(ifnode->driver, string, len + 1);
719+
720+ /* Activate */
721+ ifnode->active[SELECT_DRIVER] = 1;
722+ active[SELECT_DRIVER] = 1;
723+
724+ if(verbose)
725+ fprintf(stderr,
726+ "Parsing : Added Driver name `%s' from line %d.\n",
727+ ifnode->driver, linenum);
728+
729+ return(0);
730+}
731+
732+/*------------------------------------------------------------------*/
733+/*
734+ * Compare the Driver name of two mappings
735+ */
736+static int
737+mapping_cmpdriver(struct if_mapping * ifnode,
738+ struct if_mapping * target)
739+{
740+ /* Do wildcard matching, case insensitive */
741+ return(fnmatch(ifnode->driver, target->driver, FNM_CASEFOLD));
742+}
743+
744+/*------------------------------------------------------------------*/
745+/*
746+ * Add a Bus-Info selector to a mapping
747+ */
748+static int
749+mapping_addbusinfo(struct if_mapping * ifnode,
750+ int * active,
751+ char * string,
752+ size_t len,
753+ int linenum)
754+{
755+#if 0
756+ size_t n;
757+#endif
758+
759+ /* Verify validity of string */
760+ if(len >= sizeof(ifnode->bus_info))
761+ {
762+ fprintf(stderr, "Bus Info too long at line %d\n", linenum);
763+ return(-1);
764+ }
765+#if 0
766+ /* Hum... This doesn's seem true for non-PCI bus-info */
767+ n = strspn(string, "0123456789ABCDEFabcdef:.*");
768+ if(n < len)
769+ {
770+ fprintf(stderr, "Error: Invalid Bus Info `%s' at line %d\n",
771+ string, linenum);
772+ return(-1);
773+ }
774+#endif
775+
776+ /* Copy */
777+ memcpy(ifnode->bus_info, string, len + 1);
778+
779+ /* Activate */
780+ ifnode->active[SELECT_BUSINFO] = 1;
781+ active[SELECT_BUSINFO] = 1;
782+
783+ if(verbose)
784+ fprintf(stderr,
785+ "Parsing : Added Bus Info `%s' from line %d.\n",
786+ ifnode->bus_info, linenum);
787+
788+ return(0);
789+}
790+
791+/*------------------------------------------------------------------*/
792+/*
793+ * Compare the Bus-Info of two mappings
794+ */
795+static int
796+mapping_cmpbusinfo(struct if_mapping * ifnode,
797+ struct if_mapping * target)
798+{
799+ /* Do wildcard matching, case insensitive */
800+ return(fnmatch(ifnode->bus_info, target->bus_info, FNM_CASEFOLD));
801+}
802+
803+/*------------------------------------------------------------------*/
804+/*
805+ * Add a Firmare revision selector to a mapping
806+ */
807+static int
808+mapping_addfirmware(struct if_mapping * ifnode,
809+ int * active,
810+ char * string,
811+ size_t len,
812+ int linenum)
813+{
814+ /* Verify validity of string */
815+ if(len >= sizeof(ifnode->fw_version))
816+ {
817+ fprintf(stderr, "Firmware revision too long at line %d\n", linenum);
818+ return(-1);
819+ }
820+
821+ /* Copy */
822+ memcpy(ifnode->fw_version, string, len + 1);
823+
824+ /* Activate */
825+ ifnode->active[SELECT_FIRMWARE] = 1;
826+ active[SELECT_FIRMWARE] = 1;
827+
828+ if(verbose)
829+ fprintf(stderr,
830+ "Parsing : Added Firmware Revision `%s' from line %d.\n",
831+ ifnode->fw_version, linenum);
832+
833+ return(0);
834+}
835+
836+/*------------------------------------------------------------------*/
837+/*
838+ * Compare the Bus-Info of two mappings
839+ */
840+static int
841+mapping_cmpfirmware(struct if_mapping * ifnode,
842+ struct if_mapping * target)
843+{
844+ /* Do wildcard matching, case insensitive */
845+ return(fnmatch(ifnode->fw_version, target->fw_version, FNM_CASEFOLD));
846+}
847+
848+/*------------------------------------------------------------------*/
849+/*
850+ * Extract the Driver name and Bus-Info from a live interface
851+ */
852+static int
853+mapping_getdriverbusinfo(int skfd,
854+ const char * ifname,
855+ struct if_mapping * target,
856+ int flag)
857+{
858+ struct ifreq ifr;
859+ struct ethtool_drvinfo drvinfo;
860+ int ret;
861+
862+ /* Avoid "Unused parameter" warning */
863+ flag = flag;
864+
865+ /* We may come here twice or more, so do the job only once */
866+ if(target->active[SELECT_DRIVER] || target->active[SELECT_BUSINFO]
867+ || target->active[SELECT_FIRMWARE])
868+ return(0);
869+
870+ /* Prepare request */
871+ bzero(&ifr, sizeof(struct ifreq));
872+ bzero(&drvinfo, sizeof(struct ethtool_drvinfo));
873+ strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
874+ drvinfo.cmd = ETHTOOL_GDRVINFO;
875+ ifr.ifr_data = (caddr_t) &drvinfo;
876+
877+ /* Do it */
878+ ret = ioctl(skfd, SIOCETHTOOL, &ifr);
879+ if(ret < 0)
880+ {
881+ /* Most drivers don't support that, keep quiet for now */
882+ if(verbose)
883+ fprintf(stderr,
884+ "Error: Can't read driver/bus-info on interface `%s' : %s\n",
885+ ifname, strerror(errno));
886+ return(-1);
887+ }
888+
889+ /* Copy over */
890+ strcpy(target->driver, drvinfo.driver);
891+ strcpy(target->bus_info, drvinfo.bus_info);
892+ strcpy(target->fw_version, drvinfo.fw_version);
893+
894+ /* Activate */
895+ target->active[SELECT_DRIVER] = 1;
896+ target->active[SELECT_BUSINFO] = 1;
897+ target->active[SELECT_FIRMWARE] = 1;
898+
899+ if(verbose)
900+ fprintf(stderr,
901+ "Querying %s : Got Driver name `%s', Bus Info `%s' and Firmware `%s'.\n",
902+ ifname, target->driver, target->bus_info, target->fw_version);
903+
904+ return(0);
905+}
906+
907+/*------------------------------------------------------------------*/
908+/*
909+ * Add a Base Address selector to a mapping
910+ */
911+static int
912+mapping_addbaseaddr(struct if_mapping * ifnode,
913+ int * active,
914+ char * string,
915+ size_t len,
916+ int linenum)
917+{
918+ size_t n;
919+ unsigned int address;
920+
921+ /* Verify validity of string */
922+ n = strspn(string, "0123456789ABCDEFabcdefx");
923+ if((n < len) || (sscanf(string, "0x%X", &address) != 1))
924+ {
925+ fprintf(stderr, "Error: Invalid Base Address `%s' at line %d\n",
926+ string, linenum);
927+ return(-1);
928+ }
929+
930+ /* Copy */
931+ ifnode->base_addr = (unsigned short) address;
932+
933+ /* Activate */
934+ ifnode->active[SELECT_BASEADDR] = 1;
935+ active[SELECT_BASEADDR] = 1;
936+
937+ if(verbose)
938+ fprintf(stderr,
939+ "Parsing : Added Base Address `0x%X' from line %d.\n",
940+ ifnode->base_addr, linenum);
941+
942+ return(0);
943+}
944+
945+/*------------------------------------------------------------------*/
946+/*
947+ * Compare the Base Address of two mappings
948+ */
949+static int
950+mapping_cmpbaseaddr(struct if_mapping * ifnode,
951+ struct if_mapping * target)
952+{
953+ /* Do wildcard matching, case insensitive */
954+ return(!(ifnode->base_addr == target->base_addr));
955+}
956+
957+/*------------------------------------------------------------------*/
958+/*
959+ * Add a IRQ selector to a mapping
960+ */
961+static int
962+mapping_addirq(struct if_mapping * ifnode,
963+ int * active,
964+ char * string,
965+ size_t len,
966+ int linenum)
967+{
968+ size_t n;
969+ unsigned int irq;
970+
971+ /* Verify validity of string */
972+ n = strspn(string, "0123456789");
973+ if((n < len) || (sscanf(string, "%d", &irq) != 1))
974+ {
975+ fprintf(stderr, "Error: Invalid Base Address `%s' at line %d\n",
976+ string, linenum);
977+ return(-1);
978+ }
979+
980+ /* Copy */
981+ ifnode->irq = (unsigned char) irq;
982+
983+ /* Activate */
984+ ifnode->active[SELECT_IRQ] = 1;
985+ active[SELECT_IRQ] = 1;
986+
987+ if(verbose)
988+ fprintf(stderr,
989+ "Parsing : Added IRQ `%d' from line %d.\n",
990+ ifnode->irq, linenum);
991+
992+ return(0);
993+}
994+
995+/*------------------------------------------------------------------*/
996+/*
997+ * Compare the IRQ of two mappings
998+ */
999+static int
1000+mapping_cmpirq(struct if_mapping * ifnode,
1001+ struct if_mapping * target)
1002+{
1003+ /* Do wildcard matching, case insensitive */
1004+ return(!(ifnode->irq == target->irq));
1005+}
1006+
1007+/*------------------------------------------------------------------*/
1008+/*
1009+ * Extract the Driver name and Bus-Info from a live interface
1010+ */
1011+static int
1012+mapping_getbaseaddrirq(int skfd,
1013+ const char * ifname,
1014+ struct if_mapping * target,
1015+ int flag)
1016+{
1017+ struct ifreq ifr;
1018+ struct ifmap map; /* hardware setup */
1019+ int ret;
1020+
1021+ /* Avoid "Unused parameter" warning */
1022+ flag = flag;
1023+
1024+ /* We may come here twice, so do the job only once */
1025+ if(target->active[SELECT_BASEADDR] || target->active[SELECT_IRQ])
1026+ return(0);
1027+
1028+ /* Prepare request */
1029+ bzero(&ifr, sizeof(struct ifreq));
1030+ bzero(&map, sizeof(struct ifmap));
1031+ strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
1032+
1033+ /* Do it */
1034+ ret = ioctl(skfd, SIOCGIFMAP, &ifr);
1035+ if(ret < 0)
1036+ {
1037+ /* Don't know if every interface has that, so keep quiet... */
1038+ if(verbose)
1039+ fprintf(stderr,
1040+ "Error: Can't read base address/irq on interface `%s' : %s\n",
1041+ ifname, strerror(errno));
1042+ return(-1);
1043+ }
1044+
1045+ /* Copy over, activate */
1046+ if(ifr.ifr_map.base_addr >= 0x100)
1047+ {
1048+ target->base_addr = ifr.ifr_map.base_addr;
1049+ target->active[SELECT_BASEADDR] = 1;
1050+ }
1051+ target->irq = ifr.ifr_map.irq;
1052+ target->active[SELECT_IRQ] = 1;
1053+
1054+ if(verbose)
1055+ fprintf(stderr,
1056+ "Querying %s : Got Base Address `0x%X' and IRQ `%d'.\n",
1057+ ifname, target->base_addr, target->irq);
1058+
1059+ return(0);
1060+}
1061+
1062+/*------------------------------------------------------------------*/
1063+/*
1064+ * Add a Wireless Protocol selector to a mapping
1065+ */
1066+static int
1067+mapping_addiwproto(struct if_mapping * ifnode,
1068+ int * active,
1069+ char * string,
1070+ size_t len,
1071+ int linenum)
1072+{
1073+ /* Verify validity of string */
1074+ if(len >= sizeof(ifnode->iwproto))
1075+ {
1076+ fprintf(stderr, "Wireless Protocol too long at line %d\n", linenum);
1077+ return(-1);
1078+ }
1079+
1080+ /* Copy */
1081+ memcpy(ifnode->iwproto, string, len + 1);
1082+
1083+ /* Activate */
1084+ ifnode->active[SELECT_IWPROTO] = 1;
1085+ active[SELECT_IWPROTO] = 1;
1086+
1087+ if(verbose)
1088+ fprintf(stderr,
1089+ "Parsing : Added Wireless Protocol `%s' from line %d.\n",
1090+ ifnode->iwproto, linenum);
1091+
1092+ return(0);
1093+}
1094+
1095+/*------------------------------------------------------------------*/
1096+/*
1097+ * Compare the Wireless Protocol of two mappings
1098+ */
1099+static int
1100+mapping_cmpiwproto(struct if_mapping * ifnode,
1101+ struct if_mapping * target)
1102+{
1103+ /* Do wildcard matching, case insensitive */
1104+ return(fnmatch(ifnode->iwproto, target->iwproto, FNM_CASEFOLD));
1105+}
1106+
1107+/*------------------------------------------------------------------*/
1108+/*
1109+ * Extract the Wireless Protocol from a live interface
1110+ */
1111+static int
1112+mapping_getiwproto(int skfd,
1113+ const char * ifname,
1114+ struct if_mapping * target,
1115+ int flag)
1116+{
1117+ struct iwreq wrq;
1118+
1119+ /* Avoid "Unused parameter" warning */
1120+ flag = flag;
1121+
1122+ /* Get wireless name */
1123+ if(iw_get_ext(skfd, ifname, SIOCGIWNAME, &wrq) < 0)
1124+ /* Don't complain about it, Ethernet cards will never support this */
1125+ return(-1);
1126+
1127+ strncpy(target->iwproto, wrq.u.name, IFNAMSIZ);
1128+ target->iwproto[IFNAMSIZ] = '\0';
1129+
1130+ /* Activate */
1131+ target->active[SELECT_IWPROTO] = 1;
1132+
1133+ if(verbose)
1134+ fprintf(stderr,
1135+ "Querying %s : Got Wireless Protocol `%s'.\n",
1136+ ifname, target->iwproto);
1137+
1138+ return(0);
1139+}
1140+
1141+/*------------------------------------------------------------------*/
1142+/*
1143+ * Add a Pcmcia Slot selector to a mapping
1144+ */
1145+static int
1146+mapping_addpcmciaslot(struct if_mapping * ifnode,
1147+ int * active,
1148+ char * string,
1149+ size_t len,
1150+ int linenum)
1151+{
1152+ size_t n;
1153+
1154+ /* Verify validity of string, convert to int */
1155+ n = strspn(string, "0123456789");
1156+ if((n < len) || (sscanf(string, "%d", &ifnode->pcmcia_slot) != 1))
1157+ {
1158+ fprintf(stderr, "Error: Invalid Pcmcia Slot `%s' at line %d\n",
1159+ string, linenum);
1160+ return(-1);
1161+ }
1162+
1163+ ifnode->active[SELECT_PCMCIASLOT] = 1;
1164+ active[SELECT_PCMCIASLOT] = 1;
1165+
1166+ if(verbose)
1167+ fprintf(stderr, "Parsing : Added Pcmcia Slot `%d' from line %d.\n",
1168+ ifnode->pcmcia_slot, linenum);
1169+
1170+ return(0);
1171+}
1172+
1173+/*------------------------------------------------------------------*/
1174+/*
1175+ * Compare the Pcmcia Slot of two mappings
1176+ */
1177+static int
1178+mapping_cmppcmciaslot(struct if_mapping * ifnode,
1179+ struct if_mapping * target)
1180+{
1181+ return(!(ifnode->pcmcia_slot == target->pcmcia_slot));
1182+}
1183+
1184+/*------------------------------------------------------------------*/
1185+/*
1186+ * Extract the Pcmcia Slot of an interface
1187+ * Note that this works only for cards fully managed by cardmgr.
1188+ * With the kernel pcmcia modules, 32 bits cards (CardBus) are not managed
1189+ * by cardmgr, and therefore won't have a valid slot number. For those
1190+ * cards, you should use Bus Info (when the driver exports it).
1191+ * In the long term, 16 bits card as well will no longer be managed by
1192+ * cardmgr. Currently, Bus Info for 16 bit cards don't have any information
1193+ * enabling to locate their physical location on the system, but I hope that
1194+ * this will change.
1195+ * When that happen, we can drop this code...
1196+ */
1197+static int
1198+mapping_getpcmciaslot(int skfd,
1199+ const char * ifname,
1200+ struct if_mapping * target,
1201+ int flag)
1202+{
1203+ FILE * stream;
1204+ char * linebuf = NULL;
1205+ size_t linelen = 0;
1206+ int linenum = 0;
1207+
1208+ /* Avoid "Unused parameter" warning */
1209+ skfd = skfd;
1210+ flag = flag;
1211+
1212+ /* Open the stab file for reading */
1213+ stream = fopen(PCMCIA_STAB1, "r");
1214+ if(!stream)
1215+ {
1216+ /* Try again, alternate location */
1217+ stream = fopen(PCMCIA_STAB2, "r");
1218+ if(!stream)
1219+ {
1220+ fprintf(stderr, "Error: Can't open PCMCIA Stab file `%s' or `%s': %s\n",
1221+ PCMCIA_STAB1, PCMCIA_STAB2, strerror(errno));
1222+ return(-1);
1223+ }
1224+ }
1225+
1226+ /* Read each line of file
1227+ * getline is a GNU extension :-( The buffer is recycled and increased
1228+ * as needed by getline. */
1229+ while(getline(&linebuf, &linelen, stream) > 0)
1230+ {
1231+ char * p;
1232+ size_t n;
1233+ size_t k;
1234+ int pcmcia_slot;
1235+ int i;
1236+
1237+ /* Keep track of line number */
1238+ linenum++;
1239+
1240+ /* Get Pcmcia socket number */
1241+ p = linebuf;
1242+ while(isspace(*p))
1243+ ++p;
1244+ if(*p == '\0')
1245+ continue; /* Line ended */
1246+ n = strcspn(p, " \t\n");
1247+ k = strspn(p, "0123456789");
1248+ if((k < n) || (sscanf(p, "%d", &pcmcia_slot) != 1))
1249+ /* Next line */
1250+ continue;
1251+
1252+ /* Skip socket number */
1253+ /* Skip socket number ; device class ; driver name ; instance */
1254+ for(i = 0; i < 4; i++)
1255+ {
1256+ /* Skip item */
1257+ p += n;
1258+ /* Skip space */
1259+ p += strspn(p, " \t\n");
1260+ if(*p == '\0')
1261+ break; /* Line ended */
1262+ /* Next item size */
1263+ n = strcspn(p, " \t\n");
1264+ }
1265+ if(*p == '\0')
1266+ continue; /* Line ended */
1267+
1268+ /* Terminate dev name */
1269+ p[n] = '\0';
1270+
1271+ /* Compare to interface name */
1272+ if(!strcmp(p, ifname))
1273+ {
1274+ /* Save */
1275+ target->pcmcia_slot = pcmcia_slot;
1276+
1277+ /* Activate */
1278+ target->active[SELECT_PCMCIASLOT] = 1;
1279+
1280+ if(verbose)
1281+ fprintf(stderr,
1282+ "Querying %s : Got Pcmcia Slot `%d'.\n",
1283+ ifname, target->pcmcia_slot);
1284+ /* Exit loop, found it */
1285+ break;
1286+ }
1287+
1288+ /* Finished -> next line */
1289+ }
1290+
1291+ /* Cleanup */
1292+ free(linebuf);
1293+
1294+ return(target->active[SELECT_PCMCIASLOT] ? 0 : -1);
1295+}
1296+
1297+
1298+/*********************** MAPPING MANAGEMENTS ***********************/
1299+/*
1300+ * Manage interface mappings.
1301+ * Each mapping tell us how to identify a specific interface name.
1302+ * It is composed of a bunch of selector values.
1303+ */
1304+
1305+/*------------------------------------------------------------------*/
1306+/*
1307+ * Create a new interface mapping and verify its name
1308+ */
1309+static struct if_mapping *
1310+mapping_create(char * pos,
1311+ int len,
1312+ int linenum)
1313+{
1314+ struct if_mapping * ifnode;
1315+ char * star;
1316+
1317+ /* Check overflow. */
1318+ if(len > IFNAMSIZ)
1319+ {
1320+ fprintf(stderr, "Error: Interface name `%.*s' too long at line %d\n",
1321+ (int) len, pos, linenum);
1322+ return(NULL);
1323+ }
1324+
1325+ /* Create mapping, zero it */
1326+ ifnode = calloc(1, sizeof(if_mapping));
1327+ if(!ifnode)
1328+ {
1329+ fprintf(stderr, "Error: Can't allocate interface mapping.\n");
1330+ return(NULL);
1331+ }
1332+
1333+ /* Set the name, terminates it */
1334+ memcpy(ifnode->ifname, pos, len);
1335+ ifnode->ifname[len] = '\0';
1336+
1337+ /* Check the interface name and issue various pedantic warnings */
1338+ if((!strcmp(ifnode->ifname, "eth0")) || (!strcmp(ifnode->ifname, "wlan0")))
1339+ fprintf(stderr,
1340+ "Warning: Interface name is `%s' at line %d, can't be mapped reliably.\n",
1341+ ifnode->ifname, linenum);
1342+ if(strchr(ifnode->ifname, ':'))
1343+ fprintf(stderr, "Warning: Alias device `%s' at line %d probably can't be mapped.\n",
1344+ ifnode->ifname, linenum);
1345+
1346+ /* Check for wildcard interface name, such as 'eth*' or 'wlan*'...
1347+ * This require specific kernel support (2.6.2-rc1 and later).
1348+ * We externally use '*', but the kernel doesn't know about that,
1349+ * so convert it to something it knows about... */
1350+ star = strchr(ifnode->ifname, '*');
1351+ if(star != NULL)
1352+ {
1353+ /* We need an extra char */
1354+ if(len >= IFNAMSIZ)
1355+ {
1356+ fprintf(stderr,
1357+ "Error: Interface wildcard `%s' too long at line %d\n",
1358+ ifnode->ifname, linenum);
1359+ free(ifnode);
1360+ return(NULL);
1361+ }
1362+
1363+ /* Replace '*' with '%d' */
1364+ memmove(star + 2, star + 1, len + 1 - (star - ifnode->ifname));
1365+ star[0] = '%';
1366+ star[1] = 'd';
1367+ }
1368+
1369+ if(verbose)
1370+ fprintf(stderr, "Parsing : Added Mapping `%s' from line %d.\n",
1371+ ifnode->ifname, linenum);
1372+
1373+ /* Done */
1374+ return(ifnode);
1375+}
1376+
1377+/*------------------------------------------------------------------*/
1378+/*
1379+ * Find the most appropriate selector matching a given selector name
1380+ */
1381+static inline const struct mapping_selector *
1382+selector_find(const char * string,
1383+ size_t slen,
1384+ int linenum)
1385+{
1386+ const struct mapping_selector * found = NULL;
1387+ int ambig = 0;
1388+ int i;
1389+
1390+ /* Go through all selectors */
1391+ for(i = 0; selector_list[i].name != NULL; ++i)
1392+ {
1393+ /* No match -> next one */
1394+ if(strncasecmp(selector_list[i].name, string, slen) != 0)
1395+ continue;
1396+
1397+ /* Exact match -> perfect */
1398+ if(slen == strlen(selector_list[i].name))
1399+ return &selector_list[i];
1400+
1401+ /* Partial match */
1402+ if(found == NULL)
1403+ /* First time */
1404+ found = &selector_list[i];
1405+ else
1406+ /* Another time */
1407+ if (selector_list[i].add_fn != found->add_fn)
1408+ ambig = 1;
1409+ }
1410+
1411+ if(found == NULL)
1412+ {
1413+ fprintf(stderr, "Error: Unknown selector `%.*s' at line %d.\n",
1414+ (int) slen, string, linenum);
1415+ return NULL;
1416+ }
1417+
1418+ if(ambig)
1419+ {
1420+ fprintf(stderr, "Selector `%.*s'at line %d is ambiguous.\n",
1421+ (int) slen, string, linenum);
1422+ return NULL;
1423+ }
1424+
1425+ return found;
1426+}
1427+
1428+/*------------------------------------------------------------------*/
1429+/*
1430+ * Read the configuration file and extract all valid mappings and their
1431+ * selectors.
1432+ */
1433+static int
1434+mapping_readfile(const char * filename)
1435+{
1436+ FILE * stream;
1437+ char * linebuf = NULL;
1438+ size_t linelen = 0;
1439+ int linenum = 0;
1440+
1441+ /* Reset the list of filters */
1442+ bzero(selector_active, sizeof(selector_active));
1443+
1444+ /* Check filename */
1445+ if(!strcmp(filename, "-"))
1446+ {
1447+ /* Read from stdin */
1448+ stream = stdin;
1449+
1450+ }
1451+ else
1452+ {
1453+ /* Open the file for reading */
1454+ stream = fopen(filename, "r");
1455+ if(!stream)
1456+ {
1457+ fprintf(stderr, "Error: Can't open configuration file `%s': %s\n",
1458+ filename, strerror(errno));
1459+ return(-1);
1460+ }
1461+ }
1462+
1463+ /* Read each line of file
1464+ * getline is a GNU extension :-( The buffer is recycled and increased
1465+ * as needed by getline. */
1466+ while(getline(&linebuf, &linelen, stream) > 0)
1467+ {
1468+ struct if_mapping * ifnode;
1469+ char * p;
1470+ char * e;
1471+ size_t n;
1472+ int ret = -13; /* Complain if no selectors */
1473+
1474+ /* Keep track of line number */
1475+ linenum++;
1476+
1477+ /* Every comments terminates parsing */
1478+ if((p = strchr(linebuf,'#')) != NULL)
1479+ *p = '\0';
1480+
1481+ /* Get interface name */
1482+ p = linebuf;
1483+ while(isspace(*p))
1484+ ++p;
1485+ if(*p == '\0')
1486+ continue; /* Line ended */
1487+ n = strcspn(p, " \t\n");
1488+
1489+ /* Create mapping */
1490+ ifnode = mapping_create(p, n, linenum);
1491+ if(!ifnode)
1492+ continue; /* Ignore this line */
1493+ p += n;
1494+ p += strspn(p, " \t\n");
1495+
1496+ /* Loop on all selectors */
1497+ while(*p != '\0')
1498+ {
1499+ const struct mapping_selector * selector = NULL;
1500+
1501+ /* Selector name length */
1502+ n = strcspn(p, " \t\n");
1503+
1504+ /* Find it */
1505+ selector = selector_find(p, n, linenum);
1506+ if(!selector)
1507+ {
1508+ ret = -1;
1509+ break;
1510+ }
1511+
1512+ /* Get to selector value */
1513+ p += n;
1514+ p += strspn(p, " \t\n");
1515+ if(*p == '\0')
1516+ {
1517+ fprintf(stderr, "Error: no value for selector `%s' on line %d\n",
1518+ selector->name, linenum);
1519+ ret = -1;
1520+ break; /* Line ended */
1521+ }
1522+ /* Check for quoted arguments */
1523+ if(*p == '"')
1524+ {
1525+ p++;
1526+ e = strchr(p, '"');
1527+ if(e == NULL)
1528+ {
1529+ fprintf(stderr,
1530+ "Error: unterminated quoted value on line %d\n",
1531+ linenum);
1532+ ret = -1;
1533+ break; /* Line ended */
1534+ }
1535+ n = e - p;
1536+ e++;
1537+ }
1538+ else
1539+ {
1540+ /* Just end at next blank */
1541+ n = strcspn(p, " \t\n");
1542+ e = p + n;
1543+ }
1544+ /* Make 'e' point past the '\0' we are going to add */
1545+ if(*e != '\0')
1546+ e++;
1547+ /* Terminate selector value */
1548+ p[n] = '\0';
1549+
1550+ /* Add it to the mapping */
1551+ ret = selector->add_fn(ifnode, selector_active, p, n, linenum);
1552+ if(ret < 0)
1553+ break;
1554+
1555+ /* Go to next selector */
1556+ p = e;
1557+ p += strspn(p, " \t\n");
1558+ }
1559+
1560+ /* We add a mapping only if it has at least one selector and if all
1561+ * selectors were parsed properly. */
1562+ if(ret < 0)
1563+ {
1564+ /* If we have not yet printed an error, now is a good time ;-) */
1565+ if(ret == -13)
1566+ fprintf(stderr, "Error: Line %d ignored, no valid selectors\n",
1567+ linenum);
1568+ else
1569+ fprintf(stderr, "Error: Line %d ignored due to prior errors\n",
1570+ linenum);
1571+
1572+ free(ifnode);
1573+ }
1574+ else
1575+ {
1576+ /* Link it in the list */
1577+ ifnode->next = mapping_list;
1578+ mapping_list = ifnode;
1579+ }
1580+ }
1581+
1582+ /* Cleanup */
1583+ free(linebuf);
1584+
1585+ /* Finished reading, close the file */
1586+ if(stream != stdin)
1587+ fclose(stream);
1588+ return(0);
1589+}
1590+
1591+/*------------------------------------------------------------------*/
1592+/*
1593+ * Extract all the interesting selectors for the interface in consideration
1594+ */
1595+static struct if_mapping *
1596+mapping_extract(int skfd,
1597+ const char * ifname)
1598+{
1599+ struct if_mapping * target;
1600+ int i;
1601+
1602+ /* Create mapping, zero it */
1603+ target = calloc(1, sizeof(if_mapping));
1604+ if(!target)
1605+ {
1606+ fprintf(stderr, "Error: Can't allocate interface mapping.\n");
1607+ return(NULL);
1608+ }
1609+
1610+ /* Set the interface name */
1611+ strcpy(target->ifname, ifname);
1612+
1613+ /* Loop on all active selectors */
1614+ for(i = 0; i < SELECT_NUM; i++)
1615+ {
1616+ /* Check if this selector is active */
1617+ if(selector_active[i] != 0)
1618+ {
1619+ /* Extract selector */
1620+ selector_list[i].get_fn(skfd, ifname, target, selector_active[i]);
1621+
1622+ /* Ignore errors. Some mapping may not need all selectors */
1623+ }
1624+ }
1625+
1626+ return(target);
1627+}
1628+
1629+/*------------------------------------------------------------------*/
1630+/*
1631+ * Find the first mapping in the list matching the one we want.
1632+ */
1633+static struct if_mapping *
1634+mapping_find(struct if_mapping * target)
1635+{
1636+ struct if_mapping * ifnode;
1637+ int i;
1638+
1639+ /* Look over all our mappings */
1640+ for(ifnode = mapping_list; ifnode != NULL; ifnode = ifnode->next)
1641+ {
1642+ int matches = 1;
1643+
1644+ /* Look over all our selectors, all must match */
1645+ for(i = 0; i < SELECT_NUM; i++)
1646+ {
1647+ /* Check if this selector is active */
1648+ if(ifnode->active[i] != 0)
1649+ {
1650+ /* If this selector doesn't match, game over for this mapping */
1651+ if((target->active[i] == 0) ||
1652+ (selector_list[i].cmp_fn(ifnode, target) != 0))
1653+ {
1654+ matches = 0;
1655+ break;
1656+ }
1657+ }
1658+ }
1659+
1660+ /* Check is this mapping was "the one" */
1661+ if(matches)
1662+ return(ifnode);
1663+ }
1664+
1665+ /* Not found */
1666+ return(NULL);
1667+}
1668+
1669+/************************** MODULE SUPPORT **************************/
1670+/*
1671+ * Load all necessary module so that interfaces do exist.
1672+ * This is necessary for system that are fully modular when
1673+ * doing the boot time processing, because we need to run before
1674+ * 'ifup -a'.
1675+ */
1676+
1677+/*------------------------------------------------------------------*/
1678+/*
1679+ * Probe interfaces based on our list of mappings.
1680+ * This is the default, but usually not the best way to do it.
1681+ */
1682+static void
1683+probe_mappings(int skfd)
1684+{
1685+ struct if_mapping * ifnode;
1686+ struct ether_addr mac; /* Exact MAC address, hex */
1687+ unsigned short hw_type;
1688+
1689+ /* Look over all our mappings */
1690+ for(ifnode = mapping_list; ifnode != NULL; ifnode = ifnode->next)
1691+ {
1692+ /* Can't load wildcards interface name :-( */
1693+ if(strchr(ifnode->ifname, '%') != NULL)
1694+ continue;
1695+
1696+ if(verbose)
1697+ fprintf(stderr, "Probing : Trying to load interface [%s]\n",
1698+ ifnode->ifname);
1699+
1700+ /* Trick the kernel into loading the interface.
1701+ * This allow us to not depend on the exact path and
1702+ * name of the '/sbin/modprobe' command.
1703+ * Obviously, we expect this command to 'fail', as
1704+ * the interface will load with the old/wrong name.
1705+ */
1706+ iw_get_mac_addr(skfd, ifnode->ifname, &mac, &hw_type);
1707+ }
1708+}
1709+
1710+/*------------------------------------------------------------------*/
1711+/*
1712+ * Probe interfaces based on Debian's config files.
1713+ * This allow to enly load modules for interfaces the user want active,
1714+ * all built-in interfaces that should remain unconfigured won't
1715+ * be probed (and can have mappings).
1716+ */
1717+static void
1718+probe_debian(int skfd)
1719+{
1720+ FILE * stream;
1721+ char * linebuf = NULL;
1722+ size_t linelen = 0;
1723+ struct ether_addr mac; /* Exact MAC address, hex */
1724+ unsigned short hw_type;
1725+
1726+ /* Open Debian config file */
1727+ stream = fopen(DEBIAN_CONFIG_FILE, "r");
1728+ if(stream == NULL)
1729+ {
1730+ fprintf(stderr, "Error: can't open file [%s]\n", DEBIAN_CONFIG_FILE);
1731+ return;
1732+ }
1733+
1734+ /* Read each line of file
1735+ * getline is a GNU extension :-( The buffer is recycled and increased
1736+ * as needed by getline. */
1737+ while(getline(&linebuf, &linelen, stream) > 0)
1738+ {
1739+ char * p;
1740+ char * e;
1741+ size_t n;
1742+
1743+ /* Check for auto keyword, ignore when commented out */
1744+ if(!strncasecmp(linebuf, "auto ", 5))
1745+ {
1746+ /* Skip "auto" keyword */
1747+ p = linebuf + 5;
1748+
1749+ /* Terminate at first comment */
1750+ e = strchr(p, '#');
1751+ if(e != NULL)
1752+ *e = '\0';
1753+
1754+ /* Loop on all interfaces given */
1755+ while(*p != '\0')
1756+ {
1757+ /* Interface name length */
1758+ n = strcspn(p, " \t\n");
1759+
1760+ /* Look for end of interface name */
1761+ e = p + n;
1762+ /* Make 'e' point past the '\0' we are going to add */
1763+ if(*e != '\0')
1764+ e++;
1765+ /* Terminate interface name */
1766+ p[n] = '\0';
1767+
1768+ if(verbose)
1769+ fprintf(stderr, "Probing : Trying to load interface [%s]\n",
1770+ p);
1771+
1772+ /* Do it ! */
1773+ iw_get_mac_addr(skfd, p, &mac, &hw_type);
1774+
1775+ /* Go to next interface name */
1776+ p = e;
1777+ p += strspn(p, " \t\n");
1778+ }
1779+ }
1780+ }
1781+
1782+ /* Done */
1783+ fclose(stream);
1784+ return;
1785+}
1786+
1787+/**************************** MAIN LOGIC ****************************/
1788+
1789+/*------------------------------------------------------------------*/
1790+/*
1791+ * Rename an interface to a specified new name.
1792+ */
1793+static int
1794+process_rename(int skfd,
1795+ char * ifname,
1796+ char * pattern)
1797+{
1798+ char newname[IFNAMSIZ+1];
1799+ char retname[IFNAMSIZ+1];
1800+ int len;
1801+ char * star;
1802+
1803+ len = strlen(pattern);
1804+ star = strchr(pattern, '*');
1805+
1806+ /* Check newname length, need one extra char for wildcard */
1807+ if((len + (star != NULL)) > IFNAMSIZ)
1808+ {
1809+ fprintf(stderr, "Error: Interface name `%s' too long.\n",
1810+ pattern);
1811+ return(-1);
1812+ }
1813+
1814+ /* Copy to local buffer */
1815+ memcpy(newname, pattern, len + 1);
1816+
1817+ /* Convert wildcard to the proper format */
1818+ if(star != NULL)
1819+ {
1820+ /* Replace '*' with '%d' in the new buffer */
1821+ star += newname - pattern;
1822+ memmove(star + 2, star + 1, len + 1 - (star - newname));
1823+ star[0] = '%';
1824+ star[1] = 'd';
1825+ }
1826+
1827+
1828+ /* Change the name of the interface */
1829+ if(if_set_name(skfd, ifname, newname, retname) < 0)
1830+ {
1831+ fprintf(stderr, "Error: cannot change name of %s to %s: %s\n",
1832+ ifname, newname, strerror(errno));
1833+ return(-1);
1834+ }
1835+
1836+ /* Always print out the *new* interface name so that
1837+ * the calling script can pick it up and know where its interface
1838+ * has gone. */
1839+ printf("%s\n", retname);
1840+
1841+ /* Done */
1842+ return(0);
1843+}
1844+
1845+/*------------------------------------------------------------------*/
1846+/*
1847+ * Process a specified interface.
1848+ */
1849+static int
1850+process_ifname(int skfd,
1851+ char * ifname,
1852+ char * args[],
1853+ int count)
1854+{
1855+ struct if_mapping * target;
1856+ const struct if_mapping * mapping;
1857+ char retname[IFNAMSIZ+1];
1858+
1859+ /* Avoid "Unused parameter" warning */
1860+ args = args; count = count;
1861+
1862+ /* Get description of this interface */
1863+ target = mapping_extract(skfd, ifname);
1864+ if(target == NULL)
1865+ return(-1);
1866+
1867+ /* Find matching mapping */
1868+ mapping = mapping_find(target);
1869+ if(mapping == NULL)
1870+ return(-1);
1871+
1872+ /* Check if user want only dry-run.
1873+ * Note that, in the case of wildcard, we don't resolve the wildcard.
1874+ * That would be tricky to do... */
1875+ if(dry_run)
1876+ {
1877+ printf("Dry-run : Would rename %s to %s.\n",
1878+ target->ifname, mapping->ifname);
1879+ return(0);
1880+ }
1881+
1882+ /* Change the name of the interface */
1883+ if(if_set_name(skfd, target->ifname, mapping->ifname, retname) < 0)
1884+ {
1885+ fprintf(stderr, "Error: cannot change name of %s to %s: %s\n",
1886+ target->ifname, mapping->ifname, strerror(errno));
1887+ return(-1);
1888+ }
1889+
1890+ /* Check if called with an explicit interface name */
1891+ if(!count)
1892+ {
1893+ /* Always print out the *new* interface name so that
1894+ * the calling script can pick it up and know where its interface
1895+ * has gone. */
1896+ printf("%s\n", retname);
1897+ }
1898+
1899+ /* Done */
1900+ return(0);
1901+}
1902+
1903+/*------------------------------------------------------------------*/
1904+/*
1905+ * Process all network interface present on the system.
1906+ */
1907+static inline int
1908+process_iflist(int skfd,
1909+ char * args[],
1910+ int count)
1911+{
1912+ num_takeover = 0;
1913+
1914+ /* Just do it */
1915+ iw_enum_devices(skfd, &process_ifname, args, count);
1916+
1917+ /* If we do any takeover, the interface list grabbed with
1918+ * iw_enum_devices() may get out of sync with the real interfaces,
1919+ * and we may miss the victim interface. So, let's go through the
1920+ * list again.
1921+ * On the other hand, we may have ping pong between two interfaces,
1922+ * each claiming the same name, so let's not do it forever...
1923+ * Two time should be enough for most configs...
1924+ * Jean II */
1925+ if(force_takeover && num_takeover)
1926+ /* Play it again, Sam... */
1927+ iw_enum_devices(skfd, &process_ifname, args, count);
1928+
1929+ /* Done */
1930+ return(0);
1931+}
1932+
1933+/******************************* MAIN *******************************/
1934+
1935+
1936+/*------------------------------------------------------------------*/
1937+/*
1938+ */
1939+static void
1940+usage(void)
1941+{
1942+ fprintf(stderr, "usage: ifrename [-c configurationfile] [-i ifname] [-p] [-t] [-d] [-D]\n");
1943+ exit(1);
1944+}
1945+
1946+/*------------------------------------------------------------------*/
1947+/*
1948+ * The main !
1949+ */
1950+int
1951+main(int argc,
1952+ char * argv[])
1953+{
1954+ const char * conf_file = DEFAULT_CONF;
1955+ char * ifname = NULL;
1956+ char * newname = NULL;
1957+ int use_probe = 0;
1958+ int is_debian = 0;
1959+ int skfd;
1960+ int ret;
1961+
1962+ /* Loop over all command line options */
1963+ while(1)
1964+ {
1965+ int c = getopt_long(argc, argv, "c:dDi:n:ptvV", long_opt, NULL);
1966+ if(c == -1)
1967+ break;
1968+
1969+ switch(c)
1970+ {
1971+ default:
1972+ case '?':
1973+ usage();
1974+ case 'c':
1975+ conf_file = optarg;
1976+ break;
1977+ case 'd':
1978+ is_debian = 1;
1979+ break;
1980+ case 'D':
1981+ dry_run = 1;
1982+ break;
1983+ case 'i':
1984+ ifname = optarg;
1985+ break;
1986+ case 'n':
1987+ newname = optarg;
1988+ break;
1989+ case 'p':
1990+ use_probe = 1;
1991+ break;
1992+ case 't':
1993+ force_takeover = 1;
1994+ break;
1995+ case 'v':
1996+ printf("%-8.16s Wireless-Tools version %d\n", "ifrename", WT_VERSION);
1997+ return(0);
1998+ case 'V':
1999+ verbose = 1;
2000+ break;
2001+ }
2002+ }
2003+
2004+ /* Read the specified/default config file, or stdin. */
2005+ if(mapping_readfile(conf_file) < 0)
2006+ return(-1);
2007+
2008+ /* Create a channel to the NET kernel. */
2009+ if((skfd = iw_sockets_open()) < 0)
2010+ {
2011+ perror("socket");
2012+ return(-1);
2013+ }
2014+
2015+ /* Check if interface name was specified with -i. */
2016+ if(ifname)
2017+ {
2018+ /* Check is target name specified */
2019+ if(newname != NULL)
2020+ {
2021+ /* User want to simply rename an interface to a specified name */
2022+ ret = process_rename(skfd, ifname, newname);
2023+ }
2024+ else
2025+ {
2026+ /* Rename only this interface based on mappings
2027+ * Mostly used for HotPlug processing (from /etc/hotplug/net.agent).
2028+ * Process the network interface specified on the command line,
2029+ * and return the new name on stdout.
2030+ */
2031+ ret = process_ifname(skfd, ifname, NULL, 0);
2032+ }
2033+ }
2034+ else
2035+ {
2036+ /* Load all the necesary modules */
2037+ if(use_probe)
2038+ {
2039+ if(is_debian)
2040+ probe_debian(skfd);
2041+ else
2042+ probe_mappings(skfd);
2043+ }
2044+
2045+ /* Rename all system interfaces
2046+ * Mostly used for boot time processing (from init scripts).
2047+ */
2048+ ret = process_iflist(skfd, &newname, 1);
2049+ }
2050+
2051+ /* Cleanup */
2052+ iw_sockets_close(skfd);
2053+ return(ret);
2054+}
--- /dev/null
+++ b/wireless_tools/iftab.5
@@ -0,0 +1,190 @@
1+.\" Jean II - HPL - 2004
2+.\" iftab.5
3+.\"
4+.TH IFTAB 5 "01 March 2004" "wireless-tools" "Linux Programmer's Manual"
5+.\"
6+.\" NAME part
7+.\"
8+.SH NAME
9+iftab \- static information about the network interfaces
10+.\"
11+.\" DESCRIPTION part
12+.\"
13+.SH DESCRIPTION
14+The file
15+.B /etc/iftab
16+contains descriptive information about the various network interfaces.
17+.B iftab
18+is only used by the program
19+.IR ifrename (8)
20+to assign a consistent network interface name to each network interface.
21+.PP
22+.B /etc/iftab
23+defines a set of
24+.IR mappings .
25+Each mapping contains an interface name and a set of selectors. The
26+selectors allow
27+.B ifrename
28+to identify each network interface on the system. If a network
29+interface matches all descriptors of a mapping,
30+.B ifrename
31+attempt to change the name of the interface to the interface name
32+given by the mapping.
33+.\"
34+.\" MAPPINGS part
35+.\"
36+.SH MAPPINGS
37+Each mapping is described on a separate line, it starts with an
38+.IR "interface name" ,
39+and contains a set of
40+.IR descriptors ,
41+separated by space or tabs.
42+.PP
43+The relationship between descriptors of a mapping is a
44+.IR "logical and" .
45+A mapping matches a network interface only is all the descriptors
46+match. If a network interface doesn't support a specific descriptor,
47+it won't match any mappings using this descriptor.
48+.PP
49+If you want to use alternate descriptors for an interface name
50+(logical or), specify two different mappings with the same interface
51+name (one on each line).
52+.B Ifrename
53+always use the first matching mapping starting from the
54+.I end
55+of
56+.BR iftab ,
57+therefore more restrictive mapping should be specified last.
58+.\"
59+.\" INTERFACE NAME part
60+.\"
61+.SH INTERFACE NAME
62+The first part of each mapping is an interface name. If a network
63+interface matches all descriptors of a mapping,
64+.B ifrename
65+attempt to change the name of the interface to the interface name
66+given by the mapping.
67+.PP
68+The interface name of a mapping is either a plain interface name (such as
69+.IR eth2 " or " wlan0 )
70+or a interface name pattern containing a single wildcard (such as
71+.IR eth* " or " wlan* ).
72+In case of wildcard, the kernel replace the '*' with the lowest
73+available integer making this interface name unique.
74+.\"
75+.\" DESCRIPTORS part
76+.\"
77+.SH DESCRIPTORS
78+Each descriptor is composed of a descriptor name and descriptor
79+value. Descriptors specify a static attribute of a network interface,
80+the goal is to uniquely identify each piece of hardware.
81+.PP
82+Most users will only use the
83+.B mac
84+selector, other selectors are for more specialised setup.
85+.TP
86+.BI mac " mac address"
87+Matches the MAC Address of the interface with the specified MAC
88+address. The MAC address of the interface can be shown using
89+.IR ifconfig (8)
90+or
91+.IR ip (8).
92+The specified MAC address may contain a '*' for wilcard matching.
93+.br
94+This is the most common selector, as most interfaces have a unique MAC
95+address allowing to identify network interfaces without ambiguity.
96+However, some interfaces don't have a valid MAC address until they are
97+brought up, in such case using this selector is tricky.
98+.TP
99+.BI arp " arp type"
100+Matches the ARP Type (also called Link Type) of the interface with the
101+specified ARP type. The ARP Type of the interface can be shown using
102+.IR ifconfig (8)
103+or
104+.IR ip (8).
105+.br
106+This selector is useful when a driver create multiple network
107+interfaces for a single network card.
108+.TP
109+.BI driver " driver name"
110+Matches the Driver Name of the interface with the specified driver
111+name. The Driver Name of the interface can be shown using
112+.IR "ethtool -i" (8).
113+.TP
114+.BI businfo " bus information"
115+Matches the Bus Information of the interface with the specified bus
116+information. The Bus Information of the interface can be shown using
117+.IR "ethtool -i" (8).
118+.TP
119+.BI firmware " firmware revision"
120+Matches the Firmware Revision of the interface with the firmware
121+revision information. The Firmware Revision of the interface can be
122+shown using
123+.IR "ethtool -i" (8).
124+.TP
125+.BI baseaddress " base address"
126+Matches the Base Address of the interface with the specified base
127+address. The Base Address of the interface can be shown using
128+.IR ifconfig (8).
129+.br
130+Because most cards use dynamic allocation of the Base Address, this
131+selector is only useful for ISA and EISA cards.
132+.TP
133+.BI irq " irq line"
134+Matches the IRQ Line (interrupt) of the interface with the specified
135+IRQ line. The IRQ Line of the interface can be shown using
136+.IR ifconfig (8).
137+.br
138+Because there are IRQ Lines may be shared, this selector is usually
139+not sufficient to uniquely identify an interface.
140+.TP
141+.BI iwproto " wireless protocol"
142+Matches the Wireless Protocol of the interface with the specified
143+wireless protocol. The Wireless Protocol of the interface can be shown
144+using
145+.IR iwconfig (8).
146+.br
147+This selector is only supported on wireless interfaces and is not
148+sufficient to uniquely identify an interface.
149+.TP
150+.BI pcmciaslot " pcmcia slot"
151+Matches the Pcmcia Socket number of the interface with the specified
152+slot number. Pcmcia Socket number of the interface can be shown
153+using
154+.IR "cardctl ident" (8).
155+.br
156+This selector is usually only supported on 16 bits cards, for 32 bits
157+cards it is advised to use the selector
158+.BR businfo .
159+.\"
160+.\" EXAMPLE part
161+.\"
162+.SH EXAMPLE
163+# This is a comment
164+.br
165+eth2 mac 08:00:09:DE:82:0E
166+.br
167+eth3 driver wavelan interrupt 15 baseaddress 0x390
168+.br
169+eth4 driver pcnet32 businfo 0000:02:05.0
170+.br
171+air* mac 00:07:0E:* arp 1
172+.\"
173+.\" AUTHOR part
174+.\"
175+.SH AUTHOR
176+Jean Tourrilhes \- jt@hpl.hp.com
177+.\"
178+.\" FILES part
179+.\"
180+.SH FILES
181+.I /etc/iftab
182+.\"
183+.\" SEE ALSO part
184+.\"
185+.SH SEE ALSO
186+.BR ifrename (8),
187+.BR ifconfig (8),
188+.BR ip (8),
189+.BR ethtool (8),
190+.BR iwconfig (8).
--- a/wireless_tools/iwconfig.8
+++ b/wireless_tools/iwconfig.8
@@ -1,7 +1,7 @@
1-.\" Jean II - HPLB - 96
1+.\" Jean II - HPLB - 1996 => HPL - 2004
22 .\" iwconfig.8
33 .\"
4-.TH IWCONFIG 8 "31 October 1996" "net-tools" "Linux Programmer's Manual"
4+.TH IWCONFIG 8 "22 June 2004" "wireless-tools" "Linux Programmer's Manual"
55 .\"
66 .\" NAME part
77 .\"
@@ -41,9 +41,9 @@ may also be used to display those parameters, and the wireless
4141 statistics (extracted from
4242 .IR /proc/net/wireless ).
4343 .PP
44-All these parameters and statistics are device dependant. Each driver
45-will provide only some of them depending on the hardware support, and
46-the range of value may change. Please refer to the man page of each
44+All these parameters and statistics are device dependent. Each driver
45+will provide only some of them depending on hardware support, and the
46+range of values may change. Please refer to the man page of each
4747 device for details.
4848 .\"
4949 .\" PARAMETER part
@@ -51,14 +51,16 @@ device for details.
5151 .SH PARAMETERS
5252 .TP
5353 .B essid
54-Set the ESSID (or Network Name - in some products it may also called
55-Domain ID). The ESSID is used to identify cells which are part of the
56-same virtual network.
57-.br
58-As opposed to the NWID which defines a single cell, the ESSID defines
59-a group of cell connected via repeaters or infrastructure, where the
60-user may roam. With some card, you may disable the ESSID checking
61-(ESSID promiscuous) with
54+Set the ESSID (or Network Name - in some products it may also be
55+called Domain ID). The ESSID is used to identify cells which are part
56+of the same virtual network.
57+.br
58+As opposed to the AP Address or NWID which define a single cell, the
59+ESSID defines a group of cells connected via repeaters or
60+infrastructure, where the user may roam transparently.
61+.br
62+With some cards, you may disable the ESSID checking (ESSID
63+promiscuous) with
6264 .IR off " or " any " (and " on
6365 to reenable it).
6466 .br
@@ -69,11 +71,16 @@ to reenable it).
6971 .I " iwconfig eth0 essid ""My Network""
7072 .TP
7173 .BR nwid / domain
72-Set the Network ID (in some products it is also called Domain ID). As
73-all adjacent wireless networks share the same medium, this parameter
74-is used to differenciate them (create logical colocated networks) and
75-identify nodes belonguing to the same cell. With some card, you may
76-disable the Network ID checking (NWID promiscuous) with
74+Set the Network ID (in some products it may also be called Domain
75+ID). As all adjacent wireless networks share the same medium, this
76+parameter is used to differenciate them (create logical colocated
77+networks) and identify nodes belonging to the same cell.
78+.br
79+This parameter is only used for pre-802.11 hardware, the 802.11
80+protocol uses the ESSID and AP Address for this function.
81+.br
82+With some cards, you may disable the Network ID checking (NWID
83+promiscuous) with
7784 .IR off " (and " on
7885 to reenable it).
7986 .br
@@ -84,36 +91,37 @@ to reenable it).
8491 .I " iwconfig eth0 nwid off"
8592 .TP
8693 .BR freq / channel
87-Set the operating frequency or channel in the device. Value below 1000
88-are the channel number, value over this is the frequency in Hz. You
89-must append the suffix k, M or G to the value (for example, "2.46G"
90-for 2.46 GHz frequency), or add enough '0'.
91-.br
92-Channels are usually numbered starting at 1,
93-and you may use
94-.IR iwpriv (8)
95-to get the total number of channels and list the available
96-frequencies. Depending on regulations, some frequencies/channels may
97-not be available.
94+Set the operating frequency or channel in the device. A value below
95+1000 indicates a channel number, a value greater than 1000 is a
96+frequency in Hz. You may append the suffix k, M or G to the value (for
97+example, "2.46G" for 2.46 GHz frequency), or add enough '0'.
98+.br
99+Channels are usually numbered starting at 1, and you may use
100+.IR iwlist (8)
101+to get the total number of channels, list the available frequencies,
102+and display the current frequency as a channel. Depending on
103+regulations, some frequencies/channels may not be available.
98104 .br
99105 .B Examples :
100106 .br
107+.I " iwconfig eth0 freq 2422000000"
108+.br
101109 .I " iwconfig eth0 freq 2.422G"
102110 .br
103111 .I " iwconfig eth0 channel 3"
104112 .TP
105113 .B sens
106114 Set the sensitivity threshold. This is the lowest signal level for
107-which we attempt a packet reception, signal lower than this are not
108-received. This is used to avoid receiving background noise, so you
115+which the hardware attempt packet reception, signals weaker than this
116+are ignored. This is used to avoid receiving background noise, so you
109117 should set it according to the average noise level. Positive values
110118 are assumed to be the raw value used by the hardware or a percentage,
111119 negative values are assumed to be dBm.
112120 .br
113-With some hardware, this parameter also control the defer threshold
114-(lowest signal level for which we consider the channel busy) and the
115-handover threshold (lowest signal level where we stay associated with
116-the current access point).
121+With some hardware, this parameter also controls the defer threshold
122+(lowest signal level for which the hardware consider the channel busy)
123+and the handover threshold (signal level where the hardware start
124+looking for a new access point).
117125 .br
118126 .B Example :
119127 .br
@@ -122,18 +130,18 @@ the current access point).
122130 .B mode
123131 Set the operating mode of the device, which depends on the network
124132 topology. The mode can be
125-.I Ad-hoc
133+.I Ad-Hoc
126134 (network composed of only one cell and without Access Point),
127135 .I Managed
128136 (node connects to a network composed of many Access Points, with roaming),
129137 .I Master
130-(the node is the synchronisation master or act as an Access Point),
138+(the node is the synchronisation master or acts as an Access Point),
131139 .I Repeater
132-(the node forward packets between other wireless nodes),
140+(the node forwards packets between other wireless nodes),
133141 .I Secondary
134-(the node act as a backup master/repeater),
142+(the node acts as a backup master/repeater),
135143 .I Monitor
136-(the node act as a passive monitor and only receives packets) or
144+(the node acts as a passive monitor and only receives packets) or
137145 .IR Auto .
138146 .br
139147 .B Example :
@@ -145,8 +153,8 @@ topology. The mode can be
145153 .B ap
146154 Force the card to register to the Access Point given by the address,
147155 if it is possible. When the quality of the connection goes too low,
148-the driver may revert back to automatic mode (the card finds the best
149-Access Point in range).
156+the driver may revert back to automatic mode (the card selects the
157+best Access Point in range).
150158 .br
151159 You may also use
152160 .I off
@@ -155,7 +163,7 @@ or you may use
155163 .I any
156164 or
157165 .I auto
158-to force the card to reassociate with the current best Access Point.
166+to force the card to reassociate with the currently best Access Point.
159167 .br
160168 .B Example :
161169 .br
@@ -166,10 +174,10 @@ to force the card to reassociate with the current best Access Point.
166174 .I " iwconfig eth0 ap off"
167175 .TP
168176 .BR nick [name]
169-Set the nickname, or the station name. Most 802.11 products do define
177+Set the nickname, or the station name. Some 802.11 products do define
170178 it, but this is not used as far as the protocols (MAC, IP, TCP) are
171-concerned and completely accessory as far as configuration goes. In
172-fact only some diagnostic tools may use it.
179+concerned and completely useless as far as configuration goes. Only
180+some diagnostic tools may use it.
173181 .br
174182 .B Example :
175183 .br
@@ -179,18 +187,18 @@ fact only some diagnostic tools may use it.
179187 For cards supporting multiple bit rates, set the bit-rate in b/s. The
180188 bit-rate is the speed at which bits are transmitted over the medium,
181189 the user speed of the link is lower due to medium sharing and
182-overhead.
190+various overhead.
183191 .br
184-You must append the suffix k, M or G to the value (decimal multiplier
185-: 10^3, 10^6 and 10^9 b/s), or add enough '0'. Values below 1000 are
192+You may append the suffix k, M or G to the value (decimal multiplier :
193+10^3, 10^6 and 10^9 b/s), or add enough '0'. Values below 1000 are
186194 card specific, usually an index in the bit-rate list. Use
187195 .I auto
188-to select the automatic bit-rate mode (fallback to lower rate on noisy
196+to select automatic bit-rate mode (fallback to lower rate on noisy
189197 channels), which is the default for most cards, and
190198 .I fixed
191199 to revert back to fixed setting. If you specify a bit-rate value and append
192200 .IR auto ,
193-the driver will use all bit lower and equal than this value.
201+the driver will use all bit-rates lower and equal than this value.
194202 .br
195203 .B Examples :
196204 .br
@@ -202,11 +210,11 @@ the driver will use all bit lower and equal than this value.
202210 .TP
203211 .BR rts [_threshold]
204212 RTS/CTS adds a handshake before each packet transmission to make sure
205-that the channel is clear. This adds overhead, but increase
206-performance in case of hidden nodes or large number of active
207-nodes. This parameters set the size of the smallest packet for which
208-the node sends RTS, a value equal to the maximum packet size disable
209-the scheme. You may also set this parameter to
213+that the channel is clear. This adds overhead, but increases
214+performance in case of hidden nodes or a large number of active
215+nodes. This parameter sets the size of the smallest packet for which
216+the node sends RTS ; a value equal to the maximum packet size disable
217+the mechanism. You may also set this parameter to
210218 .IR auto ", " fixed " or " off .
211219 .br
212220 .B Examples :
@@ -216,11 +224,12 @@ the scheme. You may also set this parameter to
216224 .I " iwconfig eth0 rts off"
217225 .TP
218226 .BR frag [mentation_threshold]
219-Fragmentation allow to split a IP packet in a burst of smaller
227+Fragmentation allows to split an IP packet in a burst of smaller
220228 fragments transmitted on the medium. In most cases this adds overhead,
221-but in very noisy environment this reduce the error penalty. This
222-parameter set the maximum fragment size, a value equal to the maximum
223-packet size disable the scheme. You may also set this parameter to
229+but in a very noisy environment this reduces the error penalty and
230+allow packets to get through interference bursts. This parameter sets
231+the maximum fragment size ; a value equal to the maximum packet size
232+disable the mechanism. You may also set this parameter to
224233 .IR auto ", " fixed " or " off .
225234 .br
226235 .B Examples :
@@ -241,7 +250,7 @@ also enter the key as an ASCII string by using the
241250 .I s:
242251 prefix. Passphrase is currently not supported.
243252 .br
244-To change which key is the current active key, just enter
253+To change which key is the currently active key, just enter
245254 .I [index]
246255 (without entering any key value).
247256 .br
@@ -252,7 +261,7 @@ The security mode may be
252261 .I open
253262 or
254263 .IR restricted ,
255-and its meaning depend on the card used. With most card, in
264+and its meaning depends on the card used. With most cards, in
256265 .I open
257266 mode no authentication is used and the card may also accept
258267 non-encrypted sessions, whereas in
@@ -264,15 +273,19 @@ If you need to set multiple keys, or set a key and change the active
264273 key, you need to use multiple
265274 .B key
266275 directives. Arguments can be put in any order, the last one will take
267-precendence.
276+precedence.
268277 .br
269278 .B Examples :
270279 .br
271280 .I " iwconfig eth0 key 0123-4567-89"
272281 .br
282+.I " iwconfig eth0 key [3] 0123-4567-89"
283+.br
273284 .I " iwconfig eth0 key s:password [2]"
274285 .br
275-.I " iwconfig eth0 key [2] open"
286+.I " iwconfig eth0 key [2]"
287+.br
288+.I " iwconfig eth0 key open"
276289 .br
277290 .I " iwconfig eth0 key off"
278291 .br
@@ -283,16 +296,16 @@ precendence.
283296 .BR power
284297 Used to manipulate power management scheme parameters and mode.
285298 .br
286-To set the period between wake up, enter
299+To set the period between wake ups, enter
287300 .IR "period `value'" .
288301 To set the timeout before going back to sleep, enter
289302 .IR "timeout `value'" .
290303 You can also add the
291304 .IR min " and " max
292-modifiers. By defaults, those values are in seconds, append the
293-suffix m or u to specify values un milliseconds or
294-microseconds. Sometimes, those values are without units (number of
295-dwell or the like).
305+modifiers. By default, those values are in seconds, append the suffix
306+m or u to specify values in milliseconds or microseconds. Sometimes,
307+those values are without units (number of beacon periods, dwell or
308+similar).
296309 .br
297310 .IR off " and " on
298311 disable and reenable power management. Finally, you may set the power
@@ -351,11 +364,11 @@ This is an absolute value (without unit).
351364 The set the maximum length of time the MAC should retry, enter
352365 .IR "lifetime `value'" .
353366 By defaults, this value in in seconds, append the suffix m or u to
354-specify values un milliseconds or microseconds.
367+specify values in milliseconds or microseconds.
355368 .br
356369 You can also add the
357370 .IR min " and " max
358-modifiers. If the card support automatic mode, they define the bounds
371+modifiers. If the card supports automatic mode, they define the bounds
359372 of the limit or lifetime. Some other cards define different values
360373 depending on packet size, for example in 802.11
361374 .I min limit
@@ -373,15 +386,15 @@ is the short retry limit (non RTS/CTS packets).
373386 Some cards may not apply changes done through Wireless Extensions
374387 immediately (they may wait to agregate the changes or apply it only
375388 when the card is brought up via ifconfig). This command (when
376-available) force the card to apply all pending changes.
389+available) forces the card to apply all pending changes.
377390 .br
378391 This is normally not needed, because the card will eventually apply
379-the changes, but can be usefull for debugging.
392+the changes, but can be useful for debugging.
380393 .\"
381394 .\" DISPLAY part
382395 .\"
383396 .SH DISPLAY
384-For each device which support wireless extensions,
397+For each device which supports wireless extensions,
385398 .I iwconfig
386399 will display the name of the
387400 .B MAC protocol
@@ -406,15 +419,33 @@ the
406419 and the
407420 .B power management
408421 settings (depending on availability).
422+.PP
423+The parameters displayed have the same meaning and values as the
424+parameter you can set, please refer to the previous part for a
425+detailed explanation of them.
409426 .br
410-See above for explanations of what these parameters mean.
427+Some parameters are only displayed in short/abreviated form (such as
428+encryption). You may use
429+.IR iwlist (8)
430+to get all the details.
411431 .br
412-If the label for some values (such as bitrate) is followed by
432+Some parameters have two modes (such as bitrate). If the value is
433+prefixed by
413434 .RB ` = ',
414435 it means that the parameter is fixed and forced to that value, if it
415-is followed by
416-.RB ` : '
417-it is only the current value (device in normal auto mode).
436+is prefixed by
437+.RB ` : ',
438+the parameter is in automatic mode and the current value is shown (and
439+may change).
440+.TP
441+.BR "Access Point" / Cell
442+An address equal to 00:00:00:00:00:00 means that the card failed to
443+associate with an Access Point (most likely a configuration
444+issue). The
445+.B Access Point
446+parameter will be shown as
447+.B Cell
448+in ad-hoc mode (for obvious reasons), but otherwise works the same.
418449 .PP
419450 If
420451 .I /proc/net/wireless
@@ -428,7 +459,7 @@ driver documentation for proper interpretation of those values.
428459 Overall quality of the link. May be based on the level of contention
429460 or interference, the bit or frame error rate, how good the received
430461 signal is, some timing synchronisation, or other hardware metric. This
431-is an aggregate value, and depend totally on the driver and hardware.
462+is an aggregate value, and depends totally on the driver and hardware.
432463 .TP
433464 .B Signal level
434465 Received signal strength (RSSI - how strong the received signal
@@ -442,7 +473,7 @@ mode, this may be undefined and you should use
442473 .IR iwspy .
443474 .TP
444475 .B Noise level
445-Background noise level (when no packet is transmited). Similar
476+Background noise level (when no packet is transmitted). Similar
446477 comments as for
447478 .BR "Signal level" .
448479 .TP
@@ -461,16 +492,16 @@ re-assemble the link layer fragments (most likely one was missing).
461492 .TP
462493 .B Tx excessive retries
463494 Number of packets that the hardware failed to deliver. Most MAC
464-protocol will retry the packet a number of time before giving up.
495+protocols will retry the packet a number of times before giving up.
465496 .TP
466497 .B Invalid misc
467498 Other packets lost in relation with specific wireless operations.
468499 .TP
469500 .B Missed beacon
470501 Number of periodic beacons from the Cell or the Access Point we have
471-missed. Beacons are sent at regular interval to maintain the cell
472-coordination, failure to receive them usually indicate that we are out
473-of range.
502+missed. Beacons are sent at regular intervals to maintain the cell
503+coordination, failure to receive them usually indicates that the card
504+is out of range.
474505 .\"
475506 .\" AUTHOR part
476507 .\"
--- a/wireless_tools/iwconfig.c
+++ b/wireless_tools/iwconfig.c
@@ -1,14 +1,14 @@
11 /*
22 * Wireless Tools
33 *
4- * Jean II - HPLB 97->99 - HPL 99->01
4+ * Jean II - HPLB 97->99 - HPL 99->04
55 *
66 * Main code for "iwconfig". This is the generic tool for most
77 * manipulations...
88 * You need to link this code against "iwlib.c" and "-lm".
99 *
1010 * This file is released under the GPL license.
11- * Copyright (c) 1997-2002 Jean Tourrilhes <jt@hpl.hp.com>
11+ * Copyright (c) 1997-2004 Jean Tourrilhes <jt@hpl.hp.com>
1212 */
1313
1414 #include "iwlib.h" /* Header */
@@ -27,6 +27,7 @@ iw_usage(void)
2727 fprintf(stderr, " [mode {managed|ad-hoc|...}\n");
2828 fprintf(stderr, " [freq N.NNNN[k|M|G]]\n");
2929 fprintf(stderr, " [channel N]\n");
30+ fprintf(stderr, " [ap {N|off|auto}]\n");
3031 fprintf(stderr, " [sens N]\n");
3132 fprintf(stderr, " [nick N]\n");
3233 fprintf(stderr, " [rate {N|auto|fixed}]\n");
@@ -57,43 +58,24 @@ get_info(int skfd,
5758
5859 memset((char *) info, 0, sizeof(struct wireless_info));
5960
60- /* Get wireless name */
61- if(iw_get_ext(skfd, ifname, SIOCGIWNAME, &wrq) < 0)
61+ /* Get basic information */
62+ if(iw_get_basic_config(skfd, ifname, &(info->b)) < 0)
6263 {
6364 /* If no wireless name : no wireless extensions */
6465 /* But let's check if the interface exists at all */
6566 struct ifreq ifr;
6667
67- strcpy(ifr.ifr_name, ifname);
68+ strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
6869 if(ioctl(skfd, SIOCGIFFLAGS, &ifr) < 0)
6970 return(-ENODEV);
7071 else
7172 return(-ENOTSUP);
7273 }
73- else
74- {
75- strncpy(info->name, wrq.u.name, IFNAMSIZ);
76- info->name[IFNAMSIZ] = '\0';
77- }
7874
7975 /* Get ranges */
8076 if(iw_get_range_info(skfd, ifname, &(info->range)) >= 0)
8177 info->has_range = 1;
8278
83- /* Get network ID */
84- if(iw_get_ext(skfd, ifname, SIOCGIWNWID, &wrq) >= 0)
85- {
86- info->has_nwid = 1;
87- memcpy(&(info->nwid), &(wrq.u.nwid), sizeof(iwparam));
88- }
89-
90- /* Get frequency / channel */
91- if(iw_get_ext(skfd, ifname, SIOCGIWFREQ, &wrq) >= 0)
92- {
93- info->has_freq = 1;
94- info->freq = iw_freq2float(&(wrq.u.freq));
95- }
96-
9779 /* Get sensitivity */
9880 if(iw_get_ext(skfd, ifname, SIOCGIWSENS, &wrq) >= 0)
9981 {
@@ -101,27 +83,6 @@ get_info(int skfd,
10183 memcpy(&(info->sens), &(wrq.u.sens), sizeof(iwparam));
10284 }
10385
104- /* Get encryption information */
105- wrq.u.data.pointer = (caddr_t) info->key;
106- wrq.u.data.length = IW_ENCODING_TOKEN_MAX;
107- wrq.u.data.flags = 0;
108- if(iw_get_ext(skfd, ifname, SIOCGIWENCODE, &wrq) >= 0)
109- {
110- info->has_key = 1;
111- info->key_size = wrq.u.data.length;
112- info->key_flags = wrq.u.data.flags;
113- }
114-
115- /* Get ESSID */
116- wrq.u.essid.pointer = (caddr_t) info->essid;
117- wrq.u.essid.length = IW_ESSID_MAX_SIZE + 1;
118- wrq.u.essid.flags = 0;
119- if(iw_get_ext(skfd, ifname, SIOCGIWESSID, &wrq) >= 0)
120- {
121- info->has_essid = 1;
122- info->essid_on = wrq.u.data.flags;
123- }
124-
12586 /* Get AP address */
12687 if(iw_get_ext(skfd, ifname, SIOCGIWAP, &wrq) >= 0)
12788 {
@@ -158,14 +119,6 @@ get_info(int skfd,
158119 memcpy(&(info->frag), &(wrq.u.frag), sizeof(iwparam));
159120 }
160121
161- /* Get operation mode */
162- if(iw_get_ext(skfd, ifname, SIOCGIWMODE, &wrq) >= 0)
163- {
164- info->mode = wrq.u.mode;
165- if((info->mode < IW_NUM_OPER_MODE) && (info->mode >= 0))
166- info->has_mode = 1;
167- }
168-
169122 /* Get Power Management settings */
170123 wrq.u.power.flags = 0;
171124 if(iw_get_ext(skfd, ifname, SIOCGIWPOWER, &wrq) >= 0)
@@ -174,26 +127,29 @@ get_info(int skfd,
174127 memcpy(&(info->power), &(wrq.u.power), sizeof(iwparam));
175128 }
176129
177-#if WIRELESS_EXT > 9
178- /* Get Transmit Power */
179- if(iw_get_ext(skfd, ifname, SIOCGIWTXPOW, &wrq) >= 0)
130+ if((info->has_range) && (info->range.we_version_compiled > 9))
180131 {
181- info->has_txpower = 1;
182- memcpy(&(info->txpower), &(wrq.u.txpower), sizeof(iwparam));
132+ /* Get Transmit Power */
133+ if(iw_get_ext(skfd, ifname, SIOCGIWTXPOW, &wrq) >= 0)
134+ {
135+ info->has_txpower = 1;
136+ memcpy(&(info->txpower), &(wrq.u.txpower), sizeof(iwparam));
137+ }
183138 }
184-#endif
185139
186-#if WIRELESS_EXT > 10
187- /* Get retry limit/lifetime */
188- if(iw_get_ext(skfd, ifname, SIOCGIWRETRY, &wrq) >= 0)
140+ if((info->has_range) && (info->range.we_version_compiled > 10))
189141 {
190- info->has_retry = 1;
191- memcpy(&(info->retry), &(wrq.u.retry), sizeof(iwparam));
142+ /* Get retry limit/lifetime */
143+ if(iw_get_ext(skfd, ifname, SIOCGIWRETRY, &wrq) >= 0)
144+ {
145+ info->has_retry = 1;
146+ memcpy(&(info->retry), &(wrq.u.retry), sizeof(iwparam));
147+ }
192148 }
193-#endif /* WIRELESS_EXT > 10 */
194149
195150 /* Get stats */
196- if(iw_get_stats(skfd, ifname, &(info->stats)) >= 0)
151+ if(iw_get_stats(skfd, ifname, &(info->stats),
152+ &info->range, info->has_range) >= 0)
197153 {
198154 info->has_stats = 1;
199155 }
@@ -216,19 +172,19 @@ display_info(struct wireless_info * info,
216172 int tokens = 3; /* For name */
217173
218174 /* Display device name and wireless name (name of the protocol used) */
219- printf("%-8.8s %s ", ifname, info->name);
175+ printf("%-8.16s %s ", ifname, info->b.name);
220176
221177 /* Display ESSID (extended network), if any */
222- if(info->has_essid)
178+ if(info->b.has_essid)
223179 {
224- if(info->essid_on)
180+ if(info->b.essid_on)
225181 {
226182 /* Does it have an ESSID index ? */
227- if((info->essid_on & IW_ENCODE_INDEX) > 1)
228- printf("ESSID:\"%s\" [%d] ", info->essid,
229- (info->essid_on & IW_ENCODE_INDEX));
183+ if((info->b.essid_on & IW_ENCODE_INDEX) > 1)
184+ printf("ESSID:\"%s\" [%d] ", info->b.essid,
185+ (info->b.essid_on & IW_ENCODE_INDEX));
230186 else
231- printf("ESSID:\"%s\" ", info->essid);
187+ printf("ESSID:\"%s\" ", info->b.essid);
232188 }
233189 else
234190 printf("ESSID:off/any ");
@@ -239,35 +195,43 @@ display_info(struct wireless_info * info,
239195 printf("Nickname:\"%s\"", info->nickname);
240196
241197 /* Formatting */
242- if(info->has_essid || info->has_nickname)
198+ if(info->b.has_essid || info->has_nickname)
243199 {
244200 printf("\n ");
245201 tokens = 0;
246202 }
247203
248204 /* Display Network ID */
249- if(info->has_nwid)
205+ if(info->b.has_nwid)
250206 {
251207 /* Note : should display proper number of digit according to info
252208 * in range structure */
253- if(info->nwid.disabled)
209+ if(info->b.nwid.disabled)
254210 printf("NWID:off/any ");
255211 else
256- printf("NWID:%X ", info->nwid.value);
212+ printf("NWID:%X ", info->b.nwid.value);
257213 tokens +=2;
258214 }
259215
260216 /* Display the current mode of operation */
261- if(info->has_mode)
217+ if(info->b.has_mode)
262218 {
263- printf("Mode:%s ", iw_operation_mode[info->mode]);
219+ printf("Mode:%s ", iw_operation_mode[info->b.mode]);
264220 tokens +=3;
265221 }
266222
267223 /* Display frequency / channel */
268- if(info->has_freq)
224+ if(info->b.has_freq)
269225 {
270- iw_print_freq(buffer, info->freq);
226+ double freq = info->b.freq; /* Frequency/channel */
227+ int channel = -1; /* Converted to channel */
228+ /* Some driver insist of returning channel instead of frequency.
229+ * This fixes them up. Note that, driver should still return
230+ * frequency, because other tools depend on it. */
231+ if(info->has_range && (freq < KILO))
232+ channel = iw_channel_to_freq((int) freq, &freq, &info->range);
233+ /* Display */
234+ iw_print_freq(buffer, sizeof(buffer), freq, -1, info->b.freq_flags);
271235 printf("%s ", buffer);
272236 tokens +=4;
273237 }
@@ -284,11 +248,11 @@ display_info(struct wireless_info * info,
284248 tokens +=6;
285249
286250 /* Oups ! No Access Point in Ad-Hoc mode */
287- if((info->has_mode) && (info->mode == IW_MODE_ADHOC))
251+ if((info->b.has_mode) && (info->b.mode == IW_MODE_ADHOC))
288252 printf("Cell:");
289253 else
290254 printf("Access Point:");
291- printf(" %s ", iw_pr_ether(buffer, info->ap_addr.sa_data));
255+ printf(" %s ", iw_pr_ether(buffer, info->ap_addr.sa_data));
292256 }
293257
294258 /* Display the currently used/set bit-rate */
@@ -303,11 +267,10 @@ display_info(struct wireless_info * info,
303267 tokens +=3;
304268
305269 /* Display it */
306- iw_print_bitrate(buffer, info->bitrate.value);
270+ iw_print_bitrate(buffer, sizeof(buffer), info->bitrate.value);
307271 printf("Bit Rate%c%s ", (info->bitrate.fixed ? '=' : ':'), buffer);
308272 }
309273
310-#if WIRELESS_EXT > 9
311274 /* Display the Transmit Power */
312275 if(info->has_txpower)
313276 {
@@ -319,30 +282,10 @@ display_info(struct wireless_info * info,
319282 }
320283 tokens +=3;
321284
322- /* Disabled ? */
323- if(info->txpower.disabled)
324- printf("Tx-Power:off ");
325- else
326- {
327- int dbm;
328-
329- /* Fixed ? */
330- if(info->txpower.fixed)
331- printf("Tx-Power=");
332- else
333- printf("Tx-Power:");
334-
335- /* Convert everything to dBm */
336- if(info->txpower.flags & IW_TXPOW_MWATT)
337- dbm = iw_mwatt2dbm(info->txpower.value);
338- else
339- dbm = info->txpower.value;
340-
341- /* Display */
342- printf("%d dBm ", dbm);
343- }
285+ /* Display it */
286+ iw_print_txpower(buffer, sizeof(buffer), &info->txpower);
287+ printf("Tx-Power%c%s ", (info->txpower.fixed ? '=' : ':'), buffer);
344288 }
345-#endif
346289
347290 /* Display sensitivity */
348291 if(info->has_sens)
@@ -374,7 +317,6 @@ display_info(struct wireless_info * info,
374317 printf("\n ");
375318 tokens = 0;
376319
377-#if WIRELESS_EXT > 10
378320 /* Display retry limit/lifetime information */
379321 if(info->has_retry)
380322 {
@@ -387,7 +329,7 @@ display_info(struct wireless_info * info,
387329 /* Let's check the value and its type */
388330 if(info->retry.flags & IW_RETRY_TYPE)
389331 {
390- iw_print_retry_value(buffer,
332+ iw_print_retry_value(buffer, sizeof(buffer),
391333 info->retry.value, info->retry.flags);
392334 printf("%s", buffer);
393335 }
@@ -399,7 +341,6 @@ display_info(struct wireless_info * info,
399341 printf(" ");
400342 tokens += 5; /* Between 3 and 5, depend on flags */
401343 }
402-#endif /* WIRELESS_EXT > 10 */
403344
404345 /* Display the RTS threshold */
405346 if(info->has_rts)
@@ -452,23 +393,24 @@ display_info(struct wireless_info * info,
452393
453394 /* Display encryption information */
454395 /* Note : we display only the "current" key, use iwlist to list all keys */
455- if(info->has_key)
396+ if(info->b.has_key)
456397 {
457398 printf("Encryption key:");
458- if((info->key_flags & IW_ENCODE_DISABLED) || (info->key_size == 0))
399+ if((info->b.key_flags & IW_ENCODE_DISABLED) || (info->b.key_size == 0))
459400 printf("off\n ");
460401 else
461402 {
462403 /* Display the key */
463- iw_print_key(buffer, info->key, info->key_size, info->key_flags);
404+ iw_print_key(buffer, sizeof(buffer),
405+ info->b.key, info->b.key_size, info->b.key_flags);
464406 printf("%s", buffer);
465407
466408 /* Other info... */
467- if((info->key_flags & IW_ENCODE_INDEX) > 1)
468- printf(" [%d]", info->key_flags & IW_ENCODE_INDEX);
469- if(info->key_flags & IW_ENCODE_RESTRICTED)
409+ if((info->b.key_flags & IW_ENCODE_INDEX) > 1)
410+ printf(" [%d]", info->b.key_flags & IW_ENCODE_INDEX);
411+ if(info->b.key_flags & IW_ENCODE_RESTRICTED)
470412 printf(" Security mode:restricted");
471- if(info->key_flags & IW_ENCODE_OPEN)
413+ if(info->b.key_flags & IW_ENCODE_OPEN)
472414 printf(" Security mode:open");
473415 printf("\n ");
474416 }
@@ -488,12 +430,13 @@ display_info(struct wireless_info * info,
488430 /* Let's check the value and its type */
489431 if(info->power.flags & IW_POWER_TYPE)
490432 {
491- iw_print_pm_value(buffer, info->power.value, info->power.flags);
433+ iw_print_pm_value(buffer, sizeof(buffer),
434+ info->power.value, info->power.flags);
492435 printf("%s ", buffer);
493436 }
494437
495438 /* Let's check the mode */
496- iw_print_pm_mode(buffer, info->power.flags);
439+ iw_print_pm_mode(buffer, sizeof(buffer), info->power.flags);
497440 printf("%s", buffer);
498441
499442 /* Let's check if nothing (simply on) */
@@ -506,24 +449,23 @@ display_info(struct wireless_info * info,
506449 /* Display statistics */
507450 if(info->has_stats)
508451 {
509- info->stats.qual.updated = 0x0; /* Not that reliable, disable */
510- iw_print_stats(buffer, &info->stats.qual, &info->range, info->has_range);
452+ iw_print_stats(buffer, sizeof(buffer),
453+ &info->stats.qual, &info->range, info->has_range);
511454 printf("Link %s\n", buffer);
512455
513-#if WIRELESS_EXT > 11
514- printf(" Rx invalid nwid:%d Rx invalid crypt:%d Rx invalid frag:%d\n Tx excessive retries:%d Invalid misc:%d Missed beacon:%d\n",
515- info->stats.discard.nwid,
516- info->stats.discard.code,
517- info->stats.discard.fragment,
518- info->stats.discard.retries,
519- info->stats.discard.misc,
520- info->stats.miss.beacon);
521-#else /* WIRELESS_EXT > 11 */
522- printf(" Rx invalid nwid:%d invalid crypt:%d invalid misc:%d\n",
523- info->stats.discard.nwid,
524- info->stats.discard.code,
525- info->stats.discard.misc);
526-#endif /* WIRELESS_EXT > 11 */
456+ if(info->range.we_version_compiled > 11)
457+ printf(" Rx invalid nwid:%d Rx invalid crypt:%d Rx invalid frag:%d\n Tx excessive retries:%d Invalid misc:%d Missed beacon:%d\n",
458+ info->stats.discard.nwid,
459+ info->stats.discard.code,
460+ info->stats.discard.fragment,
461+ info->stats.discard.retries,
462+ info->stats.discard.misc,
463+ info->stats.miss.beacon);
464+ else
465+ printf(" Rx invalid nwid:%d invalid crypt:%d invalid misc:%d\n",
466+ info->stats.discard.nwid,
467+ info->stats.discard.code,
468+ info->stats.discard.misc);
527469 }
528470
529471 printf("\n");
@@ -555,12 +497,12 @@ print_info(int skfd,
555497 break;
556498
557499 case -ENOTSUP:
558- fprintf(stderr, "%-8.8s no wireless extensions.\n\n",
500+ fprintf(stderr, "%-8.16s no wireless extensions.\n\n",
559501 ifname);
560502 break;
561503
562504 default:
563- fprintf(stderr, "%-8.8s %s\n\n", ifname, strerror(-rc));
505+ fprintf(stderr, "%-8.16s %s\n\n", ifname, strerror(-rc));
564506 }
565507 return(rc);
566508 }
@@ -702,13 +644,48 @@ set_info(int skfd, /* The socket */
702644
703645 if(++i >= count)
704646 ABORT_ARG_NUM("Set Frequency", SIOCSIWFREQ);
705- if(sscanf(args[i], "%lg", &(freq)) != 1)
706- ABORT_ARG_TYPE("Set Frequency", SIOCSIWFREQ, args[i]);
707- if(index(args[i], 'G')) freq *= GIGA;
708- if(index(args[i], 'M')) freq *= MEGA;
709- if(index(args[i], 'k')) freq *= KILO;
647+ if(!strcasecmp(args[i], "auto"))
648+ {
649+ wrq.u.freq.m = -1;
650+ wrq.u.freq.e = 0;
651+ wrq.u.freq.flags = 0;
652+ }
653+ else
654+ {
655+ if(!strcasecmp(args[i], "fixed"))
656+ {
657+ /* Get old bitrate */
658+ IW_GET_EXT_ERR(skfd, ifname, SIOCGIWFREQ, &wrq,
659+ "Set Bit Rate");
660+ wrq.u.freq.flags = IW_FREQ_FIXED;
661+ }
662+ else /* Should be a numeric value */
663+ {
664+ if(sscanf(args[i], "%lg", &(freq)) != 1)
665+ ABORT_ARG_TYPE("Set Frequency", SIOCSIWFREQ, args[i]);
666+ if(index(args[i], 'G')) freq *= GIGA;
667+ if(index(args[i], 'M')) freq *= MEGA;
668+ if(index(args[i], 'k')) freq *= KILO;
669+
670+ iw_float2freq(freq, &(wrq.u.freq));
710671
711- iw_float2freq(freq, &(wrq.u.freq));
672+ wrq.u.freq.flags = IW_FREQ_FIXED;
673+
674+ /* Check for an additional argument */
675+ if(((i+1) < count) &&
676+ (!strcasecmp(args[i+1], "auto")))
677+ {
678+ wrq.u.freq.flags = 0;
679+ ++i;
680+ }
681+ if(((i+1) < count) &&
682+ (!strcasecmp(args[i+1], "fixed")))
683+ {
684+ wrq.u.freq.flags = IW_FREQ_FIXED;
685+ ++i;
686+ }
687+ }
688+ }
712689
713690 IW_SET_EXT_ERR(skfd, ifname, SIOCSIWFREQ, &wrq,
714691 "Set Frequency");
@@ -806,14 +783,12 @@ set_info(int skfd, /* The socket */
806783 ++i;
807784 gotone++;
808785 }
809-#if WIRELESS_EXT > 15
810786 if((i < count) && (!strncasecmp(args[i], "temporary", 4)))
811787 {
812788 wrq.u.data.flags |= IW_ENCODE_TEMP;
813789 ++i;
814790 gotone++;
815791 }
816-#endif
817792 }
818793 while(gotone != oldone);
819794
@@ -1192,7 +1167,6 @@ set_info(int skfd, /* The socket */
11921167 continue;
11931168 }
11941169
1195-#if WIRELESS_EXT > 9
11961170 /* ---------- Set Transmit-Power ---------- */
11971171 if(!strncmp(args[i], "txpower", 3))
11981172 {
@@ -1209,7 +1183,7 @@ set_info(int skfd, /* The socket */
12091183 wrq.u.txpower.value = -1;
12101184 wrq.u.txpower.fixed = 1;
12111185 wrq.u.txpower.disabled = 0;
1212- wrq.u.data.flags = IW_TXPOW_DBM;
1186+ wrq.u.txpower.flags = IW_TXPOW_DBM;
12131187 if(!strcasecmp(args[i], "off"))
12141188 wrq.u.txpower.disabled = 1; /* i.e. turn radio off */
12151189 else
@@ -1217,52 +1191,73 @@ set_info(int skfd, /* The socket */
12171191 wrq.u.txpower.fixed = 0; /* i.e. use power control */
12181192 else
12191193 {
1220- if(!strcasecmp(args[i], "fixed"))
1194+ if(!strcasecmp(args[i], "on"))
12211195 {
12221196 /* Get old tx-power */
12231197 IW_GET_EXT_ERR(skfd, ifname, SIOCGIWTXPOW, &wrq,
12241198 "Set Tx Power");
1225- wrq.u.txpower.fixed = 1;
1199+ wrq.u.txpower.disabled = 0;
12261200 }
1227- else /* Should be a numeric value */
1201+ else
12281202 {
1229- int power;
1230- int ismwatt = 0;
1231-
1232- /* Get the value */
1233- if(sscanf(args[i], "%i", &(power)) != 1)
1234- ABORT_ARG_TYPE("Set Tx Power", SIOCSIWTXPOW, args[i]);
1235-
1236- /* Check if milliwatt */
1237- ismwatt = (index(args[i], 'm') != NULL);
1238-
1239- /* Convert */
1240- if(range.txpower_capa & IW_TXPOW_MWATT)
1241- {
1242- if(!ismwatt)
1243- power = iw_dbm2mwatt(power);
1244- wrq.u.data.flags = IW_TXPOW_MWATT;
1245- }
1246- else
1203+ if(!strcasecmp(args[i], "fixed"))
12471204 {
1248- if(ismwatt)
1249- power = iw_mwatt2dbm(power);
1250- wrq.u.data.flags = IW_TXPOW_DBM;
1251- }
1252- wrq.u.txpower.value = power;
1253-
1254- /* Check for an additional argument */
1255- if(((i+1) < count) &&
1256- (!strcasecmp(args[i+1], "auto")))
1257- {
1258- wrq.u.txpower.fixed = 0;
1259- ++i;
1205+ /* Get old tx-power */
1206+ IW_GET_EXT_ERR(skfd, ifname, SIOCGIWTXPOW, &wrq,
1207+ "Set Tx Power");
1208+ wrq.u.txpower.fixed = 1;
1209+ wrq.u.txpower.disabled = 0;
12601210 }
1261- if(((i+1) < count) &&
1262- (!strcasecmp(args[i+1], "fixed")))
1211+ else /* Should be a numeric value */
12631212 {
1264- wrq.u.txpower.fixed = 1;
1265- ++i;
1213+ int power;
1214+ int ismwatt = 0;
1215+
1216+ /* Get the value */
1217+ if(sscanf(args[i], "%i", &(power)) != 1)
1218+ ABORT_ARG_TYPE("Set Tx Power", SIOCSIWTXPOW,
1219+ args[i]);
1220+
1221+ /* Check if milliwatt */
1222+ ismwatt = (index(args[i], 'm') != NULL);
1223+
1224+ /* Convert */
1225+ if(range.txpower_capa & IW_TXPOW_RELATIVE)
1226+ {
1227+ /* Can't convert */
1228+ if(ismwatt)
1229+ ABORT_ARG_TYPE("Set Tx Power",
1230+ SIOCSIWTXPOW,
1231+ args[i]);
1232+ }
1233+ else
1234+ if(range.txpower_capa & IW_TXPOW_MWATT)
1235+ {
1236+ if(!ismwatt)
1237+ power = iw_dbm2mwatt(power);
1238+ wrq.u.txpower.flags = IW_TXPOW_MWATT;
1239+ }
1240+ else
1241+ {
1242+ if(ismwatt)
1243+ power = iw_mwatt2dbm(power);
1244+ wrq.u.txpower.flags = IW_TXPOW_DBM;
1245+ }
1246+ wrq.u.txpower.value = power;
1247+
1248+ /* Check for an additional argument */
1249+ if(((i+1) < count) &&
1250+ (!strcasecmp(args[i+1], "auto")))
1251+ {
1252+ wrq.u.txpower.fixed = 0;
1253+ ++i;
1254+ }
1255+ if(((i+1) < count) &&
1256+ (!strcasecmp(args[i+1], "fixed")))
1257+ {
1258+ wrq.u.txpower.fixed = 1;
1259+ ++i;
1260+ }
12661261 }
12671262 }
12681263 }
@@ -1271,9 +1266,7 @@ set_info(int skfd, /* The socket */
12711266 "Set Tx Power");
12721267 continue;
12731268 }
1274-#endif
12751269
1276-#if WIRELESS_EXT > 10
12771270 /* ---------- Set Retry limit ---------- */
12781271 if(!strncmp(args[i], "retry", 3))
12791272 {
@@ -1343,8 +1336,6 @@ set_info(int skfd, /* The socket */
13431336 continue;
13441337 }
13451338
1346-#endif /* WIRELESS_EXT > 10 */
1347-
13481339 /* ---------- Other ---------- */
13491340 /* Here we have an unrecognised arg... */
13501341 fprintf(stderr, "Error : unrecognised wireless request \"%s\"\n",
@@ -1394,7 +1385,7 @@ main(int argc,
13941385 goterr = set_info(skfd, argv + 2, argc - 2, argv[1]);
13951386
13961387 /* Close the socket. */
1397- close(skfd);
1388+ iw_sockets_close(skfd);
13981389
13991390 return(goterr);
14001391 }
--- a/wireless_tools/iwevent.8
+++ b/wireless_tools/iwevent.8
@@ -1,7 +1,7 @@
1-.\" Jean Tourrilhes - HPL - 2002
1+.\" Jean Tourrilhes - HPL - 2002 - 2004
22 .\" iwevent.8
33 .\"
4-.TH IWEVENT 8 "25 January 2002" "net-tools" "Linux Programmer's Manual"
4+.TH IWEVENT 8 "23 June 2004" "net-tools" "Linux Programmer's Manual"
55 .\"
66 .\" NAME part
77 .\"
@@ -69,9 +69,9 @@ available (see
6969 .B Tx packet dropped
7070 A packet directed at this address has been dropped because the
7171 interface believes this node doesn't answer anymore (usually maximum
72-of MAC level retry exceeded). An early indication that the node may
73-have left the cell or gone out of range, but may be due to fading or
74-excessive contention.
72+of MAC level retry exceeded). This is usually an early indication that
73+the node may have left the cell or gone out of range, but it may be
74+due to fading or excessive contention.
7575 .TP
7676 .B Custom driver event
7777 Event specific to the driver. Please check the driver documentation.
@@ -90,10 +90,12 @@ Point (mode master).
9090 The signal strength for one of the address in the spy list went under
9191 the low threshold or went above than the high threshold.
9292 .PP
93-Only some of those events will be generated on some wireless
94-interfaces by the wireless driver, and their support depend on the
95-specific hardware/driver combination. Please refer to driver
96-documentation for details.
93+Most wireless drivers generate only a subset of those events, not all
94+of them, the exact list depends on the specific hardware/driver
95+combination. Please refer to driver documentation for details on when
96+they are generated, and use
97+.IR iwlist (8)
98+to check what the driver supports.
9799 .\"
98100 .\" AUTHOR part
99101 .\"
@@ -106,4 +108,5 @@ Jean Tourrilhes \- jt@hpl.hp.com
106108 .BR iwconfig (8),
107109 .BR iwlist (8),
108110 .BR iwspy (8),
109-.BR iwpriv (8).
111+.BR iwpriv (8),
112+.BR wireless (7).
--- a/wireless_tools/iwevent.c
+++ b/wireless_tools/iwevent.c
@@ -1,7 +1,7 @@
11 /*
22 * Wireless Tools
33 *
4- * Jean II - HPL 99->01
4+ * Jean II - HPL 99->04
55 *
66 * Main code for "iwevent". This listent for wireless events on rtnetlink.
77 * You need to link this code against "iwcommon.c" and "-lm".
@@ -12,7 +12,7 @@
1212 * about it...
1313 *
1414 * This file is released under the GPL license.
15- * Copyright (c) 1997-2002 Jean Tourrilhes <jt@hpl.hp.com>
15+ * Copyright (c) 1997-2004 Jean Tourrilhes <jt@hpl.hp.com>
1616 */
1717
1818 /***************************** INCLUDES *****************************/
@@ -31,6 +31,31 @@
3131 #define IFLA_WIRELESS (IFLA_MASTER + 1)
3232 #endif /* IFLA_WIRELESS */
3333
34+/****************************** TYPES ******************************/
35+
36+/*
37+ * Static information about wireless interface.
38+ * We cache this info for performance reason.
39+ */
40+typedef struct wireless_iface
41+{
42+ /* Linked list */
43+ struct wireless_iface * next;
44+
45+ /* Interface identification */
46+ int ifindex; /* Interface index == black magic */
47+
48+ /* Interface data */
49+ char ifname[IFNAMSIZ + 1]; /* Interface name */
50+ struct iw_range range; /* Wireless static data */
51+ int has_range;
52+} wireless_iface;
53+
54+/**************************** VARIABLES ****************************/
55+
56+/* Cache of wireless interfaces */
57+struct wireless_iface * interface_cache = NULL;
58+
3459 /************************ RTNETLINK HELPERS ************************/
3560 /*
3661 * The following code is extracted from :
@@ -97,23 +122,164 @@ static inline int rtnl_open(struct rtnl_handle *rth, unsigned subscriptions)
97122 return 0;
98123 }
99124
125+/******************* WIRELESS INTERFACE DATABASE *******************/
126+/*
127+ * We keep a few information about each wireless interface on the
128+ * system. This avoid to query this info at each event, therefore
129+ * reducing overhead.
130+ *
131+ * Each interface is indexed by the 'ifindex'. As opposed to interface
132+ * names, 'ifindex' are never reused (even if you reactivate the same
133+ * hardware), so the data we cache will never apply to the wrong
134+ * interface.
135+ * Because of that, we are pretty lazy when it come to purging the
136+ * cache...
137+ */
138+
139+/*------------------------------------------------------------------*/
140+/*
141+ * Get name of interface based on interface index...
142+ */
143+static inline int
144+index2name(int skfd,
145+ int ifindex,
146+ char * name)
147+{
148+ struct ifreq irq;
149+ int ret = 0;
150+
151+ memset(name, 0, IFNAMSIZ + 1);
152+
153+ /* Get interface name */
154+ irq.ifr_ifindex = ifindex;
155+ if(ioctl(skfd, SIOCGIFNAME, &irq) < 0)
156+ ret = -1;
157+ else
158+ strncpy(name, irq.ifr_name, IFNAMSIZ);
159+
160+ return(ret);
161+}
162+
163+/*------------------------------------------------------------------*/
164+/*
165+ * Get interface data from cache or live interface
166+ */
167+static struct wireless_iface *
168+iw_get_interface_data(int ifindex)
169+{
170+ struct wireless_iface * curr;
171+ int skfd = -1; /* ioctl socket */
172+
173+ /* Search for it in the database */
174+ curr = interface_cache;
175+ while(curr != NULL)
176+ {
177+ /* Match ? */
178+ if(curr->ifindex == ifindex)
179+ {
180+ //printf("Cache : found %d-%s\n", curr->ifindex, curr->ifname);
181+
182+ /* Return */
183+ return(curr);
184+ }
185+ /* Next entry */
186+ curr = curr->next;
187+ }
188+
189+ /* Create a channel to the NET kernel. Doesn't happen too often, so
190+ * socket creation overhead is minimal... */
191+ if((skfd = iw_sockets_open()) < 0)
192+ {
193+ perror("iw_sockets_open");
194+ return(NULL);
195+ }
196+
197+ /* Create new entry, zero, init */
198+ curr = calloc(1, sizeof(struct wireless_iface));
199+ if(!curr)
200+ {
201+ fprintf(stderr, "Malloc failed\n");
202+ return(NULL);
203+ }
204+ curr->ifindex = ifindex;
205+
206+ /* Extract static data */
207+ if(index2name(skfd, ifindex, curr->ifname) < 0)
208+ {
209+ perror("index2name");
210+ free(curr);
211+ return(NULL);
212+ }
213+ curr->has_range = (iw_get_range_info(skfd, curr->ifname, &curr->range) >= 0);
214+ //printf("Cache : create %d-%s\n", curr->ifindex, curr->ifname);
215+
216+ /* Done */
217+ iw_sockets_close(skfd);
218+
219+ /* Link it */
220+ curr->next = interface_cache;
221+ interface_cache = curr;
222+
223+ return(curr);
224+}
225+
226+/*------------------------------------------------------------------*/
227+/*
228+ * Remove interface data from cache (if it exist)
229+ */
230+static void
231+iw_del_interface_data(int ifindex)
232+{
233+ struct wireless_iface * curr;
234+ struct wireless_iface * prev = NULL;
235+ struct wireless_iface * next;
236+
237+ /* Go through the list, find the interface, kills it */
238+ curr = interface_cache;
239+ while(curr)
240+ {
241+ next = curr->next;
242+
243+ /* Got a match ? */
244+ if(curr->ifindex == ifindex)
245+ {
246+ /* Unlink. Root ? */
247+ if(!prev)
248+ interface_cache = next;
249+ else
250+ prev->next = next;
251+ //printf("Cache : purge %d-%s\n", curr->ifindex, curr->ifname);
252+
253+ /* Destroy */
254+ free(curr);
255+ }
256+ else
257+ {
258+ /* Keep as previous */
259+ prev = curr;
260+ }
261+
262+ /* Next entry */
263+ curr = next;
264+ }
265+}
266+
100267 /********************* WIRELESS EVENT DECODING *********************/
101268 /*
102- * This is the bit I wrote...
269+ * Parse the Wireless Event and print it out
103270 */
104271
105-#if WIRELESS_EXT > 13
106272 /*------------------------------------------------------------------*/
107273 /*
108274 * Print one element from the scanning results
109275 */
110276 static inline int
111-print_event_token(struct iw_event * event, /* Extracted token */
112- char * ifname,
113- struct iw_range * iwrange, /* Range info */
114- int has_iwrange)
277+print_event_token(struct iw_event * event, /* Extracted token */
278+ struct iw_range * iw_range, /* Range info */
279+ int has_range)
115280 {
116281 char buffer[128]; /* Temporary buffer */
282+ char * prefix = (IW_IS_GET(event->cmd) ? "New" : "Set");
117283
118284 /* Now, let's decode the event */
119285 switch(event->cmd)
@@ -122,23 +288,36 @@ print_event_token(struct iw_event * event, /* Extracted token */
122288 /* Events that result from a "SET XXX" operation by the user */
123289 case SIOCSIWNWID:
124290 if(event->u.nwid.disabled)
125- printf("NWID:off/any\n");
291+ printf("Set NWID:off/any\n");
126292 else
127- printf("NWID:%X\n", event->u.nwid.value);
293+ printf("Set NWID:%X\n", event->u.nwid.value);
128294 break;
129295 case SIOCSIWFREQ:
296+ case SIOCGIWFREQ:
130297 {
131- float freq; /* Frequency/channel */
298+ double freq; /* Frequency/channel */
299+ int channel = -1; /* Converted to channel */
132300 freq = iw_freq2float(&(event->u.freq));
133- iw_print_freq(buffer, freq);
134- printf("%s\n", buffer);
301+ if(has_range)
302+ {
303+ if(freq < KILO)
304+ /* Convert channel to frequency if possible */
305+ channel = iw_channel_to_freq((int) freq, &freq, iw_range);
306+ else
307+ /* Convert frequency to channel if possible */
308+ channel = iw_freq_to_channel(freq, iw_range);
309+ }
310+ iw_print_freq(buffer, sizeof(buffer),
311+ freq, channel, event->u.freq.flags);
312+ printf("%s %s\n", prefix, buffer);
135313 }
136314 break;
137315 case SIOCSIWMODE:
138- printf("Mode:%s\n",
316+ printf("Set Mode:%s\n",
139317 iw_operation_mode[event->u.mode]);
140318 break;
141319 case SIOCSIWESSID:
320+ case SIOCGIWESSID:
142321 {
143322 char essid[IW_ESSID_MAX_SIZE+1];
144323 if((event->u.essid.pointer) && (event->u.essid.length))
@@ -148,13 +327,13 @@ print_event_token(struct iw_event * event, /* Extracted token */
148327 {
149328 /* Does it have an ESSID index ? */
150329 if((event->u.essid.flags & IW_ENCODE_INDEX) > 1)
151- printf("ESSID:\"%s\" [%d]\n", essid,
330+ printf("%s ESSID:\"%s\" [%d]\n", prefix, essid,
152331 (event->u.essid.flags & IW_ENCODE_INDEX));
153332 else
154- printf("ESSID:\"%s\"\n", essid);
333+ printf("%s ESSID:\"%s\"\n", prefix, essid);
155334 }
156335 else
157- printf("ESSID:off/any\n");
336+ printf("%s ESSID:off/any\n", prefix);
158337 }
159338 break;
160339 case SIOCSIWENCODE:
@@ -164,13 +343,13 @@ print_event_token(struct iw_event * event, /* Extracted token */
164343 memcpy(key, event->u.essid.pointer, event->u.data.length);
165344 else
166345 event->u.data.flags |= IW_ENCODE_NOKEY;
167- printf("Encryption key:");
346+ printf("Set Encryption key:");
168347 if(event->u.data.flags & IW_ENCODE_DISABLED)
169348 printf("off\n");
170349 else
171350 {
172351 /* Display the key */
173- iw_print_key(buffer, key, event->u.data.length,
352+ iw_print_key(buffer, sizeof(buffer), key, event->u.data.length,
174353 event->u.data.flags);
175354 printf("%s", buffer);
176355
@@ -198,7 +377,6 @@ print_event_token(struct iw_event * event, /* Extracted token */
198377 printf("Tx packet dropped:%s\n",
199378 iw_pr_ether(buffer, event->u.addr.sa_data));
200379 break;
201-#if WIRELESS_EXT > 14
202380 case IWEVCUSTOM:
203381 {
204382 char custom[IW_CUSTOM_MAX+1];
@@ -216,42 +394,28 @@ print_event_token(struct iw_event * event, /* Extracted token */
216394 printf("Expired node:%s\n",
217395 iw_pr_ether(buffer, event->u.addr.sa_data));
218396 break;
219-#endif /* WIRELESS_EXT > 14 */
220-#if WIRELESS_EXT > 15
221397 case SIOCGIWTHRSPY:
222398 {
223399 struct iw_thrspy threshold;
224- int skfd;
225- struct iw_range range;
226- int has_range = 0;
227400 if((event->u.data.pointer) && (event->u.data.length))
228401 {
229402 memcpy(&threshold, event->u.data.pointer,
230403 sizeof(struct iw_thrspy));
231- if((skfd = iw_sockets_open()) >= 0)
232- {
233- has_range = (iw_get_range_info(skfd, ifname, &range) >= 0);
234- close(skfd);
235- }
236404 printf("Spy threshold crossed on address:%s\n",
237405 iw_pr_ether(buffer, threshold.addr.sa_data));
238- threshold.qual.updated = 0x0; /* Not that reliable, disable */
239- iw_print_stats(buffer, &threshold.qual, &range, has_range);
406+ iw_print_stats(buffer, sizeof(buffer),
407+ &threshold.qual, iw_range, has_range);
240408 printf(" Link %s\n", buffer);
241409 }
242410 else
243411 printf("Invalid Spy Threshold event\n");
244412 }
245413 break;
246-#else
247- /* Avoid "Unused parameter" warning */
248- ifname = ifname;
249-#endif /* WIRELESS_EXT > 15 */
250414 /* ----- junk ----- */
251415 /* other junk not currently in use */
252416 case SIOCGIWRATE:
253- iw_print_bitrate(buffer, event->u.bitrate.value);
254- printf("Bit Rate:%s\n", buffer);
417+ iw_print_bitrate(buffer, sizeof(buffer), event->u.bitrate.value);
418+ printf("New Bit Rate:%s\n", buffer);
255419 break;
256420 case SIOCGIWNAME:
257421 printf("Protocol:%-1.16s\n", event->u.name);
@@ -259,7 +423,8 @@ print_event_token(struct iw_event * event, /* Extracted token */
259423 case IWEVQUAL:
260424 {
261425 event->u.qual.updated = 0x0; /* Not that reliable, disable */
262- iw_print_stats(buffer, &event->u.qual, iwrange, has_iwrange);
426+ iw_print_stats(buffer, sizeof(buffer),
427+ &event->u.qual, iw_range, has_range);
263428 printf("Link %s\n", buffer);
264429 break;
265430 }
@@ -277,7 +442,7 @@ print_event_token(struct iw_event * event, /* Extracted token */
277442 * just make sure we read everything...
278443 */
279444 static inline int
280-print_event_stream(char * ifname,
445+print_event_stream(int ifindex,
281446 char * data,
282447 int len)
283448 {
@@ -287,41 +452,42 @@ print_event_stream(char * ifname,
287452 int ret;
288453 char buffer[64];
289454 struct timeval recv_time;
290-#if 0
291- struct iw_range range;
292- int has_range;
293-#endif
455+ struct wireless_iface * wireless_data;
294456
295-#if 0
296- has_range = (iw_get_range_info(skfd, ifname, &range) < 0);
297-#endif
457+ /* Get data from cache */
458+ wireless_data = iw_get_interface_data(ifindex);
459+ if(wireless_data == NULL)
460+ return(-1);
298461
299- /* In readable form */
462+ /* Print received time in readable form */
300463 gettimeofday(&recv_time, NULL);
301- iw_print_timeval(buffer, &recv_time);
464+ iw_print_timeval(buffer, sizeof(buffer), &recv_time);
302465
303466 iw_init_event_stream(&stream, data, len);
304467 do
305468 {
306469 /* Extract an event and print it */
307- ret = iw_extract_event_stream(&stream, &iwe);
470+ ret = iw_extract_event_stream(&stream, &iwe,
471+ wireless_data->range.we_version_compiled);
308472 if(ret != 0)
309473 {
310474 if(i++ == 0)
311- printf("%s %-8.8s ", buffer, ifname);
475+ printf("%s %-8.16s ", buffer, wireless_data->ifname);
312476 else
313477 printf(" ");
314478 if(ret > 0)
315- print_event_token(&iwe, ifname, NULL, 0);
479+ print_event_token(&iwe,
480+ &wireless_data->range, wireless_data->has_range);
316481 else
317482 printf("(Invalid event)\n");
483+ /* Push data out *now*, in case we are redirected to a pipe */
484+ fflush(stdout);
318485 }
319486 }
320487 while(ret > 0);
321488
322489 return(0);
323490 }
324-#endif /* WIRELESS_EXT > 13 */
325491
326492 /*********************** RTNETLINK EVENT DUMP***********************/
327493 /*
@@ -333,76 +499,51 @@ print_event_stream(char * ifname,
333499 /*
334500 * Respond to a single RTM_NEWLINK event from the rtnetlink socket.
335501 */
336-static inline int
337-index2name(int index, char *name)
338-{
339- int skfd = -1; /* generic raw socket desc. */
340- struct ifreq irq;
341- int ret = 0;
342-
343- memset(name, 0, IFNAMSIZ + 1);
344-
345- /* Create a channel to the NET kernel. */
346- if((skfd = iw_sockets_open()) < 0)
347- {
348- perror("socket");
349- exit(-1);
350- }
351-
352- /* Get interface name */
353- irq.ifr_ifindex = index;
354- if(ioctl(skfd, SIOCGIFNAME, &irq) < 0)
355- ret = -1;
356- else
357- strncpy(name, irq.ifr_name, IFNAMSIZ);
358-
359- close(skfd);
360- return(ret);
361-}
362-
363-
364-/*------------------------------------------------------------------*/
365-/*
366- * Respond to a single RTM_NEWLINK event from the rtnetlink socket.
367- */
368502 static int
369503 LinkCatcher(struct nlmsghdr *nlh)
370504 {
371505 struct ifinfomsg* ifi;
372- char ifname[IFNAMSIZ + 1];
373506
374507 #if 0
375508 fprintf(stderr, "nlmsg_type = %d.\n", nlh->nlmsg_type);
376509 #endif
377510
378- if(nlh->nlmsg_type != RTM_NEWLINK)
379- return 0;
380-
381511 ifi = NLMSG_DATA(nlh);
382512
383- /* Get a name... */
384- index2name(ifi->ifi_index, ifname);
385-
386-#if WIRELESS_EXT > 13
387513 /* Code is ugly, but sort of works - Jean II */
388514
515+ /* If interface is getting destoyed */
516+ if(nlh->nlmsg_type == RTM_DELLINK)
517+ {
518+ /* Remove from cache (if in cache) */
519+ iw_del_interface_data(ifi->ifi_index);
520+ return 0;
521+ }
522+
523+ /* Only keep add/change events */
524+ if(nlh->nlmsg_type != RTM_NEWLINK)
525+ return 0;
526+
389527 /* Check for attributes */
390- if (nlh->nlmsg_len > NLMSG_ALIGN(sizeof(struct ifinfomsg))) {
528+ if (nlh->nlmsg_len > NLMSG_ALIGN(sizeof(struct ifinfomsg)))
529+ {
391530 int attrlen = nlh->nlmsg_len - NLMSG_ALIGN(sizeof(struct ifinfomsg));
392- struct rtattr *attr = (void*)ifi + NLMSG_ALIGN(sizeof(struct ifinfomsg));
393-
394- while (RTA_OK(attr, attrlen)) {
395- /* Check if the Wireless kind */
396- if(attr->rta_type == IFLA_WIRELESS) {
397- /* Go to display it */
398- print_event_stream(ifname,
399- (void *)attr + RTA_ALIGN(sizeof(struct rtattr)),
400- attr->rta_len - RTA_ALIGN(sizeof(struct rtattr)));
531+ struct rtattr *attr = (void *) ((char *) ifi +
532+ NLMSG_ALIGN(sizeof(struct ifinfomsg)));
533+
534+ while (RTA_OK(attr, attrlen))
535+ {
536+ /* Check if the Wireless kind */
537+ if(attr->rta_type == IFLA_WIRELESS)
538+ {
539+ /* Go to display it */
540+ print_event_stream(ifi->ifi_index,
541+ (char *) attr + RTA_ALIGN(sizeof(struct rtattr)),
542+ attr->rta_len - RTA_ALIGN(sizeof(struct rtattr)));
543+ }
544+ attr = RTA_NEXT(attr, attrlen);
401545 }
402- attr = RTA_NEXT(attr, attrlen);
403- }
404- }
405-#endif /* WIRELESS_EXT > 13 */
546+ }
406547
407548 return 0;
408549 }
@@ -419,7 +560,7 @@ handle_netlink_events(struct rtnl_handle * rth)
419560 while(1)
420561 {
421562 struct sockaddr_nl sanl;
422- socklen_t sanllen;
563+ socklen_t sanllen = sizeof(struct sockaddr_nl);
423564
424565 struct nlmsghdr *h;
425566 int amt;
@@ -457,6 +598,7 @@ handle_netlink_events(struct rtnl_handle * rth)
457598 switch(h->nlmsg_type)
458599 {
459600 case RTM_NEWLINK:
601+ case RTM_DELLINK:
460602 LinkCatcher(h);
461603 break;
462604 default:
@@ -593,12 +735,7 @@ main(int argc,
593735 return(1);
594736 }
595737
596-#if WIRELESS_EXT > 13
597- fprintf(stderr, "Waiting for Wireless Events...\n");
598-#else /* WIRELESS_EXT > 13 */
599- fprintf(stderr, "Unsupported in Wireless Extensions <= 14 :-(\n");
600- return(-1);
601-#endif /* WIRELESS_EXT > 13 */
738+ fprintf(stderr, "Waiting for Wireless Events from interfaces...\n");
602739
603740 /* Do what we have to do */
604741 wait_for_event(&rth);
--- a/wireless_tools/iwgetid.8
+++ b/wireless_tools/iwgetid.8
@@ -1,8 +1,8 @@
11 .\" Guus Sliepen - 2001
2-.\" Completed and fixed up by Jean Tourrilhes - 2002
2+.\" Completed and fixed up by Jean Tourrilhes - 2002-2003
33 .\" iwgetid.8
44 .\"
5-.TH IWGETID 8 "7 August 2001" "net-tools" "Linux Programmer's Manual"
5+.TH IWGETID 8 "02 December 2003" "wireless-tools" "Linux Programmer's Manual"
66 .\"
77 .\" NAME part
88 .\"
@@ -12,9 +12,9 @@ iwgetid \- Report ESSID, NWID or AP/Cell Address of wireless network
1212 .\" SYNOPSIS part
1313 .\"
1414 .SH SYNOPSIS
15-.BI "iwgetid " [interface] " [--scheme] [--ap] [--freq] [--mode]"
15+.BI "iwgetid " [interface] " [--raw] [--scheme] [--ap] [--freq]"
1616 .br
17-.BI " [--protocol]
17+.BI " [--mode] [--protocol] [--channel]
1818 .br
1919 .\"
2020 .\" DESCRIPTION part
@@ -34,26 +34,42 @@ will print the
3434 of the device, and if the device doesn't have any ESSID it will print
3535 its
3636 .IR NWID .
37+.br
38+The default formatting output is pretty-print.
3739 .\"
3840 .\" OPTIONS part
3941 .\"
4042 .SH OPTIONS
4143 .TP
44+.B --raw
45+This option disables pretty-printing of the information. This options
46+is orthogonal to the other options (except
47+.BR --scheme ),
48+so with the appropriate combination of options you can print the raw
49+ESSID, AP Address or Mode.
50+.br
51+This format is ideal when storing the result of iwgetid as a
52+variable in
53+.I Shell
54+or
55+.I Perl
56+scripts or to pass the result as an argument on the command line of
57+.BR iwconfig .
58+.TP
4259 .B --scheme
43-This option disables pretty-printing of the information, only the raw
44-ESSID (or NWID, or AP Address) is printed. Also, characters that are
45-not alphanumerics (like space, punctuation and control characters) are
46-skipped.
60+This option is similar to the previous one, it disables
61+pretty-printing of the information and remove all characters that are
62+not alphanumerics (like space, punctuation and control characters).
4763 .br
4864 The resulting output is a valid Pcmcia scheme identifier (that may be
4965 used as an argument of the command
5066 .BR "cardctl scheme" ).
5167 This format is also ideal when using the result of iwgetid as a
52-variable in
68+selector in
5369 .I Shell
5470 or
5571 .I Perl
56-scripts.
72+scripts, or as a file name.
5773 .TP
5874 .B --ap
5975 Display the MAC address of the Wireless
@@ -68,6 +84,12 @@ or
6884 .I channel
6985 used by the interface.
7086 .TP
87+.B --channel
88+Display the current
89+.I channel
90+used by the interface. The channel is determined using the current
91+frequency and the frequency list provided by the interface.
92+.TP
7193 .B --mode
7294 Display the current
7395 .I mode
--- a/wireless_tools/iwgetid.c
+++ b/wireless_tools/iwgetid.c
@@ -6,21 +6,13 @@
66 * Just print the ESSID or NWID...
77 *
88 * This file is released under the GPL license.
9- * Copyright (c) 1997-2002 Jean Tourrilhes <jt@hpl.hp.com>
9+ * Copyright (c) 1997-2004 Jean Tourrilhes <jt@hpl.hp.com>
1010 */
1111
1212 #include "iwlib.h" /* Header */
1313
1414 #include <getopt.h>
1515
16-#define FORMAT_DEFAULT 0 /* Nice looking display for the user */
17-#define FORMAT_SCHEME 1 /* To be used as a Pcmcia Scheme */
18-#define WTYPE_ESSID 0 /* Display ESSID or NWID */
19-#define WTYPE_AP 1 /* Display AP/Cell Address */
20-#define WTYPE_FREQ 2 /* Display frequency/channel */
21-#define WTYPE_MODE 3 /* Display mode */
22-#define WTYPE_PROTO 4 /* Display protocol name */
23-
2416 /*
2517 * Note on Pcmcia Schemes :
2618 * ----------------------
@@ -68,119 +60,17 @@
6860 * Jean II - 29/3/01
6961 */
7062
71-/*************************** SUBROUTINES ***************************/
72-/*
73- * Just for the heck of it, let's try to not link with iwlib.
74- * This will keep the binary small and tiny...
75- *
76- * Note : maybe it's time to admit that we have lost the battle
77- * and we start using iwlib ? Maybe we should default to dynamic
78- * lib first...
79- */
80-
81-/*------------------------------------------------------------------*/
82-/*
83- * Open a socket.
84- * Depending on the protocol present, open the right socket. The socket
85- * will allow us to talk to the driver.
86- */
87-int
88-iw_sockets_open(void)
89-{
90- int ipx_sock = -1; /* IPX socket */
91- int ax25_sock = -1; /* AX.25 socket */
92- int inet_sock = -1; /* INET socket */
93- int ddp_sock = -1; /* Appletalk DDP socket */
94-
95- /*
96- * Now pick any (exisiting) useful socket family for generic queries
97- * Note : don't open all the socket, only returns when one matches,
98- * all protocols might not be valid.
99- * Workaround by Jim Kaba <jkaba@sarnoff.com>
100- * Note : in 99% of the case, we will just open the inet_sock.
101- * The remaining 1% case are not fully correct...
102- */
103- inet_sock=socket(AF_INET, SOCK_DGRAM, 0);
104- if(inet_sock!=-1)
105- return inet_sock;
106- ipx_sock=socket(AF_IPX, SOCK_DGRAM, 0);
107- if(ipx_sock!=-1)
108- return ipx_sock;
109- ax25_sock=socket(AF_AX25, SOCK_DGRAM, 0);
110- if(ax25_sock!=-1)
111- return ax25_sock;
112- ddp_sock=socket(AF_APPLETALK, SOCK_DGRAM, 0);
113- /*
114- * If this is -1 we have no known network layers and its time to jump.
115- */
116- return ddp_sock;
117-}
118-
119-/*------------------------------------------------------------------*/
120-/*
121- * Display an Ethernet address in readable format.
122- */
123-void
124-iw_ether_ntop(const struct ether_addr* eth, char* buf)
125-{
126- sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X",
127- eth->ether_addr_octet[0], eth->ether_addr_octet[1],
128- eth->ether_addr_octet[2], eth->ether_addr_octet[3],
129- eth->ether_addr_octet[4], eth->ether_addr_octet[5]);
130-}
63+/**************************** CONSTANTS ****************************/
13164
132-/*------------------------------------------------------------------*/
133-/*
134- * Convert our internal representation of frequencies to a floating point.
135- */
136-double
137-iw_freq2float(iwfreq * in)
138-{
139-#ifdef WE_NOLIBM
140- /* Version without libm : slower */
141- int i;
142- double res = (double) in->m;
143- for(i = 0; i < in->e; i++)
144- res *= 10;
145- return(res);
146-#else /* WE_NOLIBM */
147- /* Version with libm : faster */
148- return ((double) in->m) * pow(10,in->e);
149-#endif /* WE_NOLIBM */
150-}
151-
152-/*------------------------------------------------------------------*/
153-/*
154- * Output a frequency with proper scaling
155- */
156-void
157-iw_print_freq(char * buffer,
158- double freq)
159-{
160- if(freq < KILO)
161- sprintf(buffer, "Channel:%g", freq);
162- else
163- {
164- if(freq >= GIGA)
165- sprintf(buffer, "Frequency:%gGHz", freq / GIGA);
166- else
167- {
168- if(freq >= MEGA)
169- sprintf(buffer, "Frequency:%gMHz", freq / MEGA);
170- else
171- sprintf(buffer, "Frequency:%gkHz", freq / KILO);
172- }
173- }
174-}
175-
176-/*------------------------------------------------------------------*/
177-const char * const iw_operation_mode[] = { "Auto",
178- "Ad-Hoc",
179- "Managed",
180- "Master",
181- "Repeater",
182- "Secondary",
183- "Monitor" };
65+#define FORMAT_DEFAULT 0 /* Nice looking display for the user */
66+#define FORMAT_SCHEME 1 /* To be used as a Pcmcia Scheme */
67+#define FORMAT_RAW 2 /* Raw value, for shell scripts */
68+#define WTYPE_ESSID 0 /* Display ESSID or NWID */
69+#define WTYPE_AP 1 /* Display AP/Cell Address */
70+#define WTYPE_FREQ 2 /* Display frequency/channel */
71+#define WTYPE_CHANNEL 3 /* Display channel (converted from freq) */
72+#define WTYPE_MODE 4 /* Display mode */
73+#define WTYPE_PROTO 5 /* Display protocol name */
18474
18575 /************************ DISPLAY ESSID/NWID ************************/
18676
@@ -199,12 +89,14 @@ print_essid(int skfd,
19989 unsigned int i;
20090 unsigned int j;
20191
92+ /* Make shure ESSID is NULL terminated */
93+ memset(essid, 0, sizeof(essid));
94+
20295 /* Get ESSID */
203- strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
20496 wrq.u.essid.pointer = (caddr_t) essid;
20597 wrq.u.essid.length = IW_ESSID_MAX_SIZE + 1;
20698 wrq.u.essid.flags = 0;
207- if(ioctl(skfd, SIOCGIWESSID, &wrq) < 0)
99+ if(iw_get_ext(skfd, ifname, SIOCGIWESSID, &wrq) < 0)
208100 return(-1);
209101
210102 switch(format)
@@ -220,8 +112,11 @@ print_essid(int skfd,
220112 return(-2);
221113 printf("%s\n", pessid);
222114 break;
115+ case FORMAT_RAW:
116+ printf("%s\n", essid);
117+ break;
223118 default:
224- printf("%-8.8s ESSID:\"%s\"\n", ifname, essid);
119+ printf("%-8.16s ESSID:\"%s\"\n", ifname, essid);
225120 break;
226121 }
227122
@@ -240,8 +135,7 @@ print_nwid(int skfd,
240135 struct iwreq wrq;
241136
242137 /* Get network ID */
243- strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
244- if(ioctl(skfd, SIOCGIWNWID, &wrq) < 0)
138+ if(iw_get_ext(skfd, ifname, SIOCGIWNWID, &wrq) < 0)
245139 return(-1);
246140
247141 switch(format)
@@ -250,8 +144,11 @@ print_nwid(int skfd,
250144 /* Prefix with nwid to avoid name space collisions */
251145 printf("nwid%X\n", wrq.u.nwid.value);
252146 break;
147+ case FORMAT_RAW:
148+ printf("%X\n", wrq.u.nwid.value);
149+ break;
253150 default:
254- printf("%-8.8s NWID:%X\n", ifname, wrq.u.nwid.value);
151+ printf("%-8.16s NWID:%X\n", ifname, wrq.u.nwid.value);
255152 break;
256153 }
257154
@@ -273,8 +170,7 @@ print_ap(int skfd,
273170 char buffer[64];
274171
275172 /* Get AP Address */
276- strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
277- if(ioctl(skfd, SIOCGIWAP, &wrq) < 0)
173+ if(iw_get_ext(skfd, ifname, SIOCGIWAP, &wrq) < 0)
278174 return(-1);
279175
280176 /* Print */
@@ -284,10 +180,11 @@ print_ap(int skfd,
284180 case FORMAT_SCHEME:
285181 /* I think ':' are not problematic, because Pcmcia scripts
286182 * seem to handle them properly... */
183+ case FORMAT_RAW:
287184 printf("%s\n", buffer);
288185 break;
289186 default:
290- printf("%-8.8s Access Point/Cell: %s\n", ifname, buffer);
187+ printf("%-8.16s Access Point/Cell: %s\n", ifname, buffer);
291188 break;
292189 }
293190
@@ -310,8 +207,7 @@ print_freq(int skfd,
310207 char buffer[64];
311208
312209 /* Get frequency / channel */
313- strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
314- if(ioctl(skfd, SIOCGIWFREQ, &wrq) < 0)
210+ if(iw_get_ext(skfd, ifname, SIOCGIWFREQ, &wrq) < 0)
315211 return(-1);
316212
317213 /* Print */
@@ -319,11 +215,64 @@ print_freq(int skfd,
319215 switch(format)
320216 {
321217 case FORMAT_SCHEME:
218+ /* Prefix with freq to avoid name space collisions */
219+ printf("freq%g\n", freq);
220+ break;
221+ case FORMAT_RAW:
322222 printf("%g\n", freq);
323223 break;
324224 default:
325- iw_print_freq(buffer, freq);
326- printf("%-8.8s %s\n", ifname, buffer);
225+ iw_print_freq(buffer, sizeof(buffer), freq, -1, wrq.u.freq.flags);
226+ printf("%-8.16s %s\n", ifname, buffer);
227+ break;
228+ }
229+
230+ return(0);
231+}
232+
233+/*------------------------------------------------------------------*/
234+/*
235+ * Display the channel (converted from frequency) if possible
236+ */
237+static int
238+print_channel(int skfd,
239+ const char * ifname,
240+ int format)
241+{
242+ struct iwreq wrq;
243+ struct iw_range range;
244+ double freq;
245+ int channel;
246+
247+ /* Get frequency / channel */
248+ if(iw_get_ext(skfd, ifname, SIOCGIWFREQ, &wrq) < 0)
249+ return(-1);
250+
251+ /* Convert to channel */
252+ if(iw_get_range_info(skfd, ifname, &range) < 0)
253+ return(-2);
254+ freq = iw_freq2float(&(wrq.u.freq));
255+ if(freq < KILO)
256+ channel = (int) freq;
257+ else
258+ {
259+ channel = iw_freq_to_channel(freq, &range);
260+ if(channel < 0)
261+ return(-3);
262+ }
263+
264+ /* Print */
265+ switch(format)
266+ {
267+ case FORMAT_SCHEME:
268+ /* Prefix with freq to avoid name space collisions */
269+ printf("channel%d\n", channel);
270+ break;
271+ case FORMAT_RAW:
272+ printf("%d\n", channel);
273+ break;
274+ default:
275+ printf("%-8.16s Channel:%d\n", ifname, channel);
327276 break;
328277 }
329278
@@ -342,8 +291,7 @@ print_mode(int skfd,
342291 struct iwreq wrq;
343292
344293 /* Get frequency / channel */
345- strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
346- if(ioctl(skfd, SIOCGIWMODE, &wrq) < 0)
294+ if(iw_get_ext(skfd, ifname, SIOCGIWMODE, &wrq) < 0)
347295 return(-1);
348296 if(wrq.u.mode >= IW_NUM_OPER_MODE)
349297 return(-2);
@@ -352,10 +300,17 @@ print_mode(int skfd,
352300 switch(format)
353301 {
354302 case FORMAT_SCHEME:
303+ /* Strip all white space and stuff */
304+ if(wrq.u.mode == IW_MODE_ADHOC)
305+ printf("AdHoc\n");
306+ else
307+ printf("%s\n", iw_operation_mode[wrq.u.mode]);
308+ break;
309+ case FORMAT_RAW:
355310 printf("%d\n", wrq.u.mode);
356311 break;
357312 default:
358- printf("%-8.8s Mode:%s\n", ifname, iw_operation_mode[wrq.u.mode]);
313+ printf("%-8.16s Mode:%s\n", ifname, iw_operation_mode[wrq.u.mode]);
359314 break;
360315 }
361316
@@ -378,8 +333,7 @@ print_protocol(int skfd,
378333 unsigned int j;
379334
380335 /* Get Protocol name */
381- strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
382- if(ioctl(skfd, SIOCGIWNAME, &wrq) < 0)
336+ if(iw_get_ext(skfd, ifname, SIOCGIWNAME, &wrq) < 0)
383337 return(-1);
384338 strncpy(proto, wrq.u.name, IFNAMSIZ);
385339 proto[IFNAMSIZ] = '\0';
@@ -397,8 +351,11 @@ print_protocol(int skfd,
397351 return(-2);
398352 printf("%s\n", pproto);
399353 break;
354+ case FORMAT_RAW:
355+ printf("%s\n", proto);
356+ break;
400357 default:
401- printf("%-8.8s Protocol Name:\"%s\"\n", ifname, proto);
358+ printf("%-8.16s Protocol Name:\"%s\"\n", ifname, proto);
402359 break;
403360 }
404361
@@ -427,6 +384,11 @@ print_one_device(int skfd,
427384 ret = print_ap(skfd, ifname, format);
428385 break;
429386
387+ case WTYPE_CHANNEL:
388+ /* Try to print channel */
389+ ret = print_channel(skfd, ifname, format);
390+ break;
391+
430392 case WTYPE_FREQ:
431393 /* Try to print frequency */
432394 ret = print_freq(skfd, ifname, format);
@@ -458,6 +420,11 @@ print_one_device(int skfd,
458420 /*------------------------------------------------------------------*/
459421 /*
460422 * Try the various devices until one return something we can use
423+ *
424+ * Note : we can't use iw_enum_devices() because we want a different
425+ * behaviour :
426+ * 1) Stop at the first valid wireless device
427+ * 2) Only go through active devices
461428 */
462429 static int
463430 scan_devices(int skfd,
@@ -498,9 +465,11 @@ iw_usage(int status)
498465 fputs("Usage iwgetid [OPTIONS] [ifname]\n"
499466 " Options are:\n"
500467 " -a,--ap Print the access point address\n"
468+ " -c,--channel Print the current channel\n"
501469 " -f,--freq Print the current frequency\n"
502470 " -m,--mode Print the current mode\n"
503471 " -p,--protocol Print the protocol name\n"
472+ " -r,--raw Format the output as raw value for shell scripts\n"
504473 " -s,--scheme Format the output as a PCMCIA scheme identifier\n"
505474 " -h,--help Print this message\n",
506475 status ? stderr : stdout);
@@ -509,10 +478,12 @@ iw_usage(int status)
509478
510479 static const struct option long_opts[] = {
511480 { "ap", no_argument, NULL, 'a' },
481+ { "channel", no_argument, NULL, 'c' },
512482 { "freq", no_argument, NULL, 'f' },
513483 { "mode", no_argument, NULL, 'm' },
514484 { "protocol", no_argument, NULL, 'p' },
515485 { "help", no_argument, NULL, 'h' },
486+ { "raw", no_argument, NULL, 'r' },
516487 { "scheme", no_argument, NULL, 's' },
517488 { NULL, 0, NULL, 0 }
518489 };
@@ -532,7 +503,7 @@ main(int argc,
532503 int ret = -1;
533504
534505 /* Check command line arguments */
535- while((opt = getopt_long(argc, argv, "afhmps", long_opts, NULL)) > 0)
506+ while((opt = getopt_long(argc, argv, "acfhmprs", long_opts, NULL)) > 0)
536507 {
537508 switch(opt)
538509 {
@@ -541,6 +512,11 @@ main(int argc,
541512 wtype = WTYPE_AP;
542513 break;
543514
515+ case 'c':
516+ /* User wants channel only */
517+ wtype = WTYPE_CHANNEL;
518+ break;
519+
544520 case 'f':
545521 /* User wants frequency/channel */
546522 wtype = WTYPE_FREQ;
@@ -560,6 +536,11 @@ main(int argc,
560536 iw_usage(0);
561537 break;
562538
539+ case 'r':
540+ /* User wants a Raw format */
541+ format = FORMAT_RAW;
542+ break;
543+
563544 case 's':
564545 /* User wants a Scheme format */
565546 format = FORMAT_SCHEME;
@@ -595,6 +576,6 @@ main(int argc,
595576 }
596577
597578 fflush(stdout);
598- close(skfd);
579+ iw_sockets_close(skfd);
599580 return(ret);
600581 }
--- a/wireless_tools/iwlib.c
+++ b/wireless_tools/iwlib.c
@@ -1,12 +1,12 @@
11 /*
22 * Wireless Tools
33 *
4- * Jean II - HPLB 97->99 - HPL 99->03
4+ * Jean II - HPLB 97->99 - HPL 99->04
55 *
66 * Common subroutines to all the wireless tools...
77 *
88 * This file is released under the GPL license.
9- * Copyright (c) 1997-2003 Jean Tourrilhes <jt@hpl.hp.com>
9+ * Copyright (c) 1997-2004 Jean Tourrilhes <jt@hpl.hp.com>
1010 */
1111
1212 /***************************** INCLUDES *****************************/
@@ -15,40 +15,84 @@
1515
1616 /************************ CONSTANTS & MACROS ************************/
1717
18-/* Various versions information */
19-/* Recommended Wireless Extension version */
20-#define WE_VERSION 16 /* ### don't forget #warning ### */
21-/* Version of Wireless Tools */
22-#define WT_VERSION 26
18+/*
19+ * Constants fof WE-9->15
20+ */
21+#define IW15_MAX_FREQUENCIES 16
22+#define IW15_MAX_BITRATES 8
23+#define IW15_MAX_TXPOWER 8
24+#define IW15_MAX_ENCODING_SIZES 8
25+#define IW15_MAX_SPY 8
26+#define IW15_MAX_AP 8
27+
28+/****************************** TYPES ******************************/
2329
2430 /*
25- * Verify a few things about Wireless Extensions.
26- * I try to maximise backward and forward compatibility, but things are
27- * tricky because I'm fixing bugs and adding new features.
28- * Wireless Tools *must* be compiled with the same version of WE
29- * as the driver. Sometime, the size or layout of some structure changes,
30- * and might produce interesting results.
31- * Wireless Tools will usually compile properly against different
32- * versions of WE, thanks to the zillions of #ifdefs in my code.
33- * Jean II
31+ * Struct iw_range up to WE-15
3432 */
35-#if WIRELESS_EXT < 9
36-#error "Wireless Extension v9 or newer required :-("
37-#error "Use Wireless Tools v19 or update your kernel headers !"
38-#endif
39-#if WIRELESS_EXT < WE_VERSION && !defined(WEXT_HEADER)
40-#warning "Wireless Extension earlier than v16 detected,"
41-#warning "Not all tools features will be compiled in !"
42-#warning "No worry, I'll try to make the best of it ;-)"
43-#endif
44-#if WIRELESS_EXT > WE_VERSION && !defined(WEXT_HEADER)
45-#warning "Wireless Extension later than v16 detected,"
46-#warning "Maybe you should get a more recent version"
47-#warning "of the Wireless Tools package !"
48-#endif
33+struct iw15_range
34+{
35+ __u32 throughput;
36+ __u32 min_nwid;
37+ __u32 max_nwid;
38+ __u16 num_channels;
39+ __u8 num_frequency;
40+ struct iw_freq freq[IW15_MAX_FREQUENCIES];
41+ __s32 sensitivity;
42+ struct iw_quality max_qual;
43+ __u8 num_bitrates;
44+ __s32 bitrate[IW15_MAX_BITRATES];
45+ __s32 min_rts;
46+ __s32 max_rts;
47+ __s32 min_frag;
48+ __s32 max_frag;
49+ __s32 min_pmp;
50+ __s32 max_pmp;
51+ __s32 min_pmt;
52+ __s32 max_pmt;
53+ __u16 pmp_flags;
54+ __u16 pmt_flags;
55+ __u16 pm_capa;
56+ __u16 encoding_size[IW15_MAX_ENCODING_SIZES];
57+ __u8 num_encoding_sizes;
58+ __u8 max_encoding_tokens;
59+ __u16 txpower_capa;
60+ __u8 num_txpower;
61+ __s32 txpower[IW15_MAX_TXPOWER];
62+ __u8 we_version_compiled;
63+ __u8 we_version_source;
64+ __u16 retry_capa;
65+ __u16 retry_flags;
66+ __u16 r_time_flags;
67+ __s32 min_retry;
68+ __s32 max_retry;
69+ __s32 min_r_time;
70+ __s32 max_r_time;
71+ struct iw_quality avg_qual;
72+};
73+
74+/*
75+ * Union for all the versions of iwrange.
76+ * Fortunately, I mostly only add fields at the end, and big-bang
77+ * reorganisations are few.
78+ */
79+union iw_range_raw
80+{
81+ struct iw15_range range15; /* WE 9->15 */
82+ struct iw_range range; /* WE 16->current */
83+};
84+
85+/*
86+ * Offsets in iw_range struct
87+ */
88+#define iwr15_off(f) ( ((char *) &(((struct iw15_range *) NULL)->f)) - \
89+ (char *) NULL)
90+#define iwr_off(f) ( ((char *) &(((struct iw_range *) NULL)->f)) - \
91+ (char *) NULL)
4992
5093 /**************************** VARIABLES ****************************/
5194
95+/* Modes as human readable strings */
5296 const char * const iw_operation_mode[] = { "Auto",
5397 "Ad-Hoc",
5498 "Managed",
@@ -146,7 +190,7 @@ iw_get_ifname(char * name, /* Where to store the name */
146190 */
147191 void
148192 iw_enum_devices(int skfd,
149- iw_enum_handler fn,
193+ iw_enum_handler fn,
150194 char * args[],
151195 int count)
152196 {
@@ -217,77 +261,63 @@ iw_enum_devices(int skfd,
217261
218262 /*------------------------------------------------------------------*/
219263 /*
220- * Get the range information out of the driver
264+ * Extract WE version number from /proc/net/wireless
265+ * In most cases, you really want to get version information from
266+ * the range info (range->we_version_compiled), see below...
267+ *
268+ * If we have WE-16 and later, the WE version is available at the
269+ * end of the header line of the file.
270+ * For version prior to that, we can only detect the change from
271+ * v11 to v12, so we do an approximate job. Fortunately, v12 to v15
272+ * are highly binary compatible (on the struct level).
221273 */
222274 int
223-iw_get_range_info(int skfd,
224- char * ifname,
225- iwrange * range)
275+iw_get_kernel_we_version(void)
226276 {
227- struct iwreq wrq;
228- char buffer[sizeof(iwrange) * 2]; /* Large enough */
277+ char buff[1024];
278+ FILE * fh;
279+ char * p;
280+ int v;
229281
230- /* Cleanup */
231- memset(buffer, 0, sizeof(buffer));
282+ /* Check if /proc/net/wireless is available */
283+ fh = fopen(PROC_NET_WIRELESS, "r");
232284
233- wrq.u.data.pointer = (caddr_t) buffer;
234- wrq.u.data.length = sizeof(buffer);
235- wrq.u.data.flags = 0;
236- if(iw_get_ext(skfd, ifname, SIOCGIWRANGE, &wrq) < 0)
237- return(-1);
285+ if(fh == NULL)
286+ {
287+ fprintf(stderr, "Cannot read " PROC_NET_WIRELESS "\n");
288+ return(-1);
289+ }
238290
239- /* Copy stuff at the right place, ignore extra */
240- memcpy((char *) range, buffer, sizeof(iwrange));
291+ /* Read the first line of buffer */
292+ fgets(buff, sizeof(buff), fh);
241293
242- /* Lots of people have driver and tools out of sync as far as Wireless
243- * Extensions are concerned. It's because /usr/include/linux/wireless.h
244- * and /usr/src/linux/include/linux/wireless.h are different.
245- * We try to catch this stuff here... */
246- if(!iw_ignore_version)
294+ if(strstr(buff, "| WE") == NULL)
247295 {
248- /* For new versions, we can check the version directly, for old versions
249- * we use magic. 300 bytes is a also magic number, don't touch... */
250- if((WIRELESS_EXT > 10) && (wrq.u.data.length >= 300))
251- {
252-#if WIRELESS_EXT > 10
253- /* Version verification - for new versions */
254- if(range->we_version_compiled != WIRELESS_EXT)
255- {
256- fprintf(stderr, "Warning: Driver for device %s has been compiled with version %d\n", ifname, range->we_version_compiled);
257- fprintf(stderr, "of Wireless Extension, while this program is using version %d.\n", WIRELESS_EXT);
258- fprintf(stderr, "Some things may be broken...\n\n");
259- }
260- /* Driver version verification */
261- if(range->we_version_compiled < range->we_version_source)
262- {
263- fprintf(stderr, "Warning: Driver for device %s recommend version %d of Wireless Extension,\n", ifname, range->we_version_source);
264- fprintf(stderr, "but has been compiled with version %d, therefore some driver features\n", range->we_version_compiled);
265- fprintf(stderr, "may not be available...\n\n");
266- }
267-#endif /* WIRELESS_EXT > 10 */
268- }
296+ /* Prior to WE16, so explicit version not present */
297+
298+ /* Black magic */
299+ if(strstr(buff, "| Missed") == NULL)
300+ v = 11;
269301 else
270- {
271- /* Version verification - for old versions */
272- if(wrq.u.data.length != sizeof(iwrange))
273- {
274- fprintf(stderr, "Warning: Driver for device %s has been compiled with an ancient version\n", ifname);
275- fprintf(stderr, "of Wireless Extension, while this program is using version %d.\n", WIRELESS_EXT);
276- fprintf(stderr, "Some things may be broken...\n\n");
277- }
278- }
302+ v = 15;
303+ fclose(fh);
304+ return(v);
279305 }
280- /* Don't complain twice.
281- * In theory, the test apply to each individual driver, but usually
282- * all drivers are compiled from the same kernel, and most often
283- * problem is the system/glibc headers. */
284- iw_ignore_version = 1;
285306
286- /* Note : we are only trying to catch compile difference, not source.
287- * If the driver source has not been updated to the latest, it doesn't
288- * matter because the new fields are set to zero */
307+ /* Read the second line of buffer */
308+ fgets(buff, sizeof(buff), fh);
289309
290- return(0);
310+ /* Get to the last separator, to get the version */
311+ p = strrchr(buff, '|');
312+ if((p == NULL) || (sscanf(p + 1, "%d", &v) != 1))
313+ {
314+ fprintf(stderr, "Cannot parse " PROC_NET_WIRELESS "\n");
315+ fclose(fh);
316+ return(-1);
317+ }
318+
319+ fclose(fh);
320+ return(v);
291321 }
292322
293323 /*------------------------------------------------------------------*/
@@ -321,7 +351,7 @@ print_iface_version_info(int skfd,
321351 if(iw_get_ext(skfd, ifname, SIOCGIWRANGE, &wrq) < 0)
322352 {
323353 /* Interface support WE (see above), but not IWRANGE */
324- fprintf(stderr, "%-8.8s Driver has no Wireless Extension version information.\n\n", ifname);
354+ fprintf(stderr, "%-8.16s Driver has no Wireless Extension version information.\n\n", ifname);
325355 return(0);
326356 }
327357
@@ -330,21 +360,18 @@ print_iface_version_info(int skfd,
330360
331361 /* For new versions, we can check the version directly, for old versions
332362 * we use magic. 300 bytes is a also magic number, don't touch... */
333- if((WIRELESS_EXT > 10) && (wrq.u.data.length >= 300))
363+ if(wrq.u.data.length >= 300)
334364 {
335-#if WIRELESS_EXT > 10
336- printf("%-8.8s Recommend Wireless Extension v%d or later,\n",
365+ /* Version is always at the same offset, so it's ok */
366+ printf("%-8.16s Recommend Wireless Extension v%d or later,\n",
337367 ifname, range->we_version_source);
338368 printf(" Currently compiled with Wireless Extension v%d.\n\n",
339369 range->we_version_compiled);
340-#endif /* WIRELESS_EXT > 10 */
341370 }
342371 else
343372 {
344-#if 0
345- fprintf(stderr, "%-8.8s Wireless Extension version too old.\n\n",
373+ fprintf(stderr, "%-8.16s Wireless Extension version too old.\n\n",
346374 ifname);
347-#endif
348375 }
349376
350377
@@ -356,13 +383,10 @@ print_iface_version_info(int skfd,
356383 * Print the WE versions of the tools.
357384 */
358385 int
359-iw_print_version_info(char * toolname)
386+iw_print_version_info(const char * toolname)
360387 {
361388 int skfd; /* generic raw socket desc. */
362- char buff[1024];
363- FILE * fh;
364- char * p;
365- int v;
389+ int we_kernel_version;
366390
367391 /* Create a channel to the NET kernel. */
368392 if((skfd = iw_sockets_open()) < 0)
@@ -373,64 +397,214 @@ iw_print_version_info(char * toolname)
373397
374398 /* Information about the tools themselves */
375399 if(toolname != NULL)
376- printf("%-8.8s Version %d\n", toolname, WT_VERSION);
377- printf(" Compatible with Wireless Extension v%d or earlier,\n",
400+ printf("%-8.16s Wireless-Tools version %d\n", toolname, WT_VERSION);
401+ printf(" Compatible with Wireless Extension v11 to v%d.\n\n",
378402 WE_VERSION);
379- printf(" Currently compiled with Wireless Extension v%d.\n\n",
380- WIRELESS_EXT);
381403
382- /* Check if /proc/net/wireless is available */
383- fh = fopen(PROC_NET_WIRELESS, "r");
384- if(fh != NULL)
404+ /* Get version from kernel */
405+ we_kernel_version = iw_get_kernel_we_version();
406+ /* Only version >= 16 can be verified, other are guessed */
407+ if(we_kernel_version > 15)
408+ printf("Kernel Currently compiled with Wireless Extension v%d.\n\n",
409+ we_kernel_version);
410+
411+ /* Version for each device */
412+ iw_enum_devices(skfd, &print_iface_version_info, NULL, 0);
413+
414+ iw_sockets_close(skfd);
415+
416+ return 0;
417+}
418+
419+/*------------------------------------------------------------------*/
420+/*
421+ * Get the range information out of the driver
422+ */
423+int
424+iw_get_range_info(int skfd,
425+ const char * ifname,
426+ iwrange * range)
427+{
428+ struct iwreq wrq;
429+ char buffer[sizeof(iwrange) * 2]; /* Large enough */
430+ union iw_range_raw * range_raw;
431+
432+ /* Cleanup */
433+ bzero(buffer, sizeof(buffer));
434+
435+ wrq.u.data.pointer = (caddr_t) buffer;
436+ wrq.u.data.length = sizeof(buffer);
437+ wrq.u.data.flags = 0;
438+ if(iw_get_ext(skfd, ifname, SIOCGIWRANGE, &wrq) < 0)
439+ return(-1);
440+
441+ /* Point to the buffer */
442+ range_raw = (union iw_range_raw *) buffer;
443+
444+ /* For new versions, we can check the version directly, for old versions
445+ * we use magic. 300 bytes is a also magic number, don't touch... */
446+ if(wrq.u.data.length < 300)
385447 {
386- /* Read the first line of buffer */
387- fgets(buff, sizeof(buff), fh);
448+ /* That's v10 or earlier. Ouch ! Let's make a guess...*/
449+ range_raw->range.we_version_compiled = 9;
450+ }
451+
452+ /* Check how it needs to be processed */
453+ if(range_raw->range.we_version_compiled > 15)
454+ {
455+ /* This is our native format, that's easy... */
456+ /* Copy stuff at the right place, ignore extra */
457+ memcpy((char *) range, buffer, sizeof(iwrange));
458+ }
459+ else
460+ {
461+ /* Zero unknown fields */
462+ bzero((char *) range, sizeof(struct iw_range));
463+
464+ /* Initial part unmoved */
465+ memcpy((char *) range,
466+ buffer,
467+ iwr15_off(num_channels));
468+ /* Frequencies pushed futher down towards the end */
469+ memcpy((char *) range + iwr_off(num_channels),
470+ buffer + iwr15_off(num_channels),
471+ iwr15_off(sensitivity) - iwr15_off(num_channels));
472+ /* This one moved up */
473+ memcpy((char *) range + iwr_off(sensitivity),
474+ buffer + iwr15_off(sensitivity),
475+ iwr15_off(num_bitrates) - iwr15_off(sensitivity));
476+ /* This one goes after avg_qual */
477+ memcpy((char *) range + iwr_off(num_bitrates),
478+ buffer + iwr15_off(num_bitrates),
479+ iwr15_off(min_rts) - iwr15_off(num_bitrates));
480+ /* Number of bitrates has changed, put it after */
481+ memcpy((char *) range + iwr_off(min_rts),
482+ buffer + iwr15_off(min_rts),
483+ iwr15_off(txpower_capa) - iwr15_off(min_rts));
484+ /* Added encoding_login_index, put it after */
485+ memcpy((char *) range + iwr_off(txpower_capa),
486+ buffer + iwr15_off(txpower_capa),
487+ iwr15_off(txpower) - iwr15_off(txpower_capa));
488+ /* Hum... That's an unexpected glitch. Bummer. */
489+ memcpy((char *) range + iwr_off(txpower),
490+ buffer + iwr15_off(txpower),
491+ iwr15_off(avg_qual) - iwr15_off(txpower));
492+ /* Avg qual moved up next to max_qual */
493+ memcpy((char *) range + iwr_off(avg_qual),
494+ buffer + iwr15_off(avg_qual),
495+ sizeof(struct iw_quality));
496+ }
388497
389- /* Check if it's WE-16 or later */
390- if(strstr(buff, "| WE") != NULL)
498+ /* We are now checking much less than we used to do, because we can
499+ * accomodate more WE version. But, there are still cases where things
500+ * will break... */
501+ if(!iw_ignore_version)
502+ {
503+ /* We don't like very old version (unfortunately kernel 2.2.X) */
504+ if(range->we_version_compiled <= 10)
391505 {
392- /* Read the second line of buffer */
393- fgets(buff, sizeof(buff), fh);
394-
395- /* Get to the last separator, to get the version */
396- p = strrchr(buff, '|');
397- if((p != NULL) && (sscanf(p + 1, "%d", &v) == 1))
398- /* That was it ! */
399- printf("Kernel Currently compiled with Wireless Extension v%d.\n\n", v);
506+ fprintf(stderr, "Warning: Driver for device %s has been compiled with an ancient version\n", ifname);
507+ fprintf(stderr, "of Wireless Extension, while this program support version 11 and later.\n");
508+ fprintf(stderr, "Some things may be broken...\n\n");
400509 }
401- /* Cleanup */
402- fclose(fh);
403- }
404510
405- /* Version for each device */
406- iw_enum_devices(skfd, &print_iface_version_info, NULL, 0);
511+ /* We don't like future versions of WE, because we can't cope with
512+ * the unknown */
513+ if(range->we_version_compiled > WE_VERSION)
514+ {
515+ fprintf(stderr, "Warning: Driver for device %s has been compiled with version %d\n", ifname, range->we_version_compiled);
516+ fprintf(stderr, "of Wireless Extension, while this program supports up to version %d.\n", WE_VERSION);
517+ fprintf(stderr, "Some things may be broken...\n\n");
518+ }
407519
408- close(skfd);
520+ /* Driver version verification */
521+ if((range->we_version_compiled > 10) &&
522+ (range->we_version_compiled < range->we_version_source))
523+ {
524+ fprintf(stderr, "Warning: Driver for device %s recommend version %d of Wireless Extension,\n", ifname, range->we_version_source);
525+ fprintf(stderr, "but has been compiled with version %d, therefore some driver features\n", range->we_version_compiled);
526+ fprintf(stderr, "may not be available...\n\n");
527+ }
528+ /* Note : we are only trying to catch compile difference, not source.
529+ * If the driver source has not been updated to the latest, it doesn't
530+ * matter because the new fields are set to zero */
531+ }
409532
410- return 0;
533+ /* Don't complain twice.
534+ * In theory, the test apply to each individual driver, but usually
535+ * all drivers are compiled from the same kernel. */
536+ iw_ignore_version = 1;
537+
538+ return(0);
411539 }
412540
413541 /*------------------------------------------------------------------*/
414542 /*
415543 * Get information about what private ioctls are supported by the driver
544+ *
545+ * Note : there is one danger using this function. If it return 0, you
546+ * still need to free() the buffer. Beware.
416547 */
417548 int
418549 iw_get_priv_info(int skfd,
419- char * ifname,
420- iwprivargs * priv,
421- int maxpriv)
550+ const char * ifname,
551+ iwprivargs ** ppriv)
422552 {
423553 struct iwreq wrq;
554+ iwprivargs * priv = NULL; /* Not allocated yet */
555+ int maxpriv = 16; /* Minimum for compatibility WE<13 */
556+ iwprivargs * newpriv;
557+
558+ /* Some driver may return a very large number of ioctls. Some
559+ * others a very small number. We now use a dynamic allocation
560+ * of the array to satisfy everybody. Of course, as we don't know
561+ * in advance the size of the array, we try various increasing
562+ * sizes. Jean II */
563+ do
564+ {
565+ /* (Re)allocate the buffer */
566+ newpriv = realloc(priv, maxpriv * sizeof(priv[0]));
567+ if(newpriv == NULL)
568+ {
569+ fprintf(stderr, "%s: Allocation failed\n", __FUNCTION__);
570+ break;
571+ }
572+ priv = newpriv;
424573
425- /* Ask the driver */
426- wrq.u.data.pointer = (caddr_t) priv;
427- wrq.u.data.length = maxpriv;
428- wrq.u.data.flags = 0;
429- if(iw_get_ext(skfd, ifname, SIOCGIWPRIV, &wrq) < 0)
430- return(-1);
574+ /* Ask the driver if it's large enough */
575+ wrq.u.data.pointer = (caddr_t) priv;
576+ wrq.u.data.length = maxpriv;
577+ wrq.u.data.flags = 0;
578+ if(iw_get_ext(skfd, ifname, SIOCGIWPRIV, &wrq) >= 0)
579+ {
580+ /* Success. Pass the buffer by pointer */
581+ *ppriv = priv;
582+ /* Return the number of ioctls */
583+ return(wrq.u.data.length);
584+ }
585+
586+ /* Only E2BIG means the buffer was too small, abort on other errors */
587+ if(errno != E2BIG)
588+ {
589+ /* Most likely "not supported". Don't barf. */
590+ break;
591+ }
431592
432- /* Return the number of ioctls */
433- return(wrq.u.data.length);
593+ /* Failed. We probably need a bigger buffer. Check if the kernel
594+ * gave us any hints. */
595+ if(wrq.u.data.length > maxpriv)
596+ maxpriv = wrq.u.data.length;
597+ else
598+ maxpriv *= 2;
599+ }
600+ while(maxpriv < 1000);
601+
602+ /* Cleanup */
603+ if(priv)
604+ free(priv);
605+ *ppriv = NULL;
606+
607+ return(-1);
434608 }
435609
436610 /*------------------------------------------------------------------*/
@@ -443,7 +617,7 @@ iw_get_priv_info(int skfd,
443617 */
444618 int
445619 iw_get_basic_config(int skfd,
446- char * ifname,
620+ const char * ifname,
447621 wireless_config * info)
448622 {
449623 struct iwreq wrq;
@@ -472,6 +646,7 @@ iw_get_basic_config(int skfd,
472646 {
473647 info->has_freq = 1;
474648 info->freq = iw_freq2float(&(wrq.u.freq));
649+ info->freq_flags = wrq.u.freq.flags;
475650 }
476651
477652 /* Get encryption information */
@@ -499,7 +674,7 @@ iw_get_basic_config(int skfd,
499674 if(iw_get_ext(skfd, ifname, SIOCGIWMODE, &wrq) >= 0)
500675 {
501676 info->mode = wrq.u.mode;
502- if((info->mode < 6) && (info->mode >= 0))
677+ if((info->mode < IW_NUM_OPER_MODE) && (info->mode >= 0))
503678 info->has_mode = 1;
504679 }
505680
@@ -515,7 +690,7 @@ iw_get_basic_config(int skfd,
515690 */
516691 int
517692 iw_set_basic_config(int skfd,
518- char * ifname,
693+ const char * ifname,
519694 wireless_config * info)
520695 {
521696 struct iwreq wrq;
@@ -526,15 +701,18 @@ iw_set_basic_config(int skfd,
526701 /* If no wireless name : no wireless extensions */
527702 return(-2);
528703
529- /* Set Network ID, if available (this is for non-802.11 cards) */
530- if(info->has_nwid)
704+ /* Set the current mode of operation
705+ * Mode need to be first : some settings apply only in a specific mode
706+ * (such as frequency).
707+ */
708+ if(info->has_mode)
531709 {
532- memcpy(&(wrq.u.nwid), &(info->nwid), sizeof(iwparam));
533- wrq.u.nwid.fixed = 1; /* Hum... When in Rome... */
710+ strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
711+ wrq.u.mode = info->mode;
534712
535- if(iw_set_ext(skfd, ifname, SIOCSIWNWID, &wrq) < 0)
713+ if(iw_get_ext(skfd, ifname, SIOCSIWMODE, &wrq) < 0)
536714 {
537- fprintf(stderr, "SIOCSIWNWID: %s\n", strerror(errno));
715+ fprintf(stderr, "SIOCSIWMODE: %s\n", strerror(errno));
538716 ret = -1;
539717 }
540718 }
@@ -580,6 +758,10 @@ iw_set_basic_config(int skfd,
580758 wrq.u.data.length = info->key_size;
581759 wrq.u.data.flags = flags;
582760
761+ /* Compatibility with WE<13 */
762+ if(flags & IW_ENCODE_NOKEY)
763+ wrq.u.data.pointer = NULL;
764+
583765 if(iw_set_ext(skfd, ifname, SIOCSIWENCODE, &wrq) < 0)
584766 {
585767 fprintf(stderr, "SIOCSIWENCODE(%d): %s\n",
@@ -588,29 +770,33 @@ iw_set_basic_config(int skfd,
588770 }
589771 }
590772
591- /* Set ESSID (extended network), if available */
592- if(info->has_essid)
773+ /* Set Network ID, if available (this is for non-802.11 cards) */
774+ if(info->has_nwid)
593775 {
594- wrq.u.essid.pointer = (caddr_t) info->essid;
595- wrq.u.essid.length = strlen(info->essid) + 1;
596- wrq.u.data.flags = info->essid_on;
776+ memcpy(&(wrq.u.nwid), &(info->nwid), sizeof(iwparam));
777+ wrq.u.nwid.fixed = 1; /* Hum... When in Rome... */
597778
598- if(iw_set_ext(skfd, ifname, SIOCSIWESSID, &wrq) < 0)
779+ if(iw_set_ext(skfd, ifname, SIOCSIWNWID, &wrq) < 0)
599780 {
600- fprintf(stderr, "SIOCSIWESSID: %s\n", strerror(errno));
781+ fprintf(stderr, "SIOCSIWNWID: %s\n", strerror(errno));
601782 ret = -1;
602783 }
603784 }
604785
605- /* Set the current mode of operation */
606- if(info->has_mode)
786+ /* Set ESSID (extended network), if available.
787+ * ESSID need to be last : most device re-perform the scanning/discovery
788+ * when this is set, and things like encryption keys are better be
789+ * defined if we want to discover the right set of APs/nodes.
790+ */
791+ if(info->has_essid)
607792 {
608- strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
609- wrq.u.mode = info->mode;
793+ wrq.u.essid.pointer = (caddr_t) info->essid;
794+ wrq.u.essid.length = strlen(info->essid) + 1;
795+ wrq.u.data.flags = info->essid_on;
610796
611- if(iw_get_ext(skfd, ifname, SIOCSIWMODE, &wrq) < 0)
797+ if(iw_set_ext(skfd, ifname, SIOCSIWESSID, &wrq) < 0)
612798 {
613- fprintf(stderr, "SIOCSIWMODE: %s\n", strerror(errno));
799+ fprintf(stderr, "SIOCSIWESSID: %s\n", strerror(errno));
614800 ret = -1;
615801 }
616802 }
@@ -632,14 +818,15 @@ iw_set_basic_config(int skfd,
632818 * but if they interoperate at some level, and also if they accept the
633819 * same type of config (ESSID vs NWID, freq...).
634820 * This is supposed to work around the alphabet soup.
635- * Return 1 if protocols are compatible
821+ * Return 1 if protocols are compatible, 0 otherwise
636822 */
637823 int
638-iw_protocol_compare(char * protocol1,
639- char * protocol2)
824+iw_protocol_compare(const char * protocol1,
825+ const char * protocol2)
640826 {
641- char * dot11 = "IEEE 802.11";
642- char * dot11_ds = "Dbg";
827+ const char * dot11 = "IEEE 802.11";
828+ const char * dot11_ds = "Dbg";
829+ const char * dot11_5g = "a";
643830
644831 /* If the strings are the same -> easy */
645832 if(!strncmp(protocol1, protocol2, IFNAMSIZ))
@@ -649,18 +836,34 @@ iw_protocol_compare(char * protocol1,
649836 if( (!strncmp(protocol1, dot11, strlen(dot11))) &&
650837 (!strncmp(protocol2, dot11, strlen(dot11))) )
651838 {
652- char * sub1 = protocol1 + strlen(dot11);
653- char * sub2 = protocol2 + strlen(dot11);
654-
655- /* Skip optional separator */
656- if(*sub1 == '-')
657- sub1++;
658- if(*sub2 == '-')
659- sub2++;
839+ const char * sub1 = protocol1 + strlen(dot11);
840+ const char * sub2 = protocol2 + strlen(dot11);
841+ unsigned int i;
842+ int isds1 = 0;
843+ int isds2 = 0;
844+ int is5g1 = 0;
845+ int is5g2 = 0;
846+
847+ /* Check if we find the magic letters telling it's DS compatible */
848+ for(i = 0; i < strlen(dot11_ds); i++)
849+ {
850+ if(strchr(sub1, dot11_ds[i]) != NULL)
851+ isds1 = 1;
852+ if(strchr(sub2, dot11_ds[i]) != NULL)
853+ isds2 = 1;
854+ }
855+ if(isds1 && isds2)
856+ return(1);
660857
661- /* Check if they are both 2.4 GHz Direct Sequence compatible */
662- if( (strchr(dot11_ds, *sub1) != NULL) &&
663- (strchr(dot11_ds, *sub2) != NULL) )
858+ /* Check if we find the magic letters telling it's 5GHz compatible */
859+ for(i = 0; i < strlen(dot11_5g); i++)
860+ {
861+ if(strchr(sub1, dot11_5g[i]) != NULL)
862+ is5g1 = 1;
863+ if(strchr(sub2, dot11_5g[i]) != NULL)
864+ is5g2 = 1;
865+ }
866+ if(is5g1 && is5g2)
664867 return(1);
665868 }
666869 /* Not compatible */
@@ -718,7 +921,7 @@ iw_float2freq(double in,
718921 * Convert our internal representation of frequencies to a floating point.
719922 */
720923 double
721-iw_freq2float(iwfreq * in)
924+iw_freq2float(const iwfreq * in)
722925 {
723926 #ifdef WE_NOLIBM
724927 /* Version without libm : slower */
@@ -738,22 +941,67 @@ iw_freq2float(iwfreq * in)
738941 * Output a frequency with proper scaling
739942 */
740943 void
741-iw_print_freq(char * buffer,
742- double freq)
944+iw_print_freq_value(char * buffer,
945+ int buflen,
946+ double freq)
743947 {
744948 if(freq < KILO)
745- sprintf(buffer, "Channel:%g", freq);
949+ snprintf(buffer, buflen, "%g", freq);
746950 else
747951 {
952+ char scale;
953+ int divisor;
954+
748955 if(freq >= GIGA)
749- sprintf(buffer, "Frequency:%gGHz", freq / GIGA);
956+ {
957+ scale = 'G';
958+ divisor = GIGA;
959+ }
750960 else
751961 {
752962 if(freq >= MEGA)
753- sprintf(buffer, "Frequency:%gMHz", freq / MEGA);
963+ {
964+ scale = 'M';
965+ divisor = MEGA;
966+ }
754967 else
755- sprintf(buffer, "Frequency:%gkHz", freq / KILO);
968+ {
969+ scale = 'k';
970+ divisor = KILO;
971+ }
756972 }
973+ snprintf(buffer, buflen, "%g %cHz", freq / divisor, scale);
974+ }
975+}
976+
977+/*------------------------------------------------------------------*/
978+/*
979+ * Output a frequency with proper scaling
980+ */
981+void
982+iw_print_freq(char * buffer,
983+ int buflen,
984+ double freq,
985+ int channel,
986+ int freq_flags)
987+{
988+ char sep = ((freq_flags & IW_FREQ_FIXED) ? '=' : ':');
989+ char vbuf[16];
990+
991+ /* Print the frequency/channel value */
992+ iw_print_freq_value(vbuf, sizeof(vbuf), freq);
993+
994+ /* Check if channel only */
995+ if(freq < KILO)
996+ snprintf(buffer, buflen, "Channel%c%s", sep, vbuf);
997+ else
998+ {
999+ /* Frequency. Check if we have a channel as well */
1000+ if(channel >= 0)
1001+ snprintf(buffer, buflen, "Frequency%c%s (Channel %d)",
1002+ sep, vbuf, channel);
1003+ else
1004+ snprintf(buffer, buflen, "Frequency%c%s", sep, vbuf);
7571005 }
7581006 }
7591007
@@ -762,8 +1010,8 @@ iw_print_freq(char * buffer,
7621010 * Convert a frequency to a channel (negative -> error)
7631011 */
7641012 int
765-iw_freq_to_channel(double freq,
766- struct iw_range * range)
1013+iw_freq_to_channel(double freq,
1014+ const struct iw_range * range)
7671015 {
7681016 double ref_freq;
7691017 int k;
@@ -784,6 +1032,41 @@ iw_freq_to_channel(double freq,
7841032 return(-2);
7851033 }
7861034
1035+/*------------------------------------------------------------------*/
1036+/*
1037+ * Convert a channel to a frequency (negative -> error)
1038+ * Return the channel on success
1039+ */
1040+int
1041+iw_channel_to_freq(int channel,
1042+ double * pfreq,
1043+ const struct iw_range * range)
1044+{
1045+ int has_freq = 0;
1046+ int k;
1047+
1048+ /* Check if the driver support only channels or if it has frequencies */
1049+ for(k = 0; k < range->num_frequency; k++)
1050+ {
1051+ if((range->freq[k].e != 0) || (range->freq[k].m > (int) KILO))
1052+ has_freq = 1;
1053+ }
1054+ if(!has_freq)
1055+ return(-1);
1056+
1057+ /* Find the correct frequency in the list */
1058+ for(k = 0; k < range->num_frequency; k++)
1059+ {
1060+ if(range->freq[k].i == channel)
1061+ {
1062+ *pfreq = iw_freq2float(&(range->freq[k]));
1063+ return(channel);
1064+ }
1065+ }
1066+ /* Not found */
1067+ return(-2);
1068+}
1069+
7871070 /*********************** BITRATE SUBROUTINES ***********************/
7881071
7891072 /*------------------------------------------------------------------*/
@@ -792,17 +1075,32 @@ iw_freq_to_channel(double freq,
7921075 */
7931076 void
7941077 iw_print_bitrate(char * buffer,
1078+ int buflen,
7951079 int bitrate)
7961080 {
7971081 double rate = bitrate;
1082+ char scale;
1083+ int divisor;
7981084
7991085 if(rate >= GIGA)
800- sprintf(buffer, "%gGb/s", rate / GIGA);
1086+ {
1087+ scale = 'G';
1088+ divisor = GIGA;
1089+ }
8011090 else
802- if(rate >= MEGA)
803- sprintf(buffer, "%gMb/s", rate / MEGA);
804- else
805- sprintf(buffer, "%gkb/s", rate / KILO);
1091+ {
1092+ if(rate >= MEGA)
1093+ {
1094+ scale = 'M';
1095+ divisor = MEGA;
1096+ }
1097+ else
1098+ {
1099+ scale = 'k';
1100+ divisor = KILO;
1101+ }
1102+ }
1103+ snprintf(buffer, buflen, "%g %cb/s", rate / divisor, scale);
8061104 }
8071105
8081106 /************************ POWER SUBROUTINES *************************/
@@ -863,6 +1161,43 @@ iw_mwatt2dbm(int in)
8631161 #endif /* WE_NOLIBM */
8641162 }
8651163
1164+/*------------------------------------------------------------------*/
1165+/*
1166+ * Output a txpower with proper conversion
1167+ */
1168+void
1169+iw_print_txpower(char * buffer,
1170+ int buflen,
1171+ struct iw_param * txpower)
1172+{
1173+ int dbm;
1174+
1175+ /* Check if disabled */
1176+ if(txpower->disabled)
1177+ {
1178+ snprintf(buffer, buflen, "off");
1179+ }
1180+ else
1181+ {
1182+ /* Check for relative values */
1183+ if(txpower->flags & IW_TXPOW_RELATIVE)
1184+ {
1185+ snprintf(buffer, buflen, "%d", txpower->value);
1186+ }
1187+ else
1188+ {
1189+ /* Convert everything to dBm */
1190+ if(txpower->flags & IW_TXPOW_MWATT)
1191+ dbm = iw_mwatt2dbm(txpower->value);
1192+ else
1193+ dbm = txpower->value;
1194+
1195+ /* Display */
1196+ snprintf(buffer, buflen, "%d dBm", dbm);
1197+ }
1198+ }
1199+}
1200+
8661201 /********************** STATISTICS SUBROUTINES **********************/
8671202
8681203 /*------------------------------------------------------------------*/
@@ -870,76 +1205,84 @@ iw_mwatt2dbm(int in)
8701205 * Read /proc/net/wireless to get the latest statistics
8711206 */
8721207 int
873-iw_get_stats(int skfd,
874- char * ifname,
875- iwstats * stats)
1208+iw_get_stats(int skfd,
1209+ const char * ifname,
1210+ iwstats * stats,
1211+ const iwrange * range,
1212+ int has_range)
8761213 {
877-#if WIRELESS_EXT > 11
878- struct iwreq wrq;
879- wrq.u.data.pointer = (caddr_t) stats;
880- wrq.u.data.length = 0;
881- wrq.u.data.flags = 1; /* Clear updated flag */
882- strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
883- if(iw_get_ext(skfd, ifname, SIOCGIWSTATS, &wrq) < 0)
884- return(-1);
1214+ /* Fortunately, we can always detect this condition properly */
1215+ if((has_range) && (range->we_version_compiled > 11))
1216+ {
1217+ struct iwreq wrq;
1218+ wrq.u.data.pointer = (caddr_t) stats;
1219+ wrq.u.data.length = sizeof(struct iw_statistics);
1220+ wrq.u.data.flags = 1; /* Clear updated flag */
1221+ strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
1222+ if(iw_get_ext(skfd, ifname, SIOCGIWSTATS, &wrq) < 0)
1223+ return(-1);
8851224
886- return(0);
887-#else /* WIRELESS_EXT > 11 */
888- FILE * f = fopen(PROC_NET_WIRELESS, "r");
889- char buf[256];
890- char * bp;
891- int t;
892- skfd = skfd; /* Avoid "Unused parameter" warning */
893- if(f==NULL)
894- return -1;
895- /* Loop on all devices */
896- while(fgets(buf,255,f))
897- {
898- bp=buf;
899- while(*bp&&isspace(*bp))
900- bp++;
901- /* Is it the good device ? */
902- if(strncmp(bp,ifname,strlen(ifname))==0 && bp[strlen(ifname)]==':')
903- {
904- /* Skip ethX: */
905- bp=strchr(bp,':');
906- bp++;
907- /* -- status -- */
908- bp = strtok(bp, " ");
909- sscanf(bp, "%X", &t);
910- stats->status = (unsigned short) t;
911- /* -- link quality -- */
912- bp = strtok(NULL, " ");
913- if(strchr(bp,'.') != NULL)
914- stats->qual.updated |= 1;
915- sscanf(bp, "%d", &t);
916- stats->qual.qual = (unsigned char) t;
917- /* -- signal level -- */
918- bp = strtok(NULL, " ");
919- if(strchr(bp,'.') != NULL)
920- stats->qual.updated |= 2;
921- sscanf(bp, "%d", &t);
922- stats->qual.level = (unsigned char) t;
923- /* -- noise level -- */
924- bp = strtok(NULL, " ");
925- if(strchr(bp,'.') != NULL)
926- stats->qual.updated += 4;
927- sscanf(bp, "%d", &t);
928- stats->qual.noise = (unsigned char) t;
929- /* -- discarded packets -- */
930- bp = strtok(NULL, " ");
931- sscanf(bp, "%d", &stats->discard.nwid);
932- bp = strtok(NULL, " ");
933- sscanf(bp, "%d", &stats->discard.code);
934- bp = strtok(NULL, " ");
935- sscanf(bp, "%d", &stats->discard.misc);
936- fclose(f);
937- return 0;
938- }
939- }
940- fclose(f);
941- return -1;
942-#endif /* WIRELESS_EXT > 11 */
1225+ /* Format has not changed since WE-12, no conversion */
1226+ return(0);
1227+ }
1228+ else
1229+ {
1230+ FILE * f = fopen(PROC_NET_WIRELESS, "r");
1231+ char buf[256];
1232+ char * bp;
1233+ int t;
1234+
1235+ if(f==NULL)
1236+ return -1;
1237+ /* Loop on all devices */
1238+ while(fgets(buf,255,f))
1239+ {
1240+ bp=buf;
1241+ while(*bp&&isspace(*bp))
1242+ bp++;
1243+ /* Is it the good device ? */
1244+ if(strncmp(bp,ifname,strlen(ifname))==0 && bp[strlen(ifname)]==':')
1245+ {
1246+ /* Skip ethX: */
1247+ bp=strchr(bp,':');
1248+ bp++;
1249+ /* -- status -- */
1250+ bp = strtok(bp, " ");
1251+ sscanf(bp, "%X", &t);
1252+ stats->status = (unsigned short) t;
1253+ /* -- link quality -- */
1254+ bp = strtok(NULL, " ");
1255+ if(strchr(bp,'.') != NULL)
1256+ stats->qual.updated |= 1;
1257+ sscanf(bp, "%d", &t);
1258+ stats->qual.qual = (unsigned char) t;
1259+ /* -- signal level -- */
1260+ bp = strtok(NULL, " ");
1261+ if(strchr(bp,'.') != NULL)
1262+ stats->qual.updated |= 2;
1263+ sscanf(bp, "%d", &t);
1264+ stats->qual.level = (unsigned char) t;
1265+ /* -- noise level -- */
1266+ bp = strtok(NULL, " ");
1267+ if(strchr(bp,'.') != NULL)
1268+ stats->qual.updated += 4;
1269+ sscanf(bp, "%d", &t);
1270+ stats->qual.noise = (unsigned char) t;
1271+ /* -- discarded packets -- */
1272+ bp = strtok(NULL, " ");
1273+ sscanf(bp, "%d", &stats->discard.nwid);
1274+ bp = strtok(NULL, " ");
1275+ sscanf(bp, "%d", &stats->discard.code);
1276+ bp = strtok(NULL, " ");
1277+ sscanf(bp, "%d", &stats->discard.misc);
1278+ fclose(f);
1279+ /* No conversion needed */
1280+ return 0;
1281+ }
1282+ }
1283+ fclose(f);
1284+ return -1;
1285+ }
9431286 }
9441287
9451288 /*------------------------------------------------------------------*/
@@ -948,40 +1291,99 @@ iw_get_stats(int skfd,
9481291 */
9491292 void
9501293 iw_print_stats(char * buffer,
951- iwqual * qual,
952- iwrange * range,
1294+ int buflen,
1295+ const iwqual * qual,
1296+ const iwrange * range,
9531297 int has_range)
9541298 {
1299+ int len;
1300+
1301+ /* People are very often confused by the 8 bit arithmetic happening
1302+ * here.
1303+ * All the values here are encoded in a 8 bit integer. 8 bit integers
1304+ * are either unsigned [0 ; 255], signed [-128 ; +127] or
1305+ * negative [-255 ; 0].
1306+ * Further, on 8 bits, 0x100 == 256 == 0.
1307+ *
1308+ * Relative/percent values are always encoded unsigned, between 0 and 255.
1309+ * Absolute/dBm values are always encoded negative, between -255 and 0.
1310+ *
1311+ * How do we separate relative from absolute values ? We use the
1312+ * range to do that. The range allow to specify the real min/max
1313+ * of the value. As the range struct only specify one bound of the
1314+ * value, we assume that the other bound is 0 (zero).
1315+ * For relative values, range is [0 ; range->max].
1316+ * For absolute values, range is [range->max ; 0].
1317+ *
1318+ * Let's take two example :
1319+ * 1) value is 75%. qual->value = 75 ; range->max_qual.value = 100
1320+ * 2) value is -54dBm. noise floor of the radio is -104dBm.
1321+ * qual->value = -54 = 202 ; range->max_qual.value = -104 = 152
1322+ *
1323+ * Jean II
1324+ */
1325+
9551326 /* Just do it */
9561327 if(has_range && (qual->level != 0))
9571328 {
958- /* If the statistics are in dBm */
1329+ /* Deal with quality : always a relative value */
1330+ if(!(qual->updated & IW_QUAL_QUAL_INVALID))
1331+ {
1332+ len = snprintf(buffer, buflen, "Quality%c%d/%d ",
1333+ qual->updated & IW_QUAL_QUAL_UPDATED ? '=' : ':',
1334+ qual->qual, range->max_qual.qual);
1335+ buffer += len;
1336+ buflen -= len;
1337+ }
1338+
1339+ /* If the statistics are in dBm or relative */
9591340 if(qual->level > range->max_qual.level)
9601341 {
961- /* Statistics are in dBm (absolute power measurement) */
962- sprintf(buffer,
963- "Quality:%d/%d Signal level:%d dBm Noise level:%d dBm%s",
964- qual->qual, range->max_qual.qual,
965- qual->level - 0x100, qual->noise - 0x100,
966- (qual->updated & 0x7) ? " (updated)" : "");
1342+ /* Deal with signal level in dBm (absolute power measurement) */
1343+ if(!(qual->updated & IW_QUAL_LEVEL_INVALID))
1344+ {
1345+ len = snprintf(buffer, buflen, "Signal level%c%d dBm ",
1346+ qual->updated & IW_QUAL_LEVEL_UPDATED ? '=' : ':',
1347+ qual->level - 0x100);
1348+ buffer += len;
1349+ buflen -= len;
1350+ }
1351+
1352+ /* Deal with noise level in dBm (absolute power measurement) */
1353+ if(!(qual->updated & IW_QUAL_NOISE_INVALID))
1354+ {
1355+ len = snprintf(buffer, buflen, "Noise level%c%d dBm",
1356+ qual->updated & IW_QUAL_NOISE_UPDATED ? '=' : ':',
1357+ qual->noise - 0x100);
1358+ }
9671359 }
9681360 else
9691361 {
970- /* Statistics are relative values (0 -> max) */
971- sprintf(buffer,
972- "Quality:%d/%d Signal level:%d/%d Noise level:%d/%d%s",
973- qual->qual, range->max_qual.qual,
974- qual->level, range->max_qual.level,
975- qual->noise, range->max_qual.noise,
976- (qual->updated & 0x7) ? " (updated)" : "");
1362+ /* Deal with signal level as relative value (0 -> max) */
1363+ if(!(qual->updated & IW_QUAL_LEVEL_INVALID))
1364+ {
1365+ len = snprintf(buffer, buflen, "Signal level%c%d/%d ",
1366+ qual->updated & IW_QUAL_LEVEL_UPDATED ? '=' : ':',
1367+ qual->level, range->max_qual.level);
1368+ buffer += len;
1369+ buflen -= len;
1370+ }
1371+
1372+ /* Deal with noise level as relative value (0 -> max) */
1373+ if(!(qual->updated & IW_QUAL_NOISE_INVALID))
1374+ {
1375+ len = snprintf(buffer, buflen, "Noise level%c%d/%d",
1376+ qual->updated & IW_QUAL_NOISE_UPDATED ? '=' : ':',
1377+ qual->noise, range->max_qual.noise);
1378+ }
9771379 }
9781380 }
9791381 else
9801382 {
9811383 /* We can't read the range, so we don't know... */
982- sprintf(buffer, "Quality:%d Signal level:%d Noise level:%d%s",
983- qual->qual, qual->level, qual->noise,
984- (qual->updated & 0x7) ? " (updated)" : "");
1384+ snprintf(buffer, buflen,
1385+ "Quality:%d Signal level:%d Noise level:%d",
1386+ qual->qual, qual->level, qual->noise);
9851387 }
9861388 }
9871389
@@ -992,28 +1394,36 @@ iw_print_stats(char * buffer,
9921394 * Output the encoding key, with a nice formating
9931395 */
9941396 void
995-iw_print_key(char * buffer,
996- unsigned char * key,
997- int key_size,
998- int key_flags)
1397+iw_print_key(char * buffer,
1398+ int buflen,
1399+ const unsigned char * key, /* Must be unsigned */
1400+ int key_size,
1401+ int key_flags)
9991402 {
10001403 int i;
10011404
1405+ /* Check buffer size -> 1 bytes => 2 digits + 1/2 separator */
1406+ if((key_size * 3) > buflen)
1407+ {
1408+ snprintf(buffer, buflen, "<too big>");
1409+ return;
1410+ }
1411+
10021412 /* Is the key present ??? */
10031413 if(key_flags & IW_ENCODE_NOKEY)
10041414 {
10051415 /* Nope : print on or dummy */
10061416 if(key_size <= 0)
1007- strcpy(buffer, "on");
1417+ strcpy(buffer, "on"); /* Size checked */
10081418 else
10091419 {
1010- strcpy(buffer, "**");
1420+ strcpy(buffer, "**"); /* Size checked */
10111421 buffer +=2;
10121422 for(i = 1; i < key_size; i++)
10131423 {
10141424 if((i & 0x1) == 0)
1015- strcpy(buffer++, "-");
1016- strcpy(buffer, "**");
1425+ strcpy(buffer++, "-"); /* Size checked */
1426+ strcpy(buffer, "**"); /* Size checked */
10171427 buffer +=2;
10181428 }
10191429 }
@@ -1021,13 +1431,13 @@ iw_print_key(char * buffer,
10211431 else
10221432 {
10231433 /* Yes : print the key */
1024- sprintf(buffer, "%.2X", key[0]);
1434+ sprintf(buffer, "%.2X", key[0]); /* Size checked */
10251435 buffer +=2;
10261436 for(i = 1; i < key_size; i++)
10271437 {
10281438 if((i & 0x1) == 0)
1029- strcpy(buffer++, "-");
1030- sprintf(buffer, "%.2X", key[i]);
1439+ strcpy(buffer++, "-"); /* Size checked */
1440+ sprintf(buffer, "%.2X", key[i]); /* Size checked */
10311441 buffer +=2;
10321442 }
10331443 }
@@ -1039,8 +1449,8 @@ iw_print_key(char * buffer,
10391449 * ### NOT IMPLEMENTED ###
10401450 * Return size of the key, or 0 (no key) or -1 (error)
10411451 */
1042-int
1043-iw_pass_key(char * input,
1452+static int
1453+iw_pass_key(const char * input,
10441454 unsigned char * key)
10451455 {
10461456 input = input; key = key;
@@ -1054,7 +1464,7 @@ iw_pass_key(char * input,
10541464 * Return size of the key, or 0 (no key) or -1 (error)
10551465 */
10561466 int
1057-iw_in_key(char * input,
1467+iw_in_key(const char * input,
10581468 unsigned char * key)
10591469 {
10601470 int keylen = 0;
@@ -1090,7 +1500,7 @@ iw_in_key(char * input,
10901500 }
10911501 /* Preserve original buffers (both in & out) */
10921502 hex = buff + IW_ENCODING_TOKEN_MAX;
1093- strcpy(hex, input);
1503+ strcpy(hex, input); /* Size checked */
10941504 out = buff;
10951505
10961506 /* Parse */
@@ -1136,8 +1546,8 @@ iw_in_key(char * input,
11361546 */
11371547 int
11381548 iw_in_key_full(int skfd,
1139- char * ifname,
1140- char * input,
1549+ const char * ifname,
1550+ const char * input,
11411551 unsigned char * key,
11421552 __u16 * flags)
11431553 {
@@ -1146,9 +1556,7 @@ iw_in_key_full(int skfd,
11461556
11471557 if(!strncmp(input, "l:", 2))
11481558 {
1149-#if WIRELESS_EXT > 15
11501559 struct iw_range range;
1151-#endif
11521560
11531561 /* Extra case : as a login (user:passwd - Cisco LEAP) */
11541562 keylen = strlen(input + 2) + 1; /* skip "l:", add '\0' */
@@ -1166,22 +1574,27 @@ iw_in_key_full(int skfd,
11661574 }
11671575 *p = '\0';
11681576
1169-#if WIRELESS_EXT > 15
1170- printf("flags = %X, index = %X\n", *flags, range.encoding_login_index);
1171- if((*flags & IW_ENCODE_INDEX) == 0)
1577+ /* Extract range info */
1578+ if(iw_get_range_info(skfd, ifname, &range) < 0)
1579+ /* Hum... Maybe we should return an error ??? */
1580+ memset(&range, 0, sizeof(range));
1581+
1582+ if(range.we_version_compiled > 15)
11721583 {
1173- /* Extract range info */
1174- if(iw_get_range_info(skfd, ifname, &range) < 0)
1175- memset(&range, 0, sizeof(range));
1584+
1585+ printf("flags = %X, index = %X\n",
1586+ *flags, range.encoding_login_index);
1587+ if((*flags & IW_ENCODE_INDEX) == 0)
1588+ {
1589+ /* Extract range info */
1590+ if(iw_get_range_info(skfd, ifname, &range) < 0)
1591+ memset(&range, 0, sizeof(range));
1592+ printf("flags = %X, index = %X\n", *flags, range.encoding_login_index);
1593+ /* Set the index the driver expects */
1594+ *flags |= range.encoding_login_index & IW_ENCODE_INDEX;
1595+ }
11761596 printf("flags = %X, index = %X\n", *flags, range.encoding_login_index);
1177- /* Set the index the driver expects */
1178- *flags |= range.encoding_login_index & IW_ENCODE_INDEX;
11791597 }
1180- printf("flags = %X, index = %X\n", *flags, range.encoding_login_index);
1181-#else
1182- /* Avoid "Unused parameter" warning */
1183- skfd = skfd; ifname = ifname; flags = flags;
1184-#endif
11851598 }
11861599 else
11871600 /* Simpler routine above */
@@ -1198,46 +1611,55 @@ iw_in_key_full(int skfd,
11981611 */
11991612 void
12001613 iw_print_pm_value(char * buffer,
1614+ int buflen,
12011615 int value,
12021616 int flags)
12031617 {
1618+ /* Check size */
1619+ if(buflen < 25)
1620+ {
1621+ snprintf(buffer, buflen, "<too big>");
1622+ return;
1623+ }
1624+ buflen -= 25;
1625+
12041626 /* Modifiers */
12051627 if(flags & IW_POWER_MIN)
12061628 {
1207- strcpy(buffer, " min");
1629+ strcpy(buffer, " min"); /* Size checked */
12081630 buffer += 4;
12091631 }
12101632 if(flags & IW_POWER_MAX)
12111633 {
1212- strcpy(buffer, " max");
1634+ strcpy(buffer, " max"); /* Size checked */
12131635 buffer += 4;
12141636 }
12151637
12161638 /* Type */
12171639 if(flags & IW_POWER_TIMEOUT)
12181640 {
1219- strcpy(buffer, " timeout:");
1641+ strcpy(buffer, " timeout:"); /* Size checked */
12201642 buffer += 9;
12211643 }
12221644 else
12231645 {
1224- strcpy(buffer, " period:");
1646+ strcpy(buffer, " period:"); /* Size checked */
12251647 buffer += 8;
12261648 }
12271649
12281650 /* Display value without units */
12291651 if(flags & IW_POWER_RELATIVE)
1230- sprintf(buffer, "%g", ((double) value) / MEGA);
1652+ snprintf(buffer, buflen, "%g", ((double) value) / MEGA);
12311653 else
12321654 {
12331655 /* Display value with units */
12341656 if(value >= (int) MEGA)
1235- sprintf(buffer, "%gs", ((double) value) / MEGA);
1657+ snprintf(buffer, buflen, "%gs", ((double) value) / MEGA);
12361658 else
12371659 if(value >= (int) KILO)
1238- sprintf(buffer, "%gms", ((double) value) / KILO);
1660+ snprintf(buffer, buflen, "%gms", ((double) value) / KILO);
12391661 else
1240- sprintf(buffer, "%dus", value);
1662+ snprintf(buffer, buflen, "%dus", value);
12411663 }
12421664 }
12431665
@@ -1247,81 +1669,96 @@ iw_print_pm_value(char * buffer,
12471669 */
12481670 void
12491671 iw_print_pm_mode(char * buffer,
1672+ int buflen,
12501673 int flags)
12511674 {
1675+ /* Check size */
1676+ if(buflen < 28)
1677+ {
1678+ snprintf(buffer, buflen, "<too big>");
1679+ return;
1680+ }
1681+
12521682 /* Print the proper mode... */
12531683 switch(flags & IW_POWER_MODE)
12541684 {
12551685 case IW_POWER_UNICAST_R:
1256- strcpy(buffer, "mode:Unicast only received");
1686+ strcpy(buffer, "mode:Unicast only received"); /* Size checked */
12571687 break;
12581688 case IW_POWER_MULTICAST_R:
1259- strcpy(buffer, "mode:Multicast only received");
1689+ strcpy(buffer, "mode:Multicast only received"); /* Size checked */
12601690 break;
12611691 case IW_POWER_ALL_R:
1262- strcpy(buffer, "mode:All packets received");
1692+ strcpy(buffer, "mode:All packets received"); /* Size checked */
12631693 break;
12641694 case IW_POWER_FORCE_S:
1265- strcpy(buffer, "mode:Force sending");
1695+ strcpy(buffer, "mode:Force sending"); /* Size checked */
12661696 break;
12671697 case IW_POWER_REPEATER:
1268- strcpy(buffer, "mode:Repeat multicasts");
1698+ strcpy(buffer, "mode:Repeat multicasts"); /* Size checked */
12691699 break;
12701700 default:
1271- strcpy(buffer, "");
1701+ strcpy(buffer, ""); /* Size checked */
12721702 break;
12731703 }
12741704 }
12751705
12761706 /***************** RETRY LIMIT/LIFETIME SUBROUTINES *****************/
12771707
1278-#if WIRELESS_EXT > 10
12791708 /*------------------------------------------------------------------*/
12801709 /*
12811710 * Output a retry value with all attributes...
12821711 */
12831712 void
12841713 iw_print_retry_value(char * buffer,
1714+ int buflen,
12851715 int value,
12861716 int flags)
12871717 {
1718+ /* Check buffer size */
1719+ if(buflen < 18)
1720+ {
1721+ snprintf(buffer, buflen, "<too big>");
1722+ return;
1723+ }
1724+ buflen -= 18;
1725+
12881726 /* Modifiers */
12891727 if(flags & IW_RETRY_MIN)
12901728 {
1291- strcpy(buffer, " min");
1729+ strcpy(buffer, " min"); /* Size checked */
12921730 buffer += 4;
12931731 }
12941732 if(flags & IW_RETRY_MAX)
12951733 {
1296- strcpy(buffer, " max");
1734+ strcpy(buffer, " max"); /* Size checked */
12971735 buffer += 4;
12981736 }
12991737
13001738 /* Type lifetime of limit */
13011739 if(flags & IW_RETRY_LIFETIME)
13021740 {
1303- strcpy(buffer, " lifetime:");
1741+ strcpy(buffer, " lifetime:"); /* Size checked */
13041742 buffer += 10;
13051743
13061744 /* Display value without units */
13071745 if(flags & IW_POWER_RELATIVE)
1308- sprintf(buffer, "%g", ((double) value) / MEGA);
1746+ snprintf(buffer, buflen, "%g", ((double) value) / MEGA);
13091747 else
13101748 {
13111749 /* Display value with units */
13121750 if(value >= (int) MEGA)
1313- sprintf(buffer, "%gs", ((double) value) / MEGA);
1751+ snprintf(buffer, buflen, "%gs", ((double) value) / MEGA);
13141752 else
13151753 if(value >= (int) KILO)
1316- sprintf(buffer, "%gms", ((double) value) / KILO);
1754+ snprintf(buffer, buflen, "%gms", ((double) value) / KILO);
13171755 else
1318- sprintf(buffer, "%dus", value);
1756+ snprintf(buffer, buflen, "%dus", value);
13191757 }
13201758 }
13211759 else
1322- sprintf(buffer, " limit:%d", value);
1760+ snprintf(buffer, buflen, " limit:%d", value);
13231761 }
1324-#endif /* WIRELESS_EXT > 10 */
13251762
13261763 /************************* TIME SUBROUTINES *************************/
13271764
@@ -1332,12 +1769,13 @@ iw_print_retry_value(char * buffer,
13321769 */
13331770 void
13341771 iw_print_timeval(char * buffer,
1772+ int buflen,
13351773 const struct timeval * time)
13361774 {
13371775 int s;
13381776
13391777 s = (time->tv_sec) % 86400;
1340- sprintf(buffer, "%02d:%02d:%02d.%06u ",
1778+ snprintf(buffer, buflen, "%02d:%02d:%02d.%06u ",
13411779 s / 3600, (s % 3600) / 60,
13421780 s % 60, (u_int32_t) time->tv_usec);
13431781 }
@@ -1345,6 +1783,7 @@ iw_print_timeval(char * buffer,
13451783 /*********************** ADDRESS SUBROUTINES ************************/
13461784 /*
13471785 * This section is mostly a cut & past from net-tools-1.2.0
1786+ * (Well... This has evolved over the years)
13481787 * manage address display and input...
13491788 */
13501789
@@ -1429,6 +1868,31 @@ iw_check_addr_type(int skfd,
14291868
14301869 /*------------------------------------------------------------------*/
14311870 /*
1871+ * Ask the kernel for the MAC address of an interface.
1872+ */
1873+int
1874+iw_get_mac_addr(int skfd,
1875+ const char * ifname,
1876+ struct ether_addr * eth,
1877+ unsigned short * ptype)
1878+{
1879+ struct ifreq ifr;
1880+ int ret;
1881+
1882+ /* Prepare request */
1883+ bzero(&ifr, sizeof(struct ifreq));
1884+ strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
1885+
1886+ /* Do it */
1887+ ret = ioctl(skfd, SIOCGIFHWADDR, &ifr);
1888+
1889+ memcpy(eth->ether_addr_octet, ifr.ifr_hwaddr.sa_data, 6);
1890+ *ptype = ifr.ifr_hwaddr.sa_family;
1891+ return(ret);
1892+}
1893+
1894+/*------------------------------------------------------------------*/
1895+/*
14321896 * Display an Ethernet address in readable format.
14331897 */
14341898 void
@@ -1516,21 +1980,21 @@ iw_in_inet(char *name, struct sockaddr *sap)
15161980 {
15171981 struct hostent *hp;
15181982 struct netent *np;
1519- struct sockaddr_in *sin = (struct sockaddr_in *) sap;
1983+ struct sockaddr_in *sain = (struct sockaddr_in *) sap;
15201984
15211985 /* Grmpf. -FvK */
1522- sin->sin_family = AF_INET;
1523- sin->sin_port = 0;
1986+ sain->sin_family = AF_INET;
1987+ sain->sin_port = 0;
15241988
15251989 /* Default is special, meaning 0.0.0.0. */
15261990 if (!strcmp(name, "default")) {
1527- sin->sin_addr.s_addr = INADDR_ANY;
1991+ sain->sin_addr.s_addr = INADDR_ANY;
15281992 return(1);
15291993 }
15301994
15311995 /* Try the NETWORKS database to see if this is a known network. */
15321996 if ((np = getnetbyname(name)) != (struct netent *)NULL) {
1533- sin->sin_addr.s_addr = htonl(np->n_net);
1997+ sain->sin_addr.s_addr = htonl(np->n_net);
15341998 strcpy(name, np->n_name);
15351999 return(1);
15362000 }
@@ -1540,7 +2004,7 @@ iw_in_inet(char *name, struct sockaddr *sap)
15402004 errno = h_errno;
15412005 return(-1);
15422006 }
1543- memcpy((char *) &sin->sin_addr, (char *) hp->h_addr_list[0], hp->h_length);
2007+ memcpy((char *) &sain->sin_addr, (char *) hp->h_addr_list[0], hp->h_length);
15442008 strcpy(name, hp->h_name);
15452009 return(0);
15462010 }
@@ -1564,7 +2028,7 @@ iw_in_addr(int skfd,
15642028 /* Check if we have valid interface address type */
15652029 if(iw_check_if_addr_type(skfd, ifname) < 0)
15662030 {
1567- fprintf(stderr, "%-8.8s Interface doesn't support IP addresses\n", ifname);
2031+ fprintf(stderr, "%-8.16s Interface doesn't support IP addresses\n", ifname);
15682032 return(-1);
15692033 }
15702034
@@ -1607,7 +2071,7 @@ iw_in_addr(int skfd,
16072071 /* Check if we have valid mac address type */
16082072 if(iw_check_mac_addr_type(skfd, ifname) < 0)
16092073 {
1610- fprintf(stderr, "%-8.8s Interface doesn't support MAC addresses\n", ifname);
2074+ fprintf(stderr, "%-8.16s Interface doesn't support MAC addresses\n", ifname);
16112075 return(-1);
16122076 }
16132077
@@ -1660,7 +2124,6 @@ iw_get_priv_size(int args)
16602124 * Those functions help the decoding of events, so are needed only in
16612125 * this case.
16622126 */
1663-#if WIRELESS_EXT > 13
16642127
16652128 /* Type of headers we know about (basically union iwreq_data) */
16662129 #define IW_HEADER_TYPE_NULL 0 /* Not available */
@@ -1751,6 +2214,10 @@ static const int event_type_size[] = {
17512214 IW_EV_QUAL_LEN, /* IW_HEADER_TYPE_QUAL */
17522215 };
17532216
2217+/* Forward compatibility with WE-19 */
2218+#define IW_EV_POINT_OFF (((char *) &(((struct iw_point *) NULL)->length)) - \
2219+ (char *) NULL)
2220+
17542221 /*------------------------------------------------------------------*/
17552222 /*
17562223 * Initialise the struct stream_descr so that we can extract
@@ -1775,7 +2242,8 @@ iw_init_event_stream(struct stream_descr * stream, /* Stream of events */
17752242 */
17762243 int
17772244 iw_extract_event_stream(struct stream_descr * stream, /* Stream of events */
1778- struct iw_event * iwe) /* Extracted event */
2245+ struct iw_event * iwe, /* Extracted event */
2246+ int we_version)
17792247 {
17802248 int event_type = 0;
17812249 unsigned int event_len = 1; /* Invalid */
@@ -1783,6 +2251,9 @@ iw_extract_event_stream(struct stream_descr * stream, /* Stream of events */
17832251 /* Don't "optimise" the following variable, it will crash */
17842252 unsigned cmd_index; /* *MUST* be unsigned */
17852253
2254+ /* Unused for now. Will be later on... */
2255+ we_version = we_version;
2256+
17862257 /* Check for end of stream */
17872258 if((stream->current + IW_EV_LCP_LEN) > stream->end)
17882259 return(0);
@@ -1820,6 +2291,9 @@ iw_extract_event_stream(struct stream_descr * stream, /* Stream of events */
18202291 }
18212292 /* Unknown events -> event_type=0 => IW_EV_LCP_LEN */
18222293 event_len = event_type_size[event_type];
2294+ /* Fixup for later version of WE */
2295+ if((we_version > 18) && (event_type == IW_HEADER_TYPE_POINT))
2296+ event_len -= IW_EV_POINT_OFF;
18232297
18242298 /* Check if we know about this event */
18252299 if(event_len <= IW_EV_LCP_LEN)
@@ -1848,7 +2322,12 @@ iw_extract_event_stream(struct stream_descr * stream, /* Stream of events */
18482322 stream->current += iwe->len;
18492323 return(-2);
18502324 }
1851- memcpy((char *) iwe + IW_EV_LCP_LEN, pointer, event_len);
2325+ /* Fixup for later version of WE */
2326+ if((we_version > 18) && (event_type == IW_HEADER_TYPE_POINT))
2327+ memcpy((char *) iwe + IW_EV_LCP_LEN + IW_EV_POINT_OFF,
2328+ pointer, event_len);
2329+ else
2330+ memcpy((char *) iwe + IW_EV_LCP_LEN, pointer, event_len);
18522331
18532332 /* Skip event in the stream */
18542333 pointer += event_len;
@@ -1883,4 +2362,301 @@ iw_extract_event_stream(struct stream_descr * stream, /* Stream of events */
18832362 return(1);
18842363 }
18852364
1886-#endif /* WIRELESS_EXT > 13 */
2365+/*********************** SCANNING SUBROUTINES ***********************/
2366+/*
2367+ * The Wireless Extension API 14 and greater define Wireless Scanning.
2368+ * The normal API is complex, this is an easy API that return
2369+ * a subset of the scanning results. This should be enough for most
2370+ * applications that want to use Scanning.
2371+ * If you want to have use the full/normal API, check iwlist.c...
2372+ *
2373+ * Precaution when using scanning :
2374+ * The scanning operation disable normal network traffic, and therefore
2375+ * you should not abuse of scan.
2376+ * The scan need to check the presence of network on other frequencies.
2377+ * While you are checking those other frequencies, you can *NOT* be on
2378+ * your normal frequency to listen to normal traffic in the cell.
2379+ * You need typically in the order of one second to actively probe all
2380+ * 802.11b channels (do the maths). Some cards may do that in background,
2381+ * to reply to scan commands faster, but they still have to do it.
2382+ * Leaving the cell for such an extended period of time is pretty bad.
2383+ * Any kind of streaming/low latency traffic will be impacted, and the
2384+ * user will perceive it (easily checked with telnet). People trying to
2385+ * send traffic to you will retry packets and waste bandwidth. Some
2386+ * applications may be sensitive to those packet losses in weird ways,
2387+ * and tracing those weird behavior back to scanning may take time.
2388+ * If you are in ad-hoc mode, if two nodes scan approx at the same
2389+ * time, they won't see each other, which may create associations issues.
2390+ * For those reasons, the scanning activity should be limited to
2391+ * what's really needed, and continuous scanning is a bad idea.
2392+ * Jean II
2393+ */
2394+
2395+/*------------------------------------------------------------------*/
2396+/*
2397+ * Process/store one element from the scanning results in wireless_scan
2398+ */
2399+static inline struct wireless_scan *
2400+iw_process_scanning_token(struct iw_event * event,
2401+ struct wireless_scan * wscan)
2402+{
2403+ struct wireless_scan * oldwscan;
2404+
2405+ /* Now, let's decode the event */
2406+ switch(event->cmd)
2407+ {
2408+ case SIOCGIWAP:
2409+ /* New cell description. Allocate new cell descriptor, zero it. */
2410+ oldwscan = wscan;
2411+ wscan = (struct wireless_scan *) malloc(sizeof(struct wireless_scan));
2412+ if(wscan == NULL)
2413+ return(wscan);
2414+ /* Link at the end of the list */
2415+ if(oldwscan != NULL)
2416+ oldwscan->next = wscan;
2417+
2418+ /* Reset it */
2419+ bzero(wscan, sizeof(struct wireless_scan));
2420+
2421+ /* Save cell identifier */
2422+ wscan->has_ap_addr = 1;
2423+ memcpy(&(wscan->ap_addr), &(event->u.ap_addr), sizeof (sockaddr));
2424+ break;
2425+ case SIOCGIWNWID:
2426+ wscan->b.has_nwid = 1;
2427+ memcpy(&(wscan->b.nwid), &(event->u.nwid), sizeof(iwparam));
2428+ break;
2429+ case SIOCGIWFREQ:
2430+ wscan->b.has_freq = 1;
2431+ wscan->b.freq = iw_freq2float(&(event->u.freq));
2432+ wscan->b.freq_flags = event->u.freq.flags;
2433+ break;
2434+ case SIOCGIWMODE:
2435+ wscan->b.mode = event->u.mode;
2436+ if((wscan->b.mode < IW_NUM_OPER_MODE) && (wscan->b.mode >= 0))
2437+ wscan->b.has_mode = 1;
2438+ break;
2439+ case SIOCGIWESSID:
2440+ wscan->b.has_essid = 1;
2441+ wscan->b.essid_on = event->u.data.flags;
2442+ if((event->u.essid.pointer) && (event->u.essid.length))
2443+ memcpy(wscan->b.essid, event->u.essid.pointer, event->u.essid.length);
2444+ wscan->b.essid[event->u.essid.length] = '\0';
2445+ break;
2446+ case SIOCGIWENCODE:
2447+ wscan->b.has_key = 1;
2448+ wscan->b.key_size = event->u.data.length;
2449+ wscan->b.key_flags = event->u.data.flags;
2450+ if(event->u.data.pointer)
2451+ memcpy(wscan->b.key, event->u.essid.pointer, event->u.data.length);
2452+ else
2453+ wscan->b.key_flags |= IW_ENCODE_NOKEY;
2454+ break;
2455+ case IWEVQUAL:
2456+ /* We don't get complete stats, only qual */
2457+ wscan->has_stats = 1;
2458+ memcpy(&wscan->stats.qual, &event->u.qual, sizeof(iwstats));
2459+ break;
2460+ case SIOCGIWRATE:
2461+ /* Scan may return a list of bitrates. Should we really bother with
2462+ * an array of bitrates ? Or only the maximum bitrate ? Jean II */
2463+ case IWEVCUSTOM:
2464+ /* How can we deal with those sanely ? Jean II */
2465+ default:
2466+ break;
2467+ } /* switch(event->cmd) */
2468+
2469+ return(wscan);
2470+}
2471+
2472+/*------------------------------------------------------------------*/
2473+/*
2474+ * Initiate the scan procedure, and process results.
2475+ * This is a non-blocking procedure and it will return each time
2476+ * it would block, returning the amount of time the caller should wait
2477+ * before calling again.
2478+ * Return -1 for error, delay to wait for (in ms), or 0 for success.
2479+ * Error code is in errno
2480+ */
2481+int
2482+iw_process_scan(int skfd,
2483+ char * ifname,
2484+ int we_version,
2485+ wireless_scan_head * context)
2486+{
2487+ struct iwreq wrq;
2488+ unsigned char * buffer = NULL; /* Results */
2489+ int buflen = IW_SCAN_MAX_DATA; /* Min for compat WE<17 */
2490+ unsigned char * newbuf;
2491+
2492+ /* Don't waste too much time on interfaces (50 * 100 = 5s) */
2493+ context->retry++;
2494+ if(context->retry > 50)
2495+ {
2496+ errno = ETIME;
2497+ return(-1);
2498+ }
2499+
2500+ /* If we have not yet initiated scanning on the interface */
2501+ if(context->retry == 1)
2502+ {
2503+ /* Initiate Scan */
2504+ wrq.u.data.pointer = NULL; /* Later */
2505+ wrq.u.data.flags = 0;
2506+ wrq.u.data.length = 0;
2507+ if(iw_set_ext(skfd, ifname, SIOCSIWSCAN, &wrq) < 0)
2508+ return(-1);
2509+ /* Success : now, just wait for event or results */
2510+ return(250); /* Wait 250 ms */
2511+ }
2512+
2513+ realloc:
2514+ /* (Re)allocate the buffer - realloc(NULL, len) == malloc(len) */
2515+ newbuf = realloc(buffer, buflen);
2516+ if(newbuf == NULL)
2517+ {
2518+ /* man says : If realloc() fails the original block is left untouched */
2519+ if(buffer)
2520+ free(buffer);
2521+ errno = ENOMEM;
2522+ return(-1);
2523+ }
2524+ buffer = newbuf;
2525+
2526+ /* Try to read the results */
2527+ wrq.u.data.pointer = buffer;
2528+ wrq.u.data.flags = 0;
2529+ wrq.u.data.length = buflen;
2530+ if(iw_get_ext(skfd, ifname, SIOCGIWSCAN, &wrq) < 0)
2531+ {
2532+ /* Check if buffer was too small (WE-17 only) */
2533+ if((errno == E2BIG) && (we_version > 16))
2534+ {
2535+ /* Some driver may return very large scan results, either
2536+ * because there are many cells, or because they have many
2537+ * large elements in cells (like IWEVCUSTOM). Most will
2538+ * only need the regular sized buffer. We now use a dynamic
2539+ * allocation of the buffer to satisfy everybody. Of course,
2540+ * as we don't know in advance the size of the array, we try
2541+ * various increasing sizes. Jean II */
2542+
2543+ /* Check if the driver gave us any hints. */
2544+ if(wrq.u.data.length > buflen)
2545+ buflen = wrq.u.data.length;
2546+ else
2547+ buflen *= 2;
2548+
2549+ /* Try again */
2550+ goto realloc;
2551+ }
2552+
2553+ /* Check if results not available yet */
2554+ if(errno == EAGAIN)
2555+ {
2556+ free(buffer);
2557+ /* Wait for only 100ms from now on */
2558+ return(100); /* Wait 100 ms */
2559+ }
2560+
2561+ free(buffer);
2562+ /* Bad error, please don't come back... */
2563+ return(-1);
2564+ }
2565+
2566+ /* We have the results, process them */
2567+ if(wrq.u.data.length)
2568+ {
2569+ struct iw_event iwe;
2570+ struct stream_descr stream;
2571+ struct wireless_scan * wscan = NULL;
2572+ int ret;
2573+#if 0
2574+ /* Debugging code. In theory useless, because it's debugged ;-) */
2575+ int i;
2576+ printf("Scan result [%02X", buffer[0]);
2577+ for(i = 1; i < wrq.u.data.length; i++)
2578+ printf(":%02X", buffer[i]);
2579+ printf("]\n");
2580+#endif
2581+
2582+ /* Init */
2583+ iw_init_event_stream(&stream, buffer, wrq.u.data.length);
2584+ /* This is dangerous, we may leak user data... */
2585+ context->result = NULL;
2586+
2587+ /* Look every token */
2588+ do
2589+ {
2590+ /* Extract an event and print it */
2591+ ret = iw_extract_event_stream(&stream, &iwe, we_version);
2592+ if(ret > 0)
2593+ {
2594+ /* Convert to wireless_scan struct */
2595+ wscan = iw_process_scanning_token(&iwe, wscan);
2596+ /* Check problems */
2597+ if(wscan == NULL)
2598+ {
2599+ free(buffer);
2600+ errno = ENOMEM;
2601+ return(-1);
2602+ }
2603+ /* Save head of list */
2604+ if(context->result == NULL)
2605+ context->result = wscan;
2606+ }
2607+ }
2608+ while(ret > 0);
2609+ }
2610+
2611+ /* Done with this interface - return success */
2612+ free(buffer);
2613+ return(0);
2614+}
2615+
2616+/*------------------------------------------------------------------*/
2617+/*
2618+ * Perform a wireless scan on the specified interface.
2619+ * This is a blocking procedure and it will when the scan is completed
2620+ * or when an error occur.
2621+ *
2622+ * The scan results are given in a linked list of wireless_scan objects.
2623+ * The caller *must* free the result himself (by walking the list).
2624+ * If there is an error, -1 is returned and the error code is available
2625+ * in errno.
2626+ *
2627+ * The parameter we_version can be extracted from the range structure
2628+ * (range.we_version_compiled - see iw_get_range_info()), or using
2629+ * iw_get_kernel_we_version(). For performance reason, you should
2630+ * cache this parameter when possible rather than querying it every time.
2631+ *
2632+ * Return -1 for error and 0 for success.
2633+ */
2634+int
2635+iw_scan(int skfd,
2636+ char * ifname,
2637+ int we_version,
2638+ wireless_scan_head * context)
2639+{
2640+ int delay; /* in ms */
2641+
2642+ /* Clean up context. Potential memory leak if(context.result != NULL) */
2643+ context->result = NULL;
2644+ context->retry = 0;
2645+
2646+ /* Wait until we get results or error */
2647+ while(1)
2648+ {
2649+ /* Try to get scan results */
2650+ delay = iw_process_scan(skfd, ifname, we_version, context);
2651+
2652+ /* Check termination */
2653+ if(delay <= 0)
2654+ break;
2655+
2656+ /* Wait a bit */
2657+ usleep(delay * 1000);
2658+ }
2659+
2660+ /* End - return -1 or 0 */
2661+ return(delay);
2662+}
--- a/wireless_tools/iwlib.h
+++ b/wireless_tools/iwlib.h
@@ -1,12 +1,12 @@
11 /*
22 * Wireless Tools
33 *
4- * Jean II - HPLB 97->99 - HPL 99->02
4+ * Jean II - HPLB 97->99 - HPL 99->04
55 *
66 * Common header for the Wireless Extension library...
77 *
88 * This file is released under the GPL license.
9- * Copyright (c) 1997-2002 Jean Tourrilhes <jt@hpl.hp.com>
9+ * Copyright (c) 1997-2004 Jean Tourrilhes <jt@hpl.hp.com>
1010 */
1111
1212 #ifndef IWLIB_H
@@ -127,13 +127,23 @@
127127 #include <linux/socket.h> /* for "struct sockaddr" et al */
128128 #include <linux/if.h> /* for IFNAMSIZ and co... */
129129
130-#ifdef WEXT_HEADER
131130 /* Private copy of Wireless extensions */
132-#include WEXT_HEADER
133-#else /* !WEXT_HEADER */
134-/* System wide Wireless extensions */
135-#include <linux/wireless.h>
136-#endif /* !WEXT_HEADER */
131+#include <wireless.h>
132+
133+/* Make gcc understant that when we say inline, we mean it.
134+ * I really hate when the compiler is trying to be more clever than me,
135+ * because in this case gcc is not able to figure out functions with a
136+ * single call site, so not only I have to tag those functions inline
137+ * by hand, but then it refuse to inline them properly.
138+ * Total saving for iwevent : 150B = 0.7%.
139+ * Fortunately, in gcc 3.4, they now automatically inline static functions
140+ * with a single call site. Hurrah !
141+ * Jean II */
142+#if __GNUC__ == 3
143+#if __GNUC_MINOR__ >= 1 && __GNUC_MINOR__ < 4
144+#define inline inline __attribute__((always_inline))
145+#endif
146+#endif /* __GNUC__ */
137147
138148 #ifdef __cplusplus
139149 extern "C" {
@@ -144,6 +154,12 @@ extern "C" {
144154
145155 /************************ CONSTANTS & MACROS ************************/
146156
157+/* Various versions information */
158+/* Recommended Wireless Extension version */
159+#define WE_VERSION 17
160+/* Version of Wireless Tools */
161+#define WT_VERSION 27
162+
147163 /* Paths */
148164 #define PROC_NET_WIRELESS "/proc/net/wireless"
149165 #define PROC_NET_DEV "/proc/net/dev"
@@ -176,6 +192,11 @@ extern "C" {
176192 #define SIOCSIWCOMMIT SIOCSIWNAME
177193 #endif /* SIOCSIWCOMMIT */
178194
195+/* Still more backward compatibility */
196+#ifndef IW_FREQ_FIXED
197+#define IW_FREQ_FIXED 0x01
198+#endif /* IW_FREQ_FIXED */
199+
179200 /****************************** TYPES ******************************/
180201
181202 /* Shortcuts */
@@ -188,16 +209,17 @@ typedef struct iw_priv_args iwprivargs;
188209 typedef struct sockaddr sockaddr;
189210
190211 /* Structure for storing all wireless information for each device
191- * This is pretty exhaustive... */
192-typedef struct wireless_info
212+ * This is a cut down version of the one above, containing only
213+ * the things *truly* needed to configure a card.
214+ * Don't add other junk, I'll remove it... */
215+typedef struct wireless_config
193216 {
194217 char name[IFNAMSIZ + 1]; /* Wireless/protocol name */
195218 int has_nwid;
196219 iwparam nwid; /* Network ID */
197220 int has_freq;
198221 double freq; /* Frequency/channel */
199- int has_sens;
200- iwparam sens; /* sensitivity */
222+ int freq_flags;
201223 int has_key;
202224 unsigned char key[IW_ENCODING_TOKEN_MAX]; /* Encoding key used */
203225 int key_size; /* Number of bytes */
@@ -205,6 +227,18 @@ typedef struct wireless_info
205227 int has_essid;
206228 int essid_on;
207229 char essid[IW_ESSID_MAX_SIZE + 1]; /* ESSID (extended network) */
230+ int has_mode;
231+ int mode; /* Operation mode */
232+} wireless_config;
233+
234+/* Structure for storing all wireless information for each device
235+ * This is pretty exhaustive... */
236+typedef struct wireless_info
237+{
238+ struct wireless_config b; /* Basic information */
239+
240+ int has_sens;
241+ iwparam sens; /* sensitivity */
208242 int has_nickname;
209243 char nickname[IW_ESSID_MAX_SIZE + 1]; /* NickName */
210244 int has_ap_addr;
@@ -215,8 +249,6 @@ typedef struct wireless_info
215249 iwparam rts; /* RTS threshold in bytes */
216250 int has_frag;
217251 iwparam frag; /* Fragmentation threshold in bytes */
218- int has_mode;
219- int mode; /* Operation mode */
220252 int has_power;
221253 iwparam power; /* Power management parameters */
222254 int has_txpower;
@@ -231,28 +263,36 @@ typedef struct wireless_info
231263 int has_range;
232264 } wireless_info;
233265
234-/* Structure for storing all wireless information for each device
235- * This is a cut down version of the one above, containing only
236- * the things *truly* needed to configure a card.
237- * Don't add other junk, I'll remove it... */
238-typedef struct wireless_config
266+/* Structure for storing an entry of a wireless scan.
267+ * This is only a subset of all possible information, the flexible
268+ * structure of scan results make it impossible to capture all
269+ * information in such a static structure. */
270+typedef struct wireless_scan
239271 {
240- char name[IFNAMSIZ + 1]; /* Wireless/protocol name */
241- int has_nwid;
242- iwparam nwid; /* Network ID */
243- int has_freq;
244- double freq; /* Frequency/channel */
245- int has_key;
246- unsigned char key[IW_ENCODING_TOKEN_MAX]; /* Encoding key used */
247- int key_size; /* Number of bytes */
248- int key_flags; /* Various flags */
249- int has_essid;
250- int essid_on;
251- char essid[IW_ESSID_MAX_SIZE + 1]; /* ESSID (extended network) */
252- int has_mode;
253- int mode; /* Operation mode */
254-} wireless_config;
272+ /* Linked list */
273+ struct wireless_scan * next;
274+
275+ /* Cell identifiaction */
276+ int has_ap_addr;
277+ sockaddr ap_addr; /* Access point address */
278+
279+ /* Other information */
280+ struct wireless_config b; /* Basic information */
281+ iwstats stats; /* Signal strength */
282+ int has_stats;
283+} wireless_scan;
284+
285+/*
286+ * Context used for non-blocking scan.
287+ */
288+typedef struct wireless_scan_head
289+{
290+ wireless_scan * result; /* Result of the scan */
291+ int retry; /* Retry level */
292+} wireless_scan_head;
255293
294+/* Structure used for parsing event streams, such as Wireless Events
295+ * and scan results */
256296 typedef struct stream_descr
257297 {
258298 char * end; /* End of the stream */
@@ -282,91 +322,114 @@ void
282322 int count);
283323 /* --------------------- WIRELESS SUBROUTINES ----------------------*/
284324 int
325+ iw_get_kernel_we_version(void);
326+int
327+ iw_print_version_info(const char * toolname);
328+int
285329 iw_get_range_info(int skfd,
286- char * ifname,
330+ const char * ifname,
287331 iwrange * range);
288332 int
289- iw_print_version_info(char * toolname);
290-int
291333 iw_get_priv_info(int skfd,
292- char * ifname,
293- iwprivargs * priv,
294- int maxpriv);
334+ const char * ifname,
335+ iwprivargs ** ppriv);
295336 int
296337 iw_get_basic_config(int skfd,
297- char * ifname,
338+ const char * ifname,
298339 wireless_config * info);
299340 int
300341 iw_set_basic_config(int skfd,
301- char * ifname,
342+ const char * ifname,
302343 wireless_config * info);
303344 /* --------------------- PROTOCOL SUBROUTINES --------------------- */
304345 int
305- iw_protocol_compare(char * protocol1,
306- char * protocol2);
346+ iw_protocol_compare(const char * protocol1,
347+ const char * protocol2);
307348 /* -------------------- FREQUENCY SUBROUTINES --------------------- */
308349 void
309350 iw_float2freq(double in,
310- iwfreq * out);
351+ iwfreq * out);
311352 double
312- iw_freq2float(iwfreq * in);
353+ iw_freq2float(const iwfreq * in);
354+void
355+ iw_print_freq_value(char * buffer,
356+ int buflen,
357+ double freq);
313358 void
314359 iw_print_freq(char * buffer,
315- double freq);
360+ int buflen,
361+ double freq,
362+ int channel,
363+ int freq_flags);
364+int
365+ iw_freq_to_channel(double freq,
366+ const struct iw_range * range);
316367 int
317- iw_freq_to_channel(double freq,
318- struct iw_range * range);
368+ iw_channel_to_freq(int channel,
369+ double * pfreq,
370+ const struct iw_range * range);
319371 void
320372 iw_print_bitrate(char * buffer,
373+ int buflen,
321374 int bitrate);
322375 /* ---------------------- POWER SUBROUTINES ----------------------- */
323376 int
324377 iw_dbm2mwatt(int in);
325378 int
326379 iw_mwatt2dbm(int in);
380+void
381+ iw_print_txpower(char * buffer,
382+ int buflen,
383+ struct iw_param * txpower);
327384 /* -------------------- STATISTICS SUBROUTINES -------------------- */
328385 int
329- iw_get_stats(int skfd,
330- char * ifname,
331- iwstats * stats);
386+ iw_get_stats(int skfd,
387+ const char * ifname,
388+ iwstats * stats,
389+ const iwrange * range,
390+ int has_range);
332391 void
333392 iw_print_stats(char * buffer,
334- iwqual * qual,
335- iwrange * range,
393+ int buflen,
394+ const iwqual * qual,
395+ const iwrange * range,
336396 int has_range);
337397 /* --------------------- ENCODING SUBROUTINES --------------------- */
338398 void
339- iw_print_key(char * buffer,
340- unsigned char * key,
341- int key_size,
342- int key_flags);
399+ iw_print_key(char * buffer,
400+ int buflen,
401+ const unsigned char * key,
402+ int key_size,
403+ int key_flags);
343404 int
344- iw_in_key(char * input,
405+ iw_in_key(const char * input,
345406 unsigned char * key);
346407 int
347408 iw_in_key_full(int skfd,
348- char * ifname,
349- char * input,
409+ const char * ifname,
410+ const char * input,
350411 unsigned char * key,
351412 __u16 * flags);
352413 /* ----------------- POWER MANAGEMENT SUBROUTINES ----------------- */
353414 void
354415 iw_print_pm_value(char * buffer,
416+ int buflen,
355417 int value,
356418 int flags);
357419 void
358420 iw_print_pm_mode(char * buffer,
421+ int buflen,
359422 int flags);
360423 /* --------------- RETRY LIMIT/LIFETIME SUBROUTINES --------------- */
361-#if WIRELESS_EXT > 10
362424 void
363425 iw_print_retry_value(char * buffer,
426+ int buflen,
364427 int value,
365428 int flags);
366-#endif
367429 /* ----------------------- TIME SUBROUTINES ----------------------- */
368430 void
369431 iw_print_timeval(char * buffer,
432+ int buflen,
370433 const struct timeval * time);
371434 /* --------------------- ADDRESS SUBROUTINES ---------------------- */
372435 int
@@ -380,6 +443,11 @@ int
380443 iw_check_addr_type(int skfd,
381444 char * ifname);
382445 #endif
446+int
447+ iw_get_mac_addr(int skfd,
448+ const char * name,
449+ struct ether_addr * eth,
450+ unsigned short * ptype);
383451 void
384452 iw_ether_ntop(const struct ether_addr* eth, char* buf);
385453 char*
@@ -397,7 +465,6 @@ int
397465 int
398466 iw_get_priv_size(int args);
399467
400-#if WIRELESS_EXT > 13
401468 /* ---------------------- EVENT SUBROUTINES ---------------------- */
402469 void
403470 iw_init_event_stream(struct stream_descr * stream,
@@ -405,11 +472,23 @@ void
405472 int len);
406473 int
407474 iw_extract_event_stream(struct stream_descr * stream,
408- struct iw_event * iwe);
409-#endif /* WIRELESS_EXT > 13 */
475+ struct iw_event * iwe,
476+ int we_version);
477+/* --------------------- SCANNING SUBROUTINES --------------------- */
478+int
479+ iw_process_scan(int skfd,
480+ char * ifname,
481+ int we_version,
482+ wireless_scan_head * context);
483+int
484+ iw_scan(int skfd,
485+ char * ifname,
486+ int we_version,
487+ wireless_scan_head * context);
410488
411489 /**************************** VARIABLES ****************************/
412490
491+/* Modes as human readable strings */
413492 extern const char * const iw_operation_mode[];
414493 #define IW_NUM_OPER_MODE 7
415494
@@ -429,7 +508,7 @@ extern const char * const iw_operation_mode[];
429508 */
430509 static inline int
431510 iw_set_ext(int skfd, /* Socket to the kernel */
432- char * ifname, /* Device name */
511+ const char * ifname, /* Device name */
433512 int request, /* WE ID */
434513 struct iwreq * pwrq) /* Fixed part of the request */
435514 {
@@ -445,7 +524,7 @@ iw_set_ext(int skfd, /* Socket to the kernel */
445524 */
446525 static inline int
447526 iw_get_ext(int skfd, /* Socket to the kernel */
448- char * ifname, /* Device name */
527+ const char * ifname, /* Device name */
449528 int request, /* WE ID */
450529 struct iwreq * pwrq) /* Fixed part of the request */
451530 {
@@ -456,6 +535,16 @@ iw_get_ext(int skfd, /* Socket to the kernel */
456535 }
457536
458537 /*------------------------------------------------------------------*/
538+/*
539+ * Close the socket used for ioctl.
540+ */
541+static inline void
542+iw_sockets_close(int skfd)
543+{
544+ close(skfd);
545+}
546+
547+/*------------------------------------------------------------------*/
459548 /* Backwards compatability
460549 * Actually, those form are much easier to use when dealing with
461550 * struct sockaddr... */
--- a/wireless_tools/iwlist.8
+++ b/wireless_tools/iwlist.8
@@ -1,21 +1,19 @@
11 .\" Jean II - HPLB - 96
22 .\" iwlist.8
33 .\"
4-.TH IWLIST 8 "31 October 1996" "net-tools" "Linux Programmer's Manual"
4+.TH IWLIST 8 "23 June 2004" "wireless-tools" "Linux Programmer's Manual"
55 .\"
66 .\" NAME part
77 .\"
88 .SH NAME
9-iwlist \- Get wireless statistics from specific nodes
9+iwlist \- Get more detailed wireless information from a wireless interface
1010 .\"
1111 .\" SYNOPSIS part
1212 .\"
1313 .SH SYNOPSIS
14-.BI "iwlist " interface " freq"
14+.BI "iwlist " interface " scanning"
1515 .br
16-.BI "iwlist " interface " ap"
17-.br
18-.BI "iwlist " interface " scan"
16+.BI "iwlist " interface " frequency"
1917 .br
2018 .BI "iwlist " interface " rate"
2119 .br
@@ -27,6 +25,8 @@ iwlist \- Get wireless statistics from specific nodes
2725 .br
2826 .BI "iwlist " interface " retry"
2927 .br
28+.BI "iwlist " interface " event"
29+.br
3030 .BI "iwlist --help"
3131 .br
3232 .BI "iwlist --version"
@@ -35,60 +35,71 @@ iwlist \- Get wireless statistics from specific nodes
3535 .\"
3636 .SH DESCRIPTION
3737 .B Iwlist
38-is used to display some large chunk of information from a wireless
39-network interface that is not displayed by iwconfig. This is typically
40-list of parameters.
38+is used to display some additional information from a wireless network
39+interface that is not displayed by
40+.IR iwconfig (8).
41+The main argument is used
42+to select a category of information,
43+.B iwlist
44+displays in detailed form all information related to this category,
45+including information already shown by
46+.IR iwconfig (8).
4147 .\"
4248 .\" PARAMETER part
4349 .\"
4450 .SH PARAMETERS
4551 .TP
46-.BR freq / channel
47-Give the list of available frequencies in the device and the number of
48-defined channels. Please note that usually the driver returns the
49-total number of channels and only the frequencies available in the
50-present locale, so there is no one to one mapping between frequencies
51-displayed and channel numbers.
52-.TP
5352 .BR scan [ning]
5453 Give the list of Access Points and Ad-Hoc cells in range, and
5554 optionally a whole bunch of information about them (ESSID, Quality,
56-Frequency, Mode...). The type of information returned depend on what
57-the card support.
55+Frequency, Mode...). The type of information returned depends on what
56+the card supports.
5857 .br
59-Triggering scanning is a priviledged operation
58+Triggering scanning is a privileged operation
6059 .RI ( root
61-only) and normal users can only read letf-over scan results. By
60+only) and normal users can only read left-over scan results. By
6261 default, the way scanning is done (the scope of the scan) will be
6362 impacted by the current setting of the driver. Also, this command is
6463 supposed to take extra arguments to control the scanning behaviour,
6564 but this is currently not implemented.
6665 .TP
67-.BR ap / accesspoint / peers
68-Give the list of Access Points in range, and optionally the quality of
69-link to them. This feature is obsolte and now deprecated in favor of
70-scanning support (above), and most drivers don't support it.
71-.br
72-Some drivers may use this command to return a specific list of Peers
73-or Access Points, such as the list of Peers associated/registered with
74-the card. See your driver documentation for details.
66+.BR freq [uency]/ channel
67+Give the list of available frequencies in the device and the number of
68+defined channels. Please note that usually the driver returns the
69+total number of channels and only the frequencies available in the
70+present locale, so there is no one-to-one mapping between frequencies
71+displayed and channel numbers.
7572 .TP
7673 .BR rate / bit [rate]
7774 List the bit-rates supported by the device.
7875 .TP
7976 .BR key / enc [ryption]
8077 List the encryption key sizes supported and display all the encryption
81-keys availables in the device.
78+keys available in the device.
8279 .TP
8380 .B power
8481 List the various Power Management attributes and modes of the device.
8582 .TP
8683 .B txpower
87-List the various Transmit Power available on the device.
84+List the various Transmit Powers available on the device.
8885 .TP
8986 .B retry
9087 List the transmit retry limits and retry lifetime on the device.
9188 .TP
89+.BR ap / accesspoint / peers
90+Give the list of Access Points in range, and optionally the quality of
91+link to them. This feature is
92+.B obsolete
93+and now deprecated in favor of scanning support (above), and most
94+drivers don't support it.
95+.br
96+Some drivers may use this command to return a specific list of Peers
97+or Access Points, such as the list of Peers associated/registered with
98+the card. See your driver documentation for details.
99+.TP
100+.B event
101+List the wireless events supported by the device.
102+.TP
92103 .B --version
93104 Display the version of the tools, as well as the recommended and
94105 current Wireless Extensions version for the tool and the various
--- a/wireless_tools/iwlist.c
+++ b/wireless_tools/iwlist.c
@@ -1,14 +1,14 @@
11 /*
22 * Wireless Tools
33 *
4- * Jean II - HPLB '99 - HPL 99->01
4+ * Jean II - HPLB '99 - HPL 99->04
55 *
66 * This tool can access various piece of information on the card
77 * not part of iwconfig...
88 * You need to link this code against "iwlist.c" and "-lm".
99 *
1010 * This file is released under the GPL license.
11- * Copyright (c) 1997-2002 Jean Tourrilhes <jt@hpl.hp.com>
11+ * Copyright (c) 1997-2004 Jean Tourrilhes <jt@hpl.hp.com>
1212 */
1313
1414 #include "iwlib.h" /* Header */
@@ -38,42 +38,35 @@ print_freq_info(int skfd,
3838
3939 /* Get list of frequencies / channels */
4040 if(iw_get_range_info(skfd, ifname, &range) < 0)
41- fprintf(stderr, "%-8.8s no frequency information.\n\n",
41+ fprintf(stderr, "%-8.16s no frequency information.\n\n",
4242 ifname);
4343 else
4444 {
4545 if(range.num_frequency > 0)
4646 {
47- printf("%-8.8s %d channels in total; available frequencies :\n",
47+ printf("%-8.16s %d channels in total; available frequencies :\n",
4848 ifname, range.num_channels);
4949 /* Print them all */
5050 for(k = 0; k < range.num_frequency; k++)
5151 {
52- printf(" Channel %.2d : ", range.freq[k].i);
5352 freq = iw_freq2float(&(range.freq[k]));
54- if(freq >= GIGA)
55- printf("%g GHz\n", freq / GIGA);
56- else
57- if(freq >= MEGA)
58- printf("%g MHz\n", freq / MEGA);
59- else
60- printf("%g kHz\n", freq / KILO);
53+ iw_print_freq_value(buffer, sizeof(buffer), freq);
54+ printf(" Channel %.2d : %s\n",
55+ range.freq[k].i, buffer);
6156 }
6257 }
6358 else
64- printf("%-8.8s %d channels\n",
59+ printf("%-8.16s %d channels\n",
6560 ifname, range.num_channels);
6661
6762 /* Get current frequency / channel and display it */
6863 if(iw_get_ext(skfd, ifname, SIOCGIWFREQ, &wrq) >= 0)
6964 {
7065 freq = iw_freq2float(&(wrq.u.freq));
71- iw_print_freq(buffer, freq);
7266 channel = iw_freq_to_channel(freq, &range);
73- if(channel >= 0)
74- printf(" Current %s (channel %.2d)\n\n", buffer, channel);
75- else
76- printf(" Current %s\n\n", buffer);
67+ iw_print_freq(buffer, sizeof(buffer),
68+ freq, channel, wrq.u.freq.flags);
69+ printf(" Current %s\n\n", buffer);
7770 }
7871 }
7972 return(0);
@@ -117,7 +110,7 @@ print_ap_info(int skfd,
117110 wrq.u.data.flags = 0;
118111 if(iw_get_ext(skfd, ifname, SIOCGIWAPLIST, &wrq) < 0)
119112 {
120- fprintf(stderr, "%-8.8s Interface doesn't have a list of Peers/Access-Points\n\n", ifname);
113+ fprintf(stderr, "%-8.16s Interface doesn't have a list of Peers/Access-Points\n\n", ifname);
121114 return(-1);
122115 }
123116
@@ -132,7 +125,7 @@ print_ap_info(int skfd,
132125 /* Check if we have valid mac address type */
133126 if(iw_check_mac_addr_type(skfd, ifname) < 0)
134127 {
135- fprintf(stderr, "%-8.8s Interface doesn't support MAC addresses\n\n", ifname);
128+ fprintf(stderr, "%-8.16s Interface doesn't support MAC addresses\n\n", ifname);
136129 return(-2);
137130 }
138131
@@ -142,16 +135,16 @@ print_ap_info(int skfd,
142135
143136 /* Display it */
144137 if(n == 0)
145- printf("%-8.8s No Peers/Access-Point in range\n", ifname);
138+ printf("%-8.16s No Peers/Access-Point in range\n", ifname);
146139 else
147- printf("%-8.8s Peers/Access-Points in range:\n", ifname);
140+ printf("%-8.16s Peers/Access-Points in range:\n", ifname);
148141 for(i = 0; i < n; i++)
149142 {
150143 if(has_qual)
151144 {
152145 /* Print stats for this address */
153146 printf(" %s : ", iw_pr_ether(temp, hwa[i].sa_data));
154- iw_print_stats(temp, &qual[i], &range, has_range);
147+ iw_print_stats(temp, sizeof(buffer), &qual[i], &range, has_range);
155148 printf("%s\n", temp);
156149 }
157150 else
@@ -184,29 +177,29 @@ print_bitrate_info(int skfd,
184177
185178 /* Extract range info */
186179 if(iw_get_range_info(skfd, ifname, &range) < 0)
187- fprintf(stderr, "%-8.8s no bit-rate information.\n\n",
180+ fprintf(stderr, "%-8.16s no bit-rate information.\n\n",
188181 ifname);
189182 else
190183 {
191184 if((range.num_bitrates > 0) && (range.num_bitrates <= IW_MAX_BITRATES))
192185 {
193- printf("%-8.8s %d available bit-rates :\n",
186+ printf("%-8.16s %d available bit-rates :\n",
194187 ifname, range.num_bitrates);
195188 /* Print them all */
196189 for(k = 0; k < range.num_bitrates; k++)
197190 {
198- iw_print_bitrate(buffer, range.bitrate[k]);
191+ iw_print_bitrate(buffer, sizeof(buffer), range.bitrate[k]);
199192 /* Maybe this should be %10s */
200193 printf("\t %s\n", buffer);
201194 }
202195 }
203196 else
204- printf("%-8.8s No bit-rates ? Please update driver...\n", ifname);
197+ printf("%-8.16s unknown bit-rate information.\n", ifname);
205198
206199 /* Get current bit rate */
207200 if(iw_get_ext(skfd, ifname, SIOCGIWRATE, &wrq) >= 0)
208201 {
209- iw_print_bitrate(buffer, wrq.u.bitrate.value);
202+ iw_print_bitrate(buffer, sizeof(buffer), wrq.u.bitrate.value);
210203 printf(" Current Bit Rate%c%s\n\n",
211204 (wrq.u.bitrate.fixed ? '=' : ':'), buffer);
212205 }
@@ -237,11 +230,11 @@ print_keys_info(int skfd,
237230
238231 /* Extract range info */
239232 if(iw_get_range_info(skfd, ifname, &range) < 0)
240- fprintf(stderr, "%-8.8s no encryption keys information.\n\n",
233+ fprintf(stderr, "%-8.16s no encryption keys information.\n\n",
241234 ifname);
242235 else
243236 {
244- printf("%-8.8s ", ifname);
237+ printf("%-8.16s ", ifname);
245238 /* Print key sizes */
246239 if((range.num_encoding_sizes > 0) &&
247240 (range.num_encoding_sizes < IW_MAX_ENCODING_SIZES))
@@ -271,7 +264,8 @@ print_keys_info(int skfd,
271264 else
272265 {
273266 /* Display the key */
274- iw_print_key(buffer, key, wrq.u.data.length, wrq.u.data.flags);
267+ iw_print_key(buffer, sizeof(buffer),
268+ key, wrq.u.data.length, wrq.u.data.flags);
275269 printf("\t\t[%d]: %s", k, buffer);
276270
277271 /* Other info... */
@@ -320,7 +314,8 @@ get_pm_value(int skfd,
320314 /* Let's check the value and its type */
321315 if(pwrq->u.power.flags & IW_POWER_TYPE)
322316 {
323- iw_print_pm_value(buffer, pwrq->u.power.value, pwrq->u.power.flags);
317+ iw_print_pm_value(buffer, sizeof(buffer),
318+ pwrq->u.power.value, pwrq->u.power.flags);
324319 printf("\n %s", buffer);
325320 }
326321 }
@@ -345,13 +340,14 @@ print_pm_info(int skfd,
345340 args = args; count = count;
346341
347342 /* Extract range info */
348- if(iw_get_range_info(skfd, ifname, &range) < 0)
349- fprintf(stderr, "%-8.8s no power management information.\n\n",
343+ if((iw_get_range_info(skfd, ifname, &range) < 0) ||
344+ (range.we_version_compiled < 10))
345+ fprintf(stderr, "%-8.16s no power management information.\n\n",
350346 ifname);
351347 else
352348 {
353- printf("%-8.8s ", ifname);
354-#if WIRELESS_EXT > 9
349+ printf("%-8.16s ", ifname);
350+
355351 /* Display modes availables */
356352 if(range.pm_capa & IW_POWER_MODE)
357353 {
@@ -377,11 +373,12 @@ print_pm_info(int skfd,
377373 else
378374 printf("Fixed period ; ");
379375 /* Print the range */
380- iw_print_pm_value(buffer, range.min_pmp, flags | IW_POWER_MIN);
376+ iw_print_pm_value(buffer, sizeof(buffer),
377+ range.min_pmp, flags | IW_POWER_MIN);
381378 printf("%s\n ", buffer);
382- iw_print_pm_value(buffer, range.max_pmp, flags | IW_POWER_MAX);
379+ iw_print_pm_value(buffer, sizeof(buffer),
380+ range.max_pmp, flags | IW_POWER_MAX);
383381 printf("%s\n ", buffer);
384-
385382 }
386383 /* Display min/max timeout availables */
387384 if(range.pmt_flags & IW_POWER_TIMEOUT)
@@ -393,13 +390,13 @@ print_pm_info(int skfd,
393390 else
394391 printf("Fixed timeout ; ");
395392 /* Print the range */
396- iw_print_pm_value(buffer, range.min_pmt, flags | IW_POWER_MIN);
393+ iw_print_pm_value(buffer, sizeof(buffer),
394+ range.min_pmt, flags | IW_POWER_MIN);
397395 printf("%s\n ", buffer);
398- iw_print_pm_value(buffer, range.max_pmt, flags | IW_POWER_MAX);
396+ iw_print_pm_value(buffer, sizeof(buffer),
397+ range.max_pmt, flags | IW_POWER_MAX);
399398 printf("%s\n ", buffer);
400-
401399 }
402-#endif /* WIRELESS_EXT > 9 */
403400
404401 /* Get current Power Management settings */
405402 wrq.u.power.flags = 0;
@@ -415,7 +412,7 @@ print_pm_info(int skfd,
415412 int pm_mask = 0;
416413
417414 /* Let's check the mode */
418- iw_print_pm_mode(buffer, flags);
415+ iw_print_pm_mode(buffer, sizeof(buffer), flags);
419416 printf("Current %s", buffer);
420417
421418 /* Let's check if nothing (simply on) */
@@ -426,7 +423,7 @@ print_pm_info(int skfd,
426423 /* Let's check the value and its type */
427424 if(wrq.u.power.flags & IW_POWER_TYPE)
428425 {
429- iw_print_pm_value(buffer,
426+ iw_print_pm_value(buffer, sizeof(buffer),
430427 wrq.u.power.value, wrq.u.power.flags);
431428 printf("%s", buffer);
432429 }
@@ -441,7 +438,6 @@ print_pm_info(int skfd,
441438 if(pm_mask)
442439 get_pm_value(skfd, ifname, &wrq, pm_mask, buffer);
443440
444-#if WIRELESS_EXT > 9
445441 /* And if we have both a period and a timeout, ask the other */
446442 pm_mask = (range.pm_capa & (~(wrq.u.power.flags) &
447443 IW_POWER_TYPE));
@@ -461,7 +457,6 @@ print_pm_info(int skfd,
461457 if(pm_mask)
462458 get_pm_value(skfd, ifname, &wrq, pm_mask, buffer);
463459 }
464-#endif /* WIRELESS_EXT > 9 */
465460 }
466461 }
467462 printf("\n");
@@ -490,49 +485,69 @@ print_txpower_info(int skfd,
490485 /* Avoid "Unused parameter" warning */
491486 args = args; count = count;
492487
493-#if WIRELESS_EXT > 9
494488 /* Extract range info */
495- if(iw_get_range_info(skfd, ifname, &range) < 0)
496- fprintf(stderr, "%-8.8s no transmit-power information.\n\n",
489+ if((iw_get_range_info(skfd, ifname, &range) < 0) ||
490+ (range.we_version_compiled < 10))
491+ fprintf(stderr, "%-8.16s no transmit-power information.\n\n",
497492 ifname);
498493 else
499494 {
500495 if((range.num_txpower <= 0) || (range.num_txpower > IW_MAX_TXPOWER))
501- printf("%-8.8s No transmit-powers ? Please update driver...\n\n", ifname);
496+ printf("%-8.16s unknown transmit-power information.\n\n", ifname);
502497 else
503498 {
504- printf("%-8.8s %d available transmit-powers :\n",
499+ printf("%-8.16s %d available transmit-powers :\n",
505500 ifname, range.num_txpower);
506501 /* Print them all */
507502 for(k = 0; k < range.num_txpower; k++)
508503 {
509- if(range.txpower_capa & IW_TXPOW_MWATT)
504+ /* Check for relative values */
505+ if(range.txpower_capa & IW_TXPOW_RELATIVE)
510506 {
511- dbm = iw_mwatt2dbm(range.txpower[k]);
512- mwatt = range.txpower[k];
507+ printf("\t %d (no units)\n", range.txpower[k]);
513508 }
514509 else
515510 {
516- dbm = range.txpower[k];
517- mwatt = iw_dbm2mwatt(range.txpower[k]);
511+ if(range.txpower_capa & IW_TXPOW_MWATT)
512+ {
513+ dbm = iw_mwatt2dbm(range.txpower[k]);
514+ mwatt = range.txpower[k];
515+ }
516+ else
517+ {
518+ dbm = range.txpower[k];
519+ mwatt = iw_dbm2mwatt(range.txpower[k]);
520+ }
521+ printf("\t %d dBm \t(%d mW)\n", dbm, mwatt);
518522 }
519- printf("\t %d dBm \t(%d mW)\n", dbm, mwatt);
520523 }
524+ }
521525
522- /* Get current Transmit Power */
523- if(iw_get_ext(skfd, ifname, SIOCGIWTXPOW, &wrq) >= 0)
526+ /* Get current Transmit Power */
527+ if(iw_get_ext(skfd, ifname, SIOCGIWTXPOW, &wrq) >= 0)
528+ {
529+ printf(" Current Tx-Power");
530+ /* Disabled ? */
531+ if(wrq.u.txpower.disabled)
532+ printf(":off\n\n");
533+ else
524534 {
525- printf(" Current Tx-Power");
526- /* Disabled ? */
527- if(wrq.u.txpower.disabled)
528- printf(":off\n\n");
535+ /* Fixed ? */
536+ if(wrq.u.txpower.fixed)
537+ printf("=");
538+ else
539+ printf(":");
540+ /* Check for relative values */
541+ if(wrq.u.txpower.flags & IW_TXPOW_RELATIVE)
542+ {
543+ /* I just hate relative value, because they are
544+ * driver specific, so not very meaningfull to apps.
545+ * But, we have to support that, because
546+ * this is the way hardware is... */
547+ printf("\t %d (no units)\n", wrq.u.txpower.value);
548+ }
529549 else
530550 {
531- /* Fixed ? */
532- if(wrq.u.txpower.fixed)
533- printf("=");
534- else
535- printf(":");
536551 if(wrq.u.txpower.flags & IW_TXPOW_MWATT)
537552 {
538553 dbm = iw_mwatt2dbm(wrq.u.txpower.value);
@@ -548,13 +563,11 @@ print_txpower_info(int skfd,
548563 }
549564 }
550565 }
551-#endif /* WIRELESS_EXT > 9 */
552566 return(0);
553567 }
554568
555569 /*********************** RETRY LIMIT/LIFETIME ***********************/
556570
557-#if WIRELESS_EXT > 10
558571 /*------------------------------------------------------------------*/
559572 /*
560573 * Print one retry value
@@ -564,7 +577,8 @@ get_retry_value(int skfd,
564577 char * ifname,
565578 struct iwreq * pwrq,
566579 int flags,
567- char * buffer)
580+ char * buffer,
581+ int buflen)
568582 {
569583 /* Get Another retry value */
570584 pwrq->u.retry.flags = flags;
@@ -573,7 +587,7 @@ get_retry_value(int skfd,
573587 /* Let's check the value and its type */
574588 if(pwrq->u.retry.flags & IW_RETRY_TYPE)
575589 {
576- iw_print_retry_value(buffer,
590+ iw_print_retry_value(buffer, buflen,
577591 pwrq->u.retry.value, pwrq->u.retry.flags);
578592 printf("%s\n ", buffer);
579593 }
@@ -599,12 +613,13 @@ print_retry_info(int skfd,
599613 args = args; count = count;
600614
601615 /* Extract range info */
602- if(iw_get_range_info(skfd, ifname, &range) < 0)
603- fprintf(stderr, "%-8.8s no retry limit/lifetime information.\n\n",
604- ifname);
616+ if((iw_get_range_info(skfd, ifname, &range) < 0) ||
617+ (range.we_version_compiled < 11))
618+ fprintf(stderr, "%-8.16s no retry limit/lifetime information.\n\n",
619+ ifname);
605620 else
606621 {
607- printf("%-8.8s ", ifname);
622+ printf("%-8.16s ", ifname);
608623
609624 /* Display min/max limit availables */
610625 if(range.retry_flags & IW_RETRY_LIMIT)
@@ -616,9 +631,11 @@ print_retry_info(int skfd,
616631 else
617632 printf("Fixed limit ; ");
618633 /* Print the range */
619- iw_print_retry_value(buffer, range.min_retry, flags | IW_RETRY_MIN);
634+ iw_print_retry_value(buffer, sizeof(buffer),
635+ range.min_retry, flags | IW_RETRY_MIN);
620636 printf("%s\n ", buffer);
621- iw_print_retry_value(buffer, range.max_retry, flags | IW_RETRY_MAX);
637+ iw_print_retry_value(buffer, sizeof(buffer),
638+ range.max_retry, flags | IW_RETRY_MAX);
622639 printf("%s\n ", buffer);
623640
624641 }
@@ -632,9 +649,11 @@ print_retry_info(int skfd,
632649 else
633650 printf("Fixed lifetime ; ");
634651 /* Print the range */
635- iw_print_retry_value(buffer, range.min_r_time, flags | IW_RETRY_MIN);
652+ iw_print_retry_value(buffer, sizeof(buffer),
653+ range.min_r_time, flags | IW_RETRY_MIN);
636654 printf("%s\n ", buffer);
637- iw_print_retry_value(buffer, range.max_r_time, flags | IW_RETRY_MAX);
655+ iw_print_retry_value(buffer, sizeof(buffer),
656+ range.max_r_time, flags | IW_RETRY_MAX);
638657 printf("%s\n ", buffer);
639658
640659 }
@@ -658,9 +677,9 @@ print_retry_info(int skfd,
658677 /* Let's check the value and its type */
659678 if(wrq.u.retry.flags & IW_RETRY_TYPE)
660679 {
661- iw_print_retry_value(buffer,
680+ iw_print_retry_value(buffer, sizeof(buffer),
662681 wrq.u.retry.value, wrq.u.retry.flags);
663- printf("%s", buffer);
682+ printf("%s\n ", buffer);
664683 }
665684
666685 /* If we have been returned a MIN value, ask for the MAX */
@@ -671,7 +690,8 @@ print_retry_info(int skfd,
671690 retry_mask = IW_RETRY_MIN;
672691 /* If we have something to ask for... */
673692 if(retry_mask)
674- get_retry_value(skfd, ifname, &wrq, retry_mask, buffer);
693+ get_retry_value(skfd, ifname, &wrq, retry_mask,
694+ buffer, sizeof(buffer));
675695
676696 /* And if we have both a period and a timeout, ask the other */
677697 retry_mask = (range.retry_capa & (~(wrq.u.retry.flags) &
@@ -680,7 +700,7 @@ print_retry_info(int skfd,
680700 {
681701 int base_mask = retry_mask;
682702 flags = get_retry_value(skfd, ifname, &wrq, retry_mask,
683- buffer);
703+ buffer, sizeof(buffer));
684704 retry_mask = 0;
685705
686706 /* If we have been returned a MIN value, ask for the MAX */
@@ -691,7 +711,8 @@ print_retry_info(int skfd,
691711 retry_mask = IW_RETRY_MIN | base_mask;
692712 /* If we have something to ask for... */
693713 if(retry_mask)
694- get_retry_value(skfd, ifname, &wrq, retry_mask, buffer);
714+ get_retry_value(skfd, ifname, &wrq, retry_mask,
715+ buffer, sizeof(buffer));
695716 }
696717 }
697718 }
@@ -700,13 +721,17 @@ print_retry_info(int skfd,
700721 return(0);
701722 }
702723
703-#endif /* WIRELESS_EXT > 10 */
704-
705724 /***************************** SCANNING *****************************/
706725 /*
707726 * This one behave quite differently from the others
727+ *
728+ * Note that we don't use the scanning capability of iwlib (functions
729+ * iw_process_scan() and iw_scan()). The main reason is that
730+ * iw_process_scan() return only a subset of the scan data to the caller,
731+ * for example custom elements and bitrates are ommited. Here, we
732+ * do the complete job...
708733 */
709-#if WIRELESS_EXT > 13
734+
710735 /*------------------------------------------------------------------*/
711736 /*
712737 * Print one element from the scanning results
@@ -714,7 +739,7 @@ print_retry_info(int skfd,
714739 static inline int
715740 print_scanning_token(struct iw_event * event, /* Extracted token */
716741 int ap_num, /* AP number */
717- struct iw_range * iwrange, /* Range info */
742+ struct iw_range * iw_range, /* Range info */
718743 int has_range)
719744 {
720745 char buffer[128]; /* Temporary buffer */
@@ -736,8 +761,13 @@ print_scanning_token(struct iw_event * event, /* Extracted token */
736761 case SIOCGIWFREQ:
737762 {
738763 double freq; /* Frequency/channel */
764+ int channel = -1; /* Converted to channel */
739765 freq = iw_freq2float(&(event->u.freq));
740- iw_print_freq(buffer, freq);
766+ /* Convert to channel if possible */
767+ if(has_range)
768+ channel = iw_freq_to_channel(freq, iw_range);
769+ iw_print_freq(buffer, sizeof(buffer),
770+ freq, channel, event->u.freq.flags);
741771 printf(" %s\n", buffer);
742772 }
743773 break;
@@ -780,7 +810,7 @@ print_scanning_token(struct iw_event * event, /* Extracted token */
780810 else
781811 {
782812 /* Display the key */
783- iw_print_key(buffer, key, event->u.data.length,
813+ iw_print_key(buffer, sizeof(buffer), key, event->u.data.length,
784814 event->u.data.flags);
785815 printf("%s", buffer);
786816
@@ -796,17 +826,16 @@ print_scanning_token(struct iw_event * event, /* Extracted token */
796826 }
797827 break;
798828 case SIOCGIWRATE:
799- iw_print_bitrate(buffer, event->u.bitrate.value);
829+ iw_print_bitrate(buffer, sizeof(buffer), event->u.bitrate.value);
800830 printf(" Bit Rate:%s\n", buffer);
801831 break;
802832 case IWEVQUAL:
803833 {
804- event->u.qual.updated = 0x0; /* Not that reliable, disable */
805- iw_print_stats(buffer, &event->u.qual, iwrange, has_range);
834+ iw_print_stats(buffer, sizeof(buffer),
835+ &event->u.qual, iw_range, has_range);
806836 printf(" %s\n", buffer);
807837 break;
808838 }
809-#if WIRELESS_EXT > 14
810839 case IWEVCUSTOM:
811840 {
812841 char custom[IW_CUSTOM_MAX+1];
@@ -816,7 +845,6 @@ print_scanning_token(struct iw_event * event, /* Extracted token */
816845 printf(" Extra:%s\n", custom);
817846 }
818847 break;
819-#endif /* WIRELESS_EXT > 14 */
820848 default:
821849 printf(" (Unknown Wireless Token 0x%04X)\n",
822850 event->cmd);
@@ -837,13 +865,27 @@ print_scanning_info(int skfd,
837865 int count) /* Args count */
838866 {
839867 struct iwreq wrq;
840- unsigned char buffer[IW_SCAN_MAX_DATA]; /* Results */
868+ unsigned char * buffer = NULL; /* Results */
869+ int buflen = IW_SCAN_MAX_DATA; /* Min for compat WE<17 */
870+ struct iw_range range;
871+ int has_range;
841872 struct timeval tv; /* Select timeout */
842873 int timeout = 5000000; /* 5s */
843874
844875 /* Avoid "Unused parameter" warning */
845876 args = args; count = count;
846877
878+ /* Get range stuff */
879+ has_range = (iw_get_range_info(skfd, ifname, &range) >= 0);
880+
881+ /* Check if the interface could support scanning. */
882+ if((!has_range) || (range.we_version_compiled < 14))
883+ {
884+ fprintf(stderr, "%-8.16s Interface doesn't support scanning.\n\n",
885+ ifname);
886+ return(-1);
887+ }
888+
847889 /* Init timeout value -> 250ms*/
848890 tv.tv_sec = 0;
849891 tv.tv_usec = 250000;
@@ -852,15 +894,16 @@ print_scanning_info(int skfd,
852894 * Here we should look at the command line args and set the IW_SCAN_ flags
853895 * properly
854896 */
855- wrq.u.param.flags = IW_SCAN_DEFAULT;
856- wrq.u.param.value = 0; /* Later */
897+ wrq.u.data.pointer = NULL; /* Later */
898+ wrq.u.data.flags = 0;
899+ wrq.u.data.length = 0;
857900
858901 /* Initiate Scanning */
859902 if(iw_set_ext(skfd, ifname, SIOCSIWSCAN, &wrq) < 0)
860903 {
861904 if(errno != EPERM)
862905 {
863- fprintf(stderr, "%-8.8s Interface doesn't support scanning : %s\n\n",
906+ fprintf(stderr, "%-8.16s Interface doesn't support scanning : %s\n\n",
864907 ifname, strerror(errno));
865908 return(-1);
866909 }
@@ -869,7 +912,7 @@ print_scanning_info(int skfd,
869912 * But, don't wait !!! */
870913 #if 0
871914 /* Not cool, it display for non wireless interfaces... */
872- fprintf(stderr, "%-8.8s (Could not trigger scanning, just reading left-over results)\n", ifname);
915+ fprintf(stderr, "%-8.16s (Could not trigger scanning, just reading left-over results)\n", ifname);
873916 #endif
874917 tv.tv_usec = 0;
875918 }
@@ -903,12 +946,47 @@ print_scanning_info(int skfd,
903946 /* Check if there was a timeout */
904947 if(ret == 0)
905948 {
949+ unsigned char * newbuf;
950+
951+ realloc:
952+ /* (Re)allocate the buffer - realloc(NULL, len) == malloc(len) */
953+ newbuf = realloc(buffer, buflen);
954+ if(newbuf == NULL)
955+ {
956+ if(buffer)
957+ free(buffer);
958+ fprintf(stderr, "%s: Allocation failed\n", __FUNCTION__);
959+ return(-1);
960+ }
961+ buffer = newbuf;
962+
906963 /* Try to read the results */
907964 wrq.u.data.pointer = buffer;
908965 wrq.u.data.flags = 0;
909- wrq.u.data.length = sizeof(buffer);
966+ wrq.u.data.length = buflen;
910967 if(iw_get_ext(skfd, ifname, SIOCGIWSCAN, &wrq) < 0)
911968 {
969+ /* Check if buffer was too small (WE-17 only) */
970+ if((errno == E2BIG) && (range.we_version_compiled > 16))
971+ {
972+ /* Some driver may return very large scan results, either
973+ * because there are many cells, or because they have many
974+ * large elements in cells (like IWEVCUSTOM). Most will
975+ * only need the regular sized buffer. We now use a dynamic
976+ * allocation of the buffer to satisfy everybody. Of course,
977+ * as we don't know in advance the size of the array, we try
978+ * various increasing sizes. Jean II */
979+
980+ /* Check if the driver gave us any hints. */
981+ if(wrq.u.data.length > buflen)
982+ buflen = wrq.u.data.length;
983+ else
984+ buflen *= 2;
985+
986+ /* Try again */
987+ goto realloc;
988+ }
989+
912990 /* Check if results not available yet */
913991 if(errno == EAGAIN)
914992 {
@@ -921,7 +999,8 @@ print_scanning_info(int skfd,
921999 }
9221000
9231001 /* Bad error */
924- fprintf(stderr, "%-8.8s Failed to read scan data : %s\n\n",
1002+ free(buffer);
1003+ fprintf(stderr, "%-8.16s Failed to read scan data : %s\n\n",
9251004 ifname, strerror(errno));
9261005 return(-2);
9271006 }
@@ -940,23 +1019,21 @@ print_scanning_info(int skfd,
9401019 struct stream_descr stream;
9411020 int ap_num = 1;
9421021 int ret;
943- struct iw_range range;
944- int has_range;
9451022 #if 0
9461023 /* Debugging code. In theory useless, because it's debugged ;-) */
9471024 int i;
948- printf("Scan result [%02X", buffer[0]);
1025+ printf("Scan result %d [%02X", wrq.u.data.length, buffer[0]);
9491026 for(i = 1; i < wrq.u.data.length; i++)
9501027 printf(":%02X", buffer[i]);
9511028 printf("]\n");
9521029 #endif
953- has_range = (iw_get_range_info(skfd, ifname, &range) >= 0);
954- printf("%-8.8s Scan completed :\n", ifname);
1030+ printf("%-8.16s Scan completed :\n", ifname);
9551031 iw_init_event_stream(&stream, buffer, wrq.u.data.length);
9561032 do
9571033 {
9581034 /* Extract an event and print it */
959- ret = iw_extract_event_stream(&stream, &iwe);
1035+ ret = iw_extract_event_stream(&stream, &iwe,
1036+ range.we_version_compiled);
9601037 if(ret > 0)
9611038 ap_num = print_scanning_token(&iwe, ap_num, &range, has_range);
9621039 }
@@ -964,11 +1041,93 @@ print_scanning_info(int skfd,
9641041 printf("\n");
9651042 }
9661043 else
967- printf("%-8.8s No scan results\n", ifname);
1044+ printf("%-8.16s No scan results\n", ifname);
9681045
1046+ free(buffer);
1047+ return(0);
1048+}
1049+
1050+/******************** WIRELESS EVENT CAPABILITY ********************/
1051+
1052+static const char * event_capa_req[] =
1053+{
1054+ [SIOCSIWNWID - SIOCIWFIRST] = "Set NWID (kernel generated)",
1055+ [SIOCSIWFREQ - SIOCIWFIRST] = "Set Frequency/Channel (kernel generated)",
1056+ [SIOCGIWFREQ - SIOCIWFIRST] = "New Frequency/Channel",
1057+ [SIOCSIWMODE - SIOCIWFIRST] = "Set Mode (kernel generated)",
1058+ [SIOCGIWTHRSPY - SIOCIWFIRST] = "Spy threshold crossed",
1059+ [SIOCGIWAP - SIOCIWFIRST] = "New Access Point/Cell address - roaming",
1060+ [SIOCGIWSCAN - SIOCIWFIRST] = "Scan request completed",
1061+ [SIOCSIWESSID - SIOCIWFIRST] = "Set ESSID (kernel generated)",
1062+ [SIOCGIWESSID - SIOCIWFIRST] = "New ESSID",
1063+ [SIOCGIWRATE - SIOCIWFIRST] = "New bit-rate",
1064+ [SIOCSIWENCODE - SIOCIWFIRST] = "Set Encoding (kernel generated)",
1065+ [SIOCGIWPOWER - SIOCIWFIRST] = NULL,
1066+};
1067+
1068+static const char * event_capa_evt[] =
1069+{
1070+ [IWEVTXDROP - IWEVFIRST] = "Tx packet dropped - retry exceeded",
1071+ [IWEVCUSTOM - IWEVFIRST] = "Custom driver event",
1072+ [IWEVREGISTERED - IWEVFIRST] = "Registered node",
1073+ [IWEVEXPIRED - IWEVFIRST] = "Expired node",
1074+};
1075+
1076+/*------------------------------------------------------------------*/
1077+/*
1078+ * Print the number of available transmit powers for the device
1079+ */
1080+static int
1081+print_event_capa_info(int skfd,
1082+ char * ifname,
1083+ char * args[], /* Command line args */
1084+ int count) /* Args count */
1085+{
1086+ struct iw_range range;
1087+ int cmd;
1088+
1089+ /* Avoid "Unused parameter" warning */
1090+ args = args; count = count;
1091+
1092+ /* Extract range info */
1093+ if((iw_get_range_info(skfd, ifname, &range) < 0) ||
1094+ (range.we_version_compiled < 10))
1095+ fprintf(stderr, "%-8.16s no wireless event capability information.\n\n",
1096+ ifname);
1097+ else
1098+ {
1099+#if 0
1100+ /* Debugging ;-) */
1101+ for(cmd = 0x8B00; cmd < 0x8C0F; cmd++)
1102+ {
1103+ int idx = IW_EVENT_CAPA_INDEX(cmd);
1104+ int mask = IW_EVENT_CAPA_MASK(cmd);
1105+ printf("0x%X - %d - %X\n", cmd, idx, mask);
1106+ }
1107+#endif
1108+
1109+ printf("%-8.16s Wireless Events supported :\n", ifname);
1110+
1111+ for(cmd = SIOCIWFIRST; cmd <= SIOCGIWPOWER; cmd++)
1112+ {
1113+ int idx = IW_EVENT_CAPA_INDEX(cmd);
1114+ int mask = IW_EVENT_CAPA_MASK(cmd);
1115+ if(range.event_capa[idx] & mask)
1116+ printf(" 0x%04X : %s\n",
1117+ cmd, event_capa_req[cmd - SIOCIWFIRST]);
1118+ }
1119+ for(cmd = IWEVFIRST; cmd <= IWEVEXPIRED; cmd++)
1120+ {
1121+ int idx = IW_EVENT_CAPA_INDEX(cmd);
1122+ int mask = IW_EVENT_CAPA_MASK(cmd);
1123+ if(range.event_capa[idx] & mask)
1124+ printf(" 0x%04X : %s\n",
1125+ cmd, event_capa_evt[cmd - IWEVFIRST]);
1126+ }
1127+ printf("\n");
1128+ }
9691129 return(0);
9701130 }
971-#endif /* WIRELESS_EXT > 13 */
9721131
9731132 /************************* COMMON UTILITIES *************************/
9741133 /*
@@ -985,23 +1144,20 @@ typedef struct iwlist_entry {
9851144 } iwlist_cmd;
9861145
9871146 static const struct iwlist_entry iwlist_cmds[] = {
1147+ { "scanning", print_scanning_info, 0, 5 },
9881148 { "frequency", print_freq_info, 0, 0 },
9891149 { "channel", print_freq_info, 0, 0 },
990- { "ap", print_ap_info, 0, 0 },
991- { "accesspoints", print_ap_info, 0, 0 },
992- { "peers", print_ap_info, 0, 0 },
9931150 { "bitrate", print_bitrate_info, 0, 0 },
9941151 { "rate", print_bitrate_info, 0, 0 },
9951152 { "encryption", print_keys_info, 0, 0 },
9961153 { "key", print_keys_info, 0, 0 },
9971154 { "power", print_pm_info, 0, 0 },
9981155 { "txpower", print_txpower_info, 0, 0 },
999-#if WIRELESS_EXT > 10
10001156 { "retry", print_retry_info, 0, 0 },
1001-#endif
1002-#if WIRELESS_EXT > 13
1003- { "scanning", print_scanning_info, 0, 5 },
1004-#endif
1157+ { "ap", print_ap_info, 0, 0 },
1158+ { "accesspoints", print_ap_info, 0, 0 },
1159+ { "peers", print_ap_info, 0, 0 },
1160+ { "event", print_event_capa_info, 0, 0 },
10051161 { NULL, NULL, 0, 0 },
10061162 };
10071163
@@ -1141,7 +1297,7 @@ main(int argc,
11411297 iw_enum_devices(skfd, iwcmd->fn, args, count);
11421298
11431299 /* Close the socket. */
1144- close(skfd);
1300+ iw_sockets_close(skfd);
11451301
11461302 return 0;
11471303 }
--- a/wireless_tools/iwpriv.c
+++ b/wireless_tools/iwpriv.c
@@ -1,14 +1,14 @@
11 /*
22 * Wireless Tools
33 *
4- * Jean II - HPLB 97->99 - HPL 99->00
4+ * Jean II - HPLB 97->99 - HPL 99->04
55 *
66 * Main code for "iwconfig". This is the generic tool for most
77 * manipulations...
88 * You need to link this code against "iwlib.c" and "-lm".
99 *
1010 * This file is released under the GPL license.
11- * Copyright (c) 1997-2002 Jean Tourrilhes <jt@hpl.hp.com>
11+ * Copyright (c) 1997-2004 Jean Tourrilhes <jt@hpl.hp.com>
1212 */
1313
1414 #include "iwlib.h" /* Header */
@@ -16,6 +16,29 @@
1616 /************************** DOCUMENTATION **************************/
1717
1818 /*
19+ * BASIC PRINCIPLE
20+ * ---------------
21+ * Wireless Extension recognise that each wireless device has some
22+ * specific features not covered by the standard wireless extensions.
23+ * Private wireless ioctls/requests allow a device to export the control
24+ * of those device specific features, and allow users to directly interact
25+ * with your driver.
26+ * There are many other ways you can implement such functionality :
27+ * o module parameters
28+ * o netlink socket
29+ * o file system (/proc/ or /sysfs/)
30+ * o extra character device (/dev/)
31+ * Private wireless ioctls is one of the simplest implementation,
32+ * however it is limited, so you may want to check the alternatives.
33+ *
34+ * Like for standard Wireless Extensions, each private wireless
35+ * request is identified by an IOCTL NUMBER and carry a certain number
36+ * of arguments (SET or GET).
37+ * The driver exports a description of those requests (ioctl number,
38+ * request name, set and get arguments). Then, iwpriv uses those request
39+ * descriptions to call the appropriate request and handle the
40+ * arguments.
41+ *
1942 * IOCTL RANGES :
2043 * ------------
2144 * The initial implementation of iwpriv was using the SIOCDEVPRIVATE
@@ -27,74 +50,99 @@
2750 * worry about collisions with other usages. On the other hand, in the
2851 * new range, the SET convention is enforced (see below).
2952 * The differences are : SIOCDEVPRIVATE SIOCIWFIRSTPRIV
30- * o availability : <= 2.5.X WE > 11 (>= 2.4.13)
53+ * o availability <= 2.5.X WE > 11 (>= 2.4.13)
3154 * o collisions yes no
3255 * o SET convention optional enforced
3356 * o number 16 32
3457 *
3558 * NEW DRIVER API :
3659 * --------------
37- * Wireless Extension 13 introduce a new driver API. Wireless
60+ * Wireless Extension 13 introduces a new driver API. Wireless
3861 * Extensions requests can be handled via a iw_handler table instead
3962 * of through the regular ioctl handler.
4063 * The new driver API can be handled only with the new ioctl range
41- * and enforce the GET convention (see below).
64+ * and enforces the GET convention (see below).
4265 * The differences are : old API new API
4366 * o handler do_ioctl() struct iw_handler_def
4467 * o SIOCIWFIRSTPRIV WE > 11 yes
4568 * o SIOCDEVPRIVATE yes no
4669 * o GET convention optional enforced
4770 * Note that the new API before Wireless Extension 15 contains bugs
48- * with regards to handling sub-ioctls and addr/float data types.
71+ * when handling sub-ioctls and addr/float data types.
72+ *
73+ * INLINING vs. POINTER :
74+ * --------------------
75+ * One of the tricky aspect of the old driver API is how the data
76+ * is handled, which is how the driver is supposed to extract the data
77+ * passed to it by iwpriv.
78+ * 1) If the data has a fixed size (private ioctl definition
79+ * has the flag IW_PRIV_SIZE_FIXED) and the byte size of the data is
80+ * lower than 16 bytes, the data will be inlined. The driver can extract
81+ * data in the field 'u.name' of the struct iwreq.
82+ * 2) If the if the data doesn't have a fixed size or is larger than
83+ * 16 bytes, the data is passed by pointer. struct iwreq contains a
84+ * struct iwpoint with a user space pointer to the data. Appropriate
85+ * copy_from/to_user() function should be used.
86+ *
87+ * With the new API, this is handled transparently, the data is
88+ * always available as the fourth argument of the request handler
89+ * (usually called 'extra').
4990 *
5091 * SET/GET CONVENTION :
5192 * ------------------
52- * The regular Wireless Extensions use a SET/GET convention, where
53- * the low order bit identify a SET (0) or a GET (1) request.
54- * The new ioctl range enforce the SET convention : SET request will
93+ * Simplistic summary :
94+ * o even numbered ioctls are SET, restricted to root, and should not
95+ * return arguments (get_args = 0).
96+ * o odd numbered ioctls are GET, authorised to anybody, and should
97+ * not expect any arguments (set_args = 0).
98+ *
99+ * The regular Wireless Extensions use the SET/GET convention, where
100+ * the low order bit identify a SET (0) or a GET (1) request. The private
101+ * Wireless Extension is not as restrictive, but still has some
102+ * limitations.
103+ * The new ioctl range enforces the SET convention : SET request will
55104 * be available to root only and can't return any arguments. If you don't
56105 * like that, just use every other two ioctl.
57106 * The new driver API enforce the GET convention : GET request won't
58107 * be able to accept any arguments (except if its fits within (union
59- * iwreq_data)). If you don't like that, just use the old API (aka the
60- * ioctl handler).
108+ * iwreq_data)). If you don't like that, you can either use the Token Index
109+ * support or the old API (aka the ioctl handler).
61110 * In any case, it's a good idea to not have ioctl with both SET
62111 * and GET arguments. If the GET arguments doesn't fit within
63112 * (union iwreq_data) and SET do, or vice versa, the current code in iwpriv
64113 * won't work. One exception is if both SET and GET arguments fit within
65114 * (union iwreq_data), this case should be handled safely in a GET
66115 * request.
116+ * If you don't fully understand those limitations, just follow the
117+ * rules of the simplistic summary ;-)
67118 *
68119 * SUB-IOCTLS :
69120 * ----------
70- * Wireless Extension 15 introduce sub-ioctls. For some applications,
71- * 32 ioctl is not enough, and this simple mechanism allow to increase
72- * the number of ioctls by adding a sub-ioctl index to some of the ioctl
73- * (so basically a two level addressing).
121+ * Wireless Extension 15 introduces sub-ioctls. For some applications,
122+ * 32 ioctls is not enough, and this simple mechanism allows to increase
123+ * the number of ioctls by adding a sub-ioctl index to some of the ioctls
124+ * (so basically it's a two level addressing).
74125 * One might argue that at the point, some other mechanisms might be
75126 * better, like using a real filesystem abstraction (/proc, driverfs, ...),
76- * but sub-ioctls are simple enough to not have much drawbacks (which means
77- * that it's a quick and dirty hack ;-).
127+ * but sub-ioctls are simple enough and don't have much drawbacks (which
128+ * means that it's a quick and dirty hack ;-).
78129 *
79- * There is two slightly different variation of the sub-ioctl scheme :
80- * If the payload fit within (union iwreq_data), the first int (4 bytes)
81- * is reserved as the sub-ioctl number and the regular payload shifted by
82- * 4 bytes.
83- * If the ioctl use (struct iw_point), the sub-ioctl number is in the
84- * flags member of the structure.
85- * Then, in your handler you would just extract the sub-ioctl number
86- * and do the appropriate processing.
130+ * There are two slightly different variations of the sub-ioctl scheme :
131+ * 1) If the payload fits within (union iwreq_data), the first int
132+ * (4 bytes) is reserved as the sub-ioctl number and the regular payload
133+ * shifted by 4 bytes. The handler must extract the sub-ioctl number,
134+ * increment the data pointer and then use it in the usual way.
135+ * 2) If the ioctl uses (struct iw_point), the sub-ioctl number is
136+ * set in the flags member of the structure. In this case, the handler
137+ * should simply get the sub-ioctl number from the flags and process the
138+ * data in the usual way.
87139 *
88140 * Sub-ioctls are declared normally in the private definition table,
89- * with cmd (first arg) beeing the sub-ioctl number. Then, you need to
90- * declare the real ioctl which will process the sub-ioctls with the
91- * SAME ARGUMENTS and a NULL NAME.
92- * It could look like, for example :
141+ * with cmd (first arg) being the sub-ioctl number. Then, you should
142+ * declare the real ioctl, which will process the sub-ioctls, with
143+ * the SAME ARGUMENTS and a EMPTY NAME.
144+ * Here's an example of how it could look like :
93145 * --------------------------------------------
94- // --- Raw access to sub-ioctl handlers ---
95- { 0x8BE0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "set_paramN" },
96- { 0x8BE1, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
97- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_paramN" },
98146 // --- sub-ioctls handlers ---
99147 { 0x8BE0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "" },
100148 { 0x8BE1, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "" },
@@ -103,21 +151,26 @@
103151 { 1, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_param1" },
104152 { 2, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_param2" },
105153 { 2, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_param2" },
154+ // --- Raw access to sub-ioctl handlers ---
155+ { 0x8BE0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "set_paramN" },
156+ { 0x8BE1, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
157+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_paramN" },
106158 * --------------------------------------------
107159 * And iwpriv should do the rest for you ;-)
108160 *
109- * Note that version of iwpriv up to v24 (included) expect at most
161+ * Note that versions of iwpriv up to v24 (included) expect at most
110162 * 16 ioctls definitions and will likely crash when given more.
111- * There is no fix that I can see, apart from recommending an upgrade
112- * of Wireless Tools. Wireless Extensions 15 will check this condition, so
113- * another workaround is restricting those extra definitions to WE-15.
163+ * There is no fix that I can see, apart from recommending your users
164+ * to upgrade their Wireless Tools. Wireless Extensions 15 will check this
165+ * condition, so another workaround is restricting those extra definitions
166+ * to WE-15.
114167 *
115- * Another problem is that new API before Wireless Extension 15
116- * will get it wrong when passing fixed arguments of 12-15 bytes. It will
168+ * Another problem is that the new API before Wireless Extension 15
169+ * has a bug when passing fixed arguments of 12-15 bytes. It will
117170 * try to get them inline instead of by pointer. You can fool the new API
118171 * to do the right thing using fake ioctl definitions (but remember that
119- * you will get more likely to hit the limit of 16 ioctl definitions).
120- * For safety, use the ioctl handler before v15.
172+ * you will be more likely to hit the limit of 16 ioctl definitions).
173+ * To play safe, use the old-style ioctl handler before v15.
121174 *
122175 * NEW DATA TYPES (ADDR/FLOAT) :
123176 * ---------------------------
@@ -127,7 +180,7 @@
127180 * However, the new API before v15 won't handle them properly.
128181 *
129182 * The first problem is that the new API won't know their size, so
130- * won't copy them. This can be workaround with a fake ioctl definition.
183+ * it won't copy them. This can be workaround with a fake ioctl definition.
131184 * The second problem is that a fixed single addr won't be inlined
132185 * in struct iwreq and will be passed as a pointer. This is due to an
133186 * off-by-one error, where all fixed data of 16 bytes is considered too
@@ -138,17 +191,19 @@
138191 *
139192 * TOKEN INDEX :
140193 * -----------
141- * Token index is very similar to sub-ioctl. It allow the user
194+ * Token index is very similar to sub-ioctl. It allows the user
142195 * to specify an integer index in front of a bunch of other arguments
143- * (addresses, strings, ...).
144- * Token index works only with data passed as pointer, and is
145- * otherwise ignored. If your data would fit within struct iwreq, you
146- * need to declare the command *without* IW_PRIV_SIZE_FIXED to force
196+ * (addresses, strings, ...). It's specified in square brackets on the
197+ * iwpriv command line before other arguments.
198+ * > iwpriv eth0 [index] args...
199+ * Token index works only when the data is passed as pointer, and
200+ * is otherwise ignored. If your data would fit within struct iwreq, you
201+ * should declare the command *without* IW_PRIV_SIZE_FIXED to force
147202 * this to happen (and check arg number yourself).
148203 * --------------------------------------------
149204 // --- Commands that would fit in struct iwreq ---
150205 { 0x8BE0, IW_PRIV_TYPE_ADDR | 1, 0, "set_param_with_token" },
151- // --- No problem here ---
206+ // --- No problem here (bigger than struct iwreq) ---
152207 { 0x8BE1, IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 2, 0, "again" },
153208 * --------------------------------------------
154209 * The token index feature is pretty transparent, the token index
@@ -156,7 +211,7 @@
156211 * (if the user doesn't specify it) will be 0. Token index itself will
157212 * work with any version of Wireless Extensions.
158213 * Token index is not compatible with sub-ioctl (both use the same
159- * field of struct iw_point). However, token index can be use to offer
214+ * field of struct iw_point). However, the token index can be used to offer
160215 * raw access to the sub-ioctl handlers (if it uses struct iw_point) :
161216 * --------------------------------------------
162217 // --- sub-ioctls handler ---
@@ -176,13 +231,6 @@
176231 static const char * argtype[] = {
177232 " ", "byte ", "char ", "", "int ", "float", "addr " };
178233
179-#define IW_MAX_PRIV_DEF 128
180-
181-/* Backward compatibility */
182-#ifndef IW_PRIV_TYPE_ADDR
183-#define IW_PRIV_TYPE_ADDR 0x6000
184-#endif /* IW_PRIV_TYPE_ADDR */
185-
186234 /************************* MISC SUBROUTINES **************************/
187235
188236 /*------------------------------------------------------------------*/
@@ -221,9 +269,9 @@ set_private_cmd(int skfd, /* Socket */
221269 int offset = 0; /* Space for sub-ioctl index */
222270
223271 /* Check if we have a token index.
224- * Do it know so that sub-ioctl takes precendence, and so that we
272+ * Do it now so that sub-ioctl takes precendence, and so that we
225273 * don't have to bother with it later on... */
226- if((count > 1) && (sscanf(args[0], "[%i]", &temp) == 1))
274+ if((count >= 1) && (sscanf(args[0], "[%i]", &temp) == 1))
227275 {
228276 subcmd = temp;
229277 args++;
@@ -261,13 +309,15 @@ set_private_cmd(int skfd, /* Socket */
261309
262310 /* Save sub-ioctl number */
263311 subcmd = priv[k].cmd;
264- /* Reserve one int (simplify alignement issues) */
312+ /* Reserve one int (simplify alignment issues) */
265313 offset = sizeof(__u32);
266314 /* Use real ioctl definition from now on */
267315 k = j;
268316
317+#if 0
269318 printf("<mapping sub-ioctl %s to cmd 0x%X-%d>\n", cmdname,
270319 priv[k].cmd, subcmd);
320+#endif
271321 }
272322
273323 /* If we have to set some data */
@@ -424,7 +474,7 @@ set_private_cmd(int skfd, /* Socket */
424474 int j;
425475 int n = 0; /* number of args */
426476
427- printf("%-8.8s %s:", ifname, cmdname);
477+ printf("%-8.16s %s:", ifname, cmdname);
428478
429479 /* Check where is the returned data */
430480 if((priv[k].get_args & IW_PRIV_SIZE_FIXED) &&
@@ -454,7 +504,7 @@ set_private_cmd(int skfd, /* Socket */
454504
455505 case IW_PRIV_TYPE_CHAR:
456506 /* Display args */
457- buffer[wrq.u.data.length - 1] = '\0';
507+ buffer[n] = '\0';
458508 printf("%s\n", buffer);
459509 break;
460510
@@ -512,31 +562,38 @@ set_private(int skfd, /* Socket */
512562 int count, /* Args count */
513563 char * ifname) /* Dev name */
514564 {
515- iwprivargs priv[IW_MAX_PRIV_DEF];
565+ iwprivargs * priv;
516566 int number; /* Max of private ioctl */
567+ int ret;
517568
518569 /* Read the private ioctls */
519- number = iw_get_priv_info(skfd, ifname, priv, IW_MAX_PRIV_DEF);
570+ number = iw_get_priv_info(skfd, ifname, &priv);
520571
521572 /* Is there any ? */
522573 if(number <= 0)
523574 {
524- /* Could skip this message ? */
525- fprintf(stderr, "%-8.8s no private ioctls.\n\n",
575+ /* Should I skip this message ? */
576+ fprintf(stderr, "%-8.16s no private ioctls.\n\n",
526577 ifname);
578+ if(priv)
579+ free(priv);
527580 return(-1);
528581 }
529582
530- return(set_private_cmd(skfd, args + 1, count - 1, ifname, args[0],
531- priv, number));
583+ /* Do it */
584+ ret = set_private_cmd(skfd, args + 1, count - 1, ifname, args[0],
585+ priv, number);
586+
587+ free(priv);
588+ return(ret);
532589 }
533590
534591 /************************ CATALOG FUNCTIONS ************************/
535592
536593 /*------------------------------------------------------------------*/
537594 /*
538- * Print on the screen in a neat fashion all the info we have collected
539- * on a device.
595+ * Print on the screen in a neat fashion the list of private ioctls
596+ * for the device.
540597 */
541598 static int
542599 print_priv_info(int skfd,
@@ -545,25 +602,25 @@ print_priv_info(int skfd,
545602 int count)
546603 {
547604 int k;
548- iwprivargs priv[IW_MAX_PRIV_DEF];
605+ iwprivargs * priv;
549606 int n;
550607
551608 /* Avoid "Unused parameter" warning */
552609 args = args; count = count;
553610
554611 /* Read the private ioctls */
555- n = iw_get_priv_info(skfd, ifname, priv, IW_MAX_PRIV_DEF);
612+ n = iw_get_priv_info(skfd, ifname, &priv);
556613
557614 /* Is there any ? */
558615 if(n <= 0)
559616 {
560- /* Could skip this message ? */
561- fprintf(stderr, "%-8.8s no private ioctls.\n\n",
617+ /* Should I skip this message ? */
618+ fprintf(stderr, "%-8.16s no private ioctls.\n\n",
562619 ifname);
563620 }
564621 else
565622 {
566- printf("%-8.8s Available private ioctl :\n", ifname);
623+ printf("%-8.16s Available private ioctl :\n", ifname);
567624 /* Print them all */
568625 for(k = 0; k < n; k++)
569626 if(priv[k].name[0] != '\0')
@@ -575,13 +632,17 @@ print_priv_info(int skfd,
575632 argtype[(priv[k].get_args & IW_PRIV_TYPE_MASK) >> 12]);
576633 printf("\n");
577634 }
635+
636+ /* Cleanup */
637+ if(priv)
638+ free(priv);
578639 return(0);
579640 }
580641
581642 /*------------------------------------------------------------------*/
582643 /*
583- * Print on the screen in a neat fashion all the info we have collected
584- * on a device.
644+ * Print on the screen in a neat fashion the list of private GET ioctl
645+ * data for the device and data returned by those.
585646 */
586647 static int
587648 print_priv_all(int skfd,
@@ -590,28 +651,28 @@ print_priv_all(int skfd,
590651 int count)
591652 {
592653 int k;
593- iwprivargs priv[IW_MAX_PRIV_DEF];
654+ iwprivargs * priv;
594655 int n;
595656
596657 /* Avoid "Unused parameter" warning */
597658 args = args; count = count;
598659
599660 /* Read the private ioctls */
600- n = iw_get_priv_info(skfd, ifname, priv, IW_MAX_PRIV_DEF);
661+ n = iw_get_priv_info(skfd, ifname, &priv);
601662
602663 /* Is there any ? */
603664 if(n <= 0)
604665 {
605- /* Could skip this message ? */
606- fprintf(stderr, "%-8.8s no private ioctls.\n\n",
666+ /* Should I skip this message ? */
667+ fprintf(stderr, "%-8.16s no private ioctls.\n\n",
607668 ifname);
608669 }
609670 else
610671 {
611- printf("%-8.8s Available read-only private ioctl :\n", ifname);
672+ printf("%-8.16s Available read-only private ioctl :\n", ifname);
612673 /* Print them all */
613674 for(k = 0; k < n; k++)
614- /* We call all ioctl that don't have a null name, don't require
675+ /* We call all ioctls that don't have a null name, don't require
615676 * args and return some (avoid triggering "reset" commands) */
616677 if((priv[k].name[0] != '\0') && (priv[k].set_args == 0) &&
617678 (priv[k].get_args != 0))
@@ -619,13 +680,10 @@ print_priv_all(int skfd,
619680 priv, n);
620681 printf("\n");
621682 }
622-#if 0
623- // Debug
624- printf("struct ifreq = %d ; struct iwreq = %d ; IFNAMSIZ = %d\n",
625- sizeof(struct ifreq), sizeof(struct iwreq), IFNAMSIZ);
626- printf("struct iw_freq = %d ; struct sockaddr = %d\n",
627- sizeof(struct iw_freq), sizeof(struct sockaddr));
628-#endif
683+
684+ /* Cleanup */
685+ if(priv)
686+ free(priv);
629687 return(0);
630688 }
631689
@@ -638,6 +696,8 @@ print_priv_all(int skfd,
638696 /*
639697 * Set roaming mode on and off
640698 * Found in wavelan_cs driver
699+ * Note : this is obsolete, most 802.11 devices should use the
700+ * SIOCSIWAP request.
641701 */
642702 static int
643703 set_roaming(int skfd, /* Socket */
@@ -649,24 +709,41 @@ set_roaming(int skfd, /* Socket */
649709 struct iwreq wrq;
650710 int i = 0; /* Start with first arg */
651711 int k;
652- iwprivargs priv[IW_MAX_PRIV_DEF];
712+ iwprivargs * priv;
653713 int number;
714+ int roamcmd;
654715 char RoamState; /* buffer to hold new roam state */
655716 char ChangeRoamState=0; /* whether or not we are going to
656717 change roam states */
657718
658719 /* Read the private ioctls */
659- number = iw_get_priv_info(skfd, ifname, priv, IW_MAX_PRIV_DEF);
720+ number = iw_get_priv_info(skfd, ifname, &priv);
660721
661722 /* Is there any ? */
662723 if(number <= 0)
663724 {
664- /* Could skip this message ? */
665- fprintf(stderr, "%-8.8s no private ioctls.\n\n",
725+ /* Should I skip this message ? */
726+ fprintf(stderr, "%-8.16s no private ioctls.\n\n",
666727 ifname);
728+ if(priv)
729+ free(priv);
667730 return(-1);
668731 }
669732
733+ /* Get the ioctl number */
734+ k = -1;
735+ while((++k < number) && strcmp(priv[k].name, "setroam"));
736+ if(k == number)
737+ {
738+ fprintf(stderr, "This device doesn't support roaming\n");
739+ free(priv);
740+ return(-1);
741+ }
742+ roamcmd = priv[k].cmd;
743+
744+ /* Cleanup */
745+ free(priv);
746+
670747 if(count != 1)
671748 {
672749 iw_usage();
@@ -675,7 +752,7 @@ set_roaming(int skfd, /* Socket */
675752
676753 if(!strcasecmp(args[i], "on"))
677754 {
678- printf("%-8.8s enable roaming\n", ifname);
755+ printf("%-8.16s enable roaming\n", ifname);
679756 if(!number)
680757 {
681758 fprintf(stderr, "This device doesn't support roaming\n");
@@ -688,7 +765,7 @@ set_roaming(int skfd, /* Socket */
688765 if(!strcasecmp(args[i], "off"))
689766 {
690767 i++;
691- printf("%-8.8s disable roaming\n", ifname);
768+ printf("%-8.16s disable roaming\n", ifname);
692769 if(!number)
693770 {
694771 fprintf(stderr, "This device doesn't support roaming\n");
@@ -705,20 +782,13 @@ set_roaming(int skfd, /* Socket */
705782
706783 if(ChangeRoamState)
707784 {
708- k = -1;
709- while((++k < number) && strcmp(priv[k].name, "setroam"));
710- if(k == number)
711- {
712- fprintf(stderr, "This device doesn't support roaming\n");
713- return(-1);
714- }
715785 strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
716786
717787 buffer[0]=RoamState;
718788
719789 memcpy(wrq.u.name, &buffer, IFNAMSIZ);
720790
721- if(ioctl(skfd, priv[k].cmd, &wrq) < 0)
791+ if(ioctl(skfd, roamcmd, &wrq) < 0)
722792 {
723793 fprintf(stderr, "Roaming support is broken.\n");
724794 return(-1);
@@ -732,6 +802,7 @@ set_roaming(int skfd, /* Socket */
732802 /*
733803 * Get and set the port type
734804 * Found in wavelan2_cs and wvlan_cs drivers
805+ * TODO : Add support for HostAP ?
735806 */
736807 static int
737808 port_type(int skfd, /* Socket */
@@ -742,19 +813,21 @@ port_type(int skfd, /* Socket */
742813 struct iwreq wrq;
743814 int i = 0; /* Start with first arg */
744815 int k;
745- iwprivargs priv[IW_MAX_PRIV_DEF];
816+ iwprivargs * priv;
746817 int number;
747818 char ptype = 0;
748819 char * modes[] = { "invalid", "managed (BSS)", "reserved", "ad-hoc" };
749820
750821 /* Read the private ioctls */
751- number = iw_get_priv_info(skfd, ifname, priv, IW_MAX_PRIV_DEF);
822+ number = iw_get_priv_info(skfd, ifname, &priv);
752823
753824 /* Is there any ? */
754825 if(number <= 0)
755826 {
756- /* Could skip this message ? */
757- fprintf(stderr, "%-8.8s no private ioctls.\n\n", ifname);
827+ /* Should I skip this message ? */
828+ fprintf(stderr, "%-8.16s no private ioctls.\n\n", ifname);
829+ if(priv)
830+ free(priv);
758831 return(-1);
759832 }
760833
@@ -768,7 +841,7 @@ port_type(int skfd, /* Socket */
768841 if(k == number)
769842 {
770843 fprintf(stderr, "This device doesn't support getting port type\n");
771- return(-1);
844+ goto err;
772845 }
773846 strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
774847
@@ -776,21 +849,22 @@ port_type(int skfd, /* Socket */
776849 if(ioctl(skfd, priv[k].cmd, &wrq) < 0)
777850 {
778851 fprintf(stderr, "Port type support is broken.\n");
779- exit(0);
852+ goto err;
780853 }
781854 ptype = *wrq.u.name;
782855
783856 /* Display it */
784- printf("%-8.8s Current port mode is %s <port type is %d>.\n\n",
857+ printf("%-8.16s Current port mode is %s <port type is %d>.\n\n",
785858 ifname, modes[(int) ptype], ptype);
786859
860+ free(priv);
787861 return(0);
788862 }
789863
790864 if(count != 1)
791865 {
792866 iw_usage();
793- return(-1);
867+ goto err;
794868 }
795869
796870 /* Read it */
@@ -805,7 +879,7 @@ port_type(int skfd, /* Socket */
805879 if(sscanf(args[i], "%i", (int *) &ptype) != 1)
806880 {
807881 iw_usage();
808- return(-1);
882+ goto err;
809883 }
810884
811885 k = -1;
@@ -814,7 +888,7 @@ port_type(int skfd, /* Socket */
814888 if(k == number)
815889 {
816890 fprintf(stderr, "This device doesn't support setting port type\n");
817- return(-1);
891+ goto err;
818892 }
819893 strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
820894
@@ -823,10 +897,15 @@ port_type(int skfd, /* Socket */
823897 if(ioctl(skfd, priv[k].cmd, &wrq) < 0)
824898 {
825899 fprintf(stderr, "Invalid port type (or setting not allowed)\n");
826- return(-1);
900+ goto err;
827901 }
828902
903+ free(priv);
829904 return(0);
905+
906+ err:
907+ free(priv);
908+ return(-1);
830909 }
831910
832911 /******************************* MAIN ********************************/
@@ -849,7 +928,7 @@ main(int argc,
849928 return(-1);
850929 }
851930
852- /* No argument : show the list of all device + info */
931+ /* No argument : show the list of all devices + ioctl list */
853932 if(argc == 1)
854933 iw_enum_devices(skfd, &print_priv_info, NULL, 0);
855934 else
@@ -890,7 +969,7 @@ main(int argc,
890969 goterr = set_private(skfd, argv + 2, argc - 2, argv[1]);
891970
892971 /* Close the socket. */
893- close(skfd);
972+ iw_sockets_close(skfd);
894973
895974 return(goterr);
896975 }
--- a/wireless_tools/iwredir.8
+++ /dev/null
@@ -1,89 +0,0 @@
1-.\" Jean II - HPL - 03
2-.\" iwredir.8
3-.\"
4-.TH IWREDIR 8 "31 October 1996" "net-tools" "Linux Programmer's Manual"
5-.\"
6-.\" NAME part
7-.\"
8-.SH NAME
9-iwredir \- WE-version wireless tool redirectot
10-.\"
11-.\" SYNOPSIS part
12-.\"
13-.SH SYNOPSIS
14-.BI "iw" XXX " [ " args " ]"
15-.br
16-.BI "iwredir -wev
17-.\"
18-.\" DESCRIPTION part
19-.\"
20-.SH DESCRIPTION
21-.B Iwredir
22-is used to enable the use multiple version of the Wireless Tools on
23-the same system.
24-.B Iwredir
25-pick the proper version of the wireless tools based on the version of
26-Wireless Extension of the current kernel.
27-.PP
28-A version of the Wireless Tools need to be compiled for each version
29-of Wireless Extensions expected to be used (this require specific
30-.I make
31-instructions), and each tool name need to be suffixed by the WE
32-version (ex.
33-.I iwconfig16
34-for the binary of iwconfig compiled for Wireless Extension 16).
35-.br
36-Then,
37-.B iwredir
38-need to be installed under the name of each of the tool that need
39-redirection
40-.RI "(" iwconfig ", " iwlist "...)."
41-.br
42-.B Iwredir
43-just adds the version of WE from the current kernel to the name it was
44-called and executed the resulting command name. If the user invoque
45-.I iwlist
46-(that is now replaced with
47-.IR iwredir )
48-and the current kernel has WE version
49-.IR 17 ,
50-the final command executed will be
51-.IR iwlist17 .
52-.br
53-.B Iwredir
54-will read the Wireless Extension version of the current kernel from
55-.IR /proc/net/wireless .
56-.PP
57-.B Iwredir
58-works only for Wireless Extension 16 and later, all previous version
59-of WE are assumed to be version 15 or version 11.
60-.B Iwredir
61-is usually not installed by default and is expected to be used only by
62-.I advanced
63-users.
64-.\"
65-.\" PARAMETER part
66-.\"
67-.SH PARAMETERS
68-.TP
69-.BR -wev
70-Give the Wireless Extension version that
71-.B iwredir
72-will use for redirection. This is mostly used in the Wireless Tools
73-Makefile when doing a versioned installation of the tools.
74-.\"
75-.\" FILES part
76-.\"
77-.SH FILES
78-.I /proc/net/wireless
79-.\"
80-.\" SEE ALSO part
81-.\"
82-.SH SEE ALSO
83-.BR iwconfig (8),
84-.BR iwlist (8),
85-.BR iwspy (8),
86-.BR iwevent (8),
87-.BR iwpriv (8),
88-.BR wireless (7).
89-
--- a/wireless_tools/iwredir.c
+++ /dev/null
@@ -1,124 +0,0 @@
1-/*
2- * Wireless Tools
3- *
4- * Jean II - HPL 03
5- *
6- * Main code for "iwredir". This is a hack to match multiple version
7- * of the tools with multiple kernels on the same system...
8- *
9- * This file is released under the GPL license.
10- * Copyright (c) 2003 Jean Tourrilhes <jt@hpl.hp.com>
11- */
12-
13-/***************************** INCLUDES *****************************/
14-
15-#include "iwlib.h" /* Header */
16-
17-/*********************** VERSION SUBROUTINES ***********************/
18-
19-/*------------------------------------------------------------------*/
20-/*
21- * Extract WE version number from /proc/net/wireless
22- * If we have WE-16 and later, the WE version is available at the
23- * end of the header line of the file.
24- * For version prior to that, we can only detect the change from
25- * v11 to v12, so we do an approximate job. Fortunately, v12 to v15
26- * are highly binary compatible (on the struct level).
27- */
28-static int
29-iw_get_kernel_we_version(void)
30-{
31- char buff[1024];
32- FILE * fh;
33- char * p;
34- int v;
35-
36- /* Check if /proc/net/wireless is available */
37- fh = fopen(PROC_NET_WIRELESS, "r");
38-
39- if(fh == NULL)
40- {
41- fprintf(stderr, "Cannot read " PROC_NET_WIRELESS "\n");
42- return(-1);
43- }
44-
45- /* Read the first line of buffer */
46- fgets(buff, sizeof(buff), fh);
47-
48- if(strstr(buff, "| WE") == NULL)
49- {
50- /* Prior to WE16, so explicit version not present */
51-
52- /* Black magic */
53- if(strstr(buff, "| Missed") == NULL)
54- v = 11;
55- else
56- v = 15;
57- fclose(fh);
58- return(v);
59- }
60-
61- /* Read the second line of buffer */
62- fgets(buff, sizeof(buff), fh);
63-
64- /* Get to the last separator, to get the version */
65- p = strrchr(buff, '|');
66- if((p == NULL) || (sscanf(p + 1, "%d", &v) != 1))
67- {
68- fprintf(stderr, "Cannot parse " PROC_NET_WIRELESS "\n");
69- fclose(fh);
70- return(-1);
71- }
72-
73- fclose(fh);
74- return(v);
75-}
76-
77-/******************************* MAIN ********************************/
78-
79-/*------------------------------------------------------------------*/
80-/*
81- * The main !
82- */
83-int
84-main(int argc,
85- char ** argv)
86-{
87- int version = 0;
88- int goterr = 0;
89- char file[512];
90- int flen;
91-
92- /* Get current version */
93- version = iw_get_kernel_we_version();
94- if(version <= 0)
95- version = 15; /* We can only read only WE16 and higher */
96-
97- /* Special case for Wireless Extension Version... */
98- /* This is mostly used in the Makefile, we use an "unlikely" option
99- * to maximise transparency to the tool we masquerade - Jean II */
100- if((argc > 1) && !strcmp(argv[1], "-wev"))
101- {
102- printf("%d\n", version);
103- return(version);
104- }
105-
106- /* Mangle the command name */
107- flen = strlen(argv[0]);
108- if((flen + 3) >= 512)
109- {
110- fprintf(stderr, "Command name too long [%s]\n", argv[0]);
111- return(-1);
112- }
113- memcpy(file, argv[0], flen + 1);
114- sprintf(file + flen, "%d", version);
115-
116- /* Execute (won't return) */
117- goterr = execvp(file, argv);
118-
119- /* In case of error */
120- fprintf(stderr, "Can't execute command %s: %s\n", file, strerror(errno));
121- return(goterr);
122-}
123-
124-
--- a/wireless_tools/iwspy.c
+++ b/wireless_tools/iwspy.c
@@ -1,13 +1,13 @@
11 /*
22 * Wireless Tools
33 *
4- * Jean II - HPLB '99
4+ * Jean II - HPLB '99 - HPL 99->04
55 *
66 * This tool can manipulate the spy list : add addresses and display stat
77 * You need to link this code against "iwlib.c" and "-lm".
88 *
99 * This file is released under the GPL license.
10- * Copyright (c) 1997-2002 Jean Tourrilhes <jt@hpl.hp.com>
10+ * Copyright (c) 1997-2004 Jean Tourrilhes <jt@hpl.hp.com>
1111 */
1212
1313 #include "iwlib.h" /* Header */
@@ -44,7 +44,7 @@ print_spy_info(int skfd,
4444 wrq.u.data.flags = 0;
4545 if(iw_get_ext(skfd, ifname, SIOCGIWSPY, &wrq) < 0)
4646 {
47- fprintf(stderr, "%-8.8s Interface doesn't support wireless statistic collection\n\n", ifname);
47+ fprintf(stderr, "%-8.16s Interface doesn't support wireless statistic collection\n\n", ifname);
4848 return(-1);
4949 }
5050
@@ -54,7 +54,7 @@ print_spy_info(int skfd,
5454 /* Check if we have valid mac address type */
5555 if(iw_check_mac_addr_type(skfd, ifname) < 0)
5656 {
57- fprintf(stderr, "%-8.8s Interface doesn't support MAC addresses\n\n", ifname);
57+ fprintf(stderr, "%-8.16s Interface doesn't support MAC addresses\n\n", ifname);
5858 return(-2);
5959 }
6060
@@ -64,9 +64,9 @@ print_spy_info(int skfd,
6464
6565 /* Display it */
6666 if(n == 0)
67- printf("%-8.8s No statistics to collect\n", ifname);
67+ printf("%-8.16s No statistics to collect\n", ifname);
6868 else
69- printf("%-8.8s Statistics collected:\n", ifname);
69+ printf("%-8.16s Statistics collected:\n", ifname);
7070
7171 /* The two lists */
7272 hwa = (struct sockaddr *) buffer;
@@ -76,25 +76,25 @@ print_spy_info(int skfd,
7676 {
7777 /* Print stats for each address */
7878 printf(" %s : ", iw_pr_ether(temp, hwa[i].sa_data));
79- iw_print_stats(temp, &qual[i], &range, has_range);
79+ iw_print_stats(temp, sizeof(temp), &qual[i], &range, has_range);
8080 printf("%s\n", temp);
8181 }
82-#if WIRELESS_EXT > 11
83- if((n > 0) && (has_range))
82+
83+ if((n > 0) && (has_range) && (range.we_version_compiled > 11))
8484 {
8585 iwstats stats;
8686
8787 /* Get /proc/net/wireless */
88- if(iw_get_stats(skfd, ifname, &stats) >= 0)
88+ if(iw_get_stats(skfd, ifname, &stats, &range, has_range) >= 0)
8989 {
90- iw_print_stats(buffer, &stats.qual, &range, has_range);
91- printf(" Link/Cell/AP : %s\n", buffer);
90+ iw_print_stats(temp, sizeof(temp), &stats.qual, &range, has_range);
91+ printf(" Link/Cell/AP : %s\n", temp);
9292 /* Display the static data */
93- iw_print_stats(temp, &range.avg_qual, &range, has_range);
93+ iw_print_stats(temp, sizeof(temp),
94+ &range.avg_qual, &range, has_range);
9495 printf(" Typical/Reference : %s\n", temp);
9596 }
9697 }
97-#endif /* WIRELESS_EXT > 11 */
9898
9999 printf("\n");
100100 return(0);
@@ -110,7 +110,6 @@ get_spy_threshold(int skfd, /* The socket */
110110 char * args[], /* Command line args */
111111 int count) /* Args count */
112112 {
113-#if WIRELESS_EXT > 15
114113 struct iwreq wrq;
115114 struct iw_thrspy threshold;
116115 iwrange range;
@@ -141,14 +140,14 @@ get_spy_threshold(int skfd, /* The socket */
141140 if(threshold.low.level > range.max_qual.level)
142141 {
143142 /* Statistics are in dBm (absolute power measurement) */
144- printf("%-8.8s Low threshold:%d dBm High threshold:%d dBm\n\n",
143+ printf("%-8.16s Low threshold:%d dBm High threshold:%d dBm\n\n",
145144 ifname,
146145 threshold.low.level - 0x100, threshold.high.level - 0x100);
147146 }
148147 else
149148 {
150149 /* Statistics are relative values (0 -> max) */
151- printf("%-8.8s Low threshold:%d/%d High threshold:%d/%d\n\n",
150+ printf("%-8.16s Low threshold:%d/%d High threshold:%d/%d\n\n",
152151 ifname,
153152 threshold.low.level, range.max_qual.level,
154153 threshold.high.level, range.max_qual.level);
@@ -157,19 +156,12 @@ get_spy_threshold(int skfd, /* The socket */
157156 else
158157 {
159158 /* We can't read the range, so we don't know... */
160- printf("%-8.8s Low threshold:%d High threshold:%d\n\n",
159+ printf("%-8.16s Low threshold:%d High threshold:%d\n\n",
161160 ifname,
162161 threshold.low.level, threshold.high.level);
163162 }
164163
165164 return(0);
166-#else /* WIRELESS_EXT > 15 */
167- /* Avoid "Unused parameter" warning */
168- skfd = skfd; ifname = ifname; args = args; count = count;
169-
170- fprintf(stderr, "Feature not available...\n");
171- return(-1);
172-#endif /* WIRELESS_EXT > 15 */
173165 }
174166
175167 /************************* SETTING ROUTINES **************************/
@@ -207,12 +199,12 @@ set_spy_info(int skfd, /* The socket */
207199 /* Check if we have valid mac address type */
208200 if(iw_check_mac_addr_type(skfd, ifname) < 0)
209201 {
210- fprintf(stderr, "%-8.8s Interface doesn't support MAC addresses\n", ifname);
202+ fprintf(stderr, "%-8.16s Interface doesn't support MAC addresses\n", ifname);
211203 return(-1);
212204 }
213205
214206 wrq.u.data.pointer = (caddr_t) buffer;
215- wrq.u.data.length = 0;
207+ wrq.u.data.length = IW_MAX_SPY;
216208 wrq.u.data.flags = 0;
217209 if(iw_get_ext(skfd, ifname, SIOCGIWSPY, &wrq) < 0)
218210 {
@@ -275,7 +267,6 @@ set_spy_threshold(int skfd, /* The socket */
275267 char * args[], /* Command line args */
276268 int count) /* Args count */
277269 {
278-#if WIRELESS_EXT > 15
279270 struct iwreq wrq;
280271 struct iw_thrspy threshold;
281272 int low_thr;
@@ -294,19 +285,19 @@ set_spy_threshold(int skfd, /* The socket */
294285 /* Try to get our threshold */
295286 if(count < 2)
296287 {
297- fprintf(stderr, "%-8.8s Need two threshold values\n", ifname);
288+ fprintf(stderr, "%-8.16s Need two threshold values\n", ifname);
298289 return(-1);
299290 }
300291 if((sscanf(args[0], "%i", &low_thr) != 1) ||
301292 (sscanf(args[1], "%i", &high_thr) != 1))
302293 {
303- fprintf(stderr, "%-8.8s Invalid threshold values\n", ifname);
294+ fprintf(stderr, "%-8.16s Invalid threshold values\n", ifname);
304295 return(-1);
305296 }
306297 /* Basic sanity check */
307298 if(high_thr < low_thr)
308299 {
309- fprintf(stderr, "%-8.8s Inverted threshold range\n", ifname);
300+ fprintf(stderr, "%-8.16s Inverted threshold range\n", ifname);
310301 return(-1);
311302 }
312303 /* Copy thresholds */
@@ -328,13 +319,6 @@ set_spy_threshold(int skfd, /* The socket */
328319 }
329320
330321 return(0);
331-#else /* WIRELESS_EXT > 15 */
332- /* Avoid "Unused parameter" warning */
333- skfd = skfd; ifname = ifname; args = args; count = count;
334-
335- fprintf(stderr, "Feature not available...\n");
336- return(-1);
337-#endif /* WIRELESS_EXT > 15 */
338322 }
339323
340324 /******************************* MAIN ********************************/
@@ -386,7 +370,7 @@ main(int argc,
386370 goterr = set_spy_info(skfd, argv[1], argv + 2, argc - 2);
387371
388372 /* Close the socket. */
389- close(skfd);
373+ iw_sockets_close(skfd);
390374
391375 return(goterr);
392376 }
--- /dev/null
+++ b/wireless_tools/wireless.17.h
@@ -0,0 +1,773 @@
1+/*
2+ * This file define a set of standard wireless extensions
3+ *
4+ * Version : 17 21.6.04
5+ *
6+ * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com>
7+ * Copyright (c) 1997-2004 Jean Tourrilhes, All Rights Reserved.
8+ */
9+
10+#ifndef _LINUX_WIRELESS_H
11+#define _LINUX_WIRELESS_H
12+
13+/************************** DOCUMENTATION **************************/
14+/*
15+ * Initial APIs (1996 -> onward) :
16+ * -----------------------------
17+ * Basically, the wireless extensions are for now a set of standard ioctl
18+ * call + /proc/net/wireless
19+ *
20+ * The entry /proc/net/wireless give statistics and information on the
21+ * driver.
22+ * This is better than having each driver having its entry because
23+ * its centralised and we may remove the driver module safely.
24+ *
25+ * Ioctl are used to configure the driver and issue commands. This is
26+ * better than command line options of insmod because we may want to
27+ * change dynamically (while the driver is running) some parameters.
28+ *
29+ * The ioctl mechanimsm are copied from standard devices ioctl.
30+ * We have the list of command plus a structure descibing the
31+ * data exchanged...
32+ * Note that to add these ioctl, I was obliged to modify :
33+ * # net/core/dev.c (two place + add include)
34+ * # net/ipv4/af_inet.c (one place + add include)
35+ *
36+ * /proc/net/wireless is a copy of /proc/net/dev.
37+ * We have a structure for data passed from the driver to /proc/net/wireless
38+ * Too add this, I've modified :
39+ * # net/core/dev.c (two other places)
40+ * # include/linux/netdevice.h (one place)
41+ * # include/linux/proc_fs.h (one place)
42+ *
43+ * New driver API (2002 -> onward) :
44+ * -------------------------------
45+ * This file is only concerned with the user space API and common definitions.
46+ * The new driver API is defined and documented in :
47+ * # include/net/iw_handler.h
48+ *
49+ * Note as well that /proc/net/wireless implementation has now moved in :
50+ * # net/core/wireless.c
51+ *
52+ * Wireless Events (2002 -> onward) :
53+ * --------------------------------
54+ * Events are defined at the end of this file, and implemented in :
55+ * # net/core/wireless.c
56+ *
57+ * Other comments :
58+ * --------------
59+ * Do not add here things that are redundant with other mechanisms
60+ * (drivers init, ifconfig, /proc/net/dev, ...) and with are not
61+ * wireless specific.
62+ *
63+ * These wireless extensions are not magic : each driver has to provide
64+ * support for them...
65+ *
66+ * IMPORTANT NOTE : As everything in the kernel, this is very much a
67+ * work in progress. Contact me if you have ideas of improvements...
68+ */
69+
70+/***************************** INCLUDES *****************************/
71+
72+/* To minimise problems in user space, I might remove those headers
73+ * at some point. Jean II */
74+#include <linux/types.h> /* for "caddr_t" et al */
75+#include <linux/socket.h> /* for "struct sockaddr" et al */
76+#include <linux/if.h> /* for IFNAMSIZ and co... */
77+
78+/***************************** VERSION *****************************/
79+/*
80+ * This constant is used to know the availability of the wireless
81+ * extensions and to know which version of wireless extensions it is
82+ * (there is some stuff that will be added in the future...)
83+ * I just plan to increment with each new version.
84+ */
85+#define WIRELESS_EXT 17
86+
87+/*
88+ * Changes :
89+ *
90+ * V2 to V3
91+ * --------
92+ * Alan Cox start some incompatibles changes. I've integrated a bit more.
93+ * - Encryption renamed to Encode to avoid US regulation problems
94+ * - Frequency changed from float to struct to avoid problems on old 386
95+ *
96+ * V3 to V4
97+ * --------
98+ * - Add sensitivity
99+ *
100+ * V4 to V5
101+ * --------
102+ * - Missing encoding definitions in range
103+ * - Access points stuff
104+ *
105+ * V5 to V6
106+ * --------
107+ * - 802.11 support (ESSID ioctls)
108+ *
109+ * V6 to V7
110+ * --------
111+ * - define IW_ESSID_MAX_SIZE and IW_MAX_AP
112+ *
113+ * V7 to V8
114+ * --------
115+ * - Changed my e-mail address
116+ * - More 802.11 support (nickname, rate, rts, frag)
117+ * - List index in frequencies
118+ *
119+ * V8 to V9
120+ * --------
121+ * - Support for 'mode of operation' (ad-hoc, managed...)
122+ * - Support for unicast and multicast power saving
123+ * - Change encoding to support larger tokens (>64 bits)
124+ * - Updated iw_params (disable, flags) and use it for NWID
125+ * - Extracted iw_point from iwreq for clarity
126+ *
127+ * V9 to V10
128+ * ---------
129+ * - Add PM capability to range structure
130+ * - Add PM modifier : MAX/MIN/RELATIVE
131+ * - Add encoding option : IW_ENCODE_NOKEY
132+ * - Add TxPower ioctls (work like TxRate)
133+ *
134+ * V10 to V11
135+ * ----------
136+ * - Add WE version in range (help backward/forward compatibility)
137+ * - Add retry ioctls (work like PM)
138+ *
139+ * V11 to V12
140+ * ----------
141+ * - Add SIOCSIWSTATS to get /proc/net/wireless programatically
142+ * - Add DEV PRIVATE IOCTL to avoid collisions in SIOCDEVPRIVATE space
143+ * - Add new statistics (frag, retry, beacon)
144+ * - Add average quality (for user space calibration)
145+ *
146+ * V12 to V13
147+ * ----------
148+ * - Document creation of new driver API.
149+ * - Extract union iwreq_data from struct iwreq (for new driver API).
150+ * - Rename SIOCSIWNAME as SIOCSIWCOMMIT
151+ *
152+ * V13 to V14
153+ * ----------
154+ * - Wireless Events support : define struct iw_event
155+ * - Define additional specific event numbers
156+ * - Add "addr" and "param" fields in union iwreq_data
157+ * - AP scanning stuff (SIOCSIWSCAN and friends)
158+ *
159+ * V14 to V15
160+ * ----------
161+ * - Add IW_PRIV_TYPE_ADDR for struct sockaddr private arg
162+ * - Make struct iw_freq signed (both m & e), add explicit padding
163+ * - Add IWEVCUSTOM for driver specific event/scanning token
164+ * - Add IW_MAX_GET_SPY for driver returning a lot of addresses
165+ * - Add IW_TXPOW_RANGE for range of Tx Powers
166+ * - Add IWEVREGISTERED & IWEVEXPIRED events for Access Points
167+ * - Add IW_MODE_MONITOR for passive monitor
168+ *
169+ * V15 to V16
170+ * ----------
171+ * - Increase the number of bitrates in iw_range to 32 (for 802.11g)
172+ * - Increase the number of frequencies in iw_range to 32 (for 802.11b+a)
173+ * - Reshuffle struct iw_range for increases, add filler
174+ * - Increase IW_MAX_AP to 64 for driver returning a lot of addresses
175+ * - Remove IW_MAX_GET_SPY because conflict with enhanced spy support
176+ * - Add SIOCSIWTHRSPY/SIOCGIWTHRSPY and "struct iw_thrspy"
177+ * - Add IW_ENCODE_TEMP and iw_range->encoding_login_index
178+ *
179+ * V16 to V17
180+ * ----------
181+ * - Add flags to frequency -> auto/fixed
182+ * - Document (struct iw_quality *)->updated, add new flags (INVALID)
183+ * - Wireless Event capability in struct iw_range
184+ * - Add support for relative TxPower (yick !)
185+ */
186+
187+/**************************** CONSTANTS ****************************/
188+
189+/* -------------------------- IOCTL LIST -------------------------- */
190+
191+/* Wireless Identification */
192+#define SIOCSIWCOMMIT 0x8B00 /* Commit pending changes to driver */
193+#define SIOCGIWNAME 0x8B01 /* get name == wireless protocol */
194+/* SIOCGIWNAME is used to verify the presence of Wireless Extensions.
195+ * Common values : "IEEE 802.11-DS", "IEEE 802.11-FH", "IEEE 802.11b"...
196+ * Don't put the name of your driver there, it's useless. */
197+
198+/* Basic operations */
199+#define SIOCSIWNWID 0x8B02 /* set network id (pre-802.11) */
200+#define SIOCGIWNWID 0x8B03 /* get network id (the cell) */
201+#define SIOCSIWFREQ 0x8B04 /* set channel/frequency (Hz) */
202+#define SIOCGIWFREQ 0x8B05 /* get channel/frequency (Hz) */
203+#define SIOCSIWMODE 0x8B06 /* set operation mode */
204+#define SIOCGIWMODE 0x8B07 /* get operation mode */
205+#define SIOCSIWSENS 0x8B08 /* set sensitivity (dBm) */
206+#define SIOCGIWSENS 0x8B09 /* get sensitivity (dBm) */
207+
208+/* Informative stuff */
209+#define SIOCSIWRANGE 0x8B0A /* Unused */
210+#define SIOCGIWRANGE 0x8B0B /* Get range of parameters */
211+#define SIOCSIWPRIV 0x8B0C /* Unused */
212+#define SIOCGIWPRIV 0x8B0D /* get private ioctl interface info */
213+#define SIOCSIWSTATS 0x8B0E /* Unused */
214+#define SIOCGIWSTATS 0x8B0F /* Get /proc/net/wireless stats */
215+/* SIOCGIWSTATS is strictly used between user space and the kernel, and
216+ * is never passed to the driver (i.e. the driver will never see it). */
217+
218+/* Spy support (statistics per MAC address - used for Mobile IP support) */
219+#define SIOCSIWSPY 0x8B10 /* set spy addresses */
220+#define SIOCGIWSPY 0x8B11 /* get spy info (quality of link) */
221+#define SIOCSIWTHRSPY 0x8B12 /* set spy threshold (spy event) */
222+#define SIOCGIWTHRSPY 0x8B13 /* get spy threshold */
223+
224+/* Access Point manipulation */
225+#define SIOCSIWAP 0x8B14 /* set access point MAC addresses */
226+#define SIOCGIWAP 0x8B15 /* get access point MAC addresses */
227+#define SIOCGIWAPLIST 0x8B17 /* Deprecated in favor of scanning */
228+#define SIOCSIWSCAN 0x8B18 /* trigger scanning (list cells) */
229+#define SIOCGIWSCAN 0x8B19 /* get scanning results */
230+
231+/* 802.11 specific support */
232+#define SIOCSIWESSID 0x8B1A /* set ESSID (network name) */
233+#define SIOCGIWESSID 0x8B1B /* get ESSID */
234+#define SIOCSIWNICKN 0x8B1C /* set node name/nickname */
235+#define SIOCGIWNICKN 0x8B1D /* get node name/nickname */
236+/* As the ESSID and NICKN are strings up to 32 bytes long, it doesn't fit
237+ * within the 'iwreq' structure, so we need to use the 'data' member to
238+ * point to a string in user space, like it is done for RANGE... */
239+
240+/* Other parameters useful in 802.11 and some other devices */
241+#define SIOCSIWRATE 0x8B20 /* set default bit rate (bps) */
242+#define SIOCGIWRATE 0x8B21 /* get default bit rate (bps) */
243+#define SIOCSIWRTS 0x8B22 /* set RTS/CTS threshold (bytes) */
244+#define SIOCGIWRTS 0x8B23 /* get RTS/CTS threshold (bytes) */
245+#define SIOCSIWFRAG 0x8B24 /* set fragmentation thr (bytes) */
246+#define SIOCGIWFRAG 0x8B25 /* get fragmentation thr (bytes) */
247+#define SIOCSIWTXPOW 0x8B26 /* set transmit power (dBm) */
248+#define SIOCGIWTXPOW 0x8B27 /* get transmit power (dBm) */
249+#define SIOCSIWRETRY 0x8B28 /* set retry limits and lifetime */
250+#define SIOCGIWRETRY 0x8B29 /* get retry limits and lifetime */
251+
252+/* Encoding stuff (scrambling, hardware security, WEP...) */
253+#define SIOCSIWENCODE 0x8B2A /* set encoding token & mode */
254+#define SIOCGIWENCODE 0x8B2B /* get encoding token & mode */
255+/* Power saving stuff (power management, unicast and multicast) */
256+#define SIOCSIWPOWER 0x8B2C /* set Power Management settings */
257+#define SIOCGIWPOWER 0x8B2D /* get Power Management settings */
258+
259+/* -------------------- DEV PRIVATE IOCTL LIST -------------------- */
260+
261+/* These 32 ioctl are wireless device private, for 16 commands.
262+ * Each driver is free to use them for whatever purpose it chooses,
263+ * however the driver *must* export the description of those ioctls
264+ * with SIOCGIWPRIV and *must* use arguments as defined below.
265+ * If you don't follow those rules, DaveM is going to hate you (reason :
266+ * it make mixed 32/64bit operation impossible).
267+ */
268+#define SIOCIWFIRSTPRIV 0x8BE0
269+#define SIOCIWLASTPRIV 0x8BFF
270+/* Previously, we were using SIOCDEVPRIVATE, but we now have our
271+ * separate range because of collisions with other tools such as
272+ * 'mii-tool'.
273+ * We now have 32 commands, so a bit more space ;-).
274+ * Also, all 'odd' commands are only usable by root and don't return the
275+ * content of ifr/iwr to user (but you are not obliged to use the set/get
276+ * convention, just use every other two command). More details in iwpriv.c.
277+ * And I repeat : you are not forced to use them with iwpriv, but you
278+ * must be compliant with it.
279+ */
280+
281+/* ------------------------- IOCTL STUFF ------------------------- */
282+
283+/* The first and the last (range) */
284+#define SIOCIWFIRST 0x8B00
285+#define SIOCIWLAST SIOCIWLASTPRIV /* 0x8BFF */
286+
287+/* Even : get (world access), odd : set (root access) */
288+#define IW_IS_SET(cmd) (!((cmd) & 0x1))
289+#define IW_IS_GET(cmd) ((cmd) & 0x1)
290+
291+/* ----------------------- WIRELESS EVENTS ----------------------- */
292+/* Those are *NOT* ioctls, do not issue request on them !!! */
293+/* Most events use the same identifier as ioctl requests */
294+
295+#define IWEVTXDROP 0x8C00 /* Packet dropped to excessive retry */
296+#define IWEVQUAL 0x8C01 /* Quality part of statistics (scan) */
297+#define IWEVCUSTOM 0x8C02 /* Driver specific ascii string */
298+#define IWEVREGISTERED 0x8C03 /* Discovered a new node (AP mode) */
299+#define IWEVEXPIRED 0x8C04 /* Expired a node (AP mode) */
300+
301+#define IWEVFIRST 0x8C00
302+
303+/* ------------------------- PRIVATE INFO ------------------------- */
304+/*
305+ * The following is used with SIOCGIWPRIV. It allow a driver to define
306+ * the interface (name, type of data) for its private ioctl.
307+ * Privates ioctl are SIOCIWFIRSTPRIV -> SIOCIWLASTPRIV
308+ */
309+
310+#define IW_PRIV_TYPE_MASK 0x7000 /* Type of arguments */
311+#define IW_PRIV_TYPE_NONE 0x0000
312+#define IW_PRIV_TYPE_BYTE 0x1000 /* Char as number */
313+#define IW_PRIV_TYPE_CHAR 0x2000 /* Char as character */
314+#define IW_PRIV_TYPE_INT 0x4000 /* 32 bits int */
315+#define IW_PRIV_TYPE_FLOAT 0x5000 /* struct iw_freq */
316+#define IW_PRIV_TYPE_ADDR 0x6000 /* struct sockaddr */
317+
318+#define IW_PRIV_SIZE_FIXED 0x0800 /* Variable or fixed number of args */
319+
320+#define IW_PRIV_SIZE_MASK 0x07FF /* Max number of those args */
321+
322+/*
323+ * Note : if the number of args is fixed and the size < 16 octets,
324+ * instead of passing a pointer we will put args in the iwreq struct...
325+ */
326+
327+/* ----------------------- OTHER CONSTANTS ----------------------- */
328+
329+/* Maximum frequencies in the range struct */
330+#define IW_MAX_FREQUENCIES 32
331+/* Note : if you have something like 80 frequencies,
332+ * don't increase this constant and don't fill the frequency list.
333+ * The user will be able to set by channel anyway... */
334+
335+/* Maximum bit rates in the range struct */
336+#define IW_MAX_BITRATES 32
337+
338+/* Maximum tx powers in the range struct */
339+#define IW_MAX_TXPOWER 8
340+/* Note : if you more than 8 TXPowers, just set the max and min or
341+ * a few of them in the struct iw_range. */
342+
343+/* Maximum of address that you may set with SPY */
344+#define IW_MAX_SPY 8
345+
346+/* Maximum of address that you may get in the
347+ list of access points in range */
348+#define IW_MAX_AP 64
349+
350+/* Maximum size of the ESSID and NICKN strings */
351+#define IW_ESSID_MAX_SIZE 32
352+
353+/* Modes of operation */
354+#define IW_MODE_AUTO 0 /* Let the driver decides */
355+#define IW_MODE_ADHOC 1 /* Single cell network */
356+#define IW_MODE_INFRA 2 /* Multi cell network, roaming, ... */
357+#define IW_MODE_MASTER 3 /* Synchronisation master or Access Point */
358+#define IW_MODE_REPEAT 4 /* Wireless Repeater (forwarder) */
359+#define IW_MODE_SECOND 5 /* Secondary master/repeater (backup) */
360+#define IW_MODE_MONITOR 6 /* Passive monitor (listen only) */
361+
362+/* Statistics flags (bitmask in updated) */
363+#define IW_QUAL_QUAL_UPDATED 0x1 /* Value was updated since last read */
364+#define IW_QUAL_LEVEL_UPDATED 0x2
365+#define IW_QUAL_NOISE_UPDATED 0x4
366+#define IW_QUAL_QUAL_INVALID 0x10 /* Driver doesn't provide value */
367+#define IW_QUAL_LEVEL_INVALID 0x20
368+#define IW_QUAL_NOISE_INVALID 0x40
369+
370+/* Frequency flags */
371+#define IW_FREQ_AUTO 0x00 /* Let the driver decides */
372+#define IW_FREQ_FIXED 0x01 /* Force a specific value */
373+
374+/* Maximum number of size of encoding token available
375+ * they are listed in the range structure */
376+#define IW_MAX_ENCODING_SIZES 8
377+
378+/* Maximum size of the encoding token in bytes */
379+#define IW_ENCODING_TOKEN_MAX 32 /* 256 bits (for now) */
380+
381+/* Flags for encoding (along with the token) */
382+#define IW_ENCODE_INDEX 0x00FF /* Token index (if needed) */
383+#define IW_ENCODE_FLAGS 0xFF00 /* Flags defined below */
384+#define IW_ENCODE_MODE 0xF000 /* Modes defined below */
385+#define IW_ENCODE_DISABLED 0x8000 /* Encoding disabled */
386+#define IW_ENCODE_ENABLED 0x0000 /* Encoding enabled */
387+#define IW_ENCODE_RESTRICTED 0x4000 /* Refuse non-encoded packets */
388+#define IW_ENCODE_OPEN 0x2000 /* Accept non-encoded packets */
389+#define IW_ENCODE_NOKEY 0x0800 /* Key is write only, so not present */
390+#define IW_ENCODE_TEMP 0x0400 /* Temporary key */
391+
392+/* Power management flags available (along with the value, if any) */
393+#define IW_POWER_ON 0x0000 /* No details... */
394+#define IW_POWER_TYPE 0xF000 /* Type of parameter */
395+#define IW_POWER_PERIOD 0x1000 /* Value is a period/duration of */
396+#define IW_POWER_TIMEOUT 0x2000 /* Value is a timeout (to go asleep) */
397+#define IW_POWER_MODE 0x0F00 /* Power Management mode */
398+#define IW_POWER_UNICAST_R 0x0100 /* Receive only unicast messages */
399+#define IW_POWER_MULTICAST_R 0x0200 /* Receive only multicast messages */
400+#define IW_POWER_ALL_R 0x0300 /* Receive all messages though PM */
401+#define IW_POWER_FORCE_S 0x0400 /* Force PM procedure for sending unicast */
402+#define IW_POWER_REPEATER 0x0800 /* Repeat broadcast messages in PM period */
403+#define IW_POWER_MODIFIER 0x000F /* Modify a parameter */
404+#define IW_POWER_MIN 0x0001 /* Value is a minimum */
405+#define IW_POWER_MAX 0x0002 /* Value is a maximum */
406+#define IW_POWER_RELATIVE 0x0004 /* Value is not in seconds/ms/us */
407+
408+/* Transmit Power flags available */
409+#define IW_TXPOW_TYPE 0x00FF /* Type of value */
410+#define IW_TXPOW_DBM 0x0000 /* Value is in dBm */
411+#define IW_TXPOW_MWATT 0x0001 /* Value is in mW */
412+#define IW_TXPOW_RELATIVE 0x0002 /* Value is in arbitrary units */
413+#define IW_TXPOW_RANGE 0x1000 /* Range of value between min/max */
414+
415+/* Retry limits and lifetime flags available */
416+#define IW_RETRY_ON 0x0000 /* No details... */
417+#define IW_RETRY_TYPE 0xF000 /* Type of parameter */
418+#define IW_RETRY_LIMIT 0x1000 /* Maximum number of retries*/
419+#define IW_RETRY_LIFETIME 0x2000 /* Maximum duration of retries in us */
420+#define IW_RETRY_MODIFIER 0x000F /* Modify a parameter */
421+#define IW_RETRY_MIN 0x0001 /* Value is a minimum */
422+#define IW_RETRY_MAX 0x0002 /* Value is a maximum */
423+#define IW_RETRY_RELATIVE 0x0004 /* Value is not in seconds/ms/us */
424+
425+/* Scanning request flags */
426+#define IW_SCAN_DEFAULT 0x0000 /* Default scan of the driver */
427+#define IW_SCAN_ALL_ESSID 0x0001 /* Scan all ESSIDs */
428+#define IW_SCAN_THIS_ESSID 0x0002 /* Scan only this ESSID */
429+#define IW_SCAN_ALL_FREQ 0x0004 /* Scan all Frequencies */
430+#define IW_SCAN_THIS_FREQ 0x0008 /* Scan only this Frequency */
431+#define IW_SCAN_ALL_MODE 0x0010 /* Scan all Modes */
432+#define IW_SCAN_THIS_MODE 0x0020 /* Scan only this Mode */
433+#define IW_SCAN_ALL_RATE 0x0040 /* Scan all Bit-Rates */
434+#define IW_SCAN_THIS_RATE 0x0080 /* Scan only this Bit-Rate */
435+/* Maximum size of returned data */
436+#define IW_SCAN_MAX_DATA 4096 /* In bytes */
437+
438+/* Max number of char in custom event - use multiple of them if needed */
439+#define IW_CUSTOM_MAX 256 /* In bytes */
440+
441+/* Event capability macros - in (struct iw_range *)->event_capa
442+ * Because we have more than 32 possible events, we use an array of
443+ * 32 bit bitmasks. Note : 32 bits = 0x20 = 2^5. */
444+#define IW_EVENT_CAPA_BASE(cmd) ((cmd >= SIOCIWFIRSTPRIV) ? \
445+ (cmd - SIOCIWFIRSTPRIV + 0x60) : \
446+ (cmd - SIOCSIWCOMMIT))
447+#define IW_EVENT_CAPA_INDEX(cmd) (IW_EVENT_CAPA_BASE(cmd) >> 5)
448+#define IW_EVENT_CAPA_MASK(cmd) (1 << (IW_EVENT_CAPA_BASE(cmd) & 0x1F))
449+/* Event capability constants - event autogenerated by the kernel
450+ * This list is valid for most 802.11 devices, customise as needed... */
451+#define IW_EVENT_CAPA_K_0 (IW_EVENT_CAPA_MASK(0x8B04) | \
452+ IW_EVENT_CAPA_MASK(0x8B06) | \
453+ IW_EVENT_CAPA_MASK(0x8B1A))
454+#define IW_EVENT_CAPA_K_1 (IW_EVENT_CAPA_MASK(0x8B2A))
455+/* "Easy" macro to set events in iw_range (less efficient) */
456+#define IW_EVENT_CAPA_SET(event_capa, cmd) (event_capa[IW_EVENT_CAPA_INDEX(cmd)] |= IW_EVENT_CAPA_MASK(cmd))
457+#define IW_EVENT_CAPA_SET_KERNEL(event_capa) {event_capa[0] |= IW_EVENT_CAPA_K_0; event_capa[1] |= IW_EVENT_CAPA_K_1; }
458+
459+
460+/****************************** TYPES ******************************/
461+
462+/* --------------------------- SUBTYPES --------------------------- */
463+/*
464+ * Generic format for most parameters that fit in an int
465+ */
466+struct iw_param
467+{
468+ __s32 value; /* The value of the parameter itself */
469+ __u8 fixed; /* Hardware should not use auto select */
470+ __u8 disabled; /* Disable the feature */
471+ __u16 flags; /* Various specifc flags (if any) */
472+};
473+
474+/*
475+ * For all data larger than 16 octets, we need to use a
476+ * pointer to memory allocated in user space.
477+ */
478+struct iw_point
479+{
480+ caddr_t pointer; /* Pointer to the data (in user space) */
481+ __u16 length; /* number of fields or size in bytes */
482+ __u16 flags; /* Optional params */
483+};
484+
485+/*
486+ * A frequency
487+ * For numbers lower than 10^9, we encode the number in 'm' and
488+ * set 'e' to 0
489+ * For number greater than 10^9, we divide it by the lowest power
490+ * of 10 to get 'm' lower than 10^9, with 'm'= f / (10^'e')...
491+ * The power of 10 is in 'e', the result of the division is in 'm'.
492+ */
493+struct iw_freq
494+{
495+ __s32 m; /* Mantissa */
496+ __s16 e; /* Exponent */
497+ __u8 i; /* List index (when in range struct) */
498+ __u8 flags; /* Flags (fixed/auto) */
499+};
500+
501+/*
502+ * Quality of the link
503+ */
504+struct iw_quality
505+{
506+ __u8 qual; /* link quality (%retries, SNR,
507+ %missed beacons or better...) */
508+ __u8 level; /* signal level (dBm) */
509+ __u8 noise; /* noise level (dBm) */
510+ __u8 updated; /* Flags to know if updated */
511+};
512+
513+/*
514+ * Packet discarded in the wireless adapter due to
515+ * "wireless" specific problems...
516+ * Note : the list of counter and statistics in net_device_stats
517+ * is already pretty exhaustive, and you should use that first.
518+ * This is only additional stats...
519+ */
520+struct iw_discarded
521+{
522+ __u32 nwid; /* Rx : Wrong nwid/essid */
523+ __u32 code; /* Rx : Unable to code/decode (WEP) */
524+ __u32 fragment; /* Rx : Can't perform MAC reassembly */
525+ __u32 retries; /* Tx : Max MAC retries num reached */
526+ __u32 misc; /* Others cases */
527+};
528+
529+/*
530+ * Packet/Time period missed in the wireless adapter due to
531+ * "wireless" specific problems...
532+ */
533+struct iw_missed
534+{
535+ __u32 beacon; /* Missed beacons/superframe */
536+};
537+
538+/*
539+ * Quality range (for spy threshold)
540+ */
541+struct iw_thrspy
542+{
543+ struct sockaddr addr; /* Source address (hw/mac) */
544+ struct iw_quality qual; /* Quality of the link */
545+ struct iw_quality low; /* Low threshold */
546+ struct iw_quality high; /* High threshold */
547+};
548+
549+/* ------------------------ WIRELESS STATS ------------------------ */
550+/*
551+ * Wireless statistics (used for /proc/net/wireless)
552+ */
553+struct iw_statistics
554+{
555+ __u16 status; /* Status
556+ * - device dependent for now */
557+
558+ struct iw_quality qual; /* Quality of the link
559+ * (instant/mean/max) */
560+ struct iw_discarded discard; /* Packet discarded counts */
561+ struct iw_missed miss; /* Packet missed counts */
562+};
563+
564+/* ------------------------ IOCTL REQUEST ------------------------ */
565+/*
566+ * This structure defines the payload of an ioctl, and is used
567+ * below.
568+ *
569+ * Note that this structure should fit on the memory footprint
570+ * of iwreq (which is the same as ifreq), which mean a max size of
571+ * 16 octets = 128 bits. Warning, pointers might be 64 bits wide...
572+ * You should check this when increasing the structures defined
573+ * above in this file...
574+ */
575+union iwreq_data
576+{
577+ /* Config - generic */
578+ char name[IFNAMSIZ];
579+ /* Name : used to verify the presence of wireless extensions.
580+ * Name of the protocol/provider... */
581+
582+ struct iw_point essid; /* Extended network name */
583+ struct iw_param nwid; /* network id (or domain - the cell) */
584+ struct iw_freq freq; /* frequency or channel :
585+ * 0-1000 = channel
586+ * > 1000 = frequency in Hz */
587+
588+ struct iw_param sens; /* signal level threshold */
589+ struct iw_param bitrate; /* default bit rate */
590+ struct iw_param txpower; /* default transmit power */
591+ struct iw_param rts; /* RTS threshold threshold */
592+ struct iw_param frag; /* Fragmentation threshold */
593+ __u32 mode; /* Operation mode */
594+ struct iw_param retry; /* Retry limits & lifetime */
595+
596+ struct iw_point encoding; /* Encoding stuff : tokens */
597+ struct iw_param power; /* PM duration/timeout */
598+ struct iw_quality qual; /* Quality part of statistics */
599+
600+ struct sockaddr ap_addr; /* Access point address */
601+ struct sockaddr addr; /* Destination address (hw/mac) */
602+
603+ struct iw_param param; /* Other small parameters */
604+ struct iw_point data; /* Other large parameters */
605+};
606+
607+/*
608+ * The structure to exchange data for ioctl.
609+ * This structure is the same as 'struct ifreq', but (re)defined for
610+ * convenience...
611+ * Do I need to remind you about structure size (32 octets) ?
612+ */
613+struct iwreq
614+{
615+ union
616+ {
617+ char ifrn_name[IFNAMSIZ]; /* if name, e.g. "eth0" */
618+ } ifr_ifrn;
619+
620+ /* Data part (defined just above) */
621+ union iwreq_data u;
622+};
623+
624+/* -------------------------- IOCTL DATA -------------------------- */
625+/*
626+ * For those ioctl which want to exchange mode data that what could
627+ * fit in the above structure...
628+ */
629+
630+/*
631+ * Range of parameters
632+ */
633+
634+struct iw_range
635+{
636+ /* Informative stuff (to choose between different interface) */
637+ __u32 throughput; /* To give an idea... */
638+ /* In theory this value should be the maximum benchmarked
639+ * TCP/IP throughput, because with most of these devices the
640+ * bit rate is meaningless (overhead an co) to estimate how
641+ * fast the connection will go and pick the fastest one.
642+ * I suggest people to play with Netperf or any benchmark...
643+ */
644+
645+ /* NWID (or domain id) */
646+ __u32 min_nwid; /* Minimal NWID we are able to set */
647+ __u32 max_nwid; /* Maximal NWID we are able to set */
648+
649+ /* Old Frequency (backward compat - moved lower ) */
650+ __u16 old_num_channels;
651+ __u8 old_num_frequency;
652+
653+ /* Wireless event capability bitmasks */
654+ __u32 event_capa[6];
655+
656+ /* signal level threshold range */
657+ __s32 sensitivity;
658+
659+ /* Quality of link & SNR stuff */
660+ /* Quality range (link, level, noise)
661+ * If the quality is absolute, it will be in the range [0 ; max_qual],
662+ * if the quality is dBm, it will be in the range [max_qual ; 0].
663+ * Don't forget that we use 8 bit arithmetics... */
664+ struct iw_quality max_qual; /* Quality of the link */
665+ /* This should contain the average/typical values of the quality
666+ * indicator. This should be the threshold between a "good" and
667+ * a "bad" link (example : monitor going from green to orange).
668+ * Currently, user space apps like quality monitors don't have any
669+ * way to calibrate the measurement. With this, they can split
670+ * the range between 0 and max_qual in different quality level
671+ * (using a geometric subdivision centered on the average).
672+ * I expect that people doing the user space apps will feedback
673+ * us on which value we need to put in each driver... */
674+ struct iw_quality avg_qual; /* Quality of the link */
675+
676+ /* Rates */
677+ __u8 num_bitrates; /* Number of entries in the list */
678+ __s32 bitrate[IW_MAX_BITRATES]; /* list, in bps */
679+
680+ /* RTS threshold */
681+ __s32 min_rts; /* Minimal RTS threshold */
682+ __s32 max_rts; /* Maximal RTS threshold */
683+
684+ /* Frag threshold */
685+ __s32 min_frag; /* Minimal frag threshold */
686+ __s32 max_frag; /* Maximal frag threshold */
687+
688+ /* Power Management duration & timeout */
689+ __s32 min_pmp; /* Minimal PM period */
690+ __s32 max_pmp; /* Maximal PM period */
691+ __s32 min_pmt; /* Minimal PM timeout */
692+ __s32 max_pmt; /* Maximal PM timeout */
693+ __u16 pmp_flags; /* How to decode max/min PM period */
694+ __u16 pmt_flags; /* How to decode max/min PM timeout */
695+ __u16 pm_capa; /* What PM options are supported */
696+
697+ /* Encoder stuff */
698+ __u16 encoding_size[IW_MAX_ENCODING_SIZES]; /* Different token sizes */
699+ __u8 num_encoding_sizes; /* Number of entry in the list */
700+ __u8 max_encoding_tokens; /* Max number of tokens */
701+ /* For drivers that need a "login/passwd" form */
702+ __u8 encoding_login_index; /* token index for login token */
703+
704+ /* Transmit power */
705+ __u16 txpower_capa; /* What options are supported */
706+ __u8 num_txpower; /* Number of entries in the list */
707+ __s32 txpower[IW_MAX_TXPOWER]; /* list, in bps */
708+
709+ /* Wireless Extension version info */
710+ __u8 we_version_compiled; /* Must be WIRELESS_EXT */
711+ __u8 we_version_source; /* Last update of source */
712+
713+ /* Retry limits and lifetime */
714+ __u16 retry_capa; /* What retry options are supported */
715+ __u16 retry_flags; /* How to decode max/min retry limit */
716+ __u16 r_time_flags; /* How to decode max/min retry life */
717+ __s32 min_retry; /* Minimal number of retries */
718+ __s32 max_retry; /* Maximal number of retries */
719+ __s32 min_r_time; /* Minimal retry lifetime */
720+ __s32 max_r_time; /* Maximal retry lifetime */
721+
722+ /* Frequency */
723+ __u16 num_channels; /* Number of channels [0; num - 1] */
724+ __u8 num_frequency; /* Number of entry in the list */
725+ struct iw_freq freq[IW_MAX_FREQUENCIES]; /* list */
726+ /* Note : this frequency list doesn't need to fit channel numbers,
727+ * because each entry contain its channel index */
728+};
729+
730+/*
731+ * Private ioctl interface information
732+ */
733+
734+struct iw_priv_args
735+{
736+ __u32 cmd; /* Number of the ioctl to issue */
737+ __u16 set_args; /* Type and number of args */
738+ __u16 get_args; /* Type and number of args */
739+ char name[IFNAMSIZ]; /* Name of the extension */
740+};
741+
742+/* ----------------------- WIRELESS EVENTS ----------------------- */
743+/*
744+ * Wireless events are carried through the rtnetlink socket to user
745+ * space. They are encapsulated in the IFLA_WIRELESS field of
746+ * a RTM_NEWLINK message.
747+ */
748+
749+/*
750+ * A Wireless Event. Contains basically the same data as the ioctl...
751+ */
752+struct iw_event
753+{
754+ __u16 len; /* Real lenght of this stuff */
755+ __u16 cmd; /* Wireless IOCTL */
756+ union iwreq_data u; /* IOCTL fixed payload */
757+};
758+
759+/* Size of the Event prefix (including padding and alignement junk) */
760+#define IW_EV_LCP_LEN (sizeof(struct iw_event) - sizeof(union iwreq_data))
761+/* Size of the various events */
762+#define IW_EV_CHAR_LEN (IW_EV_LCP_LEN + IFNAMSIZ)
763+#define IW_EV_UINT_LEN (IW_EV_LCP_LEN + sizeof(__u32))
764+#define IW_EV_FREQ_LEN (IW_EV_LCP_LEN + sizeof(struct iw_freq))
765+#define IW_EV_POINT_LEN (IW_EV_LCP_LEN + sizeof(struct iw_point))
766+#define IW_EV_PARAM_LEN (IW_EV_LCP_LEN + sizeof(struct iw_param))
767+#define IW_EV_ADDR_LEN (IW_EV_LCP_LEN + sizeof(struct sockaddr))
768+#define IW_EV_QUAL_LEN (IW_EV_LCP_LEN + sizeof(struct iw_quality))
769+
770+/* Note : in the case of iw_point, the extra data will come at the
771+ * end of the event */
772+
773+#endif /* _LINUX_WIRELESS_H */
--- a/wireless_tools/wireless.7
+++ b/wireless_tools/wireless.7
@@ -1,7 +1,7 @@
1-.\" Jean Tourrilhes - HPL - 2002
1+.\" Jean Tourrilhes - HPL - 2002 - 2004
22 .\" wireless.7
33 .\"
4-.TH WIRELESS 7 "12 July 2002" "net-tools" "Linux Programmer's Manual"
4+.TH WIRELESS 7 "4 March 2004" "wireless-tools" "Linux Programmer's Manual"
55 .\"
66 .\" NAME part
77 .\"
@@ -13,7 +13,7 @@ wireless \- Wireless Tools and Wireless Extensions
1313 .SH SYNOPSIS
1414 .B iwconfig
1515 .br
16-.B iwpriv -a
16+.B iwpriv \-a
1717 .br
1818 .\"
1919 .\" DESCRIPTION part
@@ -23,40 +23,42 @@ The
2323 .B Wireless Extensions
2424 is an API allowing you manipulate Wireless LAN networking interfaces.
2525 It is composed of a variety of tools and configuration files. It is
26-documented in more details in the Linux Wireless LAN Howto.
26+documented in more detail in the Linux Wireless LAN Howto.
2727 .br
2828 The
2929 .B Wireless Tools
30-are use to change configuration on the fly, to get statistics and
31-diagnose those interfaces. They are described in their own man page
32-(see below).
30+are used to change the configuration of wireless LAN networking
31+interfaces on the fly, to get their current configuration, to get
32+statistics and diagnose them. They are described in their own man
33+page, see below for references.
3334 .br
3435 .B Wireless configuration
3536 is specific to each Linux distribution. This man page will contain in
36-the future the configuration procedure for a few common distributions
37-(when I get the necessary info from them). For the time being, check
38-the various files included with the Wireless Tools package.
37+the future the configuration procedure for a few common
38+distributions. For the time being, check the file DISTRIBUTIONS.txt
39+included with the Wireless Tools package.
3940 .\"
4041 .\" DEBIAN 3.0 part
4142 .\"
4243 .SH DEBIAN 3.0
43-Debian 3.0 (and later) has integrated wireless configuration in their
44-network scripts.
44+In Debian 3.0 (and later) you can configure wireless LAN networking
45+devices using the network configuration tool
46+.BR ifupdown (8).
4547 .TP
4648 .B File :
4749 .I /etc/network/interfaces
4850 .TP
4951 .B Form :
50-.RI wireless_ "<function> <value>"
52+.RI wireless\- "<function> <value>"
5153 .br
52-wireless_essid Home
54+wireless\-essid Home
5355 .br
54-wireless_mode ad_hoc
56+wireless\-mode Ad\-Hoc
5557 .TP
5658 .B See also :
57-.I /etc/network/if-pre-up.d/wireless-tool
59+.I /etc/network/if\-pre\-up.d/wireless\-tools
5860 .br
59-.I /usr/share/doc/wireless.##/README.Debian
61+.I /usr/share/doc/wireless\-tools/README.Debian
6062 .\"
6163 .\" SuSE 8.0 part
6264 .\"
@@ -70,14 +72,14 @@ network scripts.
7072 .B File :
7173 .I /etc/sysconfig/network/wireless
7274 .br
73-.I /etc/sysconfig/network/ifcfg-*
75+.I /etc/sysconfig/network/ifcfg\-*
7476 .TP
7577 .B Form :
7678 .RI WIRELESS_ "<function>" = "<value>"
7779 .br
7880 WIRELESS_ESSID="Home"
7981 .br
80-WIRELESS_MODE=ad_hoc
82+WIRELESS_MODE=Ad\-Hoc
8183 .TP
8284 .B See also :
8385 man ifup
@@ -96,9 +98,9 @@ package, you can use this method.
9698 .B Form :
9799 *,*,*,*)
98100 .br
99- ESSID="MY_ESSID"
101+ ESSID="Home"
100102 .br
101- MODE="Managed"
103+ MODE="Ad-Hoc"
102104 .br
103105 ;;
104106 .TP