external/wireless-tools
Révision | 9d82610feb36dcd56d621e7831cbf5eec3f51104 (tree) |
---|---|
l'heure | 2016-10-12 06:10:33 |
Auteur | chris-kirby <chris.kirby@hpe....> |
Commiter | chris-kirby |
v27
@@ -1,7 +1,7 @@ | ||
1 | 1 | /* |
2 | 2 | * Wireless Tools |
3 | 3 | * |
4 | - * Jean II - HPLB 97->99 - HPL 99->02 | |
4 | + * Jean II - HPLB 97->99 - HPL 99->04 | |
5 | 5 | * |
6 | 6 | * The changelog... |
7 | 7 | * |
@@ -367,6 +367,171 @@ | ||
367 | 367 | * o Don't cast "int power" to unsigned long in sscanf [iwconfig] |
368 | 368 | * (From Pavel Roskin <proski@gnu.org>) |
369 | 369 | * 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] | |
370 | 535 | */ |
371 | 536 | |
372 | 537 | /* ----------------------------- TODO ----------------------------- */ |
@@ -391,9 +556,10 @@ | ||
391 | 556 | * Add scanning command line modifiers |
392 | 557 | * More scan types support |
393 | 558 | * |
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 ? | |
397 | 563 | * |
398 | 564 | * Doc & man pages : |
399 | 565 | * --------------- |
@@ -103,7 +103,7 @@ You can now add extra statements to the iface sections of the files in | ||
103 | 103 | /etc/network/interfaces that are specific for wireless interfaces. They |
104 | 104 | are of the form: |
105 | 105 | |
106 | - wireless_<function> <value> | |
106 | + wireless-<function> <value> | |
107 | 107 | |
108 | 108 | Before the interface is brought up, such a statement will result in the |
109 | 109 | execution of the following command: |
@@ -117,8 +117,8 @@ iface eth0 inet static | ||
117 | 117 | network 192.168.1.0 |
118 | 118 | netmask 255.255.255.0 |
119 | 119 | broadcast 192.168.1.255 |
120 | - wireless_essid Home | |
121 | - wireless_mode ad_hoc | |
120 | + wireless-essid Home | |
121 | + wireless-mode ad-hoc | |
122 | 122 | |
123 | 123 | The current Debian script support all arguments present in |
124 | 124 | 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: | ||
135 | 135 | |
136 | 136 | auto wlan0 |
137 | 137 | mapping wlan0 |
138 | - script /usr/local/bin/ifscheme | |
138 | + script /usr/local/bin/ifscheme-mapping | |
139 | 139 | |
140 | 140 | iface wlan0-home inet static |
141 | 141 | address 192.168.1.5 |
142 | 142 | gateway 192.168.1.1 |
143 | 143 | 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 | |
148 | 148 | |
149 | 149 | iface wlan0-away inet dhcp |
150 | - wireless_mode managed | |
150 | + wireless-mode managed | |
151 | 151 | |
152 | 152 | Now I can type 'ifscheme -s away' when I leave home, rather like |
153 | 153 | cardctl scheme. |
@@ -171,8 +171,23 @@ ifupdown. | ||
171 | 171 | |
172 | 172 | ----- |
173 | 173 | |
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 : | |
175 | 188 | http://panopticon.csustan.edu/thood/ifupdown-roaming.html |
189 | + o waproamd | |
190 | + http://0pointer.de/lennart/projects/waproamd/ | |
176 | 191 | |
177 | 192 | --------------------------------------------------------------------- |
178 | 193 |
@@ -339,13 +354,21 @@ eth0, eth1, ...). | ||
339 | 354 | all of them. The script doing the configuration and where you can |
340 | 355 | check the details is : |
341 | 356 | /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 : | |
343 | 358 | rpm -Uvh wireless-tools-XX-Xmdk.XXX.rpm |
344 | 359 | |
345 | 360 | Mandrake can also have wireless setting added to its |
346 | 361 | Auto-Install procedure : |
347 | 362 | http://members.shaw.ca/mandrake/drakx/8.2/HTML/section4-13.html |
348 | 363 | |
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 | + | |
349 | 372 | --------------------------------------------------------------------- |
350 | 373 | |
351 | 374 |
@@ -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 |
@@ -1,96 +1,89 @@ | ||
1 | 1 | Very important note : |
2 | 2 | ------------------- |
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. | |
9 | 8 | |
10 | 9 | You need : |
11 | 10 | -------- |
12 | 11 | 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) | |
16 | 14 | Note : CONFIG_NET_RADIO must be enabled |
17 | 15 | o (Optional) A Pcmcia package supporting Wireless Extension |
18 | 16 | 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. | |
21 | 18 | Note : more recent kernels and drivers are likely to support |
22 | 19 | more wireless extension features... |
23 | 20 | |
24 | 21 | Compile wireless tools : |
25 | 22 | ---------------------- |
26 | 23 | 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. | |
32 | 24 | |
33 | 25 | Installation : |
34 | 26 | ------------ |
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. | |
45 | 34 | |
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. | |
71 | 49 | |
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. | |
80 | 65 | |
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"). | |
94 | 73 | |
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. | |
95 | 88 | |
96 | 89 | Jean <jt@hpl.hp.com> |
@@ -3,51 +3,58 @@ | ||
3 | 3 | ## |
4 | 4 | |
5 | 5 | ## 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... | |
7 | 7 | ifndef PREFIX |
8 | 8 | PREFIX = /usr/local |
9 | 9 | endif |
10 | 10 | |
11 | -## Compiler to use | |
11 | +## Compiler to use (modify this for cross compile) | |
12 | 12 | CC = gcc |
13 | +## Other tools you need to modify for cross compile (static lib only) | |
14 | +AR = ar | |
15 | +RANLIB = ranlib | |
13 | 16 | |
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 | |
26 | 21 | |
27 | 22 | ## 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. | |
29 | 24 | # BUILD_NOLIBM = y |
30 | 25 | |
31 | 26 | # *************************************************************************** |
32 | 27 | # ***** Most users should not need to change anything beyond this point ***** |
33 | 28 | # *************************************************************************** |
34 | 29 | |
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 | + | |
35 | 39 | # Targets to build |
36 | 40 | 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 | |
40 | 44 | MANPAGES7=wireless.7 |
41 | -EXTRAPROGS= macaddr iwredir | |
45 | +MANPAGES5=iftab.5 | |
46 | +EXTRAPROGS= macaddr | |
42 | 47 | |
43 | 48 | # Composition of the library : |
44 | 49 | OBJS = iwlib.o |
45 | 50 | |
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 | |
50 | 53 | IWLIB=$(STATIC) |
54 | + IWLIB_INSTALL=install-static | |
55 | +else | |
56 | + IWLIB=$(DYNAMIC) | |
57 | + IWLIB_INSTALL=install-dynamic | |
51 | 58 | endif |
52 | 59 | |
53 | 60 | # Standard name for dynamic library so that the dynamic linker can pick it. |
@@ -60,21 +67,10 @@ INSTALL_LIB= $(PREFIX)/lib/ | ||
60 | 67 | INSTALL_INC= $(PREFIX)/include/ |
61 | 68 | INSTALL_MAN= $(PREFIX)/man/ |
62 | 69 | |
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 | |
68 | 71 | 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 | |
78 | 74 | |
79 | 75 | # Do we want to build with or without libm ? |
80 | 76 | ifdef BUILD_NOLIBM |
@@ -84,18 +80,22 @@ else | ||
84 | 80 | LIBS= -lm |
85 | 81 | endif |
86 | 82 | |
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) | |
90 | 89 | PICFLAG=-fPIC |
91 | 90 | |
92 | -all:: $(STATIC) $(DYNAMIC) $(PROGS) | |
91 | +# Standard compilation targets | |
92 | +all:: $(IWLIB) $(PROGS) | |
93 | 93 | |
94 | 94 | %: %.o |
95 | 95 | $(CC) $(LDFLAGS) $(XCFLAGS) -o $@ $^ $(LIBS) |
96 | -%.o: %.c | |
96 | +%.o: %.c wireless.h | |
97 | 97 | $(CC) $(XCFLAGS) -c $< |
98 | -%.so: %.c | |
98 | +%.so: %.c wireless.h | |
99 | 99 | $(CC) $(XCFLAGS) $(PICFLAG) -c -o $@ $< |
100 | 100 | |
101 | 101 | iwconfig: iwconfig.o $(IWLIB) |
@@ -106,14 +106,18 @@ iwpriv: iwpriv.o $(IWLIB) | ||
106 | 106 | |
107 | 107 | iwspy: iwspy.o $(IWLIB) |
108 | 108 | |
109 | -iwgetid: iwgetid.o | |
109 | +iwgetid: iwgetid.o $(IWLIB) | |
110 | 110 | |
111 | 111 | iwevent: iwevent.o $(IWLIB) |
112 | 112 | |
113 | -iwredir: iwredir.o | |
113 | +ifrename: ifrename.o $(IWLIB) | |
114 | 114 | |
115 | 115 | macaddr: macaddr.o $(IWLIB) |
116 | 116 | |
117 | +# It's a kind of magic... | |
118 | +wireless.h: | |
119 | + cp $(WEXT_HEADER) wireless.h | |
120 | + | |
117 | 121 | # Compilation of the dynamic library |
118 | 122 | $(DYNAMIC): $(OBJS:.o=.so) |
119 | 123 | $(CC) -shared -o $@ -Wl,-soname,$@ $(LIBS) -lc $^ |
@@ -121,32 +125,43 @@ $(DYNAMIC): $(OBJS:.o=.so) | ||
121 | 125 | # Compilation of the static library |
122 | 126 | $(STATIC): $(OBJS) |
123 | 127 | $(RM) $@ |
124 | - ar cru $@ $^ | |
125 | - ranlib $@ | |
128 | + $(AR) cru $@ $^ | |
129 | + $(RANLIB) $@ | |
126 | 130 | |
127 | 131 | # So crude but so effective ;-) |
128 | 132 | # Less crude thanks to many contributions ;-) |
129 | -install:: all | |
133 | +install:: all $(IWLIB_INSTALL) | |
130 | 134 | install -m 755 -d $(INSTALL_DIR) |
131 | 135 | 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." | |
137 | 136 | install -m 755 -d $(INSTALL_INC) |
138 | 137 | install -m 644 iwlib.h $(INSTALL_INC) |
138 | + install -m 644 wireless.h $(INSTALL_INC) | |
139 | 139 | install -m 755 -d $(INSTALL_MAN)/man8/ |
140 | 140 | install -m 644 $(MANPAGES8) $(INSTALL_MAN)/man8/ |
141 | 141 | install -m 755 -d $(INSTALL_MAN)/man7/ |
142 | 142 | 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) | |
143 | 158 | |
144 | 159 | clean:: |
145 | 160 | $(RM_CMD) |
146 | 161 | |
147 | 162 | realclean:: |
148 | 163 | $(RM_CMD) |
149 | - $(RM) $(STATIC) $(DYNAMIC) $(PROGS) $(EXTRAPROGS) | |
164 | + $(RM) $(STATIC) $(DYNAMIC) $(PROGS) $(EXTRAPROGS) libiw* wireless.h | |
150 | 165 | |
151 | 166 | uninstall:: |
152 | 167 | for f in $(PROGS); do \ |
@@ -156,41 +171,16 @@ uninstall:: | ||
156 | 171 | $(RM) $(INSTALL_LIB)/$(DYNAMIC) |
157 | 172 | $(RM) $(INSTALL_LIB)/$(DYNAMIC_LINK) |
158 | 173 | $(RM) $(INSTALL_INC)/iwlib.h |
174 | + $(RM) $(INSTALL_INC)/wireless.h | |
159 | 175 | for f in $(MANPAGES8); do \ |
160 | 176 | $(RM) $(INSTALL_MAN)/man8/$$f; \ |
161 | 177 | done |
162 | 178 | for f in $(MANPAGES7); do \ |
163 | 179 | $(RM) $(INSTALL_MAN)/man7/$$f; \ |
164 | 180 | done |
181 | + for f in $(MANPAGES5); do \ | |
182 | + $(RM) $(INSTALL_MAN)/man5/$$f; \ | |
183 | + done | |
165 | 184 | |
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 |
@@ -1,21 +1,28 @@ | ||
1 | 1 | Wireless Tools |
2 | 2 | -------------- |
3 | 3 | |
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 | |
6 | 6 | allowing you to set Wireless LAN specific parameters and get the |
7 | 7 | specific stats. |
8 | 8 | |
9 | -web page | |
9 | +web page : | |
10 | 10 | -------- |
11 | 11 | You'll find a lot of useful info on : |
12 | 12 | http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html |
13 | 13 | http://web.hpl.hp.com/personal/Jean_Tourrilhes/Linux/ |
14 | 14 | |
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 | + | |
15 | 22 | INSTALL |
16 | 23 | ------- |
17 | - This file contains installation instruction and requirements. | |
18 | - A *must* read. | |
24 | + This file contains installation instructions and requirements. | |
25 | + A *must*-read. | |
19 | 26 | |
20 | 27 | DISTRIBUTION.txt |
21 | 28 | ---------------- |
@@ -26,28 +33,45 @@ Extensions). Please read it carefully before asking questions. | ||
26 | 33 | Extensions integration in the most common Linux distributions. I need |
27 | 34 | your help to complete this file. |
28 | 35 | |
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 | + | |
29 | 43 | PCMCIA.txt |
30 | 44 | ---------- |
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. | |
33 | 47 | |
34 | 48 | man pages (iwconfig.8, iwlist.8, iwpriv.8, iwspy.8) |
35 | 49 | --------- |
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 | |
37 | 51 | 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 | |
40 | 54 | implement even less). |
41 | 55 | |
42 | 56 | As far as I know, the man pages are the most complete, up to |
43 | 57 | 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 | |
45 | 59 | 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 | |
47 | 61 | command "man" will find them, such as /usr/local/man/man8, or can be |
48 | 62 | read locally with the command : |
49 | 63 | nroff -man xxx.8 | less |
50 | 64 | |
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 | + | |
51 | 75 | iwconfig.c |
52 | 76 | ---------- |
53 | 77 | The main wireless tool. Used for device configuration and to see |
@@ -60,9 +84,9 @@ iwlist.c | ||
60 | 84 | |
61 | 85 | iwspy.c |
62 | 86 | ------- |
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. | |
66 | 90 | |
67 | 91 | iwpriv.c |
68 | 92 | -------- |
@@ -72,19 +96,23 @@ specific to a driver or a device and therefore not part of iwconfig. | ||
72 | 96 | iwgetid.c |
73 | 97 | --------- |
74 | 98 | 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. | |
76 | 100 | |
77 | 101 | iwevent.c |
78 | 102 | --------- |
79 | 103 | Display Wireless Events. This is new, so there is not much support |
80 | 104 | in drivers for it yet... |
81 | 105 | |
106 | +ifrename.c : | |
107 | +---------- | |
108 | + Rename network interfaces based on various selectors. | |
109 | + | |
82 | 110 | iwlib.c |
83 | 111 | ------- |
84 | - The Wireless Tools helper library. May be usefull if you want | |
112 | + The Wireless Tools helper library. May be useful if you want | |
85 | 113 | to create your own applications using Wireless Extensions. |
86 | 114 | |
87 | -Changelog, contributions | |
115 | +Changelog, contributions : | |
88 | 116 | ------------------------ |
89 | 117 | See CHANGELOG.h |
90 | 118 |
@@ -94,29 +122,29 @@ wireless.h | ||
94 | 122 | definition used by the drivers and the tools must match, otherwise |
95 | 123 | funny things may happen. The tools try to check for that. |
96 | 124 | 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 | |
98 | 126 | need to use the full patches available on my web page. So, the use is |
99 | 127 | 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 | |
101 | 129 | your kernel/drivers are old, you may want to try the older releases... |
102 | 130 | |
103 | 131 | sample_xxx.c : |
104 | 132 | ------------ |
105 | 133 | Various samples of code showing how to implement some of the |
106 | 134 | 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. | |
109 | 137 | Also, have a look at existing drivers in the Linux kernel. |
110 | 138 | |
111 | 139 | Other tools : |
112 | 140 | ----------- |
113 | - My web page list many other tools using Wireless | |
141 | + My web page lists many other tools using Wireless | |
114 | 142 | Extensions that you may find useful... |
115 | 143 | http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html#links |
116 | 144 | |
117 | 145 | Other questions : |
118 | 146 | --------------- |
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, | |
120 | 148 | you will find your answer there. |
121 | 149 | |
122 | 150 | Good luck... |
@@ -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> |
@@ -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). |
@@ -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). |
@@ -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). |
@@ -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). |
@@ -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). |
@@ -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). |
@@ -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). |
@@ -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 | + |
@@ -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). |
@@ -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). |
@@ -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 | +} |
@@ -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). |
@@ -1,7 +1,7 @@ | ||
1 | -.\" Jean II - HPLB - 96 | |
1 | +.\" Jean II - HPLB - 1996 => HPL - 2004 | |
2 | 2 | .\" iwconfig.8 |
3 | 3 | .\" |
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" | |
5 | 5 | .\" |
6 | 6 | .\" NAME part |
7 | 7 | .\" |
@@ -41,9 +41,9 @@ may also be used to display those parameters, and the wireless | ||
41 | 41 | statistics (extracted from |
42 | 42 | .IR /proc/net/wireless ). |
43 | 43 | .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 | |
47 | 47 | device for details. |
48 | 48 | .\" |
49 | 49 | .\" PARAMETER part |
@@ -51,14 +51,16 @@ device for details. | ||
51 | 51 | .SH PARAMETERS |
52 | 52 | .TP |
53 | 53 | .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 | |
62 | 64 | .IR off " or " any " (and " on |
63 | 65 | to reenable it). |
64 | 66 | .br |
@@ -69,11 +71,16 @@ to reenable it). | ||
69 | 71 | .I " iwconfig eth0 essid ""My Network"" |
70 | 72 | .TP |
71 | 73 | .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 | |
77 | 84 | .IR off " (and " on |
78 | 85 | to reenable it). |
79 | 86 | .br |
@@ -84,36 +91,37 @@ to reenable it). | ||
84 | 91 | .I " iwconfig eth0 nwid off" |
85 | 92 | .TP |
86 | 93 | .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. | |
98 | 104 | .br |
99 | 105 | .B Examples : |
100 | 106 | .br |
107 | +.I " iwconfig eth0 freq 2422000000" | |
108 | +.br | |
101 | 109 | .I " iwconfig eth0 freq 2.422G" |
102 | 110 | .br |
103 | 111 | .I " iwconfig eth0 channel 3" |
104 | 112 | .TP |
105 | 113 | .B sens |
106 | 114 | 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 | |
109 | 117 | should set it according to the average noise level. Positive values |
110 | 118 | are assumed to be the raw value used by the hardware or a percentage, |
111 | 119 | negative values are assumed to be dBm. |
112 | 120 | .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). | |
117 | 125 | .br |
118 | 126 | .B Example : |
119 | 127 | .br |
@@ -122,18 +130,18 @@ the current access point). | ||
122 | 130 | .B mode |
123 | 131 | Set the operating mode of the device, which depends on the network |
124 | 132 | topology. The mode can be |
125 | -.I Ad-hoc | |
133 | +.I Ad-Hoc | |
126 | 134 | (network composed of only one cell and without Access Point), |
127 | 135 | .I Managed |
128 | 136 | (node connects to a network composed of many Access Points, with roaming), |
129 | 137 | .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), | |
131 | 139 | .I Repeater |
132 | -(the node forward packets between other wireless nodes), | |
140 | +(the node forwards packets between other wireless nodes), | |
133 | 141 | .I Secondary |
134 | -(the node act as a backup master/repeater), | |
142 | +(the node acts as a backup master/repeater), | |
135 | 143 | .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 | |
137 | 145 | .IR Auto . |
138 | 146 | .br |
139 | 147 | .B Example : |
@@ -145,8 +153,8 @@ topology. The mode can be | ||
145 | 153 | .B ap |
146 | 154 | Force the card to register to the Access Point given by the address, |
147 | 155 | 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). | |
150 | 158 | .br |
151 | 159 | You may also use |
152 | 160 | .I off |
@@ -155,7 +163,7 @@ or you may use | ||
155 | 163 | .I any |
156 | 164 | or |
157 | 165 | .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. | |
159 | 167 | .br |
160 | 168 | .B Example : |
161 | 169 | .br |
@@ -166,10 +174,10 @@ to force the card to reassociate with the current best Access Point. | ||
166 | 174 | .I " iwconfig eth0 ap off" |
167 | 175 | .TP |
168 | 176 | .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 | |
170 | 178 | 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. | |
173 | 181 | .br |
174 | 182 | .B Example : |
175 | 183 | .br |
@@ -179,18 +187,18 @@ fact only some diagnostic tools may use it. | ||
179 | 187 | For cards supporting multiple bit rates, set the bit-rate in b/s. The |
180 | 188 | bit-rate is the speed at which bits are transmitted over the medium, |
181 | 189 | the user speed of the link is lower due to medium sharing and |
182 | -overhead. | |
190 | +various overhead. | |
183 | 191 | .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 | |
186 | 194 | card specific, usually an index in the bit-rate list. Use |
187 | 195 | .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 | |
189 | 197 | channels), which is the default for most cards, and |
190 | 198 | .I fixed |
191 | 199 | to revert back to fixed setting. If you specify a bit-rate value and append |
192 | 200 | .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. | |
194 | 202 | .br |
195 | 203 | .B Examples : |
196 | 204 | .br |
@@ -202,11 +210,11 @@ the driver will use all bit lower and equal than this value. | ||
202 | 210 | .TP |
203 | 211 | .BR rts [_threshold] |
204 | 212 | 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 | |
210 | 218 | .IR auto ", " fixed " or " off . |
211 | 219 | .br |
212 | 220 | .B Examples : |
@@ -216,11 +224,12 @@ the scheme. You may also set this parameter to | ||
216 | 224 | .I " iwconfig eth0 rts off" |
217 | 225 | .TP |
218 | 226 | .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 | |
220 | 228 | 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 | |
224 | 233 | .IR auto ", " fixed " or " off . |
225 | 234 | .br |
226 | 235 | .B Examples : |
@@ -241,7 +250,7 @@ also enter the key as an ASCII string by using the | ||
241 | 250 | .I s: |
242 | 251 | prefix. Passphrase is currently not supported. |
243 | 252 | .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 | |
245 | 254 | .I [index] |
246 | 255 | (without entering any key value). |
247 | 256 | .br |
@@ -252,7 +261,7 @@ The security mode may be | ||
252 | 261 | .I open |
253 | 262 | or |
254 | 263 | .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 | |
256 | 265 | .I open |
257 | 266 | mode no authentication is used and the card may also accept |
258 | 267 | non-encrypted sessions, whereas in |
@@ -264,15 +273,19 @@ If you need to set multiple keys, or set a key and change the active | ||
264 | 273 | key, you need to use multiple |
265 | 274 | .B key |
266 | 275 | directives. Arguments can be put in any order, the last one will take |
267 | -precendence. | |
276 | +precedence. | |
268 | 277 | .br |
269 | 278 | .B Examples : |
270 | 279 | .br |
271 | 280 | .I " iwconfig eth0 key 0123-4567-89" |
272 | 281 | .br |
282 | +.I " iwconfig eth0 key [3] 0123-4567-89" | |
283 | +.br | |
273 | 284 | .I " iwconfig eth0 key s:password [2]" |
274 | 285 | .br |
275 | -.I " iwconfig eth0 key [2] open" | |
286 | +.I " iwconfig eth0 key [2]" | |
287 | +.br | |
288 | +.I " iwconfig eth0 key open" | |
276 | 289 | .br |
277 | 290 | .I " iwconfig eth0 key off" |
278 | 291 | .br |
@@ -283,16 +296,16 @@ precendence. | ||
283 | 296 | .BR power |
284 | 297 | Used to manipulate power management scheme parameters and mode. |
285 | 298 | .br |
286 | -To set the period between wake up, enter | |
299 | +To set the period between wake ups, enter | |
287 | 300 | .IR "period `value'" . |
288 | 301 | To set the timeout before going back to sleep, enter |
289 | 302 | .IR "timeout `value'" . |
290 | 303 | You can also add the |
291 | 304 | .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). | |
296 | 309 | .br |
297 | 310 | .IR off " and " on |
298 | 311 | disable and reenable power management. Finally, you may set the power |
@@ -351,11 +364,11 @@ This is an absolute value (without unit). | ||
351 | 364 | The set the maximum length of time the MAC should retry, enter |
352 | 365 | .IR "lifetime `value'" . |
353 | 366 | 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. | |
355 | 368 | .br |
356 | 369 | You can also add the |
357 | 370 | .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 | |
359 | 372 | of the limit or lifetime. Some other cards define different values |
360 | 373 | depending on packet size, for example in 802.11 |
361 | 374 | .I min limit |
@@ -373,15 +386,15 @@ is the short retry limit (non RTS/CTS packets). | ||
373 | 386 | Some cards may not apply changes done through Wireless Extensions |
374 | 387 | immediately (they may wait to agregate the changes or apply it only |
375 | 388 | 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. | |
377 | 390 | .br |
378 | 391 | 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. | |
380 | 393 | .\" |
381 | 394 | .\" DISPLAY part |
382 | 395 | .\" |
383 | 396 | .SH DISPLAY |
384 | -For each device which support wireless extensions, | |
397 | +For each device which supports wireless extensions, | |
385 | 398 | .I iwconfig |
386 | 399 | will display the name of the |
387 | 400 | .B MAC protocol |
@@ -406,15 +419,33 @@ the | ||
406 | 419 | and the |
407 | 420 | .B power management |
408 | 421 | 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. | |
409 | 426 | .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. | |
411 | 431 | .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 | |
413 | 434 | .RB ` = ', |
414 | 435 | 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. | |
418 | 449 | .PP |
419 | 450 | If |
420 | 451 | .I /proc/net/wireless |
@@ -428,7 +459,7 @@ driver documentation for proper interpretation of those values. | ||
428 | 459 | Overall quality of the link. May be based on the level of contention |
429 | 460 | or interference, the bit or frame error rate, how good the received |
430 | 461 | 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. | |
432 | 463 | .TP |
433 | 464 | .B Signal level |
434 | 465 | Received signal strength (RSSI - how strong the received signal |
@@ -442,7 +473,7 @@ mode, this may be undefined and you should use | ||
442 | 473 | .IR iwspy . |
443 | 474 | .TP |
444 | 475 | .B Noise level |
445 | -Background noise level (when no packet is transmited). Similar | |
476 | +Background noise level (when no packet is transmitted). Similar | |
446 | 477 | comments as for |
447 | 478 | .BR "Signal level" . |
448 | 479 | .TP |
@@ -461,16 +492,16 @@ re-assemble the link layer fragments (most likely one was missing). | ||
461 | 492 | .TP |
462 | 493 | .B Tx excessive retries |
463 | 494 | 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. | |
465 | 496 | .TP |
466 | 497 | .B Invalid misc |
467 | 498 | Other packets lost in relation with specific wireless operations. |
468 | 499 | .TP |
469 | 500 | .B Missed beacon |
470 | 501 | 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. | |
474 | 505 | .\" |
475 | 506 | .\" AUTHOR part |
476 | 507 | .\" |
@@ -1,14 +1,14 @@ | ||
1 | 1 | /* |
2 | 2 | * Wireless Tools |
3 | 3 | * |
4 | - * Jean II - HPLB 97->99 - HPL 99->01 | |
4 | + * Jean II - HPLB 97->99 - HPL 99->04 | |
5 | 5 | * |
6 | 6 | * Main code for "iwconfig". This is the generic tool for most |
7 | 7 | * manipulations... |
8 | 8 | * You need to link this code against "iwlib.c" and "-lm". |
9 | 9 | * |
10 | 10 | * 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> | |
12 | 12 | */ |
13 | 13 | |
14 | 14 | #include "iwlib.h" /* Header */ |
@@ -27,6 +27,7 @@ iw_usage(void) | ||
27 | 27 | fprintf(stderr, " [mode {managed|ad-hoc|...}\n"); |
28 | 28 | fprintf(stderr, " [freq N.NNNN[k|M|G]]\n"); |
29 | 29 | fprintf(stderr, " [channel N]\n"); |
30 | + fprintf(stderr, " [ap {N|off|auto}]\n"); | |
30 | 31 | fprintf(stderr, " [sens N]\n"); |
31 | 32 | fprintf(stderr, " [nick N]\n"); |
32 | 33 | fprintf(stderr, " [rate {N|auto|fixed}]\n"); |
@@ -57,43 +58,24 @@ get_info(int skfd, | ||
57 | 58 | |
58 | 59 | memset((char *) info, 0, sizeof(struct wireless_info)); |
59 | 60 | |
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) | |
62 | 63 | { |
63 | 64 | /* If no wireless name : no wireless extensions */ |
64 | 65 | /* But let's check if the interface exists at all */ |
65 | 66 | struct ifreq ifr; |
66 | 67 | |
67 | - strcpy(ifr.ifr_name, ifname); | |
68 | + strncpy(ifr.ifr_name, ifname, IFNAMSIZ); | |
68 | 69 | if(ioctl(skfd, SIOCGIFFLAGS, &ifr) < 0) |
69 | 70 | return(-ENODEV); |
70 | 71 | else |
71 | 72 | return(-ENOTSUP); |
72 | 73 | } |
73 | - else | |
74 | - { | |
75 | - strncpy(info->name, wrq.u.name, IFNAMSIZ); | |
76 | - info->name[IFNAMSIZ] = '\0'; | |
77 | - } | |
78 | 74 | |
79 | 75 | /* Get ranges */ |
80 | 76 | if(iw_get_range_info(skfd, ifname, &(info->range)) >= 0) |
81 | 77 | info->has_range = 1; |
82 | 78 | |
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 | - | |
97 | 79 | /* Get sensitivity */ |
98 | 80 | if(iw_get_ext(skfd, ifname, SIOCGIWSENS, &wrq) >= 0) |
99 | 81 | { |
@@ -101,27 +83,6 @@ get_info(int skfd, | ||
101 | 83 | memcpy(&(info->sens), &(wrq.u.sens), sizeof(iwparam)); |
102 | 84 | } |
103 | 85 | |
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 | - | |
125 | 86 | /* Get AP address */ |
126 | 87 | if(iw_get_ext(skfd, ifname, SIOCGIWAP, &wrq) >= 0) |
127 | 88 | { |
@@ -158,14 +119,6 @@ get_info(int skfd, | ||
158 | 119 | memcpy(&(info->frag), &(wrq.u.frag), sizeof(iwparam)); |
159 | 120 | } |
160 | 121 | |
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 | - | |
169 | 122 | /* Get Power Management settings */ |
170 | 123 | wrq.u.power.flags = 0; |
171 | 124 | if(iw_get_ext(skfd, ifname, SIOCGIWPOWER, &wrq) >= 0) |
@@ -174,26 +127,29 @@ get_info(int skfd, | ||
174 | 127 | memcpy(&(info->power), &(wrq.u.power), sizeof(iwparam)); |
175 | 128 | } |
176 | 129 | |
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)) | |
180 | 131 | { |
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 | + } | |
183 | 138 | } |
184 | -#endif | |
185 | 139 | |
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)) | |
189 | 141 | { |
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 | + } | |
192 | 148 | } |
193 | -#endif /* WIRELESS_EXT > 10 */ | |
194 | 149 | |
195 | 150 | /* 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) | |
197 | 153 | { |
198 | 154 | info->has_stats = 1; |
199 | 155 | } |
@@ -216,19 +172,19 @@ display_info(struct wireless_info * info, | ||
216 | 172 | int tokens = 3; /* For name */ |
217 | 173 | |
218 | 174 | /* 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); | |
220 | 176 | |
221 | 177 | /* Display ESSID (extended network), if any */ |
222 | - if(info->has_essid) | |
178 | + if(info->b.has_essid) | |
223 | 179 | { |
224 | - if(info->essid_on) | |
180 | + if(info->b.essid_on) | |
225 | 181 | { |
226 | 182 | /* 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)); | |
230 | 186 | else |
231 | - printf("ESSID:\"%s\" ", info->essid); | |
187 | + printf("ESSID:\"%s\" ", info->b.essid); | |
232 | 188 | } |
233 | 189 | else |
234 | 190 | printf("ESSID:off/any "); |
@@ -239,35 +195,43 @@ display_info(struct wireless_info * info, | ||
239 | 195 | printf("Nickname:\"%s\"", info->nickname); |
240 | 196 | |
241 | 197 | /* Formatting */ |
242 | - if(info->has_essid || info->has_nickname) | |
198 | + if(info->b.has_essid || info->has_nickname) | |
243 | 199 | { |
244 | 200 | printf("\n "); |
245 | 201 | tokens = 0; |
246 | 202 | } |
247 | 203 | |
248 | 204 | /* Display Network ID */ |
249 | - if(info->has_nwid) | |
205 | + if(info->b.has_nwid) | |
250 | 206 | { |
251 | 207 | /* Note : should display proper number of digit according to info |
252 | 208 | * in range structure */ |
253 | - if(info->nwid.disabled) | |
209 | + if(info->b.nwid.disabled) | |
254 | 210 | printf("NWID:off/any "); |
255 | 211 | else |
256 | - printf("NWID:%X ", info->nwid.value); | |
212 | + printf("NWID:%X ", info->b.nwid.value); | |
257 | 213 | tokens +=2; |
258 | 214 | } |
259 | 215 | |
260 | 216 | /* Display the current mode of operation */ |
261 | - if(info->has_mode) | |
217 | + if(info->b.has_mode) | |
262 | 218 | { |
263 | - printf("Mode:%s ", iw_operation_mode[info->mode]); | |
219 | + printf("Mode:%s ", iw_operation_mode[info->b.mode]); | |
264 | 220 | tokens +=3; |
265 | 221 | } |
266 | 222 | |
267 | 223 | /* Display frequency / channel */ |
268 | - if(info->has_freq) | |
224 | + if(info->b.has_freq) | |
269 | 225 | { |
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); | |
271 | 235 | printf("%s ", buffer); |
272 | 236 | tokens +=4; |
273 | 237 | } |
@@ -284,11 +248,11 @@ display_info(struct wireless_info * info, | ||
284 | 248 | tokens +=6; |
285 | 249 | |
286 | 250 | /* 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)) | |
288 | 252 | printf("Cell:"); |
289 | 253 | else |
290 | 254 | 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)); | |
292 | 256 | } |
293 | 257 | |
294 | 258 | /* Display the currently used/set bit-rate */ |
@@ -303,11 +267,10 @@ display_info(struct wireless_info * info, | ||
303 | 267 | tokens +=3; |
304 | 268 | |
305 | 269 | /* Display it */ |
306 | - iw_print_bitrate(buffer, info->bitrate.value); | |
270 | + iw_print_bitrate(buffer, sizeof(buffer), info->bitrate.value); | |
307 | 271 | printf("Bit Rate%c%s ", (info->bitrate.fixed ? '=' : ':'), buffer); |
308 | 272 | } |
309 | 273 | |
310 | -#if WIRELESS_EXT > 9 | |
311 | 274 | /* Display the Transmit Power */ |
312 | 275 | if(info->has_txpower) |
313 | 276 | { |
@@ -319,30 +282,10 @@ display_info(struct wireless_info * info, | ||
319 | 282 | } |
320 | 283 | tokens +=3; |
321 | 284 | |
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); | |
344 | 288 | } |
345 | -#endif | |
346 | 289 | |
347 | 290 | /* Display sensitivity */ |
348 | 291 | if(info->has_sens) |
@@ -374,7 +317,6 @@ display_info(struct wireless_info * info, | ||
374 | 317 | printf("\n "); |
375 | 318 | tokens = 0; |
376 | 319 | |
377 | -#if WIRELESS_EXT > 10 | |
378 | 320 | /* Display retry limit/lifetime information */ |
379 | 321 | if(info->has_retry) |
380 | 322 | { |
@@ -387,7 +329,7 @@ display_info(struct wireless_info * info, | ||
387 | 329 | /* Let's check the value and its type */ |
388 | 330 | if(info->retry.flags & IW_RETRY_TYPE) |
389 | 331 | { |
390 | - iw_print_retry_value(buffer, | |
332 | + iw_print_retry_value(buffer, sizeof(buffer), | |
391 | 333 | info->retry.value, info->retry.flags); |
392 | 334 | printf("%s", buffer); |
393 | 335 | } |
@@ -399,7 +341,6 @@ display_info(struct wireless_info * info, | ||
399 | 341 | printf(" "); |
400 | 342 | tokens += 5; /* Between 3 and 5, depend on flags */ |
401 | 343 | } |
402 | -#endif /* WIRELESS_EXT > 10 */ | |
403 | 344 | |
404 | 345 | /* Display the RTS threshold */ |
405 | 346 | if(info->has_rts) |
@@ -452,23 +393,24 @@ display_info(struct wireless_info * info, | ||
452 | 393 | |
453 | 394 | /* Display encryption information */ |
454 | 395 | /* Note : we display only the "current" key, use iwlist to list all keys */ |
455 | - if(info->has_key) | |
396 | + if(info->b.has_key) | |
456 | 397 | { |
457 | 398 | 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)) | |
459 | 400 | printf("off\n "); |
460 | 401 | else |
461 | 402 | { |
462 | 403 | /* 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); | |
464 | 406 | printf("%s", buffer); |
465 | 407 | |
466 | 408 | /* 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) | |
470 | 412 | printf(" Security mode:restricted"); |
471 | - if(info->key_flags & IW_ENCODE_OPEN) | |
413 | + if(info->b.key_flags & IW_ENCODE_OPEN) | |
472 | 414 | printf(" Security mode:open"); |
473 | 415 | printf("\n "); |
474 | 416 | } |
@@ -488,12 +430,13 @@ display_info(struct wireless_info * info, | ||
488 | 430 | /* Let's check the value and its type */ |
489 | 431 | if(info->power.flags & IW_POWER_TYPE) |
490 | 432 | { |
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); | |
492 | 435 | printf("%s ", buffer); |
493 | 436 | } |
494 | 437 | |
495 | 438 | /* 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); | |
497 | 440 | printf("%s", buffer); |
498 | 441 | |
499 | 442 | /* Let's check if nothing (simply on) */ |
@@ -506,24 +449,23 @@ display_info(struct wireless_info * info, | ||
506 | 449 | /* Display statistics */ |
507 | 450 | if(info->has_stats) |
508 | 451 | { |
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); | |
511 | 454 | printf("Link %s\n", buffer); |
512 | 455 | |
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); | |
527 | 469 | } |
528 | 470 | |
529 | 471 | printf("\n"); |
@@ -555,12 +497,12 @@ print_info(int skfd, | ||
555 | 497 | break; |
556 | 498 | |
557 | 499 | case -ENOTSUP: |
558 | - fprintf(stderr, "%-8.8s no wireless extensions.\n\n", | |
500 | + fprintf(stderr, "%-8.16s no wireless extensions.\n\n", | |
559 | 501 | ifname); |
560 | 502 | break; |
561 | 503 | |
562 | 504 | default: |
563 | - fprintf(stderr, "%-8.8s %s\n\n", ifname, strerror(-rc)); | |
505 | + fprintf(stderr, "%-8.16s %s\n\n", ifname, strerror(-rc)); | |
564 | 506 | } |
565 | 507 | return(rc); |
566 | 508 | } |
@@ -702,13 +644,48 @@ set_info(int skfd, /* The socket */ | ||
702 | 644 | |
703 | 645 | if(++i >= count) |
704 | 646 | 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)); | |
710 | 671 | |
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 | + } | |
712 | 689 | |
713 | 690 | IW_SET_EXT_ERR(skfd, ifname, SIOCSIWFREQ, &wrq, |
714 | 691 | "Set Frequency"); |
@@ -806,14 +783,12 @@ set_info(int skfd, /* The socket */ | ||
806 | 783 | ++i; |
807 | 784 | gotone++; |
808 | 785 | } |
809 | -#if WIRELESS_EXT > 15 | |
810 | 786 | if((i < count) && (!strncasecmp(args[i], "temporary", 4))) |
811 | 787 | { |
812 | 788 | wrq.u.data.flags |= IW_ENCODE_TEMP; |
813 | 789 | ++i; |
814 | 790 | gotone++; |
815 | 791 | } |
816 | -#endif | |
817 | 792 | } |
818 | 793 | while(gotone != oldone); |
819 | 794 |
@@ -1192,7 +1167,6 @@ set_info(int skfd, /* The socket */ | ||
1192 | 1167 | continue; |
1193 | 1168 | } |
1194 | 1169 | |
1195 | -#if WIRELESS_EXT > 9 | |
1196 | 1170 | /* ---------- Set Transmit-Power ---------- */ |
1197 | 1171 | if(!strncmp(args[i], "txpower", 3)) |
1198 | 1172 | { |
@@ -1209,7 +1183,7 @@ set_info(int skfd, /* The socket */ | ||
1209 | 1183 | wrq.u.txpower.value = -1; |
1210 | 1184 | wrq.u.txpower.fixed = 1; |
1211 | 1185 | wrq.u.txpower.disabled = 0; |
1212 | - wrq.u.data.flags = IW_TXPOW_DBM; | |
1186 | + wrq.u.txpower.flags = IW_TXPOW_DBM; | |
1213 | 1187 | if(!strcasecmp(args[i], "off")) |
1214 | 1188 | wrq.u.txpower.disabled = 1; /* i.e. turn radio off */ |
1215 | 1189 | else |
@@ -1217,52 +1191,73 @@ set_info(int skfd, /* The socket */ | ||
1217 | 1191 | wrq.u.txpower.fixed = 0; /* i.e. use power control */ |
1218 | 1192 | else |
1219 | 1193 | { |
1220 | - if(!strcasecmp(args[i], "fixed")) | |
1194 | + if(!strcasecmp(args[i], "on")) | |
1221 | 1195 | { |
1222 | 1196 | /* Get old tx-power */ |
1223 | 1197 | IW_GET_EXT_ERR(skfd, ifname, SIOCGIWTXPOW, &wrq, |
1224 | 1198 | "Set Tx Power"); |
1225 | - wrq.u.txpower.fixed = 1; | |
1199 | + wrq.u.txpower.disabled = 0; | |
1226 | 1200 | } |
1227 | - else /* Should be a numeric value */ | |
1201 | + else | |
1228 | 1202 | { |
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")) | |
1247 | 1204 | { |
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; | |
1260 | 1210 | } |
1261 | - if(((i+1) < count) && | |
1262 | - (!strcasecmp(args[i+1], "fixed"))) | |
1211 | + else /* Should be a numeric value */ | |
1263 | 1212 | { |
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 | + } | |
1266 | 1261 | } |
1267 | 1262 | } |
1268 | 1263 | } |
@@ -1271,9 +1266,7 @@ set_info(int skfd, /* The socket */ | ||
1271 | 1266 | "Set Tx Power"); |
1272 | 1267 | continue; |
1273 | 1268 | } |
1274 | -#endif | |
1275 | 1269 | |
1276 | -#if WIRELESS_EXT > 10 | |
1277 | 1270 | /* ---------- Set Retry limit ---------- */ |
1278 | 1271 | if(!strncmp(args[i], "retry", 3)) |
1279 | 1272 | { |
@@ -1343,8 +1336,6 @@ set_info(int skfd, /* The socket */ | ||
1343 | 1336 | continue; |
1344 | 1337 | } |
1345 | 1338 | |
1346 | -#endif /* WIRELESS_EXT > 10 */ | |
1347 | - | |
1348 | 1339 | /* ---------- Other ---------- */ |
1349 | 1340 | /* Here we have an unrecognised arg... */ |
1350 | 1341 | fprintf(stderr, "Error : unrecognised wireless request \"%s\"\n", |
@@ -1394,7 +1385,7 @@ main(int argc, | ||
1394 | 1385 | goterr = set_info(skfd, argv + 2, argc - 2, argv[1]); |
1395 | 1386 | |
1396 | 1387 | /* Close the socket. */ |
1397 | - close(skfd); | |
1388 | + iw_sockets_close(skfd); | |
1398 | 1389 | |
1399 | 1390 | return(goterr); |
1400 | 1391 | } |
@@ -1,7 +1,7 @@ | ||
1 | -.\" Jean Tourrilhes - HPL - 2002 | |
1 | +.\" Jean Tourrilhes - HPL - 2002 - 2004 | |
2 | 2 | .\" iwevent.8 |
3 | 3 | .\" |
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" | |
5 | 5 | .\" |
6 | 6 | .\" NAME part |
7 | 7 | .\" |
@@ -69,9 +69,9 @@ available (see | ||
69 | 69 | .B Tx packet dropped |
70 | 70 | A packet directed at this address has been dropped because the |
71 | 71 | 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. | |
75 | 75 | .TP |
76 | 76 | .B Custom driver event |
77 | 77 | Event specific to the driver. Please check the driver documentation. |
@@ -90,10 +90,12 @@ Point (mode master). | ||
90 | 90 | The signal strength for one of the address in the spy list went under |
91 | 91 | the low threshold or went above than the high threshold. |
92 | 92 | .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. | |
97 | 99 | .\" |
98 | 100 | .\" AUTHOR part |
99 | 101 | .\" |
@@ -106,4 +108,5 @@ Jean Tourrilhes \- jt@hpl.hp.com | ||
106 | 108 | .BR iwconfig (8), |
107 | 109 | .BR iwlist (8), |
108 | 110 | .BR iwspy (8), |
109 | -.BR iwpriv (8). | |
111 | +.BR iwpriv (8), | |
112 | +.BR wireless (7). |
@@ -1,7 +1,7 @@ | ||
1 | 1 | /* |
2 | 2 | * Wireless Tools |
3 | 3 | * |
4 | - * Jean II - HPL 99->01 | |
4 | + * Jean II - HPL 99->04 | |
5 | 5 | * |
6 | 6 | * Main code for "iwevent". This listent for wireless events on rtnetlink. |
7 | 7 | * You need to link this code against "iwcommon.c" and "-lm". |
@@ -12,7 +12,7 @@ | ||
12 | 12 | * about it... |
13 | 13 | * |
14 | 14 | * 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> | |
16 | 16 | */ |
17 | 17 | |
18 | 18 | /***************************** INCLUDES *****************************/ |
@@ -31,6 +31,31 @@ | ||
31 | 31 | #define IFLA_WIRELESS (IFLA_MASTER + 1) |
32 | 32 | #endif /* IFLA_WIRELESS */ |
33 | 33 | |
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 | + | |
34 | 59 | /************************ RTNETLINK HELPERS ************************/ |
35 | 60 | /* |
36 | 61 | * The following code is extracted from : |
@@ -97,23 +122,164 @@ static inline int rtnl_open(struct rtnl_handle *rth, unsigned subscriptions) | ||
97 | 122 | return 0; |
98 | 123 | } |
99 | 124 | |
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 | + | |
100 | 267 | /********************* WIRELESS EVENT DECODING *********************/ |
101 | 268 | /* |
102 | - * This is the bit I wrote... | |
269 | + * Parse the Wireless Event and print it out | |
103 | 270 | */ |
104 | 271 | |
105 | -#if WIRELESS_EXT > 13 | |
106 | 272 | /*------------------------------------------------------------------*/ |
107 | 273 | /* |
108 | 274 | * Print one element from the scanning results |
109 | 275 | */ |
110 | 276 | 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) | |
115 | 280 | { |
116 | 281 | char buffer[128]; /* Temporary buffer */ |
282 | + char * prefix = (IW_IS_GET(event->cmd) ? "New" : "Set"); | |
117 | 283 | |
118 | 284 | /* Now, let's decode the event */ |
119 | 285 | switch(event->cmd) |
@@ -122,23 +288,36 @@ print_event_token(struct iw_event * event, /* Extracted token */ | ||
122 | 288 | /* Events that result from a "SET XXX" operation by the user */ |
123 | 289 | case SIOCSIWNWID: |
124 | 290 | if(event->u.nwid.disabled) |
125 | - printf("NWID:off/any\n"); | |
291 | + printf("Set NWID:off/any\n"); | |
126 | 292 | else |
127 | - printf("NWID:%X\n", event->u.nwid.value); | |
293 | + printf("Set NWID:%X\n", event->u.nwid.value); | |
128 | 294 | break; |
129 | 295 | case SIOCSIWFREQ: |
296 | + case SIOCGIWFREQ: | |
130 | 297 | { |
131 | - float freq; /* Frequency/channel */ | |
298 | + double freq; /* Frequency/channel */ | |
299 | + int channel = -1; /* Converted to channel */ | |
132 | 300 | 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); | |
135 | 313 | } |
136 | 314 | break; |
137 | 315 | case SIOCSIWMODE: |
138 | - printf("Mode:%s\n", | |
316 | + printf("Set Mode:%s\n", | |
139 | 317 | iw_operation_mode[event->u.mode]); |
140 | 318 | break; |
141 | 319 | case SIOCSIWESSID: |
320 | + case SIOCGIWESSID: | |
142 | 321 | { |
143 | 322 | char essid[IW_ESSID_MAX_SIZE+1]; |
144 | 323 | if((event->u.essid.pointer) && (event->u.essid.length)) |
@@ -148,13 +327,13 @@ print_event_token(struct iw_event * event, /* Extracted token */ | ||
148 | 327 | { |
149 | 328 | /* Does it have an ESSID index ? */ |
150 | 329 | 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, | |
152 | 331 | (event->u.essid.flags & IW_ENCODE_INDEX)); |
153 | 332 | else |
154 | - printf("ESSID:\"%s\"\n", essid); | |
333 | + printf("%s ESSID:\"%s\"\n", prefix, essid); | |
155 | 334 | } |
156 | 335 | else |
157 | - printf("ESSID:off/any\n"); | |
336 | + printf("%s ESSID:off/any\n", prefix); | |
158 | 337 | } |
159 | 338 | break; |
160 | 339 | case SIOCSIWENCODE: |
@@ -164,13 +343,13 @@ print_event_token(struct iw_event * event, /* Extracted token */ | ||
164 | 343 | memcpy(key, event->u.essid.pointer, event->u.data.length); |
165 | 344 | else |
166 | 345 | event->u.data.flags |= IW_ENCODE_NOKEY; |
167 | - printf("Encryption key:"); | |
346 | + printf("Set Encryption key:"); | |
168 | 347 | if(event->u.data.flags & IW_ENCODE_DISABLED) |
169 | 348 | printf("off\n"); |
170 | 349 | else |
171 | 350 | { |
172 | 351 | /* 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, | |
174 | 353 | event->u.data.flags); |
175 | 354 | printf("%s", buffer); |
176 | 355 |
@@ -198,7 +377,6 @@ print_event_token(struct iw_event * event, /* Extracted token */ | ||
198 | 377 | printf("Tx packet dropped:%s\n", |
199 | 378 | iw_pr_ether(buffer, event->u.addr.sa_data)); |
200 | 379 | break; |
201 | -#if WIRELESS_EXT > 14 | |
202 | 380 | case IWEVCUSTOM: |
203 | 381 | { |
204 | 382 | char custom[IW_CUSTOM_MAX+1]; |
@@ -216,42 +394,28 @@ print_event_token(struct iw_event * event, /* Extracted token */ | ||
216 | 394 | printf("Expired node:%s\n", |
217 | 395 | iw_pr_ether(buffer, event->u.addr.sa_data)); |
218 | 396 | break; |
219 | -#endif /* WIRELESS_EXT > 14 */ | |
220 | -#if WIRELESS_EXT > 15 | |
221 | 397 | case SIOCGIWTHRSPY: |
222 | 398 | { |
223 | 399 | struct iw_thrspy threshold; |
224 | - int skfd; | |
225 | - struct iw_range range; | |
226 | - int has_range = 0; | |
227 | 400 | if((event->u.data.pointer) && (event->u.data.length)) |
228 | 401 | { |
229 | 402 | memcpy(&threshold, event->u.data.pointer, |
230 | 403 | 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 | - } | |
236 | 404 | printf("Spy threshold crossed on address:%s\n", |
237 | 405 | 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); | |
240 | 408 | printf(" Link %s\n", buffer); |
241 | 409 | } |
242 | 410 | else |
243 | 411 | printf("Invalid Spy Threshold event\n"); |
244 | 412 | } |
245 | 413 | break; |
246 | -#else | |
247 | - /* Avoid "Unused parameter" warning */ | |
248 | - ifname = ifname; | |
249 | -#endif /* WIRELESS_EXT > 15 */ | |
250 | 414 | /* ----- junk ----- */ |
251 | 415 | /* other junk not currently in use */ |
252 | 416 | 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); | |
255 | 419 | break; |
256 | 420 | case SIOCGIWNAME: |
257 | 421 | printf("Protocol:%-1.16s\n", event->u.name); |
@@ -259,7 +423,8 @@ print_event_token(struct iw_event * event, /* Extracted token */ | ||
259 | 423 | case IWEVQUAL: |
260 | 424 | { |
261 | 425 | 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); | |
263 | 428 | printf("Link %s\n", buffer); |
264 | 429 | break; |
265 | 430 | } |
@@ -277,7 +442,7 @@ print_event_token(struct iw_event * event, /* Extracted token */ | ||
277 | 442 | * just make sure we read everything... |
278 | 443 | */ |
279 | 444 | static inline int |
280 | -print_event_stream(char * ifname, | |
445 | +print_event_stream(int ifindex, | |
281 | 446 | char * data, |
282 | 447 | int len) |
283 | 448 | { |
@@ -287,41 +452,42 @@ print_event_stream(char * ifname, | ||
287 | 452 | int ret; |
288 | 453 | char buffer[64]; |
289 | 454 | struct timeval recv_time; |
290 | -#if 0 | |
291 | - struct iw_range range; | |
292 | - int has_range; | |
293 | -#endif | |
455 | + struct wireless_iface * wireless_data; | |
294 | 456 | |
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); | |
298 | 461 | |
299 | - /* In readable form */ | |
462 | + /* Print received time in readable form */ | |
300 | 463 | gettimeofday(&recv_time, NULL); |
301 | - iw_print_timeval(buffer, &recv_time); | |
464 | + iw_print_timeval(buffer, sizeof(buffer), &recv_time); | |
302 | 465 | |
303 | 466 | iw_init_event_stream(&stream, data, len); |
304 | 467 | do |
305 | 468 | { |
306 | 469 | /* 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); | |
308 | 472 | if(ret != 0) |
309 | 473 | { |
310 | 474 | if(i++ == 0) |
311 | - printf("%s %-8.8s ", buffer, ifname); | |
475 | + printf("%s %-8.16s ", buffer, wireless_data->ifname); | |
312 | 476 | else |
313 | 477 | printf(" "); |
314 | 478 | if(ret > 0) |
315 | - print_event_token(&iwe, ifname, NULL, 0); | |
479 | + print_event_token(&iwe, | |
480 | + &wireless_data->range, wireless_data->has_range); | |
316 | 481 | else |
317 | 482 | printf("(Invalid event)\n"); |
483 | + /* Push data out *now*, in case we are redirected to a pipe */ | |
484 | + fflush(stdout); | |
318 | 485 | } |
319 | 486 | } |
320 | 487 | while(ret > 0); |
321 | 488 | |
322 | 489 | return(0); |
323 | 490 | } |
324 | -#endif /* WIRELESS_EXT > 13 */ | |
325 | 491 | |
326 | 492 | /*********************** RTNETLINK EVENT DUMP***********************/ |
327 | 493 | /* |
@@ -333,76 +499,51 @@ print_event_stream(char * ifname, | ||
333 | 499 | /* |
334 | 500 | * Respond to a single RTM_NEWLINK event from the rtnetlink socket. |
335 | 501 | */ |
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 | - */ | |
368 | 502 | static int |
369 | 503 | LinkCatcher(struct nlmsghdr *nlh) |
370 | 504 | { |
371 | 505 | struct ifinfomsg* ifi; |
372 | - char ifname[IFNAMSIZ + 1]; | |
373 | 506 | |
374 | 507 | #if 0 |
375 | 508 | fprintf(stderr, "nlmsg_type = %d.\n", nlh->nlmsg_type); |
376 | 509 | #endif |
377 | 510 | |
378 | - if(nlh->nlmsg_type != RTM_NEWLINK) | |
379 | - return 0; | |
380 | - | |
381 | 511 | ifi = NLMSG_DATA(nlh); |
382 | 512 | |
383 | - /* Get a name... */ | |
384 | - index2name(ifi->ifi_index, ifname); | |
385 | - | |
386 | -#if WIRELESS_EXT > 13 | |
387 | 513 | /* Code is ugly, but sort of works - Jean II */ |
388 | 514 | |
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 | + | |
389 | 527 | /* Check for attributes */ |
390 | - if (nlh->nlmsg_len > NLMSG_ALIGN(sizeof(struct ifinfomsg))) { | |
528 | + if (nlh->nlmsg_len > NLMSG_ALIGN(sizeof(struct ifinfomsg))) | |
529 | + { | |
391 | 530 | 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); | |
401 | 545 | } |
402 | - attr = RTA_NEXT(attr, attrlen); | |
403 | - } | |
404 | - } | |
405 | -#endif /* WIRELESS_EXT > 13 */ | |
546 | + } | |
406 | 547 | |
407 | 548 | return 0; |
408 | 549 | } |
@@ -419,7 +560,7 @@ handle_netlink_events(struct rtnl_handle * rth) | ||
419 | 560 | while(1) |
420 | 561 | { |
421 | 562 | struct sockaddr_nl sanl; |
422 | - socklen_t sanllen; | |
563 | + socklen_t sanllen = sizeof(struct sockaddr_nl); | |
423 | 564 | |
424 | 565 | struct nlmsghdr *h; |
425 | 566 | int amt; |
@@ -457,6 +598,7 @@ handle_netlink_events(struct rtnl_handle * rth) | ||
457 | 598 | switch(h->nlmsg_type) |
458 | 599 | { |
459 | 600 | case RTM_NEWLINK: |
601 | + case RTM_DELLINK: | |
460 | 602 | LinkCatcher(h); |
461 | 603 | break; |
462 | 604 | default: |
@@ -593,12 +735,7 @@ main(int argc, | ||
593 | 735 | return(1); |
594 | 736 | } |
595 | 737 | |
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"); | |
602 | 739 | |
603 | 740 | /* Do what we have to do */ |
604 | 741 | wait_for_event(&rth); |
@@ -1,8 +1,8 @@ | ||
1 | 1 | .\" Guus Sliepen - 2001 |
2 | -.\" Completed and fixed up by Jean Tourrilhes - 2002 | |
2 | +.\" Completed and fixed up by Jean Tourrilhes - 2002-2003 | |
3 | 3 | .\" iwgetid.8 |
4 | 4 | .\" |
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" | |
6 | 6 | .\" |
7 | 7 | .\" NAME part |
8 | 8 | .\" |
@@ -12,9 +12,9 @@ iwgetid \- Report ESSID, NWID or AP/Cell Address of wireless network | ||
12 | 12 | .\" SYNOPSIS part |
13 | 13 | .\" |
14 | 14 | .SH SYNOPSIS |
15 | -.BI "iwgetid " [interface] " [--scheme] [--ap] [--freq] [--mode]" | |
15 | +.BI "iwgetid " [interface] " [--raw] [--scheme] [--ap] [--freq]" | |
16 | 16 | .br |
17 | -.BI " [--protocol] | |
17 | +.BI " [--mode] [--protocol] [--channel] | |
18 | 18 | .br |
19 | 19 | .\" |
20 | 20 | .\" DESCRIPTION part |
@@ -34,26 +34,42 @@ will print the | ||
34 | 34 | of the device, and if the device doesn't have any ESSID it will print |
35 | 35 | its |
36 | 36 | .IR NWID . |
37 | +.br | |
38 | +The default formatting output is pretty-print. | |
37 | 39 | .\" |
38 | 40 | .\" OPTIONS part |
39 | 41 | .\" |
40 | 42 | .SH OPTIONS |
41 | 43 | .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 | |
42 | 59 | .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). | |
47 | 63 | .br |
48 | 64 | The resulting output is a valid Pcmcia scheme identifier (that may be |
49 | 65 | used as an argument of the command |
50 | 66 | .BR "cardctl scheme" ). |
51 | 67 | This format is also ideal when using the result of iwgetid as a |
52 | -variable in | |
68 | +selector in | |
53 | 69 | .I Shell |
54 | 70 | or |
55 | 71 | .I Perl |
56 | -scripts. | |
72 | +scripts, or as a file name. | |
57 | 73 | .TP |
58 | 74 | .B --ap |
59 | 75 | Display the MAC address of the Wireless |
@@ -68,6 +84,12 @@ or | ||
68 | 84 | .I channel |
69 | 85 | used by the interface. |
70 | 86 | .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 | |
71 | 93 | .B --mode |
72 | 94 | Display the current |
73 | 95 | .I mode |
@@ -6,21 +6,13 @@ | ||
6 | 6 | * Just print the ESSID or NWID... |
7 | 7 | * |
8 | 8 | * 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> | |
10 | 10 | */ |
11 | 11 | |
12 | 12 | #include "iwlib.h" /* Header */ |
13 | 13 | |
14 | 14 | #include <getopt.h> |
15 | 15 | |
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 | - | |
24 | 16 | /* |
25 | 17 | * Note on Pcmcia Schemes : |
26 | 18 | * ---------------------- |
@@ -68,119 +60,17 @@ | ||
68 | 60 | * Jean II - 29/3/01 |
69 | 61 | */ |
70 | 62 | |
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 ****************************/ | |
131 | 64 | |
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 */ | |
184 | 74 | |
185 | 75 | /************************ DISPLAY ESSID/NWID ************************/ |
186 | 76 |
@@ -199,12 +89,14 @@ print_essid(int skfd, | ||
199 | 89 | unsigned int i; |
200 | 90 | unsigned int j; |
201 | 91 | |
92 | + /* Make shure ESSID is NULL terminated */ | |
93 | + memset(essid, 0, sizeof(essid)); | |
94 | + | |
202 | 95 | /* Get ESSID */ |
203 | - strncpy(wrq.ifr_name, ifname, IFNAMSIZ); | |
204 | 96 | wrq.u.essid.pointer = (caddr_t) essid; |
205 | 97 | wrq.u.essid.length = IW_ESSID_MAX_SIZE + 1; |
206 | 98 | wrq.u.essid.flags = 0; |
207 | - if(ioctl(skfd, SIOCGIWESSID, &wrq) < 0) | |
99 | + if(iw_get_ext(skfd, ifname, SIOCGIWESSID, &wrq) < 0) | |
208 | 100 | return(-1); |
209 | 101 | |
210 | 102 | switch(format) |
@@ -220,8 +112,11 @@ print_essid(int skfd, | ||
220 | 112 | return(-2); |
221 | 113 | printf("%s\n", pessid); |
222 | 114 | break; |
115 | + case FORMAT_RAW: | |
116 | + printf("%s\n", essid); | |
117 | + break; | |
223 | 118 | default: |
224 | - printf("%-8.8s ESSID:\"%s\"\n", ifname, essid); | |
119 | + printf("%-8.16s ESSID:\"%s\"\n", ifname, essid); | |
225 | 120 | break; |
226 | 121 | } |
227 | 122 |
@@ -240,8 +135,7 @@ print_nwid(int skfd, | ||
240 | 135 | struct iwreq wrq; |
241 | 136 | |
242 | 137 | /* 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) | |
245 | 139 | return(-1); |
246 | 140 | |
247 | 141 | switch(format) |
@@ -250,8 +144,11 @@ print_nwid(int skfd, | ||
250 | 144 | /* Prefix with nwid to avoid name space collisions */ |
251 | 145 | printf("nwid%X\n", wrq.u.nwid.value); |
252 | 146 | break; |
147 | + case FORMAT_RAW: | |
148 | + printf("%X\n", wrq.u.nwid.value); | |
149 | + break; | |
253 | 150 | 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); | |
255 | 152 | break; |
256 | 153 | } |
257 | 154 |
@@ -273,8 +170,7 @@ print_ap(int skfd, | ||
273 | 170 | char buffer[64]; |
274 | 171 | |
275 | 172 | /* 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) | |
278 | 174 | return(-1); |
279 | 175 | |
280 | 176 | /* Print */ |
@@ -284,10 +180,11 @@ print_ap(int skfd, | ||
284 | 180 | case FORMAT_SCHEME: |
285 | 181 | /* I think ':' are not problematic, because Pcmcia scripts |
286 | 182 | * seem to handle them properly... */ |
183 | + case FORMAT_RAW: | |
287 | 184 | printf("%s\n", buffer); |
288 | 185 | break; |
289 | 186 | default: |
290 | - printf("%-8.8s Access Point/Cell: %s\n", ifname, buffer); | |
187 | + printf("%-8.16s Access Point/Cell: %s\n", ifname, buffer); | |
291 | 188 | break; |
292 | 189 | } |
293 | 190 |
@@ -310,8 +207,7 @@ print_freq(int skfd, | ||
310 | 207 | char buffer[64]; |
311 | 208 | |
312 | 209 | /* 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) | |
315 | 211 | return(-1); |
316 | 212 | |
317 | 213 | /* Print */ |
@@ -319,11 +215,64 @@ print_freq(int skfd, | ||
319 | 215 | switch(format) |
320 | 216 | { |
321 | 217 | case FORMAT_SCHEME: |
218 | + /* Prefix with freq to avoid name space collisions */ | |
219 | + printf("freq%g\n", freq); | |
220 | + break; | |
221 | + case FORMAT_RAW: | |
322 | 222 | printf("%g\n", freq); |
323 | 223 | break; |
324 | 224 | 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); | |
327 | 276 | break; |
328 | 277 | } |
329 | 278 |
@@ -342,8 +291,7 @@ print_mode(int skfd, | ||
342 | 291 | struct iwreq wrq; |
343 | 292 | |
344 | 293 | /* 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) | |
347 | 295 | return(-1); |
348 | 296 | if(wrq.u.mode >= IW_NUM_OPER_MODE) |
349 | 297 | return(-2); |
@@ -352,10 +300,17 @@ print_mode(int skfd, | ||
352 | 300 | switch(format) |
353 | 301 | { |
354 | 302 | 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: | |
355 | 310 | printf("%d\n", wrq.u.mode); |
356 | 311 | break; |
357 | 312 | 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]); | |
359 | 314 | break; |
360 | 315 | } |
361 | 316 |
@@ -378,8 +333,7 @@ print_protocol(int skfd, | ||
378 | 333 | unsigned int j; |
379 | 334 | |
380 | 335 | /* 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) | |
383 | 337 | return(-1); |
384 | 338 | strncpy(proto, wrq.u.name, IFNAMSIZ); |
385 | 339 | proto[IFNAMSIZ] = '\0'; |
@@ -397,8 +351,11 @@ print_protocol(int skfd, | ||
397 | 351 | return(-2); |
398 | 352 | printf("%s\n", pproto); |
399 | 353 | break; |
354 | + case FORMAT_RAW: | |
355 | + printf("%s\n", proto); | |
356 | + break; | |
400 | 357 | default: |
401 | - printf("%-8.8s Protocol Name:\"%s\"\n", ifname, proto); | |
358 | + printf("%-8.16s Protocol Name:\"%s\"\n", ifname, proto); | |
402 | 359 | break; |
403 | 360 | } |
404 | 361 |
@@ -427,6 +384,11 @@ print_one_device(int skfd, | ||
427 | 384 | ret = print_ap(skfd, ifname, format); |
428 | 385 | break; |
429 | 386 | |
387 | + case WTYPE_CHANNEL: | |
388 | + /* Try to print channel */ | |
389 | + ret = print_channel(skfd, ifname, format); | |
390 | + break; | |
391 | + | |
430 | 392 | case WTYPE_FREQ: |
431 | 393 | /* Try to print frequency */ |
432 | 394 | ret = print_freq(skfd, ifname, format); |
@@ -458,6 +420,11 @@ print_one_device(int skfd, | ||
458 | 420 | /*------------------------------------------------------------------*/ |
459 | 421 | /* |
460 | 422 | * 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 | |
461 | 428 | */ |
462 | 429 | static int |
463 | 430 | scan_devices(int skfd, |
@@ -498,9 +465,11 @@ iw_usage(int status) | ||
498 | 465 | fputs("Usage iwgetid [OPTIONS] [ifname]\n" |
499 | 466 | " Options are:\n" |
500 | 467 | " -a,--ap Print the access point address\n" |
468 | + " -c,--channel Print the current channel\n" | |
501 | 469 | " -f,--freq Print the current frequency\n" |
502 | 470 | " -m,--mode Print the current mode\n" |
503 | 471 | " -p,--protocol Print the protocol name\n" |
472 | + " -r,--raw Format the output as raw value for shell scripts\n" | |
504 | 473 | " -s,--scheme Format the output as a PCMCIA scheme identifier\n" |
505 | 474 | " -h,--help Print this message\n", |
506 | 475 | status ? stderr : stdout); |
@@ -509,10 +478,12 @@ iw_usage(int status) | ||
509 | 478 | |
510 | 479 | static const struct option long_opts[] = { |
511 | 480 | { "ap", no_argument, NULL, 'a' }, |
481 | + { "channel", no_argument, NULL, 'c' }, | |
512 | 482 | { "freq", no_argument, NULL, 'f' }, |
513 | 483 | { "mode", no_argument, NULL, 'm' }, |
514 | 484 | { "protocol", no_argument, NULL, 'p' }, |
515 | 485 | { "help", no_argument, NULL, 'h' }, |
486 | + { "raw", no_argument, NULL, 'r' }, | |
516 | 487 | { "scheme", no_argument, NULL, 's' }, |
517 | 488 | { NULL, 0, NULL, 0 } |
518 | 489 | }; |
@@ -532,7 +503,7 @@ main(int argc, | ||
532 | 503 | int ret = -1; |
533 | 504 | |
534 | 505 | /* 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) | |
536 | 507 | { |
537 | 508 | switch(opt) |
538 | 509 | { |
@@ -541,6 +512,11 @@ main(int argc, | ||
541 | 512 | wtype = WTYPE_AP; |
542 | 513 | break; |
543 | 514 | |
515 | + case 'c': | |
516 | + /* User wants channel only */ | |
517 | + wtype = WTYPE_CHANNEL; | |
518 | + break; | |
519 | + | |
544 | 520 | case 'f': |
545 | 521 | /* User wants frequency/channel */ |
546 | 522 | wtype = WTYPE_FREQ; |
@@ -560,6 +536,11 @@ main(int argc, | ||
560 | 536 | iw_usage(0); |
561 | 537 | break; |
562 | 538 | |
539 | + case 'r': | |
540 | + /* User wants a Raw format */ | |
541 | + format = FORMAT_RAW; | |
542 | + break; | |
543 | + | |
563 | 544 | case 's': |
564 | 545 | /* User wants a Scheme format */ |
565 | 546 | format = FORMAT_SCHEME; |
@@ -595,6 +576,6 @@ main(int argc, | ||
595 | 576 | } |
596 | 577 | |
597 | 578 | fflush(stdout); |
598 | - close(skfd); | |
579 | + iw_sockets_close(skfd); | |
599 | 580 | return(ret); |
600 | 581 | } |
@@ -1,12 +1,12 @@ | ||
1 | 1 | /* |
2 | 2 | * Wireless Tools |
3 | 3 | * |
4 | - * Jean II - HPLB 97->99 - HPL 99->03 | |
4 | + * Jean II - HPLB 97->99 - HPL 99->04 | |
5 | 5 | * |
6 | 6 | * Common subroutines to all the wireless tools... |
7 | 7 | * |
8 | 8 | * 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> | |
10 | 10 | */ |
11 | 11 | |
12 | 12 | /***************************** INCLUDES *****************************/ |
@@ -15,40 +15,84 @@ | ||
15 | 15 | |
16 | 16 | /************************ CONSTANTS & MACROS ************************/ |
17 | 17 | |
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 ******************************/ | |
23 | 29 | |
24 | 30 | /* |
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 | |
34 | 32 | */ |
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) | |
49 | 92 | |
50 | 93 | /**************************** VARIABLES ****************************/ |
51 | 94 | |
95 | +/* Modes as human readable strings */ | |
52 | 96 | const char * const iw_operation_mode[] = { "Auto", |
53 | 97 | "Ad-Hoc", |
54 | 98 | "Managed", |
@@ -146,7 +190,7 @@ iw_get_ifname(char * name, /* Where to store the name */ | ||
146 | 190 | */ |
147 | 191 | void |
148 | 192 | iw_enum_devices(int skfd, |
149 | - iw_enum_handler fn, | |
193 | + iw_enum_handler fn, | |
150 | 194 | char * args[], |
151 | 195 | int count) |
152 | 196 | { |
@@ -217,77 +261,63 @@ iw_enum_devices(int skfd, | ||
217 | 261 | |
218 | 262 | /*------------------------------------------------------------------*/ |
219 | 263 | /* |
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). | |
221 | 273 | */ |
222 | 274 | int |
223 | -iw_get_range_info(int skfd, | |
224 | - char * ifname, | |
225 | - iwrange * range) | |
275 | +iw_get_kernel_we_version(void) | |
226 | 276 | { |
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; | |
229 | 281 | |
230 | - /* Cleanup */ | |
231 | - memset(buffer, 0, sizeof(buffer)); | |
282 | + /* Check if /proc/net/wireless is available */ | |
283 | + fh = fopen(PROC_NET_WIRELESS, "r"); | |
232 | 284 | |
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 | + } | |
238 | 290 | |
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); | |
241 | 293 | |
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) | |
247 | 295 | { |
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; | |
269 | 301 | 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); | |
279 | 305 | } |
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; | |
285 | 306 | |
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); | |
289 | 309 | |
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); | |
291 | 321 | } |
292 | 322 | |
293 | 323 | /*------------------------------------------------------------------*/ |
@@ -321,7 +351,7 @@ print_iface_version_info(int skfd, | ||
321 | 351 | if(iw_get_ext(skfd, ifname, SIOCGIWRANGE, &wrq) < 0) |
322 | 352 | { |
323 | 353 | /* 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); | |
325 | 355 | return(0); |
326 | 356 | } |
327 | 357 |
@@ -330,21 +360,18 @@ print_iface_version_info(int skfd, | ||
330 | 360 | |
331 | 361 | /* For new versions, we can check the version directly, for old versions |
332 | 362 | * 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) | |
334 | 364 | { |
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", | |
337 | 367 | ifname, range->we_version_source); |
338 | 368 | printf(" Currently compiled with Wireless Extension v%d.\n\n", |
339 | 369 | range->we_version_compiled); |
340 | -#endif /* WIRELESS_EXT > 10 */ | |
341 | 370 | } |
342 | 371 | else |
343 | 372 | { |
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", | |
346 | 374 | ifname); |
347 | -#endif | |
348 | 375 | } |
349 | 376 | |
350 | 377 |
@@ -356,13 +383,10 @@ print_iface_version_info(int skfd, | ||
356 | 383 | * Print the WE versions of the tools. |
357 | 384 | */ |
358 | 385 | int |
359 | -iw_print_version_info(char * toolname) | |
386 | +iw_print_version_info(const char * toolname) | |
360 | 387 | { |
361 | 388 | int skfd; /* generic raw socket desc. */ |
362 | - char buff[1024]; | |
363 | - FILE * fh; | |
364 | - char * p; | |
365 | - int v; | |
389 | + int we_kernel_version; | |
366 | 390 | |
367 | 391 | /* Create a channel to the NET kernel. */ |
368 | 392 | if((skfd = iw_sockets_open()) < 0) |
@@ -373,64 +397,214 @@ iw_print_version_info(char * toolname) | ||
373 | 397 | |
374 | 398 | /* Information about the tools themselves */ |
375 | 399 | 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", | |
378 | 402 | WE_VERSION); |
379 | - printf(" Currently compiled with Wireless Extension v%d.\n\n", | |
380 | - WIRELESS_EXT); | |
381 | 403 | |
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) | |
385 | 447 | { |
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 | + } | |
388 | 497 | |
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) | |
391 | 505 | { |
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"); | |
400 | 509 | } |
401 | - /* Cleanup */ | |
402 | - fclose(fh); | |
403 | - } | |
404 | 510 | |
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 | + } | |
407 | 519 | |
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 | + } | |
409 | 532 | |
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); | |
411 | 539 | } |
412 | 540 | |
413 | 541 | /*------------------------------------------------------------------*/ |
414 | 542 | /* |
415 | 543 | * 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. | |
416 | 547 | */ |
417 | 548 | int |
418 | 549 | iw_get_priv_info(int skfd, |
419 | - char * ifname, | |
420 | - iwprivargs * priv, | |
421 | - int maxpriv) | |
550 | + const char * ifname, | |
551 | + iwprivargs ** ppriv) | |
422 | 552 | { |
423 | 553 | 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; | |
424 | 573 | |
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 | + } | |
431 | 592 | |
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); | |
434 | 608 | } |
435 | 609 | |
436 | 610 | /*------------------------------------------------------------------*/ |
@@ -443,7 +617,7 @@ iw_get_priv_info(int skfd, | ||
443 | 617 | */ |
444 | 618 | int |
445 | 619 | iw_get_basic_config(int skfd, |
446 | - char * ifname, | |
620 | + const char * ifname, | |
447 | 621 | wireless_config * info) |
448 | 622 | { |
449 | 623 | struct iwreq wrq; |
@@ -472,6 +646,7 @@ iw_get_basic_config(int skfd, | ||
472 | 646 | { |
473 | 647 | info->has_freq = 1; |
474 | 648 | info->freq = iw_freq2float(&(wrq.u.freq)); |
649 | + info->freq_flags = wrq.u.freq.flags; | |
475 | 650 | } |
476 | 651 | |
477 | 652 | /* Get encryption information */ |
@@ -499,7 +674,7 @@ iw_get_basic_config(int skfd, | ||
499 | 674 | if(iw_get_ext(skfd, ifname, SIOCGIWMODE, &wrq) >= 0) |
500 | 675 | { |
501 | 676 | info->mode = wrq.u.mode; |
502 | - if((info->mode < 6) && (info->mode >= 0)) | |
677 | + if((info->mode < IW_NUM_OPER_MODE) && (info->mode >= 0)) | |
503 | 678 | info->has_mode = 1; |
504 | 679 | } |
505 | 680 |
@@ -515,7 +690,7 @@ iw_get_basic_config(int skfd, | ||
515 | 690 | */ |
516 | 691 | int |
517 | 692 | iw_set_basic_config(int skfd, |
518 | - char * ifname, | |
693 | + const char * ifname, | |
519 | 694 | wireless_config * info) |
520 | 695 | { |
521 | 696 | struct iwreq wrq; |
@@ -526,15 +701,18 @@ iw_set_basic_config(int skfd, | ||
526 | 701 | /* If no wireless name : no wireless extensions */ |
527 | 702 | return(-2); |
528 | 703 | |
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) | |
531 | 709 | { |
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; | |
534 | 712 | |
535 | - if(iw_set_ext(skfd, ifname, SIOCSIWNWID, &wrq) < 0) | |
713 | + if(iw_get_ext(skfd, ifname, SIOCSIWMODE, &wrq) < 0) | |
536 | 714 | { |
537 | - fprintf(stderr, "SIOCSIWNWID: %s\n", strerror(errno)); | |
715 | + fprintf(stderr, "SIOCSIWMODE: %s\n", strerror(errno)); | |
538 | 716 | ret = -1; |
539 | 717 | } |
540 | 718 | } |
@@ -580,6 +758,10 @@ iw_set_basic_config(int skfd, | ||
580 | 758 | wrq.u.data.length = info->key_size; |
581 | 759 | wrq.u.data.flags = flags; |
582 | 760 | |
761 | + /* Compatibility with WE<13 */ | |
762 | + if(flags & IW_ENCODE_NOKEY) | |
763 | + wrq.u.data.pointer = NULL; | |
764 | + | |
583 | 765 | if(iw_set_ext(skfd, ifname, SIOCSIWENCODE, &wrq) < 0) |
584 | 766 | { |
585 | 767 | fprintf(stderr, "SIOCSIWENCODE(%d): %s\n", |
@@ -588,29 +770,33 @@ iw_set_basic_config(int skfd, | ||
588 | 770 | } |
589 | 771 | } |
590 | 772 | |
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) | |
593 | 775 | { |
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... */ | |
597 | 778 | |
598 | - if(iw_set_ext(skfd, ifname, SIOCSIWESSID, &wrq) < 0) | |
779 | + if(iw_set_ext(skfd, ifname, SIOCSIWNWID, &wrq) < 0) | |
599 | 780 | { |
600 | - fprintf(stderr, "SIOCSIWESSID: %s\n", strerror(errno)); | |
781 | + fprintf(stderr, "SIOCSIWNWID: %s\n", strerror(errno)); | |
601 | 782 | ret = -1; |
602 | 783 | } |
603 | 784 | } |
604 | 785 | |
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) | |
607 | 792 | { |
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; | |
610 | 796 | |
611 | - if(iw_get_ext(skfd, ifname, SIOCSIWMODE, &wrq) < 0) | |
797 | + if(iw_set_ext(skfd, ifname, SIOCSIWESSID, &wrq) < 0) | |
612 | 798 | { |
613 | - fprintf(stderr, "SIOCSIWMODE: %s\n", strerror(errno)); | |
799 | + fprintf(stderr, "SIOCSIWESSID: %s\n", strerror(errno)); | |
614 | 800 | ret = -1; |
615 | 801 | } |
616 | 802 | } |
@@ -632,14 +818,15 @@ iw_set_basic_config(int skfd, | ||
632 | 818 | * but if they interoperate at some level, and also if they accept the |
633 | 819 | * same type of config (ESSID vs NWID, freq...). |
634 | 820 | * 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 | |
636 | 822 | */ |
637 | 823 | int |
638 | -iw_protocol_compare(char * protocol1, | |
639 | - char * protocol2) | |
824 | +iw_protocol_compare(const char * protocol1, | |
825 | + const char * protocol2) | |
640 | 826 | { |
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"; | |
643 | 830 | |
644 | 831 | /* If the strings are the same -> easy */ |
645 | 832 | if(!strncmp(protocol1, protocol2, IFNAMSIZ)) |
@@ -649,18 +836,34 @@ iw_protocol_compare(char * protocol1, | ||
649 | 836 | if( (!strncmp(protocol1, dot11, strlen(dot11))) && |
650 | 837 | (!strncmp(protocol2, dot11, strlen(dot11))) ) |
651 | 838 | { |
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); | |
660 | 857 | |
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) | |
664 | 867 | return(1); |
665 | 868 | } |
666 | 869 | /* Not compatible */ |
@@ -718,7 +921,7 @@ iw_float2freq(double in, | ||
718 | 921 | * Convert our internal representation of frequencies to a floating point. |
719 | 922 | */ |
720 | 923 | double |
721 | -iw_freq2float(iwfreq * in) | |
924 | +iw_freq2float(const iwfreq * in) | |
722 | 925 | { |
723 | 926 | #ifdef WE_NOLIBM |
724 | 927 | /* Version without libm : slower */ |
@@ -738,22 +941,67 @@ iw_freq2float(iwfreq * in) | ||
738 | 941 | * Output a frequency with proper scaling |
739 | 942 | */ |
740 | 943 | void |
741 | -iw_print_freq(char * buffer, | |
742 | - double freq) | |
944 | +iw_print_freq_value(char * buffer, | |
945 | + int buflen, | |
946 | + double freq) | |
743 | 947 | { |
744 | 948 | if(freq < KILO) |
745 | - sprintf(buffer, "Channel:%g", freq); | |
949 | + snprintf(buffer, buflen, "%g", freq); | |
746 | 950 | else |
747 | 951 | { |
952 | + char scale; | |
953 | + int divisor; | |
954 | + | |
748 | 955 | if(freq >= GIGA) |
749 | - sprintf(buffer, "Frequency:%gGHz", freq / GIGA); | |
956 | + { | |
957 | + scale = 'G'; | |
958 | + divisor = GIGA; | |
959 | + } | |
750 | 960 | else |
751 | 961 | { |
752 | 962 | if(freq >= MEGA) |
753 | - sprintf(buffer, "Frequency:%gMHz", freq / MEGA); | |
963 | + { | |
964 | + scale = 'M'; | |
965 | + divisor = MEGA; | |
966 | + } | |
754 | 967 | else |
755 | - sprintf(buffer, "Frequency:%gkHz", freq / KILO); | |
968 | + { | |
969 | + scale = 'k'; | |
970 | + divisor = KILO; | |
971 | + } | |
756 | 972 | } |
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); | |
757 | 1005 | } |
758 | 1006 | } |
759 | 1007 |
@@ -762,8 +1010,8 @@ iw_print_freq(char * buffer, | ||
762 | 1010 | * Convert a frequency to a channel (negative -> error) |
763 | 1011 | */ |
764 | 1012 | 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) | |
767 | 1015 | { |
768 | 1016 | double ref_freq; |
769 | 1017 | int k; |
@@ -784,6 +1032,41 @@ iw_freq_to_channel(double freq, | ||
784 | 1032 | return(-2); |
785 | 1033 | } |
786 | 1034 | |
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 | + | |
787 | 1070 | /*********************** BITRATE SUBROUTINES ***********************/ |
788 | 1071 | |
789 | 1072 | /*------------------------------------------------------------------*/ |
@@ -792,17 +1075,32 @@ iw_freq_to_channel(double freq, | ||
792 | 1075 | */ |
793 | 1076 | void |
794 | 1077 | iw_print_bitrate(char * buffer, |
1078 | + int buflen, | |
795 | 1079 | int bitrate) |
796 | 1080 | { |
797 | 1081 | double rate = bitrate; |
1082 | + char scale; | |
1083 | + int divisor; | |
798 | 1084 | |
799 | 1085 | if(rate >= GIGA) |
800 | - sprintf(buffer, "%gGb/s", rate / GIGA); | |
1086 | + { | |
1087 | + scale = 'G'; | |
1088 | + divisor = GIGA; | |
1089 | + } | |
801 | 1090 | 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); | |
806 | 1104 | } |
807 | 1105 | |
808 | 1106 | /************************ POWER SUBROUTINES *************************/ |
@@ -863,6 +1161,43 @@ iw_mwatt2dbm(int in) | ||
863 | 1161 | #endif /* WE_NOLIBM */ |
864 | 1162 | } |
865 | 1163 | |
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 | + | |
866 | 1201 | /********************** STATISTICS SUBROUTINES **********************/ |
867 | 1202 | |
868 | 1203 | /*------------------------------------------------------------------*/ |
@@ -870,76 +1205,84 @@ iw_mwatt2dbm(int in) | ||
870 | 1205 | * Read /proc/net/wireless to get the latest statistics |
871 | 1206 | */ |
872 | 1207 | 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) | |
876 | 1213 | { |
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); | |
885 | 1224 | |
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 | + } | |
943 | 1286 | } |
944 | 1287 | |
945 | 1288 | /*------------------------------------------------------------------*/ |
@@ -948,40 +1291,99 @@ iw_get_stats(int skfd, | ||
948 | 1291 | */ |
949 | 1292 | void |
950 | 1293 | iw_print_stats(char * buffer, |
951 | - iwqual * qual, | |
952 | - iwrange * range, | |
1294 | + int buflen, | |
1295 | + const iwqual * qual, | |
1296 | + const iwrange * range, | |
953 | 1297 | int has_range) |
954 | 1298 | { |
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 | + | |
955 | 1326 | /* Just do it */ |
956 | 1327 | if(has_range && (qual->level != 0)) |
957 | 1328 | { |
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 */ | |
959 | 1340 | if(qual->level > range->max_qual.level) |
960 | 1341 | { |
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 | + } | |
967 | 1359 | } |
968 | 1360 | else |
969 | 1361 | { |
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 | + } | |
977 | 1379 | } |
978 | 1380 | } |
979 | 1381 | else |
980 | 1382 | { |
981 | 1383 | /* 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); | |
985 | 1387 | } |
986 | 1388 | } |
987 | 1389 |
@@ -992,28 +1394,36 @@ iw_print_stats(char * buffer, | ||
992 | 1394 | * Output the encoding key, with a nice formating |
993 | 1395 | */ |
994 | 1396 | 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) | |
999 | 1402 | { |
1000 | 1403 | int i; |
1001 | 1404 | |
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 | + | |
1002 | 1412 | /* Is the key present ??? */ |
1003 | 1413 | if(key_flags & IW_ENCODE_NOKEY) |
1004 | 1414 | { |
1005 | 1415 | /* Nope : print on or dummy */ |
1006 | 1416 | if(key_size <= 0) |
1007 | - strcpy(buffer, "on"); | |
1417 | + strcpy(buffer, "on"); /* Size checked */ | |
1008 | 1418 | else |
1009 | 1419 | { |
1010 | - strcpy(buffer, "**"); | |
1420 | + strcpy(buffer, "**"); /* Size checked */ | |
1011 | 1421 | buffer +=2; |
1012 | 1422 | for(i = 1; i < key_size; i++) |
1013 | 1423 | { |
1014 | 1424 | if((i & 0x1) == 0) |
1015 | - strcpy(buffer++, "-"); | |
1016 | - strcpy(buffer, "**"); | |
1425 | + strcpy(buffer++, "-"); /* Size checked */ | |
1426 | + strcpy(buffer, "**"); /* Size checked */ | |
1017 | 1427 | buffer +=2; |
1018 | 1428 | } |
1019 | 1429 | } |
@@ -1021,13 +1431,13 @@ iw_print_key(char * buffer, | ||
1021 | 1431 | else |
1022 | 1432 | { |
1023 | 1433 | /* Yes : print the key */ |
1024 | - sprintf(buffer, "%.2X", key[0]); | |
1434 | + sprintf(buffer, "%.2X", key[0]); /* Size checked */ | |
1025 | 1435 | buffer +=2; |
1026 | 1436 | for(i = 1; i < key_size; i++) |
1027 | 1437 | { |
1028 | 1438 | 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 */ | |
1031 | 1441 | buffer +=2; |
1032 | 1442 | } |
1033 | 1443 | } |
@@ -1039,8 +1449,8 @@ iw_print_key(char * buffer, | ||
1039 | 1449 | * ### NOT IMPLEMENTED ### |
1040 | 1450 | * Return size of the key, or 0 (no key) or -1 (error) |
1041 | 1451 | */ |
1042 | -int | |
1043 | -iw_pass_key(char * input, | |
1452 | +static int | |
1453 | +iw_pass_key(const char * input, | |
1044 | 1454 | unsigned char * key) |
1045 | 1455 | { |
1046 | 1456 | input = input; key = key; |
@@ -1054,7 +1464,7 @@ iw_pass_key(char * input, | ||
1054 | 1464 | * Return size of the key, or 0 (no key) or -1 (error) |
1055 | 1465 | */ |
1056 | 1466 | int |
1057 | -iw_in_key(char * input, | |
1467 | +iw_in_key(const char * input, | |
1058 | 1468 | unsigned char * key) |
1059 | 1469 | { |
1060 | 1470 | int keylen = 0; |
@@ -1090,7 +1500,7 @@ iw_in_key(char * input, | ||
1090 | 1500 | } |
1091 | 1501 | /* Preserve original buffers (both in & out) */ |
1092 | 1502 | hex = buff + IW_ENCODING_TOKEN_MAX; |
1093 | - strcpy(hex, input); | |
1503 | + strcpy(hex, input); /* Size checked */ | |
1094 | 1504 | out = buff; |
1095 | 1505 | |
1096 | 1506 | /* Parse */ |
@@ -1136,8 +1546,8 @@ iw_in_key(char * input, | ||
1136 | 1546 | */ |
1137 | 1547 | int |
1138 | 1548 | iw_in_key_full(int skfd, |
1139 | - char * ifname, | |
1140 | - char * input, | |
1549 | + const char * ifname, | |
1550 | + const char * input, | |
1141 | 1551 | unsigned char * key, |
1142 | 1552 | __u16 * flags) |
1143 | 1553 | { |
@@ -1146,9 +1556,7 @@ iw_in_key_full(int skfd, | ||
1146 | 1556 | |
1147 | 1557 | if(!strncmp(input, "l:", 2)) |
1148 | 1558 | { |
1149 | -#if WIRELESS_EXT > 15 | |
1150 | 1559 | struct iw_range range; |
1151 | -#endif | |
1152 | 1560 | |
1153 | 1561 | /* Extra case : as a login (user:passwd - Cisco LEAP) */ |
1154 | 1562 | keylen = strlen(input + 2) + 1; /* skip "l:", add '\0' */ |
@@ -1166,22 +1574,27 @@ iw_in_key_full(int skfd, | ||
1166 | 1574 | } |
1167 | 1575 | *p = '\0'; |
1168 | 1576 | |
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) | |
1172 | 1583 | { |
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 | + } | |
1176 | 1596 | 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; | |
1179 | 1597 | } |
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 | |
1185 | 1598 | } |
1186 | 1599 | else |
1187 | 1600 | /* Simpler routine above */ |
@@ -1198,46 +1611,55 @@ iw_in_key_full(int skfd, | ||
1198 | 1611 | */ |
1199 | 1612 | void |
1200 | 1613 | iw_print_pm_value(char * buffer, |
1614 | + int buflen, | |
1201 | 1615 | int value, |
1202 | 1616 | int flags) |
1203 | 1617 | { |
1618 | + /* Check size */ | |
1619 | + if(buflen < 25) | |
1620 | + { | |
1621 | + snprintf(buffer, buflen, "<too big>"); | |
1622 | + return; | |
1623 | + } | |
1624 | + buflen -= 25; | |
1625 | + | |
1204 | 1626 | /* Modifiers */ |
1205 | 1627 | if(flags & IW_POWER_MIN) |
1206 | 1628 | { |
1207 | - strcpy(buffer, " min"); | |
1629 | + strcpy(buffer, " min"); /* Size checked */ | |
1208 | 1630 | buffer += 4; |
1209 | 1631 | } |
1210 | 1632 | if(flags & IW_POWER_MAX) |
1211 | 1633 | { |
1212 | - strcpy(buffer, " max"); | |
1634 | + strcpy(buffer, " max"); /* Size checked */ | |
1213 | 1635 | buffer += 4; |
1214 | 1636 | } |
1215 | 1637 | |
1216 | 1638 | /* Type */ |
1217 | 1639 | if(flags & IW_POWER_TIMEOUT) |
1218 | 1640 | { |
1219 | - strcpy(buffer, " timeout:"); | |
1641 | + strcpy(buffer, " timeout:"); /* Size checked */ | |
1220 | 1642 | buffer += 9; |
1221 | 1643 | } |
1222 | 1644 | else |
1223 | 1645 | { |
1224 | - strcpy(buffer, " period:"); | |
1646 | + strcpy(buffer, " period:"); /* Size checked */ | |
1225 | 1647 | buffer += 8; |
1226 | 1648 | } |
1227 | 1649 | |
1228 | 1650 | /* Display value without units */ |
1229 | 1651 | if(flags & IW_POWER_RELATIVE) |
1230 | - sprintf(buffer, "%g", ((double) value) / MEGA); | |
1652 | + snprintf(buffer, buflen, "%g", ((double) value) / MEGA); | |
1231 | 1653 | else |
1232 | 1654 | { |
1233 | 1655 | /* Display value with units */ |
1234 | 1656 | if(value >= (int) MEGA) |
1235 | - sprintf(buffer, "%gs", ((double) value) / MEGA); | |
1657 | + snprintf(buffer, buflen, "%gs", ((double) value) / MEGA); | |
1236 | 1658 | else |
1237 | 1659 | if(value >= (int) KILO) |
1238 | - sprintf(buffer, "%gms", ((double) value) / KILO); | |
1660 | + snprintf(buffer, buflen, "%gms", ((double) value) / KILO); | |
1239 | 1661 | else |
1240 | - sprintf(buffer, "%dus", value); | |
1662 | + snprintf(buffer, buflen, "%dus", value); | |
1241 | 1663 | } |
1242 | 1664 | } |
1243 | 1665 |
@@ -1247,81 +1669,96 @@ iw_print_pm_value(char * buffer, | ||
1247 | 1669 | */ |
1248 | 1670 | void |
1249 | 1671 | iw_print_pm_mode(char * buffer, |
1672 | + int buflen, | |
1250 | 1673 | int flags) |
1251 | 1674 | { |
1675 | + /* Check size */ | |
1676 | + if(buflen < 28) | |
1677 | + { | |
1678 | + snprintf(buffer, buflen, "<too big>"); | |
1679 | + return; | |
1680 | + } | |
1681 | + | |
1252 | 1682 | /* Print the proper mode... */ |
1253 | 1683 | switch(flags & IW_POWER_MODE) |
1254 | 1684 | { |
1255 | 1685 | case IW_POWER_UNICAST_R: |
1256 | - strcpy(buffer, "mode:Unicast only received"); | |
1686 | + strcpy(buffer, "mode:Unicast only received"); /* Size checked */ | |
1257 | 1687 | break; |
1258 | 1688 | case IW_POWER_MULTICAST_R: |
1259 | - strcpy(buffer, "mode:Multicast only received"); | |
1689 | + strcpy(buffer, "mode:Multicast only received"); /* Size checked */ | |
1260 | 1690 | break; |
1261 | 1691 | case IW_POWER_ALL_R: |
1262 | - strcpy(buffer, "mode:All packets received"); | |
1692 | + strcpy(buffer, "mode:All packets received"); /* Size checked */ | |
1263 | 1693 | break; |
1264 | 1694 | case IW_POWER_FORCE_S: |
1265 | - strcpy(buffer, "mode:Force sending"); | |
1695 | + strcpy(buffer, "mode:Force sending"); /* Size checked */ | |
1266 | 1696 | break; |
1267 | 1697 | case IW_POWER_REPEATER: |
1268 | - strcpy(buffer, "mode:Repeat multicasts"); | |
1698 | + strcpy(buffer, "mode:Repeat multicasts"); /* Size checked */ | |
1269 | 1699 | break; |
1270 | 1700 | default: |
1271 | - strcpy(buffer, ""); | |
1701 | + strcpy(buffer, ""); /* Size checked */ | |
1272 | 1702 | break; |
1273 | 1703 | } |
1274 | 1704 | } |
1275 | 1705 | |
1276 | 1706 | /***************** RETRY LIMIT/LIFETIME SUBROUTINES *****************/ |
1277 | 1707 | |
1278 | -#if WIRELESS_EXT > 10 | |
1279 | 1708 | /*------------------------------------------------------------------*/ |
1280 | 1709 | /* |
1281 | 1710 | * Output a retry value with all attributes... |
1282 | 1711 | */ |
1283 | 1712 | void |
1284 | 1713 | iw_print_retry_value(char * buffer, |
1714 | + int buflen, | |
1285 | 1715 | int value, |
1286 | 1716 | int flags) |
1287 | 1717 | { |
1718 | + /* Check buffer size */ | |
1719 | + if(buflen < 18) | |
1720 | + { | |
1721 | + snprintf(buffer, buflen, "<too big>"); | |
1722 | + return; | |
1723 | + } | |
1724 | + buflen -= 18; | |
1725 | + | |
1288 | 1726 | /* Modifiers */ |
1289 | 1727 | if(flags & IW_RETRY_MIN) |
1290 | 1728 | { |
1291 | - strcpy(buffer, " min"); | |
1729 | + strcpy(buffer, " min"); /* Size checked */ | |
1292 | 1730 | buffer += 4; |
1293 | 1731 | } |
1294 | 1732 | if(flags & IW_RETRY_MAX) |
1295 | 1733 | { |
1296 | - strcpy(buffer, " max"); | |
1734 | + strcpy(buffer, " max"); /* Size checked */ | |
1297 | 1735 | buffer += 4; |
1298 | 1736 | } |
1299 | 1737 | |
1300 | 1738 | /* Type lifetime of limit */ |
1301 | 1739 | if(flags & IW_RETRY_LIFETIME) |
1302 | 1740 | { |
1303 | - strcpy(buffer, " lifetime:"); | |
1741 | + strcpy(buffer, " lifetime:"); /* Size checked */ | |
1304 | 1742 | buffer += 10; |
1305 | 1743 | |
1306 | 1744 | /* Display value without units */ |
1307 | 1745 | if(flags & IW_POWER_RELATIVE) |
1308 | - sprintf(buffer, "%g", ((double) value) / MEGA); | |
1746 | + snprintf(buffer, buflen, "%g", ((double) value) / MEGA); | |
1309 | 1747 | else |
1310 | 1748 | { |
1311 | 1749 | /* Display value with units */ |
1312 | 1750 | if(value >= (int) MEGA) |
1313 | - sprintf(buffer, "%gs", ((double) value) / MEGA); | |
1751 | + snprintf(buffer, buflen, "%gs", ((double) value) / MEGA); | |
1314 | 1752 | else |
1315 | 1753 | if(value >= (int) KILO) |
1316 | - sprintf(buffer, "%gms", ((double) value) / KILO); | |
1754 | + snprintf(buffer, buflen, "%gms", ((double) value) / KILO); | |
1317 | 1755 | else |
1318 | - sprintf(buffer, "%dus", value); | |
1756 | + snprintf(buffer, buflen, "%dus", value); | |
1319 | 1757 | } |
1320 | 1758 | } |
1321 | 1759 | else |
1322 | - sprintf(buffer, " limit:%d", value); | |
1760 | + snprintf(buffer, buflen, " limit:%d", value); | |
1323 | 1761 | } |
1324 | -#endif /* WIRELESS_EXT > 10 */ | |
1325 | 1762 | |
1326 | 1763 | /************************* TIME SUBROUTINES *************************/ |
1327 | 1764 |
@@ -1332,12 +1769,13 @@ iw_print_retry_value(char * buffer, | ||
1332 | 1769 | */ |
1333 | 1770 | void |
1334 | 1771 | iw_print_timeval(char * buffer, |
1772 | + int buflen, | |
1335 | 1773 | const struct timeval * time) |
1336 | 1774 | { |
1337 | 1775 | int s; |
1338 | 1776 | |
1339 | 1777 | s = (time->tv_sec) % 86400; |
1340 | - sprintf(buffer, "%02d:%02d:%02d.%06u ", | |
1778 | + snprintf(buffer, buflen, "%02d:%02d:%02d.%06u ", | |
1341 | 1779 | s / 3600, (s % 3600) / 60, |
1342 | 1780 | s % 60, (u_int32_t) time->tv_usec); |
1343 | 1781 | } |
@@ -1345,6 +1783,7 @@ iw_print_timeval(char * buffer, | ||
1345 | 1783 | /*********************** ADDRESS SUBROUTINES ************************/ |
1346 | 1784 | /* |
1347 | 1785 | * This section is mostly a cut & past from net-tools-1.2.0 |
1786 | + * (Well... This has evolved over the years) | |
1348 | 1787 | * manage address display and input... |
1349 | 1788 | */ |
1350 | 1789 |
@@ -1429,6 +1868,31 @@ iw_check_addr_type(int skfd, | ||
1429 | 1868 | |
1430 | 1869 | /*------------------------------------------------------------------*/ |
1431 | 1870 | /* |
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 | +/* | |
1432 | 1896 | * Display an Ethernet address in readable format. |
1433 | 1897 | */ |
1434 | 1898 | void |
@@ -1516,21 +1980,21 @@ iw_in_inet(char *name, struct sockaddr *sap) | ||
1516 | 1980 | { |
1517 | 1981 | struct hostent *hp; |
1518 | 1982 | struct netent *np; |
1519 | - struct sockaddr_in *sin = (struct sockaddr_in *) sap; | |
1983 | + struct sockaddr_in *sain = (struct sockaddr_in *) sap; | |
1520 | 1984 | |
1521 | 1985 | /* Grmpf. -FvK */ |
1522 | - sin->sin_family = AF_INET; | |
1523 | - sin->sin_port = 0; | |
1986 | + sain->sin_family = AF_INET; | |
1987 | + sain->sin_port = 0; | |
1524 | 1988 | |
1525 | 1989 | /* Default is special, meaning 0.0.0.0. */ |
1526 | 1990 | if (!strcmp(name, "default")) { |
1527 | - sin->sin_addr.s_addr = INADDR_ANY; | |
1991 | + sain->sin_addr.s_addr = INADDR_ANY; | |
1528 | 1992 | return(1); |
1529 | 1993 | } |
1530 | 1994 | |
1531 | 1995 | /* Try the NETWORKS database to see if this is a known network. */ |
1532 | 1996 | 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); | |
1534 | 1998 | strcpy(name, np->n_name); |
1535 | 1999 | return(1); |
1536 | 2000 | } |
@@ -1540,7 +2004,7 @@ iw_in_inet(char *name, struct sockaddr *sap) | ||
1540 | 2004 | errno = h_errno; |
1541 | 2005 | return(-1); |
1542 | 2006 | } |
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); | |
1544 | 2008 | strcpy(name, hp->h_name); |
1545 | 2009 | return(0); |
1546 | 2010 | } |
@@ -1564,7 +2028,7 @@ iw_in_addr(int skfd, | ||
1564 | 2028 | /* Check if we have valid interface address type */ |
1565 | 2029 | if(iw_check_if_addr_type(skfd, ifname) < 0) |
1566 | 2030 | { |
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); | |
1568 | 2032 | return(-1); |
1569 | 2033 | } |
1570 | 2034 |
@@ -1607,7 +2071,7 @@ iw_in_addr(int skfd, | ||
1607 | 2071 | /* Check if we have valid mac address type */ |
1608 | 2072 | if(iw_check_mac_addr_type(skfd, ifname) < 0) |
1609 | 2073 | { |
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); | |
1611 | 2075 | return(-1); |
1612 | 2076 | } |
1613 | 2077 |
@@ -1660,7 +2124,6 @@ iw_get_priv_size(int args) | ||
1660 | 2124 | * Those functions help the decoding of events, so are needed only in |
1661 | 2125 | * this case. |
1662 | 2126 | */ |
1663 | -#if WIRELESS_EXT > 13 | |
1664 | 2127 | |
1665 | 2128 | /* Type of headers we know about (basically union iwreq_data) */ |
1666 | 2129 | #define IW_HEADER_TYPE_NULL 0 /* Not available */ |
@@ -1751,6 +2214,10 @@ static const int event_type_size[] = { | ||
1751 | 2214 | IW_EV_QUAL_LEN, /* IW_HEADER_TYPE_QUAL */ |
1752 | 2215 | }; |
1753 | 2216 | |
2217 | +/* Forward compatibility with WE-19 */ | |
2218 | +#define IW_EV_POINT_OFF (((char *) &(((struct iw_point *) NULL)->length)) - \ | |
2219 | + (char *) NULL) | |
2220 | + | |
1754 | 2221 | /*------------------------------------------------------------------*/ |
1755 | 2222 | /* |
1756 | 2223 | * 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 */ | ||
1775 | 2242 | */ |
1776 | 2243 | int |
1777 | 2244 | 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) | |
1779 | 2247 | { |
1780 | 2248 | int event_type = 0; |
1781 | 2249 | unsigned int event_len = 1; /* Invalid */ |
@@ -1783,6 +2251,9 @@ iw_extract_event_stream(struct stream_descr * stream, /* Stream of events */ | ||
1783 | 2251 | /* Don't "optimise" the following variable, it will crash */ |
1784 | 2252 | unsigned cmd_index; /* *MUST* be unsigned */ |
1785 | 2253 | |
2254 | + /* Unused for now. Will be later on... */ | |
2255 | + we_version = we_version; | |
2256 | + | |
1786 | 2257 | /* Check for end of stream */ |
1787 | 2258 | if((stream->current + IW_EV_LCP_LEN) > stream->end) |
1788 | 2259 | return(0); |
@@ -1820,6 +2291,9 @@ iw_extract_event_stream(struct stream_descr * stream, /* Stream of events */ | ||
1820 | 2291 | } |
1821 | 2292 | /* Unknown events -> event_type=0 => IW_EV_LCP_LEN */ |
1822 | 2293 | 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; | |
1823 | 2297 | |
1824 | 2298 | /* Check if we know about this event */ |
1825 | 2299 | if(event_len <= IW_EV_LCP_LEN) |
@@ -1848,7 +2322,12 @@ iw_extract_event_stream(struct stream_descr * stream, /* Stream of events */ | ||
1848 | 2322 | stream->current += iwe->len; |
1849 | 2323 | return(-2); |
1850 | 2324 | } |
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); | |
1852 | 2331 | |
1853 | 2332 | /* Skip event in the stream */ |
1854 | 2333 | pointer += event_len; |
@@ -1883,4 +2362,301 @@ iw_extract_event_stream(struct stream_descr * stream, /* Stream of events */ | ||
1883 | 2362 | return(1); |
1884 | 2363 | } |
1885 | 2364 | |
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 | +} |
@@ -1,12 +1,12 @@ | ||
1 | 1 | /* |
2 | 2 | * Wireless Tools |
3 | 3 | * |
4 | - * Jean II - HPLB 97->99 - HPL 99->02 | |
4 | + * Jean II - HPLB 97->99 - HPL 99->04 | |
5 | 5 | * |
6 | 6 | * Common header for the Wireless Extension library... |
7 | 7 | * |
8 | 8 | * 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> | |
10 | 10 | */ |
11 | 11 | |
12 | 12 | #ifndef IWLIB_H |
@@ -127,13 +127,23 @@ | ||
127 | 127 | #include <linux/socket.h> /* for "struct sockaddr" et al */ |
128 | 128 | #include <linux/if.h> /* for IFNAMSIZ and co... */ |
129 | 129 | |
130 | -#ifdef WEXT_HEADER | |
131 | 130 | /* 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__ */ | |
137 | 147 | |
138 | 148 | #ifdef __cplusplus |
139 | 149 | extern "C" { |
@@ -144,6 +154,12 @@ extern "C" { | ||
144 | 154 | |
145 | 155 | /************************ CONSTANTS & MACROS ************************/ |
146 | 156 | |
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 | + | |
147 | 163 | /* Paths */ |
148 | 164 | #define PROC_NET_WIRELESS "/proc/net/wireless" |
149 | 165 | #define PROC_NET_DEV "/proc/net/dev" |
@@ -176,6 +192,11 @@ extern "C" { | ||
176 | 192 | #define SIOCSIWCOMMIT SIOCSIWNAME |
177 | 193 | #endif /* SIOCSIWCOMMIT */ |
178 | 194 | |
195 | +/* Still more backward compatibility */ | |
196 | +#ifndef IW_FREQ_FIXED | |
197 | +#define IW_FREQ_FIXED 0x01 | |
198 | +#endif /* IW_FREQ_FIXED */ | |
199 | + | |
179 | 200 | /****************************** TYPES ******************************/ |
180 | 201 | |
181 | 202 | /* Shortcuts */ |
@@ -188,16 +209,17 @@ typedef struct iw_priv_args iwprivargs; | ||
188 | 209 | typedef struct sockaddr sockaddr; |
189 | 210 | |
190 | 211 | /* 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 | |
193 | 216 | { |
194 | 217 | char name[IFNAMSIZ + 1]; /* Wireless/protocol name */ |
195 | 218 | int has_nwid; |
196 | 219 | iwparam nwid; /* Network ID */ |
197 | 220 | int has_freq; |
198 | 221 | double freq; /* Frequency/channel */ |
199 | - int has_sens; | |
200 | - iwparam sens; /* sensitivity */ | |
222 | + int freq_flags; | |
201 | 223 | int has_key; |
202 | 224 | unsigned char key[IW_ENCODING_TOKEN_MAX]; /* Encoding key used */ |
203 | 225 | int key_size; /* Number of bytes */ |
@@ -205,6 +227,18 @@ typedef struct wireless_info | ||
205 | 227 | int has_essid; |
206 | 228 | int essid_on; |
207 | 229 | 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 */ | |
208 | 242 | int has_nickname; |
209 | 243 | char nickname[IW_ESSID_MAX_SIZE + 1]; /* NickName */ |
210 | 244 | int has_ap_addr; |
@@ -215,8 +249,6 @@ typedef struct wireless_info | ||
215 | 249 | iwparam rts; /* RTS threshold in bytes */ |
216 | 250 | int has_frag; |
217 | 251 | iwparam frag; /* Fragmentation threshold in bytes */ |
218 | - int has_mode; | |
219 | - int mode; /* Operation mode */ | |
220 | 252 | int has_power; |
221 | 253 | iwparam power; /* Power management parameters */ |
222 | 254 | int has_txpower; |
@@ -231,28 +263,36 @@ typedef struct wireless_info | ||
231 | 263 | int has_range; |
232 | 264 | } wireless_info; |
233 | 265 | |
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 | |
239 | 271 | { |
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; | |
255 | 293 | |
294 | +/* Structure used for parsing event streams, such as Wireless Events | |
295 | + * and scan results */ | |
256 | 296 | typedef struct stream_descr |
257 | 297 | { |
258 | 298 | char * end; /* End of the stream */ |
@@ -282,91 +322,114 @@ void | ||
282 | 322 | int count); |
283 | 323 | /* --------------------- WIRELESS SUBROUTINES ----------------------*/ |
284 | 324 | int |
325 | + iw_get_kernel_we_version(void); | |
326 | +int | |
327 | + iw_print_version_info(const char * toolname); | |
328 | +int | |
285 | 329 | iw_get_range_info(int skfd, |
286 | - char * ifname, | |
330 | + const char * ifname, | |
287 | 331 | iwrange * range); |
288 | 332 | int |
289 | - iw_print_version_info(char * toolname); | |
290 | -int | |
291 | 333 | iw_get_priv_info(int skfd, |
292 | - char * ifname, | |
293 | - iwprivargs * priv, | |
294 | - int maxpriv); | |
334 | + const char * ifname, | |
335 | + iwprivargs ** ppriv); | |
295 | 336 | int |
296 | 337 | iw_get_basic_config(int skfd, |
297 | - char * ifname, | |
338 | + const char * ifname, | |
298 | 339 | wireless_config * info); |
299 | 340 | int |
300 | 341 | iw_set_basic_config(int skfd, |
301 | - char * ifname, | |
342 | + const char * ifname, | |
302 | 343 | wireless_config * info); |
303 | 344 | /* --------------------- PROTOCOL SUBROUTINES --------------------- */ |
304 | 345 | int |
305 | - iw_protocol_compare(char * protocol1, | |
306 | - char * protocol2); | |
346 | + iw_protocol_compare(const char * protocol1, | |
347 | + const char * protocol2); | |
307 | 348 | /* -------------------- FREQUENCY SUBROUTINES --------------------- */ |
308 | 349 | void |
309 | 350 | iw_float2freq(double in, |
310 | - iwfreq * out); | |
351 | + iwfreq * out); | |
311 | 352 | 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); | |
313 | 358 | void |
314 | 359 | 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); | |
316 | 367 | 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); | |
319 | 371 | void |
320 | 372 | iw_print_bitrate(char * buffer, |
373 | + int buflen, | |
321 | 374 | int bitrate); |
322 | 375 | /* ---------------------- POWER SUBROUTINES ----------------------- */ |
323 | 376 | int |
324 | 377 | iw_dbm2mwatt(int in); |
325 | 378 | int |
326 | 379 | iw_mwatt2dbm(int in); |
380 | +void | |
381 | + iw_print_txpower(char * buffer, | |
382 | + int buflen, | |
383 | + struct iw_param * txpower); | |
327 | 384 | /* -------------------- STATISTICS SUBROUTINES -------------------- */ |
328 | 385 | 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); | |
332 | 391 | void |
333 | 392 | iw_print_stats(char * buffer, |
334 | - iwqual * qual, | |
335 | - iwrange * range, | |
393 | + int buflen, | |
394 | + const iwqual * qual, | |
395 | + const iwrange * range, | |
336 | 396 | int has_range); |
337 | 397 | /* --------------------- ENCODING SUBROUTINES --------------------- */ |
338 | 398 | 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); | |
343 | 404 | int |
344 | - iw_in_key(char * input, | |
405 | + iw_in_key(const char * input, | |
345 | 406 | unsigned char * key); |
346 | 407 | int |
347 | 408 | iw_in_key_full(int skfd, |
348 | - char * ifname, | |
349 | - char * input, | |
409 | + const char * ifname, | |
410 | + const char * input, | |
350 | 411 | unsigned char * key, |
351 | 412 | __u16 * flags); |
352 | 413 | /* ----------------- POWER MANAGEMENT SUBROUTINES ----------------- */ |
353 | 414 | void |
354 | 415 | iw_print_pm_value(char * buffer, |
416 | + int buflen, | |
355 | 417 | int value, |
356 | 418 | int flags); |
357 | 419 | void |
358 | 420 | iw_print_pm_mode(char * buffer, |
421 | + int buflen, | |
359 | 422 | int flags); |
360 | 423 | /* --------------- RETRY LIMIT/LIFETIME SUBROUTINES --------------- */ |
361 | -#if WIRELESS_EXT > 10 | |
362 | 424 | void |
363 | 425 | iw_print_retry_value(char * buffer, |
426 | + int buflen, | |
364 | 427 | int value, |
365 | 428 | int flags); |
366 | -#endif | |
367 | 429 | /* ----------------------- TIME SUBROUTINES ----------------------- */ |
368 | 430 | void |
369 | 431 | iw_print_timeval(char * buffer, |
432 | + int buflen, | |
370 | 433 | const struct timeval * time); |
371 | 434 | /* --------------------- ADDRESS SUBROUTINES ---------------------- */ |
372 | 435 | int |
@@ -380,6 +443,11 @@ int | ||
380 | 443 | iw_check_addr_type(int skfd, |
381 | 444 | char * ifname); |
382 | 445 | #endif |
446 | +int | |
447 | + iw_get_mac_addr(int skfd, | |
448 | + const char * name, | |
449 | + struct ether_addr * eth, | |
450 | + unsigned short * ptype); | |
383 | 451 | void |
384 | 452 | iw_ether_ntop(const struct ether_addr* eth, char* buf); |
385 | 453 | char* |
@@ -397,7 +465,6 @@ int | ||
397 | 465 | int |
398 | 466 | iw_get_priv_size(int args); |
399 | 467 | |
400 | -#if WIRELESS_EXT > 13 | |
401 | 468 | /* ---------------------- EVENT SUBROUTINES ---------------------- */ |
402 | 469 | void |
403 | 470 | iw_init_event_stream(struct stream_descr * stream, |
@@ -405,11 +472,23 @@ void | ||
405 | 472 | int len); |
406 | 473 | int |
407 | 474 | 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); | |
410 | 488 | |
411 | 489 | /**************************** VARIABLES ****************************/ |
412 | 490 | |
491 | +/* Modes as human readable strings */ | |
413 | 492 | extern const char * const iw_operation_mode[]; |
414 | 493 | #define IW_NUM_OPER_MODE 7 |
415 | 494 |
@@ -429,7 +508,7 @@ extern const char * const iw_operation_mode[]; | ||
429 | 508 | */ |
430 | 509 | static inline int |
431 | 510 | iw_set_ext(int skfd, /* Socket to the kernel */ |
432 | - char * ifname, /* Device name */ | |
511 | + const char * ifname, /* Device name */ | |
433 | 512 | int request, /* WE ID */ |
434 | 513 | struct iwreq * pwrq) /* Fixed part of the request */ |
435 | 514 | { |
@@ -445,7 +524,7 @@ iw_set_ext(int skfd, /* Socket to the kernel */ | ||
445 | 524 | */ |
446 | 525 | static inline int |
447 | 526 | iw_get_ext(int skfd, /* Socket to the kernel */ |
448 | - char * ifname, /* Device name */ | |
527 | + const char * ifname, /* Device name */ | |
449 | 528 | int request, /* WE ID */ |
450 | 529 | struct iwreq * pwrq) /* Fixed part of the request */ |
451 | 530 | { |
@@ -456,6 +535,16 @@ iw_get_ext(int skfd, /* Socket to the kernel */ | ||
456 | 535 | } |
457 | 536 | |
458 | 537 | /*------------------------------------------------------------------*/ |
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 | +/*------------------------------------------------------------------*/ | |
459 | 548 | /* Backwards compatability |
460 | 549 | * Actually, those form are much easier to use when dealing with |
461 | 550 | * struct sockaddr... */ |
@@ -1,21 +1,19 @@ | ||
1 | 1 | .\" Jean II - HPLB - 96 |
2 | 2 | .\" iwlist.8 |
3 | 3 | .\" |
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" | |
5 | 5 | .\" |
6 | 6 | .\" NAME part |
7 | 7 | .\" |
8 | 8 | .SH NAME |
9 | -iwlist \- Get wireless statistics from specific nodes | |
9 | +iwlist \- Get more detailed wireless information from a wireless interface | |
10 | 10 | .\" |
11 | 11 | .\" SYNOPSIS part |
12 | 12 | .\" |
13 | 13 | .SH SYNOPSIS |
14 | -.BI "iwlist " interface " freq" | |
14 | +.BI "iwlist " interface " scanning" | |
15 | 15 | .br |
16 | -.BI "iwlist " interface " ap" | |
17 | -.br | |
18 | -.BI "iwlist " interface " scan" | |
16 | +.BI "iwlist " interface " frequency" | |
19 | 17 | .br |
20 | 18 | .BI "iwlist " interface " rate" |
21 | 19 | .br |
@@ -27,6 +25,8 @@ iwlist \- Get wireless statistics from specific nodes | ||
27 | 25 | .br |
28 | 26 | .BI "iwlist " interface " retry" |
29 | 27 | .br |
28 | +.BI "iwlist " interface " event" | |
29 | +.br | |
30 | 30 | .BI "iwlist --help" |
31 | 31 | .br |
32 | 32 | .BI "iwlist --version" |
@@ -35,60 +35,71 @@ iwlist \- Get wireless statistics from specific nodes | ||
35 | 35 | .\" |
36 | 36 | .SH DESCRIPTION |
37 | 37 | .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). | |
41 | 47 | .\" |
42 | 48 | .\" PARAMETER part |
43 | 49 | .\" |
44 | 50 | .SH PARAMETERS |
45 | 51 | .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 | |
53 | 52 | .BR scan [ning] |
54 | 53 | Give the list of Access Points and Ad-Hoc cells in range, and |
55 | 54 | 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. | |
58 | 57 | .br |
59 | -Triggering scanning is a priviledged operation | |
58 | +Triggering scanning is a privileged operation | |
60 | 59 | .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 | |
62 | 61 | default, the way scanning is done (the scope of the scan) will be |
63 | 62 | impacted by the current setting of the driver. Also, this command is |
64 | 63 | supposed to take extra arguments to control the scanning behaviour, |
65 | 64 | but this is currently not implemented. |
66 | 65 | .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. | |
75 | 72 | .TP |
76 | 73 | .BR rate / bit [rate] |
77 | 74 | List the bit-rates supported by the device. |
78 | 75 | .TP |
79 | 76 | .BR key / enc [ryption] |
80 | 77 | List the encryption key sizes supported and display all the encryption |
81 | -keys availables in the device. | |
78 | +keys available in the device. | |
82 | 79 | .TP |
83 | 80 | .B power |
84 | 81 | List the various Power Management attributes and modes of the device. |
85 | 82 | .TP |
86 | 83 | .B txpower |
87 | -List the various Transmit Power available on the device. | |
84 | +List the various Transmit Powers available on the device. | |
88 | 85 | .TP |
89 | 86 | .B retry |
90 | 87 | List the transmit retry limits and retry lifetime on the device. |
91 | 88 | .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 | |
92 | 103 | .B --version |
93 | 104 | Display the version of the tools, as well as the recommended and |
94 | 105 | current Wireless Extensions version for the tool and the various |
@@ -1,14 +1,14 @@ | ||
1 | 1 | /* |
2 | 2 | * Wireless Tools |
3 | 3 | * |
4 | - * Jean II - HPLB '99 - HPL 99->01 | |
4 | + * Jean II - HPLB '99 - HPL 99->04 | |
5 | 5 | * |
6 | 6 | * This tool can access various piece of information on the card |
7 | 7 | * not part of iwconfig... |
8 | 8 | * You need to link this code against "iwlist.c" and "-lm". |
9 | 9 | * |
10 | 10 | * 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> | |
12 | 12 | */ |
13 | 13 | |
14 | 14 | #include "iwlib.h" /* Header */ |
@@ -38,42 +38,35 @@ print_freq_info(int skfd, | ||
38 | 38 | |
39 | 39 | /* Get list of frequencies / channels */ |
40 | 40 | 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", | |
42 | 42 | ifname); |
43 | 43 | else |
44 | 44 | { |
45 | 45 | if(range.num_frequency > 0) |
46 | 46 | { |
47 | - printf("%-8.8s %d channels in total; available frequencies :\n", | |
47 | + printf("%-8.16s %d channels in total; available frequencies :\n", | |
48 | 48 | ifname, range.num_channels); |
49 | 49 | /* Print them all */ |
50 | 50 | for(k = 0; k < range.num_frequency; k++) |
51 | 51 | { |
52 | - printf(" Channel %.2d : ", range.freq[k].i); | |
53 | 52 | 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); | |
61 | 56 | } |
62 | 57 | } |
63 | 58 | else |
64 | - printf("%-8.8s %d channels\n", | |
59 | + printf("%-8.16s %d channels\n", | |
65 | 60 | ifname, range.num_channels); |
66 | 61 | |
67 | 62 | /* Get current frequency / channel and display it */ |
68 | 63 | if(iw_get_ext(skfd, ifname, SIOCGIWFREQ, &wrq) >= 0) |
69 | 64 | { |
70 | 65 | freq = iw_freq2float(&(wrq.u.freq)); |
71 | - iw_print_freq(buffer, freq); | |
72 | 66 | 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); | |
77 | 70 | } |
78 | 71 | } |
79 | 72 | return(0); |
@@ -117,7 +110,7 @@ print_ap_info(int skfd, | ||
117 | 110 | wrq.u.data.flags = 0; |
118 | 111 | if(iw_get_ext(skfd, ifname, SIOCGIWAPLIST, &wrq) < 0) |
119 | 112 | { |
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); | |
121 | 114 | return(-1); |
122 | 115 | } |
123 | 116 |
@@ -132,7 +125,7 @@ print_ap_info(int skfd, | ||
132 | 125 | /* Check if we have valid mac address type */ |
133 | 126 | if(iw_check_mac_addr_type(skfd, ifname) < 0) |
134 | 127 | { |
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); | |
136 | 129 | return(-2); |
137 | 130 | } |
138 | 131 |
@@ -142,16 +135,16 @@ print_ap_info(int skfd, | ||
142 | 135 | |
143 | 136 | /* Display it */ |
144 | 137 | 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); | |
146 | 139 | else |
147 | - printf("%-8.8s Peers/Access-Points in range:\n", ifname); | |
140 | + printf("%-8.16s Peers/Access-Points in range:\n", ifname); | |
148 | 141 | for(i = 0; i < n; i++) |
149 | 142 | { |
150 | 143 | if(has_qual) |
151 | 144 | { |
152 | 145 | /* Print stats for this address */ |
153 | 146 | 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); | |
155 | 148 | printf("%s\n", temp); |
156 | 149 | } |
157 | 150 | else |
@@ -184,29 +177,29 @@ print_bitrate_info(int skfd, | ||
184 | 177 | |
185 | 178 | /* Extract range info */ |
186 | 179 | 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", | |
188 | 181 | ifname); |
189 | 182 | else |
190 | 183 | { |
191 | 184 | if((range.num_bitrates > 0) && (range.num_bitrates <= IW_MAX_BITRATES)) |
192 | 185 | { |
193 | - printf("%-8.8s %d available bit-rates :\n", | |
186 | + printf("%-8.16s %d available bit-rates :\n", | |
194 | 187 | ifname, range.num_bitrates); |
195 | 188 | /* Print them all */ |
196 | 189 | for(k = 0; k < range.num_bitrates; k++) |
197 | 190 | { |
198 | - iw_print_bitrate(buffer, range.bitrate[k]); | |
191 | + iw_print_bitrate(buffer, sizeof(buffer), range.bitrate[k]); | |
199 | 192 | /* Maybe this should be %10s */ |
200 | 193 | printf("\t %s\n", buffer); |
201 | 194 | } |
202 | 195 | } |
203 | 196 | else |
204 | - printf("%-8.8s No bit-rates ? Please update driver...\n", ifname); | |
197 | + printf("%-8.16s unknown bit-rate information.\n", ifname); | |
205 | 198 | |
206 | 199 | /* Get current bit rate */ |
207 | 200 | if(iw_get_ext(skfd, ifname, SIOCGIWRATE, &wrq) >= 0) |
208 | 201 | { |
209 | - iw_print_bitrate(buffer, wrq.u.bitrate.value); | |
202 | + iw_print_bitrate(buffer, sizeof(buffer), wrq.u.bitrate.value); | |
210 | 203 | printf(" Current Bit Rate%c%s\n\n", |
211 | 204 | (wrq.u.bitrate.fixed ? '=' : ':'), buffer); |
212 | 205 | } |
@@ -237,11 +230,11 @@ print_keys_info(int skfd, | ||
237 | 230 | |
238 | 231 | /* Extract range info */ |
239 | 232 | 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", | |
241 | 234 | ifname); |
242 | 235 | else |
243 | 236 | { |
244 | - printf("%-8.8s ", ifname); | |
237 | + printf("%-8.16s ", ifname); | |
245 | 238 | /* Print key sizes */ |
246 | 239 | if((range.num_encoding_sizes > 0) && |
247 | 240 | (range.num_encoding_sizes < IW_MAX_ENCODING_SIZES)) |
@@ -271,7 +264,8 @@ print_keys_info(int skfd, | ||
271 | 264 | else |
272 | 265 | { |
273 | 266 | /* 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); | |
275 | 269 | printf("\t\t[%d]: %s", k, buffer); |
276 | 270 | |
277 | 271 | /* Other info... */ |
@@ -320,7 +314,8 @@ get_pm_value(int skfd, | ||
320 | 314 | /* Let's check the value and its type */ |
321 | 315 | if(pwrq->u.power.flags & IW_POWER_TYPE) |
322 | 316 | { |
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); | |
324 | 319 | printf("\n %s", buffer); |
325 | 320 | } |
326 | 321 | } |
@@ -345,13 +340,14 @@ print_pm_info(int skfd, | ||
345 | 340 | args = args; count = count; |
346 | 341 | |
347 | 342 | /* 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", | |
350 | 346 | ifname); |
351 | 347 | else |
352 | 348 | { |
353 | - printf("%-8.8s ", ifname); | |
354 | -#if WIRELESS_EXT > 9 | |
349 | + printf("%-8.16s ", ifname); | |
350 | + | |
355 | 351 | /* Display modes availables */ |
356 | 352 | if(range.pm_capa & IW_POWER_MODE) |
357 | 353 | { |
@@ -377,11 +373,12 @@ print_pm_info(int skfd, | ||
377 | 373 | else |
378 | 374 | printf("Fixed period ; "); |
379 | 375 | /* 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); | |
381 | 378 | 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); | |
383 | 381 | printf("%s\n ", buffer); |
384 | - | |
385 | 382 | } |
386 | 383 | /* Display min/max timeout availables */ |
387 | 384 | if(range.pmt_flags & IW_POWER_TIMEOUT) |
@@ -393,13 +390,13 @@ print_pm_info(int skfd, | ||
393 | 390 | else |
394 | 391 | printf("Fixed timeout ; "); |
395 | 392 | /* 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); | |
397 | 395 | 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); | |
399 | 398 | printf("%s\n ", buffer); |
400 | - | |
401 | 399 | } |
402 | -#endif /* WIRELESS_EXT > 9 */ | |
403 | 400 | |
404 | 401 | /* Get current Power Management settings */ |
405 | 402 | wrq.u.power.flags = 0; |
@@ -415,7 +412,7 @@ print_pm_info(int skfd, | ||
415 | 412 | int pm_mask = 0; |
416 | 413 | |
417 | 414 | /* Let's check the mode */ |
418 | - iw_print_pm_mode(buffer, flags); | |
415 | + iw_print_pm_mode(buffer, sizeof(buffer), flags); | |
419 | 416 | printf("Current %s", buffer); |
420 | 417 | |
421 | 418 | /* Let's check if nothing (simply on) */ |
@@ -426,7 +423,7 @@ print_pm_info(int skfd, | ||
426 | 423 | /* Let's check the value and its type */ |
427 | 424 | if(wrq.u.power.flags & IW_POWER_TYPE) |
428 | 425 | { |
429 | - iw_print_pm_value(buffer, | |
426 | + iw_print_pm_value(buffer, sizeof(buffer), | |
430 | 427 | wrq.u.power.value, wrq.u.power.flags); |
431 | 428 | printf("%s", buffer); |
432 | 429 | } |
@@ -441,7 +438,6 @@ print_pm_info(int skfd, | ||
441 | 438 | if(pm_mask) |
442 | 439 | get_pm_value(skfd, ifname, &wrq, pm_mask, buffer); |
443 | 440 | |
444 | -#if WIRELESS_EXT > 9 | |
445 | 441 | /* And if we have both a period and a timeout, ask the other */ |
446 | 442 | pm_mask = (range.pm_capa & (~(wrq.u.power.flags) & |
447 | 443 | IW_POWER_TYPE)); |
@@ -461,7 +457,6 @@ print_pm_info(int skfd, | ||
461 | 457 | if(pm_mask) |
462 | 458 | get_pm_value(skfd, ifname, &wrq, pm_mask, buffer); |
463 | 459 | } |
464 | -#endif /* WIRELESS_EXT > 9 */ | |
465 | 460 | } |
466 | 461 | } |
467 | 462 | printf("\n"); |
@@ -490,49 +485,69 @@ print_txpower_info(int skfd, | ||
490 | 485 | /* Avoid "Unused parameter" warning */ |
491 | 486 | args = args; count = count; |
492 | 487 | |
493 | -#if WIRELESS_EXT > 9 | |
494 | 488 | /* 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", | |
497 | 492 | ifname); |
498 | 493 | else |
499 | 494 | { |
500 | 495 | 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); | |
502 | 497 | else |
503 | 498 | { |
504 | - printf("%-8.8s %d available transmit-powers :\n", | |
499 | + printf("%-8.16s %d available transmit-powers :\n", | |
505 | 500 | ifname, range.num_txpower); |
506 | 501 | /* Print them all */ |
507 | 502 | for(k = 0; k < range.num_txpower; k++) |
508 | 503 | { |
509 | - if(range.txpower_capa & IW_TXPOW_MWATT) | |
504 | + /* Check for relative values */ | |
505 | + if(range.txpower_capa & IW_TXPOW_RELATIVE) | |
510 | 506 | { |
511 | - dbm = iw_mwatt2dbm(range.txpower[k]); | |
512 | - mwatt = range.txpower[k]; | |
507 | + printf("\t %d (no units)\n", range.txpower[k]); | |
513 | 508 | } |
514 | 509 | else |
515 | 510 | { |
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); | |
518 | 522 | } |
519 | - printf("\t %d dBm \t(%d mW)\n", dbm, mwatt); | |
520 | 523 | } |
524 | + } | |
521 | 525 | |
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 | |
524 | 534 | { |
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 | + } | |
529 | 549 | else |
530 | 550 | { |
531 | - /* Fixed ? */ | |
532 | - if(wrq.u.txpower.fixed) | |
533 | - printf("="); | |
534 | - else | |
535 | - printf(":"); | |
536 | 551 | if(wrq.u.txpower.flags & IW_TXPOW_MWATT) |
537 | 552 | { |
538 | 553 | dbm = iw_mwatt2dbm(wrq.u.txpower.value); |
@@ -548,13 +563,11 @@ print_txpower_info(int skfd, | ||
548 | 563 | } |
549 | 564 | } |
550 | 565 | } |
551 | -#endif /* WIRELESS_EXT > 9 */ | |
552 | 566 | return(0); |
553 | 567 | } |
554 | 568 | |
555 | 569 | /*********************** RETRY LIMIT/LIFETIME ***********************/ |
556 | 570 | |
557 | -#if WIRELESS_EXT > 10 | |
558 | 571 | /*------------------------------------------------------------------*/ |
559 | 572 | /* |
560 | 573 | * Print one retry value |
@@ -564,7 +577,8 @@ get_retry_value(int skfd, | ||
564 | 577 | char * ifname, |
565 | 578 | struct iwreq * pwrq, |
566 | 579 | int flags, |
567 | - char * buffer) | |
580 | + char * buffer, | |
581 | + int buflen) | |
568 | 582 | { |
569 | 583 | /* Get Another retry value */ |
570 | 584 | pwrq->u.retry.flags = flags; |
@@ -573,7 +587,7 @@ get_retry_value(int skfd, | ||
573 | 587 | /* Let's check the value and its type */ |
574 | 588 | if(pwrq->u.retry.flags & IW_RETRY_TYPE) |
575 | 589 | { |
576 | - iw_print_retry_value(buffer, | |
590 | + iw_print_retry_value(buffer, buflen, | |
577 | 591 | pwrq->u.retry.value, pwrq->u.retry.flags); |
578 | 592 | printf("%s\n ", buffer); |
579 | 593 | } |
@@ -599,12 +613,13 @@ print_retry_info(int skfd, | ||
599 | 613 | args = args; count = count; |
600 | 614 | |
601 | 615 | /* 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); | |
605 | 620 | else |
606 | 621 | { |
607 | - printf("%-8.8s ", ifname); | |
622 | + printf("%-8.16s ", ifname); | |
608 | 623 | |
609 | 624 | /* Display min/max limit availables */ |
610 | 625 | if(range.retry_flags & IW_RETRY_LIMIT) |
@@ -616,9 +631,11 @@ print_retry_info(int skfd, | ||
616 | 631 | else |
617 | 632 | printf("Fixed limit ; "); |
618 | 633 | /* 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); | |
620 | 636 | 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); | |
622 | 639 | printf("%s\n ", buffer); |
623 | 640 | |
624 | 641 | } |
@@ -632,9 +649,11 @@ print_retry_info(int skfd, | ||
632 | 649 | else |
633 | 650 | printf("Fixed lifetime ; "); |
634 | 651 | /* 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); | |
636 | 654 | 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); | |
638 | 657 | printf("%s\n ", buffer); |
639 | 658 | |
640 | 659 | } |
@@ -658,9 +677,9 @@ print_retry_info(int skfd, | ||
658 | 677 | /* Let's check the value and its type */ |
659 | 678 | if(wrq.u.retry.flags & IW_RETRY_TYPE) |
660 | 679 | { |
661 | - iw_print_retry_value(buffer, | |
680 | + iw_print_retry_value(buffer, sizeof(buffer), | |
662 | 681 | wrq.u.retry.value, wrq.u.retry.flags); |
663 | - printf("%s", buffer); | |
682 | + printf("%s\n ", buffer); | |
664 | 683 | } |
665 | 684 | |
666 | 685 | /* If we have been returned a MIN value, ask for the MAX */ |
@@ -671,7 +690,8 @@ print_retry_info(int skfd, | ||
671 | 690 | retry_mask = IW_RETRY_MIN; |
672 | 691 | /* If we have something to ask for... */ |
673 | 692 | 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)); | |
675 | 695 | |
676 | 696 | /* And if we have both a period and a timeout, ask the other */ |
677 | 697 | retry_mask = (range.retry_capa & (~(wrq.u.retry.flags) & |
@@ -680,7 +700,7 @@ print_retry_info(int skfd, | ||
680 | 700 | { |
681 | 701 | int base_mask = retry_mask; |
682 | 702 | flags = get_retry_value(skfd, ifname, &wrq, retry_mask, |
683 | - buffer); | |
703 | + buffer, sizeof(buffer)); | |
684 | 704 | retry_mask = 0; |
685 | 705 | |
686 | 706 | /* If we have been returned a MIN value, ask for the MAX */ |
@@ -691,7 +711,8 @@ print_retry_info(int skfd, | ||
691 | 711 | retry_mask = IW_RETRY_MIN | base_mask; |
692 | 712 | /* If we have something to ask for... */ |
693 | 713 | 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)); | |
695 | 716 | } |
696 | 717 | } |
697 | 718 | } |
@@ -700,13 +721,17 @@ print_retry_info(int skfd, | ||
700 | 721 | return(0); |
701 | 722 | } |
702 | 723 | |
703 | -#endif /* WIRELESS_EXT > 10 */ | |
704 | - | |
705 | 724 | /***************************** SCANNING *****************************/ |
706 | 725 | /* |
707 | 726 | * 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... | |
708 | 733 | */ |
709 | -#if WIRELESS_EXT > 13 | |
734 | + | |
710 | 735 | /*------------------------------------------------------------------*/ |
711 | 736 | /* |
712 | 737 | * Print one element from the scanning results |
@@ -714,7 +739,7 @@ print_retry_info(int skfd, | ||
714 | 739 | static inline int |
715 | 740 | print_scanning_token(struct iw_event * event, /* Extracted token */ |
716 | 741 | int ap_num, /* AP number */ |
717 | - struct iw_range * iwrange, /* Range info */ | |
742 | + struct iw_range * iw_range, /* Range info */ | |
718 | 743 | int has_range) |
719 | 744 | { |
720 | 745 | char buffer[128]; /* Temporary buffer */ |
@@ -736,8 +761,13 @@ print_scanning_token(struct iw_event * event, /* Extracted token */ | ||
736 | 761 | case SIOCGIWFREQ: |
737 | 762 | { |
738 | 763 | double freq; /* Frequency/channel */ |
764 | + int channel = -1; /* Converted to channel */ | |
739 | 765 | 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); | |
741 | 771 | printf(" %s\n", buffer); |
742 | 772 | } |
743 | 773 | break; |
@@ -780,7 +810,7 @@ print_scanning_token(struct iw_event * event, /* Extracted token */ | ||
780 | 810 | else |
781 | 811 | { |
782 | 812 | /* 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, | |
784 | 814 | event->u.data.flags); |
785 | 815 | printf("%s", buffer); |
786 | 816 |
@@ -796,17 +826,16 @@ print_scanning_token(struct iw_event * event, /* Extracted token */ | ||
796 | 826 | } |
797 | 827 | break; |
798 | 828 | case SIOCGIWRATE: |
799 | - iw_print_bitrate(buffer, event->u.bitrate.value); | |
829 | + iw_print_bitrate(buffer, sizeof(buffer), event->u.bitrate.value); | |
800 | 830 | printf(" Bit Rate:%s\n", buffer); |
801 | 831 | break; |
802 | 832 | case IWEVQUAL: |
803 | 833 | { |
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); | |
806 | 836 | printf(" %s\n", buffer); |
807 | 837 | break; |
808 | 838 | } |
809 | -#if WIRELESS_EXT > 14 | |
810 | 839 | case IWEVCUSTOM: |
811 | 840 | { |
812 | 841 | char custom[IW_CUSTOM_MAX+1]; |
@@ -816,7 +845,6 @@ print_scanning_token(struct iw_event * event, /* Extracted token */ | ||
816 | 845 | printf(" Extra:%s\n", custom); |
817 | 846 | } |
818 | 847 | break; |
819 | -#endif /* WIRELESS_EXT > 14 */ | |
820 | 848 | default: |
821 | 849 | printf(" (Unknown Wireless Token 0x%04X)\n", |
822 | 850 | event->cmd); |
@@ -837,13 +865,27 @@ print_scanning_info(int skfd, | ||
837 | 865 | int count) /* Args count */ |
838 | 866 | { |
839 | 867 | 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; | |
841 | 872 | struct timeval tv; /* Select timeout */ |
842 | 873 | int timeout = 5000000; /* 5s */ |
843 | 874 | |
844 | 875 | /* Avoid "Unused parameter" warning */ |
845 | 876 | args = args; count = count; |
846 | 877 | |
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 | + | |
847 | 889 | /* Init timeout value -> 250ms*/ |
848 | 890 | tv.tv_sec = 0; |
849 | 891 | tv.tv_usec = 250000; |
@@ -852,15 +894,16 @@ print_scanning_info(int skfd, | ||
852 | 894 | * Here we should look at the command line args and set the IW_SCAN_ flags |
853 | 895 | * properly |
854 | 896 | */ |
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; | |
857 | 900 | |
858 | 901 | /* Initiate Scanning */ |
859 | 902 | if(iw_set_ext(skfd, ifname, SIOCSIWSCAN, &wrq) < 0) |
860 | 903 | { |
861 | 904 | if(errno != EPERM) |
862 | 905 | { |
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", | |
864 | 907 | ifname, strerror(errno)); |
865 | 908 | return(-1); |
866 | 909 | } |
@@ -869,7 +912,7 @@ print_scanning_info(int skfd, | ||
869 | 912 | * But, don't wait !!! */ |
870 | 913 | #if 0 |
871 | 914 | /* 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); | |
873 | 916 | #endif |
874 | 917 | tv.tv_usec = 0; |
875 | 918 | } |
@@ -903,12 +946,47 @@ print_scanning_info(int skfd, | ||
903 | 946 | /* Check if there was a timeout */ |
904 | 947 | if(ret == 0) |
905 | 948 | { |
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 | + | |
906 | 963 | /* Try to read the results */ |
907 | 964 | wrq.u.data.pointer = buffer; |
908 | 965 | wrq.u.data.flags = 0; |
909 | - wrq.u.data.length = sizeof(buffer); | |
966 | + wrq.u.data.length = buflen; | |
910 | 967 | if(iw_get_ext(skfd, ifname, SIOCGIWSCAN, &wrq) < 0) |
911 | 968 | { |
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 | + | |
912 | 990 | /* Check if results not available yet */ |
913 | 991 | if(errno == EAGAIN) |
914 | 992 | { |
@@ -921,7 +999,8 @@ print_scanning_info(int skfd, | ||
921 | 999 | } |
922 | 1000 | |
923 | 1001 | /* 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", | |
925 | 1004 | ifname, strerror(errno)); |
926 | 1005 | return(-2); |
927 | 1006 | } |
@@ -940,23 +1019,21 @@ print_scanning_info(int skfd, | ||
940 | 1019 | struct stream_descr stream; |
941 | 1020 | int ap_num = 1; |
942 | 1021 | int ret; |
943 | - struct iw_range range; | |
944 | - int has_range; | |
945 | 1022 | #if 0 |
946 | 1023 | /* Debugging code. In theory useless, because it's debugged ;-) */ |
947 | 1024 | int i; |
948 | - printf("Scan result [%02X", buffer[0]); | |
1025 | + printf("Scan result %d [%02X", wrq.u.data.length, buffer[0]); | |
949 | 1026 | for(i = 1; i < wrq.u.data.length; i++) |
950 | 1027 | printf(":%02X", buffer[i]); |
951 | 1028 | printf("]\n"); |
952 | 1029 | #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); | |
955 | 1031 | iw_init_event_stream(&stream, buffer, wrq.u.data.length); |
956 | 1032 | do |
957 | 1033 | { |
958 | 1034 | /* 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); | |
960 | 1037 | if(ret > 0) |
961 | 1038 | ap_num = print_scanning_token(&iwe, ap_num, &range, has_range); |
962 | 1039 | } |
@@ -964,11 +1041,93 @@ print_scanning_info(int skfd, | ||
964 | 1041 | printf("\n"); |
965 | 1042 | } |
966 | 1043 | else |
967 | - printf("%-8.8s No scan results\n", ifname); | |
1044 | + printf("%-8.16s No scan results\n", ifname); | |
968 | 1045 | |
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 | + } | |
969 | 1129 | return(0); |
970 | 1130 | } |
971 | -#endif /* WIRELESS_EXT > 13 */ | |
972 | 1131 | |
973 | 1132 | /************************* COMMON UTILITIES *************************/ |
974 | 1133 | /* |
@@ -985,23 +1144,20 @@ typedef struct iwlist_entry { | ||
985 | 1144 | } iwlist_cmd; |
986 | 1145 | |
987 | 1146 | static const struct iwlist_entry iwlist_cmds[] = { |
1147 | + { "scanning", print_scanning_info, 0, 5 }, | |
988 | 1148 | { "frequency", print_freq_info, 0, 0 }, |
989 | 1149 | { "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 }, | |
993 | 1150 | { "bitrate", print_bitrate_info, 0, 0 }, |
994 | 1151 | { "rate", print_bitrate_info, 0, 0 }, |
995 | 1152 | { "encryption", print_keys_info, 0, 0 }, |
996 | 1153 | { "key", print_keys_info, 0, 0 }, |
997 | 1154 | { "power", print_pm_info, 0, 0 }, |
998 | 1155 | { "txpower", print_txpower_info, 0, 0 }, |
999 | -#if WIRELESS_EXT > 10 | |
1000 | 1156 | { "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 }, | |
1005 | 1161 | { NULL, NULL, 0, 0 }, |
1006 | 1162 | }; |
1007 | 1163 |
@@ -1141,7 +1297,7 @@ main(int argc, | ||
1141 | 1297 | iw_enum_devices(skfd, iwcmd->fn, args, count); |
1142 | 1298 | |
1143 | 1299 | /* Close the socket. */ |
1144 | - close(skfd); | |
1300 | + iw_sockets_close(skfd); | |
1145 | 1301 | |
1146 | 1302 | return 0; |
1147 | 1303 | } |
@@ -1,14 +1,14 @@ | ||
1 | 1 | /* |
2 | 2 | * Wireless Tools |
3 | 3 | * |
4 | - * Jean II - HPLB 97->99 - HPL 99->00 | |
4 | + * Jean II - HPLB 97->99 - HPL 99->04 | |
5 | 5 | * |
6 | 6 | * Main code for "iwconfig". This is the generic tool for most |
7 | 7 | * manipulations... |
8 | 8 | * You need to link this code against "iwlib.c" and "-lm". |
9 | 9 | * |
10 | 10 | * 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> | |
12 | 12 | */ |
13 | 13 | |
14 | 14 | #include "iwlib.h" /* Header */ |
@@ -16,6 +16,29 @@ | ||
16 | 16 | /************************** DOCUMENTATION **************************/ |
17 | 17 | |
18 | 18 | /* |
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 | + * | |
19 | 42 | * IOCTL RANGES : |
20 | 43 | * ------------ |
21 | 44 | * The initial implementation of iwpriv was using the SIOCDEVPRIVATE |
@@ -27,74 +50,99 @@ | ||
27 | 50 | * worry about collisions with other usages. On the other hand, in the |
28 | 51 | * new range, the SET convention is enforced (see below). |
29 | 52 | * 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) | |
31 | 54 | * o collisions yes no |
32 | 55 | * o SET convention optional enforced |
33 | 56 | * o number 16 32 |
34 | 57 | * |
35 | 58 | * NEW DRIVER API : |
36 | 59 | * -------------- |
37 | - * Wireless Extension 13 introduce a new driver API. Wireless | |
60 | + * Wireless Extension 13 introduces a new driver API. Wireless | |
38 | 61 | * Extensions requests can be handled via a iw_handler table instead |
39 | 62 | * of through the regular ioctl handler. |
40 | 63 | * 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). | |
42 | 65 | * The differences are : old API new API |
43 | 66 | * o handler do_ioctl() struct iw_handler_def |
44 | 67 | * o SIOCIWFIRSTPRIV WE > 11 yes |
45 | 68 | * o SIOCDEVPRIVATE yes no |
46 | 69 | * o GET convention optional enforced |
47 | 70 | * 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'). | |
49 | 90 | * |
50 | 91 | * SET/GET CONVENTION : |
51 | 92 | * ------------------ |
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 | |
55 | 104 | * be available to root only and can't return any arguments. If you don't |
56 | 105 | * like that, just use every other two ioctl. |
57 | 106 | * The new driver API enforce the GET convention : GET request won't |
58 | 107 | * 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). | |
61 | 110 | * In any case, it's a good idea to not have ioctl with both SET |
62 | 111 | * and GET arguments. If the GET arguments doesn't fit within |
63 | 112 | * (union iwreq_data) and SET do, or vice versa, the current code in iwpriv |
64 | 113 | * won't work. One exception is if both SET and GET arguments fit within |
65 | 114 | * (union iwreq_data), this case should be handled safely in a GET |
66 | 115 | * request. |
116 | + * If you don't fully understand those limitations, just follow the | |
117 | + * rules of the simplistic summary ;-) | |
67 | 118 | * |
68 | 119 | * SUB-IOCTLS : |
69 | 120 | * ---------- |
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). | |
74 | 125 | * One might argue that at the point, some other mechanisms might be |
75 | 126 | * 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 ;-). | |
78 | 129 | * |
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. | |
87 | 139 | * |
88 | 140 | * 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 : | |
93 | 145 | * -------------------------------------------- |
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" }, | |
98 | 146 | // --- sub-ioctls handlers --- |
99 | 147 | { 0x8BE0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "" }, |
100 | 148 | { 0x8BE1, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "" }, |
@@ -103,21 +151,26 @@ | ||
103 | 151 | { 1, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_param1" }, |
104 | 152 | { 2, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_param2" }, |
105 | 153 | { 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" }, | |
106 | 158 | * -------------------------------------------- |
107 | 159 | * And iwpriv should do the rest for you ;-) |
108 | 160 | * |
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 | |
110 | 162 | * 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. | |
114 | 167 | * |
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 | |
117 | 170 | * try to get them inline instead of by pointer. You can fool the new API |
118 | 171 | * 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. | |
121 | 174 | * |
122 | 175 | * NEW DATA TYPES (ADDR/FLOAT) : |
123 | 176 | * --------------------------- |
@@ -127,7 +180,7 @@ | ||
127 | 180 | * However, the new API before v15 won't handle them properly. |
128 | 181 | * |
129 | 182 | * 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. | |
131 | 184 | * The second problem is that a fixed single addr won't be inlined |
132 | 185 | * in struct iwreq and will be passed as a pointer. This is due to an |
133 | 186 | * off-by-one error, where all fixed data of 16 bytes is considered too |
@@ -138,17 +191,19 @@ | ||
138 | 191 | * |
139 | 192 | * TOKEN INDEX : |
140 | 193 | * ----------- |
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 | |
142 | 195 | * 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 | |
147 | 202 | * this to happen (and check arg number yourself). |
148 | 203 | * -------------------------------------------- |
149 | 204 | // --- Commands that would fit in struct iwreq --- |
150 | 205 | { 0x8BE0, IW_PRIV_TYPE_ADDR | 1, 0, "set_param_with_token" }, |
151 | - // --- No problem here --- | |
206 | + // --- No problem here (bigger than struct iwreq) --- | |
152 | 207 | { 0x8BE1, IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 2, 0, "again" }, |
153 | 208 | * -------------------------------------------- |
154 | 209 | * The token index feature is pretty transparent, the token index |
@@ -156,7 +211,7 @@ | ||
156 | 211 | * (if the user doesn't specify it) will be 0. Token index itself will |
157 | 212 | * work with any version of Wireless Extensions. |
158 | 213 | * 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 | |
160 | 215 | * raw access to the sub-ioctl handlers (if it uses struct iw_point) : |
161 | 216 | * -------------------------------------------- |
162 | 217 | // --- sub-ioctls handler --- |
@@ -176,13 +231,6 @@ | ||
176 | 231 | static const char * argtype[] = { |
177 | 232 | " ", "byte ", "char ", "", "int ", "float", "addr " }; |
178 | 233 | |
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 | - | |
186 | 234 | /************************* MISC SUBROUTINES **************************/ |
187 | 235 | |
188 | 236 | /*------------------------------------------------------------------*/ |
@@ -221,9 +269,9 @@ set_private_cmd(int skfd, /* Socket */ | ||
221 | 269 | int offset = 0; /* Space for sub-ioctl index */ |
222 | 270 | |
223 | 271 | /* 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 | |
225 | 273 | * 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)) | |
227 | 275 | { |
228 | 276 | subcmd = temp; |
229 | 277 | args++; |
@@ -261,13 +309,15 @@ set_private_cmd(int skfd, /* Socket */ | ||
261 | 309 | |
262 | 310 | /* Save sub-ioctl number */ |
263 | 311 | subcmd = priv[k].cmd; |
264 | - /* Reserve one int (simplify alignement issues) */ | |
312 | + /* Reserve one int (simplify alignment issues) */ | |
265 | 313 | offset = sizeof(__u32); |
266 | 314 | /* Use real ioctl definition from now on */ |
267 | 315 | k = j; |
268 | 316 | |
317 | +#if 0 | |
269 | 318 | printf("<mapping sub-ioctl %s to cmd 0x%X-%d>\n", cmdname, |
270 | 319 | priv[k].cmd, subcmd); |
320 | +#endif | |
271 | 321 | } |
272 | 322 | |
273 | 323 | /* If we have to set some data */ |
@@ -424,7 +474,7 @@ set_private_cmd(int skfd, /* Socket */ | ||
424 | 474 | int j; |
425 | 475 | int n = 0; /* number of args */ |
426 | 476 | |
427 | - printf("%-8.8s %s:", ifname, cmdname); | |
477 | + printf("%-8.16s %s:", ifname, cmdname); | |
428 | 478 | |
429 | 479 | /* Check where is the returned data */ |
430 | 480 | if((priv[k].get_args & IW_PRIV_SIZE_FIXED) && |
@@ -454,7 +504,7 @@ set_private_cmd(int skfd, /* Socket */ | ||
454 | 504 | |
455 | 505 | case IW_PRIV_TYPE_CHAR: |
456 | 506 | /* Display args */ |
457 | - buffer[wrq.u.data.length - 1] = '\0'; | |
507 | + buffer[n] = '\0'; | |
458 | 508 | printf("%s\n", buffer); |
459 | 509 | break; |
460 | 510 |
@@ -512,31 +562,38 @@ set_private(int skfd, /* Socket */ | ||
512 | 562 | int count, /* Args count */ |
513 | 563 | char * ifname) /* Dev name */ |
514 | 564 | { |
515 | - iwprivargs priv[IW_MAX_PRIV_DEF]; | |
565 | + iwprivargs * priv; | |
516 | 566 | int number; /* Max of private ioctl */ |
567 | + int ret; | |
517 | 568 | |
518 | 569 | /* 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); | |
520 | 571 | |
521 | 572 | /* Is there any ? */ |
522 | 573 | if(number <= 0) |
523 | 574 | { |
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", | |
526 | 577 | ifname); |
578 | + if(priv) | |
579 | + free(priv); | |
527 | 580 | return(-1); |
528 | 581 | } |
529 | 582 | |
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); | |
532 | 589 | } |
533 | 590 | |
534 | 591 | /************************ CATALOG FUNCTIONS ************************/ |
535 | 592 | |
536 | 593 | /*------------------------------------------------------------------*/ |
537 | 594 | /* |
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. | |
540 | 597 | */ |
541 | 598 | static int |
542 | 599 | print_priv_info(int skfd, |
@@ -545,25 +602,25 @@ print_priv_info(int skfd, | ||
545 | 602 | int count) |
546 | 603 | { |
547 | 604 | int k; |
548 | - iwprivargs priv[IW_MAX_PRIV_DEF]; | |
605 | + iwprivargs * priv; | |
549 | 606 | int n; |
550 | 607 | |
551 | 608 | /* Avoid "Unused parameter" warning */ |
552 | 609 | args = args; count = count; |
553 | 610 | |
554 | 611 | /* 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); | |
556 | 613 | |
557 | 614 | /* Is there any ? */ |
558 | 615 | if(n <= 0) |
559 | 616 | { |
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", | |
562 | 619 | ifname); |
563 | 620 | } |
564 | 621 | else |
565 | 622 | { |
566 | - printf("%-8.8s Available private ioctl :\n", ifname); | |
623 | + printf("%-8.16s Available private ioctl :\n", ifname); | |
567 | 624 | /* Print them all */ |
568 | 625 | for(k = 0; k < n; k++) |
569 | 626 | if(priv[k].name[0] != '\0') |
@@ -575,13 +632,17 @@ print_priv_info(int skfd, | ||
575 | 632 | argtype[(priv[k].get_args & IW_PRIV_TYPE_MASK) >> 12]); |
576 | 633 | printf("\n"); |
577 | 634 | } |
635 | + | |
636 | + /* Cleanup */ | |
637 | + if(priv) | |
638 | + free(priv); | |
578 | 639 | return(0); |
579 | 640 | } |
580 | 641 | |
581 | 642 | /*------------------------------------------------------------------*/ |
582 | 643 | /* |
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. | |
585 | 646 | */ |
586 | 647 | static int |
587 | 648 | print_priv_all(int skfd, |
@@ -590,28 +651,28 @@ print_priv_all(int skfd, | ||
590 | 651 | int count) |
591 | 652 | { |
592 | 653 | int k; |
593 | - iwprivargs priv[IW_MAX_PRIV_DEF]; | |
654 | + iwprivargs * priv; | |
594 | 655 | int n; |
595 | 656 | |
596 | 657 | /* Avoid "Unused parameter" warning */ |
597 | 658 | args = args; count = count; |
598 | 659 | |
599 | 660 | /* 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); | |
601 | 662 | |
602 | 663 | /* Is there any ? */ |
603 | 664 | if(n <= 0) |
604 | 665 | { |
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", | |
607 | 668 | ifname); |
608 | 669 | } |
609 | 670 | else |
610 | 671 | { |
611 | - printf("%-8.8s Available read-only private ioctl :\n", ifname); | |
672 | + printf("%-8.16s Available read-only private ioctl :\n", ifname); | |
612 | 673 | /* Print them all */ |
613 | 674 | 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 | |
615 | 676 | * args and return some (avoid triggering "reset" commands) */ |
616 | 677 | if((priv[k].name[0] != '\0') && (priv[k].set_args == 0) && |
617 | 678 | (priv[k].get_args != 0)) |
@@ -619,13 +680,10 @@ print_priv_all(int skfd, | ||
619 | 680 | priv, n); |
620 | 681 | printf("\n"); |
621 | 682 | } |
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); | |
629 | 687 | return(0); |
630 | 688 | } |
631 | 689 |
@@ -638,6 +696,8 @@ print_priv_all(int skfd, | ||
638 | 696 | /* |
639 | 697 | * Set roaming mode on and off |
640 | 698 | * Found in wavelan_cs driver |
699 | + * Note : this is obsolete, most 802.11 devices should use the | |
700 | + * SIOCSIWAP request. | |
641 | 701 | */ |
642 | 702 | static int |
643 | 703 | set_roaming(int skfd, /* Socket */ |
@@ -649,24 +709,41 @@ set_roaming(int skfd, /* Socket */ | ||
649 | 709 | struct iwreq wrq; |
650 | 710 | int i = 0; /* Start with first arg */ |
651 | 711 | int k; |
652 | - iwprivargs priv[IW_MAX_PRIV_DEF]; | |
712 | + iwprivargs * priv; | |
653 | 713 | int number; |
714 | + int roamcmd; | |
654 | 715 | char RoamState; /* buffer to hold new roam state */ |
655 | 716 | char ChangeRoamState=0; /* whether or not we are going to |
656 | 717 | change roam states */ |
657 | 718 | |
658 | 719 | /* 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); | |
660 | 721 | |
661 | 722 | /* Is there any ? */ |
662 | 723 | if(number <= 0) |
663 | 724 | { |
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", | |
666 | 727 | ifname); |
728 | + if(priv) | |
729 | + free(priv); | |
667 | 730 | return(-1); |
668 | 731 | } |
669 | 732 | |
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 | + | |
670 | 747 | if(count != 1) |
671 | 748 | { |
672 | 749 | iw_usage(); |
@@ -675,7 +752,7 @@ set_roaming(int skfd, /* Socket */ | ||
675 | 752 | |
676 | 753 | if(!strcasecmp(args[i], "on")) |
677 | 754 | { |
678 | - printf("%-8.8s enable roaming\n", ifname); | |
755 | + printf("%-8.16s enable roaming\n", ifname); | |
679 | 756 | if(!number) |
680 | 757 | { |
681 | 758 | fprintf(stderr, "This device doesn't support roaming\n"); |
@@ -688,7 +765,7 @@ set_roaming(int skfd, /* Socket */ | ||
688 | 765 | if(!strcasecmp(args[i], "off")) |
689 | 766 | { |
690 | 767 | i++; |
691 | - printf("%-8.8s disable roaming\n", ifname); | |
768 | + printf("%-8.16s disable roaming\n", ifname); | |
692 | 769 | if(!number) |
693 | 770 | { |
694 | 771 | fprintf(stderr, "This device doesn't support roaming\n"); |
@@ -705,20 +782,13 @@ set_roaming(int skfd, /* Socket */ | ||
705 | 782 | |
706 | 783 | if(ChangeRoamState) |
707 | 784 | { |
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 | - } | |
715 | 785 | strncpy(wrq.ifr_name, ifname, IFNAMSIZ); |
716 | 786 | |
717 | 787 | buffer[0]=RoamState; |
718 | 788 | |
719 | 789 | memcpy(wrq.u.name, &buffer, IFNAMSIZ); |
720 | 790 | |
721 | - if(ioctl(skfd, priv[k].cmd, &wrq) < 0) | |
791 | + if(ioctl(skfd, roamcmd, &wrq) < 0) | |
722 | 792 | { |
723 | 793 | fprintf(stderr, "Roaming support is broken.\n"); |
724 | 794 | return(-1); |
@@ -732,6 +802,7 @@ set_roaming(int skfd, /* Socket */ | ||
732 | 802 | /* |
733 | 803 | * Get and set the port type |
734 | 804 | * Found in wavelan2_cs and wvlan_cs drivers |
805 | + * TODO : Add support for HostAP ? | |
735 | 806 | */ |
736 | 807 | static int |
737 | 808 | port_type(int skfd, /* Socket */ |
@@ -742,19 +813,21 @@ port_type(int skfd, /* Socket */ | ||
742 | 813 | struct iwreq wrq; |
743 | 814 | int i = 0; /* Start with first arg */ |
744 | 815 | int k; |
745 | - iwprivargs priv[IW_MAX_PRIV_DEF]; | |
816 | + iwprivargs * priv; | |
746 | 817 | int number; |
747 | 818 | char ptype = 0; |
748 | 819 | char * modes[] = { "invalid", "managed (BSS)", "reserved", "ad-hoc" }; |
749 | 820 | |
750 | 821 | /* 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); | |
752 | 823 | |
753 | 824 | /* Is there any ? */ |
754 | 825 | if(number <= 0) |
755 | 826 | { |
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); | |
758 | 831 | return(-1); |
759 | 832 | } |
760 | 833 |
@@ -768,7 +841,7 @@ port_type(int skfd, /* Socket */ | ||
768 | 841 | if(k == number) |
769 | 842 | { |
770 | 843 | fprintf(stderr, "This device doesn't support getting port type\n"); |
771 | - return(-1); | |
844 | + goto err; | |
772 | 845 | } |
773 | 846 | strncpy(wrq.ifr_name, ifname, IFNAMSIZ); |
774 | 847 |
@@ -776,21 +849,22 @@ port_type(int skfd, /* Socket */ | ||
776 | 849 | if(ioctl(skfd, priv[k].cmd, &wrq) < 0) |
777 | 850 | { |
778 | 851 | fprintf(stderr, "Port type support is broken.\n"); |
779 | - exit(0); | |
852 | + goto err; | |
780 | 853 | } |
781 | 854 | ptype = *wrq.u.name; |
782 | 855 | |
783 | 856 | /* 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", | |
785 | 858 | ifname, modes[(int) ptype], ptype); |
786 | 859 | |
860 | + free(priv); | |
787 | 861 | return(0); |
788 | 862 | } |
789 | 863 | |
790 | 864 | if(count != 1) |
791 | 865 | { |
792 | 866 | iw_usage(); |
793 | - return(-1); | |
867 | + goto err; | |
794 | 868 | } |
795 | 869 | |
796 | 870 | /* Read it */ |
@@ -805,7 +879,7 @@ port_type(int skfd, /* Socket */ | ||
805 | 879 | if(sscanf(args[i], "%i", (int *) &ptype) != 1) |
806 | 880 | { |
807 | 881 | iw_usage(); |
808 | - return(-1); | |
882 | + goto err; | |
809 | 883 | } |
810 | 884 | |
811 | 885 | k = -1; |
@@ -814,7 +888,7 @@ port_type(int skfd, /* Socket */ | ||
814 | 888 | if(k == number) |
815 | 889 | { |
816 | 890 | fprintf(stderr, "This device doesn't support setting port type\n"); |
817 | - return(-1); | |
891 | + goto err; | |
818 | 892 | } |
819 | 893 | strncpy(wrq.ifr_name, ifname, IFNAMSIZ); |
820 | 894 |
@@ -823,10 +897,15 @@ port_type(int skfd, /* Socket */ | ||
823 | 897 | if(ioctl(skfd, priv[k].cmd, &wrq) < 0) |
824 | 898 | { |
825 | 899 | fprintf(stderr, "Invalid port type (or setting not allowed)\n"); |
826 | - return(-1); | |
900 | + goto err; | |
827 | 901 | } |
828 | 902 | |
903 | + free(priv); | |
829 | 904 | return(0); |
905 | + | |
906 | + err: | |
907 | + free(priv); | |
908 | + return(-1); | |
830 | 909 | } |
831 | 910 | |
832 | 911 | /******************************* MAIN ********************************/ |
@@ -849,7 +928,7 @@ main(int argc, | ||
849 | 928 | return(-1); |
850 | 929 | } |
851 | 930 | |
852 | - /* No argument : show the list of all device + info */ | |
931 | + /* No argument : show the list of all devices + ioctl list */ | |
853 | 932 | if(argc == 1) |
854 | 933 | iw_enum_devices(skfd, &print_priv_info, NULL, 0); |
855 | 934 | else |
@@ -890,7 +969,7 @@ main(int argc, | ||
890 | 969 | goterr = set_private(skfd, argv + 2, argc - 2, argv[1]); |
891 | 970 | |
892 | 971 | /* Close the socket. */ |
893 | - close(skfd); | |
972 | + iw_sockets_close(skfd); | |
894 | 973 | |
895 | 974 | return(goterr); |
896 | 975 | } |
@@ -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 | - |
@@ -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 | - |
@@ -1,13 +1,13 @@ | ||
1 | 1 | /* |
2 | 2 | * Wireless Tools |
3 | 3 | * |
4 | - * Jean II - HPLB '99 | |
4 | + * Jean II - HPLB '99 - HPL 99->04 | |
5 | 5 | * |
6 | 6 | * This tool can manipulate the spy list : add addresses and display stat |
7 | 7 | * You need to link this code against "iwlib.c" and "-lm". |
8 | 8 | * |
9 | 9 | * 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> | |
11 | 11 | */ |
12 | 12 | |
13 | 13 | #include "iwlib.h" /* Header */ |
@@ -44,7 +44,7 @@ print_spy_info(int skfd, | ||
44 | 44 | wrq.u.data.flags = 0; |
45 | 45 | if(iw_get_ext(skfd, ifname, SIOCGIWSPY, &wrq) < 0) |
46 | 46 | { |
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); | |
48 | 48 | return(-1); |
49 | 49 | } |
50 | 50 |
@@ -54,7 +54,7 @@ print_spy_info(int skfd, | ||
54 | 54 | /* Check if we have valid mac address type */ |
55 | 55 | if(iw_check_mac_addr_type(skfd, ifname) < 0) |
56 | 56 | { |
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); | |
58 | 58 | return(-2); |
59 | 59 | } |
60 | 60 |
@@ -64,9 +64,9 @@ print_spy_info(int skfd, | ||
64 | 64 | |
65 | 65 | /* Display it */ |
66 | 66 | if(n == 0) |
67 | - printf("%-8.8s No statistics to collect\n", ifname); | |
67 | + printf("%-8.16s No statistics to collect\n", ifname); | |
68 | 68 | else |
69 | - printf("%-8.8s Statistics collected:\n", ifname); | |
69 | + printf("%-8.16s Statistics collected:\n", ifname); | |
70 | 70 | |
71 | 71 | /* The two lists */ |
72 | 72 | hwa = (struct sockaddr *) buffer; |
@@ -76,25 +76,25 @@ print_spy_info(int skfd, | ||
76 | 76 | { |
77 | 77 | /* Print stats for each address */ |
78 | 78 | 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); | |
80 | 80 | printf("%s\n", temp); |
81 | 81 | } |
82 | -#if WIRELESS_EXT > 11 | |
83 | - if((n > 0) && (has_range)) | |
82 | + | |
83 | + if((n > 0) && (has_range) && (range.we_version_compiled > 11)) | |
84 | 84 | { |
85 | 85 | iwstats stats; |
86 | 86 | |
87 | 87 | /* 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) | |
89 | 89 | { |
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); | |
92 | 92 | /* 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); | |
94 | 95 | printf(" Typical/Reference : %s\n", temp); |
95 | 96 | } |
96 | 97 | } |
97 | -#endif /* WIRELESS_EXT > 11 */ | |
98 | 98 | |
99 | 99 | printf("\n"); |
100 | 100 | return(0); |
@@ -110,7 +110,6 @@ get_spy_threshold(int skfd, /* The socket */ | ||
110 | 110 | char * args[], /* Command line args */ |
111 | 111 | int count) /* Args count */ |
112 | 112 | { |
113 | -#if WIRELESS_EXT > 15 | |
114 | 113 | struct iwreq wrq; |
115 | 114 | struct iw_thrspy threshold; |
116 | 115 | iwrange range; |
@@ -141,14 +140,14 @@ get_spy_threshold(int skfd, /* The socket */ | ||
141 | 140 | if(threshold.low.level > range.max_qual.level) |
142 | 141 | { |
143 | 142 | /* 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", | |
145 | 144 | ifname, |
146 | 145 | threshold.low.level - 0x100, threshold.high.level - 0x100); |
147 | 146 | } |
148 | 147 | else |
149 | 148 | { |
150 | 149 | /* 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", | |
152 | 151 | ifname, |
153 | 152 | threshold.low.level, range.max_qual.level, |
154 | 153 | threshold.high.level, range.max_qual.level); |
@@ -157,19 +156,12 @@ get_spy_threshold(int skfd, /* The socket */ | ||
157 | 156 | else |
158 | 157 | { |
159 | 158 | /* 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", | |
161 | 160 | ifname, |
162 | 161 | threshold.low.level, threshold.high.level); |
163 | 162 | } |
164 | 163 | |
165 | 164 | 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 */ | |
173 | 165 | } |
174 | 166 | |
175 | 167 | /************************* SETTING ROUTINES **************************/ |
@@ -207,12 +199,12 @@ set_spy_info(int skfd, /* The socket */ | ||
207 | 199 | /* Check if we have valid mac address type */ |
208 | 200 | if(iw_check_mac_addr_type(skfd, ifname) < 0) |
209 | 201 | { |
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); | |
211 | 203 | return(-1); |
212 | 204 | } |
213 | 205 | |
214 | 206 | wrq.u.data.pointer = (caddr_t) buffer; |
215 | - wrq.u.data.length = 0; | |
207 | + wrq.u.data.length = IW_MAX_SPY; | |
216 | 208 | wrq.u.data.flags = 0; |
217 | 209 | if(iw_get_ext(skfd, ifname, SIOCGIWSPY, &wrq) < 0) |
218 | 210 | { |
@@ -275,7 +267,6 @@ set_spy_threshold(int skfd, /* The socket */ | ||
275 | 267 | char * args[], /* Command line args */ |
276 | 268 | int count) /* Args count */ |
277 | 269 | { |
278 | -#if WIRELESS_EXT > 15 | |
279 | 270 | struct iwreq wrq; |
280 | 271 | struct iw_thrspy threshold; |
281 | 272 | int low_thr; |
@@ -294,19 +285,19 @@ set_spy_threshold(int skfd, /* The socket */ | ||
294 | 285 | /* Try to get our threshold */ |
295 | 286 | if(count < 2) |
296 | 287 | { |
297 | - fprintf(stderr, "%-8.8s Need two threshold values\n", ifname); | |
288 | + fprintf(stderr, "%-8.16s Need two threshold values\n", ifname); | |
298 | 289 | return(-1); |
299 | 290 | } |
300 | 291 | if((sscanf(args[0], "%i", &low_thr) != 1) || |
301 | 292 | (sscanf(args[1], "%i", &high_thr) != 1)) |
302 | 293 | { |
303 | - fprintf(stderr, "%-8.8s Invalid threshold values\n", ifname); | |
294 | + fprintf(stderr, "%-8.16s Invalid threshold values\n", ifname); | |
304 | 295 | return(-1); |
305 | 296 | } |
306 | 297 | /* Basic sanity check */ |
307 | 298 | if(high_thr < low_thr) |
308 | 299 | { |
309 | - fprintf(stderr, "%-8.8s Inverted threshold range\n", ifname); | |
300 | + fprintf(stderr, "%-8.16s Inverted threshold range\n", ifname); | |
310 | 301 | return(-1); |
311 | 302 | } |
312 | 303 | /* Copy thresholds */ |
@@ -328,13 +319,6 @@ set_spy_threshold(int skfd, /* The socket */ | ||
328 | 319 | } |
329 | 320 | |
330 | 321 | 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 */ | |
338 | 322 | } |
339 | 323 | |
340 | 324 | /******************************* MAIN ********************************/ |
@@ -386,7 +370,7 @@ main(int argc, | ||
386 | 370 | goterr = set_spy_info(skfd, argv[1], argv + 2, argc - 2); |
387 | 371 | |
388 | 372 | /* Close the socket. */ |
389 | - close(skfd); | |
373 | + iw_sockets_close(skfd); | |
390 | 374 | |
391 | 375 | return(goterr); |
392 | 376 | } |
@@ -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 */ |
@@ -1,7 +1,7 @@ | ||
1 | -.\" Jean Tourrilhes - HPL - 2002 | |
1 | +.\" Jean Tourrilhes - HPL - 2002 - 2004 | |
2 | 2 | .\" wireless.7 |
3 | 3 | .\" |
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" | |
5 | 5 | .\" |
6 | 6 | .\" NAME part |
7 | 7 | .\" |
@@ -13,7 +13,7 @@ wireless \- Wireless Tools and Wireless Extensions | ||
13 | 13 | .SH SYNOPSIS |
14 | 14 | .B iwconfig |
15 | 15 | .br |
16 | -.B iwpriv -a | |
16 | +.B iwpriv \-a | |
17 | 17 | .br |
18 | 18 | .\" |
19 | 19 | .\" DESCRIPTION part |
@@ -23,40 +23,42 @@ The | ||
23 | 23 | .B Wireless Extensions |
24 | 24 | is an API allowing you manipulate Wireless LAN networking interfaces. |
25 | 25 | 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. | |
27 | 27 | .br |
28 | 28 | The |
29 | 29 | .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. | |
33 | 34 | .br |
34 | 35 | .B Wireless configuration |
35 | 36 | 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. | |
39 | 40 | .\" |
40 | 41 | .\" DEBIAN 3.0 part |
41 | 42 | .\" |
42 | 43 | .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). | |
45 | 47 | .TP |
46 | 48 | .B File : |
47 | 49 | .I /etc/network/interfaces |
48 | 50 | .TP |
49 | 51 | .B Form : |
50 | -.RI wireless_ "<function> <value>" | |
52 | +.RI wireless\- "<function> <value>" | |
51 | 53 | .br |
52 | -wireless_essid Home | |
54 | +wireless\-essid Home | |
53 | 55 | .br |
54 | -wireless_mode ad_hoc | |
56 | +wireless\-mode Ad\-Hoc | |
55 | 57 | .TP |
56 | 58 | .B See also : |
57 | -.I /etc/network/if-pre-up.d/wireless-tool | |
59 | +.I /etc/network/if\-pre\-up.d/wireless\-tools | |
58 | 60 | .br |
59 | -.I /usr/share/doc/wireless.##/README.Debian | |
61 | +.I /usr/share/doc/wireless\-tools/README.Debian | |
60 | 62 | .\" |
61 | 63 | .\" SuSE 8.0 part |
62 | 64 | .\" |
@@ -70,14 +72,14 @@ network scripts. | ||
70 | 72 | .B File : |
71 | 73 | .I /etc/sysconfig/network/wireless |
72 | 74 | .br |
73 | -.I /etc/sysconfig/network/ifcfg-* | |
75 | +.I /etc/sysconfig/network/ifcfg\-* | |
74 | 76 | .TP |
75 | 77 | .B Form : |
76 | 78 | .RI WIRELESS_ "<function>" = "<value>" |
77 | 79 | .br |
78 | 80 | WIRELESS_ESSID="Home" |
79 | 81 | .br |
80 | -WIRELESS_MODE=ad_hoc | |
82 | +WIRELESS_MODE=Ad\-Hoc | |
81 | 83 | .TP |
82 | 84 | .B See also : |
83 | 85 | man ifup |
@@ -96,9 +98,9 @@ package, you can use this method. | ||
96 | 98 | .B Form : |
97 | 99 | *,*,*,*) |
98 | 100 | .br |
99 | - ESSID="MY_ESSID" | |
101 | + ESSID="Home" | |
100 | 102 | .br |
101 | - MODE="Managed" | |
103 | + MODE="Ad-Hoc" | |
102 | 104 | .br |
103 | 105 | ;; |
104 | 106 | .TP |