From: Javier Palacios Date: Fri, 23 Apr 2010 15:48:35 +0000 (+0200) Subject: Initial commit with current version (0.3.3) X-Git-Url: http://git.maemo.org/git/?p=pyiw;a=commitdiff_plain;h=refs%2Fheads%2Fupstream;ds=sidebyside Initial commit with current version (0.3.3) --- diff --git a/CHANGELOG b/CHANGELOG new file mode 100644 index 0000000..577c5c4 --- /dev/null +++ b/CHANGELOG @@ -0,0 +1,52 @@ +Version 0.3.3: + - Looks like I forgot to actually add the codestuffs for CHANNEL and + MODE. I've added CHANNEL support for now (thanks to Robert Berger), + but I really need to revist this entire module. It's been more than + a year, I'm a much better coder now, and there's lots of room for + improvement. *sigh* + - Added more TODO stuff in the source file. + - Fixed a bug in where packaged 0.3.2 was reporting itself as 0.3.1. + - We're using version 29 of iwlib (if you build statically), which + supports WE21. + - Small changes to the test script. + +Version 0.3.2: + - Ooops! I was using IFNAMSIZ as the maximum value of an ESSID, when + I should have been just using the max buffer size. Thanks to + Oliver Thuns for the heads up. + - Upgraded to a beta'ish version of LIBIW. + +Version 0.3.1: + - Added a LICENSE file; LGPL. + +Version 0.3.0: + - Add support for WirelessExtensions 20 method of detecting whether + WPA is on a scan result or not (using IWEVGENIE). + - Still need to change to attribute access rather than dictionary + access. + +Version 0.2.2: + - Removal of ETHTOOL includes and testing code. + +Version 0.2.1: + - "make static", er, uh, works right now. + +Version 0.2.0: + - Oops; made it so that the interface refeshes itself when you retrieve + values from the dict. This was a biggy, so I bumped to 0.2.0. + - Added some experimental (commented out) code for using ETHTOOL and + getting the currently assigned IP address. + +Version 0.1.2: + - Fixed a silly bug w/ PyArg_ParseTuple and ->ifname. + - Added a function to report the version of WE libiw is using. + - Made the version stuff behave correctly. + - Somewhat better error-handling; things throw sensible exceptions now. + +Version 0.1.1: + - Made _init bring the network interface up before operating on it. + This is particularly useful for Atheros cards, who need this in + a bad way. + +Version 0.1.0: + - First semi-psuedo-official release. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..5ab7695 --- /dev/null +++ b/LICENSE @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..45b7f35 --- /dev/null +++ b/Makefile @@ -0,0 +1,19 @@ +# jeremy@emperorlinux.com + +NAME = pyiw +GCC = gcc -Wall +FLAGS = -I/usr/include/python2.4 -I/home/cubicool/local/include +LIBS = -liw -L/home/cubicool/local/lib + +static: pyiw.c + @echo "Statically Building/Linking $(NAME)" + @$(GCC) $(FLAGS) -Istaticlibiw $(<) -shared -o $(NAME).so staticlibiw/libiw.a + +dynamic: pyiw.c + @echo "Dynamically Building/Linking $(NAME)" + @$(GCC) $(FLAGS) $(LIBS) $(<) -shared -o $(NAME).so + +clean: + @rm -rf *.o + @rm -rf $(NAME).so + @rm -rf $(NAME).so.t* diff --git a/pyiw.c b/pyiw.c new file mode 100644 index 0000000..8a78c0f --- /dev/null +++ b/pyiw.c @@ -0,0 +1,894 @@ +/* ------------------------------------------------------------------------------------------------ +jeremy@emperorlinux.com + +This module was inspired by (and uses) the iw library that comes with the Linux Wireless Tools +package. The scanning portions of this module are moderately modified versions of those already +found in iwlist.c; however, in the future I plan to clean them up (especially the goto, wtf?) + +Please run "pydoc pyiw" for more thorough, nicely formatted information on this module. + +TODO: DO NOT USE DICTIONARY ACCESS! THIS IS RETARDED! :) + +TODO: Refine WirelessInterface_Scan(). Right now there's a goto in there that makes me feel + pretty uncomfortable. This is probably the first thing I'll work on when I have time. + +TODO: Add better (more robust) support for setting the various parameters on the interface. + The wireless world has changed a lot since I worked on this last, and there's room + for me to certainly clean things up. +------------------------------------------------------------------------------------------------ */ + +#include +#include +#include + +#define PYIW_VERSION_MAJOR 0 +#define PYIW_VERSION_MINOR 3 +#define PYIW_VERSION_BUGFIX 3 +#define PYIW_VERSION_STRING "0.3.3" + +/* --------------------------------------------------------------------------- WirelessInterface */ +typedef struct { + PyObject_HEAD + wireless_info info; + char* ifname; + int sock; +} WirelessInterface; + +typedef enum { + PYIW_KE_ESSID, + PYIW_KE_WEP, + PYIW_KE_WPA, + PYIW_KE_MODE, + PYIW_KE_CHANNEL, + PYIW_KE_FREQUENCY, + PYIW_KE_PROTOCOL, + PYIW_KE_QUALITY, + PYIW_KE_BITRATE, + PYIW_KE_AP_MAC +} WirelessInterfaceKeyEnum; + +typedef struct { + WirelessInterfaceKeyEnum keys[2]; + PyObject* objs[2]; + int num; +} WirelessInterfaceScanData; + +static char* WirelessInterfaceKeys[] = { + "essid", + "wep", + "wpa", + "mode", + "channel", + "frequency", + "protocol", + "quality", + "bitrate", + "ap_mac" +}; + +int WirelessInterfaceNumKeys(void) { + return sizeof(WirelessInterfaceKeys) / sizeof(char*); +} + +/* ------------------------------------------------------------------------ Function Definitions */ +typedef struct iw_event iwevent; +typedef struct iwreq iwreq; +typedef struct ifreq ifreq; +typedef struct timeval timeval; +typedef WirelessInterface wiface; +typedef WirelessInterfaceScanData wifacesd; + +static PyObject* pyiw_version (PyObject*, PyObject*); +static PyObject* pyiw_iw_version (PyObject*, PyObject*); +static PyObject* pyiw_we_version (PyObject*, PyObject*); + +static int WirelessInterface_init (wiface*, PyObject*, PyObject*); +static void WirelessInterface_dealloc (wiface*); +static void WirelessInterface_refresh (wiface*); +static int WirelessInterface_len (PyObject*); +static PyObject* WirelessInterface_mapget (PyObject*, PyObject*); +static int WirelessInterface_mapset (PyObject*, PyObject*, PyObject*); +static PyObject* WirelessInterface_seqitem (PyObject*, int); + +static PyObject* WirelessInterface_Scan (wiface*); +static int WirelessInterface_ScanItem (iwevent*, iwrange*, wifacesd*); + +static int Py_SetValInt (PyObject*, int*, int, int); +static int Py_SetValDouble (PyObject*, double*, double, double); +static int Py_SetValString (PyObject*, char*, int); + +static PyObject* PyIWError; + +/* ----------------------------------------------------------------------------- PYIW_DOC_STRING */ +static char* PYIW_DOC_STRING = + "PYIW defines a single class, WirelessInterface, that must be instantiated\n" + "with the name of the real wireless interface you wish to operate on. If\n" + "the interface you specify doesn't exist, or if it doesn't support wireless\n" + "extensions, object creation will fail and pyiw.error will be raised.. As an\n" + "important side note: PYIW requires at least Wireless Extensions 17. It may\n" + "work in other cases, depending on how much has changed in future versions.\n\n" + "The WirelessInterface object behaves very similarly to a dictionary and has\n" + "the following keys (note that values that can be reassigned are indicated\n" + "with the text RW); changed take effect immediately:\n\n" + "- essid (RW) [string]: The AP's ESSID.\n" + "- wep (RW) [string]: The currently used key; must be root.\n" + "- wpa [bool ]: Whether or not WPA was detected.\n" + "- mode (RW) [int ]: Auto, Ad-Hoc, Mangaged, Master,\n" + " Repeater, Secondary, Monitor\n" + "- channel (RW) [double]: US standard channels 1-12. (index 0-11)\n" + "- frequency [double]: The GHz freq level.\n" + "- protocol [string]: The name representing A, B, or G WiFi.\n" + "- quality [int ]: Signal quality, 1-100%.\n" + "- bitrate [int ]: Number of BPS; 1:1 ratio.\n" + "- ap_mac [string]: The address of the current AP.\n\n" + "--- EXAMPLE USAGE --------------------------------------\n\n" + "try:\n" + " wi = pyiw.WirelessInterface(\"wlan0\")\n\n" + "except pyiw.error, error:\n" + " print error\n" + " sys.exit(1)\n\n" + "for param in wi:\n" + " print param, \"-->\", wi[param]\n\n" + "wi[\"channel\"] = 6.0\n" + "wi[\"essid\" ] = \"Xenomorph\"\n" + "wi[\"mode\" ] = 3\n" + "wi[\"wep\" ] = \"AD0F44310CEF\"\n\n" + "nets = wi.Scan()\n\n" + "for net in nets:\n" + " print net[\"essid\"]\n" +; + +/* -------------------------------------------------------------------------------- Py_SetValInt */ +static int Py_SetValInt(PyObject* arg, int* val, int min, int max) { + if(PyInt_Check(arg)) { + int tmp = (int)(PyInt_AsLong(arg)); + + if(tmp >= min && tmp <= max) { + (*val) = tmp; + + return 0; + } + + else { + PyErr_SetString(PyExc_ValueError, "Int too big/small in SetValInt"); + + return -1; + } + } + + else { + PyErr_SetString(PyExc_TypeError, "Non-int argument passed to ArgToInt"); + + return -1; + } +} + +/* ----------------------------------------------------------------------------- Py_SetValDouble */ +static int Py_SetValDouble(PyObject* arg, double* val, double min, double max) { + if(PyFloat_Check(arg)) { + double tmp = PyFloat_AsDouble(arg); + + if(tmp >= min && tmp <= max) { + (*val) = tmp; + + return 0; + } + + else { + PyErr_SetString(PyExc_ValueError, "Double too big/small in SetValDouble"); + + return -1; + } + } + + else { + PyErr_SetString(PyExc_TypeError, "Non-double argument passed to ArgToDouble"); + + return -1; + } +} + +/* ----------------------------------------------------------------------------- Py_SetValString */ +static int Py_SetValString(PyObject* arg, char* val, int maxsize) { + if(PyString_Check(arg)) { + strncpy(val, PyString_AsString(arg), maxsize); + + return 0; + } + + else { + PyErr_SetString(PyExc_TypeError, "Non-string argument passed to ArgToString"); + + return -1; + } +} + +/* ---------------------------------------------------------------------- WirelessInterface_init */ +static int WirelessInterface_init(wiface* self, PyObject* args, PyObject* kargs) { + const char* ifname; + const size_t ifnamesize; + + memset(&(self->info), 0, sizeof(wireless_info)); + + self->ifname = NULL; + self->sock = 0; + + if(PyArg_ParseTuple(args, "s#", &ifname, &ifnamesize)) { + self->sock = iw_sockets_open(); + + if(self->sock != -1) { + ifreq frq; + + self->ifname = malloc(ifnamesize + 1); + + strncpy(self->ifname, ifname, ifnamesize + 1); + strncpy(frq.ifr_name, self->ifname, IFNAMSIZ); + + if(!ioctl(self->sock, SIOCGIFFLAGS, &frq)) { + frq.ifr_flags |= IFF_UP | IFF_RUNNING; + + ioctl(self->sock, SIOCSIFFLAGS, &frq); + + WirelessInterface_refresh(self); + + return 0; + } + + else PyErr_SetString(PyIWError, "Failed to find device"); + } + + else PyErr_SetString(PyIWError, "Failed to connect to libiw"); + } + + return -1; +} + +/* ------------------------------------------------------------------- WirelessInterface_dealloc */ +static void WirelessInterface_dealloc(wiface* self) { + if(self->ifname) free(self->ifname); + + iw_sockets_close(self->sock); + self->ob_type->tp_free((PyObject*)(self)); +} + +/* ------------------------------------------------------------------- WirelessInterface_refresh */ +static void WirelessInterface_refresh(wiface* self) { + iwreq wrq; + + iw_get_basic_config(self->sock, self->ifname, &(self->info.b)); + iw_get_range_info(self->sock, self->ifname, &(self->info.range)); + + iw_get_ext(self->sock, self->ifname, SIOCGIWRATE, &wrq); + memcpy(&(self->info.bitrate), &wrq.u.bitrate, sizeof(iwparam)); + + iw_get_ext(self->sock, self->ifname, SIOCGIWAP, &wrq); + memcpy(&(self->info.ap_addr), &wrq.u.ap_addr, sizeof (sockaddr)); + + iw_get_stats( + self->sock, self->ifname, &(self->info.stats), + &(self->info.range), self->info.has_range + ); +} + +/* ----------------------------------------------------------------------- WirelessInterface_len */ +static int WirelessInterface_len(PyObject* self) { + return WirelessInterfaceNumKeys(); +} + +/* -------------------------------------------------------------------- WirelessInterface_mapget */ +static PyObject* WirelessInterface_mapget(PyObject* self, PyObject* arg) { + if(PyString_Check(arg)) { + wiface* wi = (wiface*)(self); + char* key = PyString_AsString(arg); + + static char buf[128]; + + WirelessInterface_refresh(wi); + + /* ESSID */ + if(!strncmp(key, "essid", 5)) return Py_BuildValue( + "s", wi->info.b.essid + ); + + /* WEP */ + else if(!strncmp(key, "wep", 3)) { + iw_print_key( + buf, + sizeof(buf) / sizeof(char), + wi->info.b.key, + wi->info.b.key_size, + wi->info.b.key_flags + ); + + if(!strncmp(buf, "00", 2)) return Py_BuildValue("s", "MUST_BE_ROOT"); + else return Py_BuildValue("s", buf); + } + + /* WPA */ + else if(!strncmp(key, "wpa", 3)) return Py_BuildValue( + "s", "Unsupported in pyiw version " PYIW_VERSION_STRING + ); + + /* PROTOCOL */ + else if(!strncmp(key, "protocol", 8)) return Py_BuildValue( + "s", wi->info.b.name + ); + + /* FREQUENCY */ + else if(!strncmp(key, "frequency", 9)) { + double freq = wi->info.b.freq; + + if(freq <= 14.0) iw_channel_to_freq((int)(freq), &freq, &(wi->info.range)); + + return Py_BuildValue("d", freq); + } + + /* CHANNEL */ + else if(!strncmp(key, "channel", 7)) { + double freq = wi->info.b.freq; + + if(freq >= 14.0) { + freq = (double)(iw_freq_to_channel(freq, &(wi->info.range))); + } + + return Py_BuildValue("d", freq); + } + + /* MODE */ + else if(!strncmp(key, "mode", 7)) return Py_BuildValue( + "s", iw_operation_mode[wi->info.b.mode] + ); + + /* BITRATE */ + else if(!strncmp(key, "bitrate", 7)) return Py_BuildValue( + "i", wi->info.bitrate.value + ); + + /* QUALITY */ + else if(!strncmp(key, "quality", 7)) return Py_BuildValue( + "i", wi->info.stats.qual.qual + ); + + /* AP_MAC */ + else if(!strncmp(key, "ap_mac", 6)) { + /* iw_pr_ether(buf, wi->info.ap_addr.sa_data); */ + /* iw_ether_ntop((const struct ether_addr *) addr, bufp); */ + iw_ether_ntop( + (const struct ether_addr*)(wi->info.ap_addr.sa_data), + buf + ); + + return Py_BuildValue("s", buf); + } + + else { + PyErr_SetString(PyExc_ValueError, "Bad key in WirelessInterface_mapget"); + return NULL; + } + } + + else { + PyErr_SetString(PyExc_TypeError, "Bad key type in WirelessInterface_mapget"); + return NULL; + } +} +/* -------------------------------------------------------------------- WirelessInterface_mapset */ +static int WirelessInterface_mapset(PyObject* self, PyObject* arg, PyObject* val) { + if(PyString_Check(arg)) { + wiface* wi = (wiface*)(self); + char* key = PyString_AsString(arg); + int ret = 0; + struct iwreq wreq; + + memset(&wreq, 0, sizeof(struct iwreq)); + + /* ESSID */ + if(!strncmp(key, "essid", 5)) { + if(!Py_SetValString(val, wi->info.b.essid, sizeof(wi->info.b.essid))) { + wreq.u.essid.flags = 1; + wreq.u.essid.pointer = wi->info.b.essid; + wreq.u.essid.length = strlen(wi->info.b.essid) + 1; + + #ifdef _PYIW_DEBUG_ + printf("PYIW DEBUG: iw_set_ext (ESSID) with %s\n", wi->info.b.essid); + #endif + + ret = iw_set_ext(wi->sock, wi->ifname, SIOCSIWESSID, &wreq); + + #ifdef _PYIW_DEBUG_ + printf("PYIW DEBUG: iw_set_ext (ESSID) returned %d\n", ret); + #endif + + return 0; + } + + else return -1; + } + + /* WEP */ + else if(!strncmp(key, "wep", 3)) { + if(PyString_Check(arg)) { + int len; + + memset(wi->info.b.key, 0, IW_ENCODING_TOKEN_MAX); + + len = iw_in_key( + PyString_AsString(val), wi->info.b.key + ); + + wreq.u.data.length = len; + wreq.u.data.pointer = wi->info.b.key; + + ret = iw_set_ext(wi->sock, wi->ifname, SIOCSIWENCODE, &wreq); + + wi->info.b.has_key = 1; + wi->info.b.key_size = len; + + #ifdef _PYIW_DEBUG_ + printf("PYIW DEBUG: iw_in_key returned: %d\n", len); + printf("PYIW DEBUG: iw_set_ext (ENCODE) returned: %d\n", ret); + #endif + + return 0; + } + + else { + PyErr_SetString(PyExc_TypeError, "Key must be a string"); + return -1; + } + } + + /* CHANNEL */ + else if(!strncmp(key, "channel", 7)) { + if(!Py_SetValDouble(val, &(wi->info.b.freq), 1.0, 12.0)) { + iw_float2freq(wi->info.b.freq, &(wreq.u.freq)); + + if(iw_set_ext(wi->sock, wi->ifname, SIOCSIWFREQ, &wreq)) return -1; + + else return 0; + } + + else return -1; + } + + /* MODE */ + else if(!strncmp(key, "mode", 4)) return Py_SetValInt( + val, &(wi->info.b.mode), 0, 6 + ); + + else { + PyErr_SetString(PyExc_ValueError, "Bad key in WirelessInterface_mapset"); + return -1; + } + } + + else { + PyErr_SetString(PyExc_TypeError, "Bad key type in WirelessInterface_mapset"); + return -1; + } +} + +/* ------------------------------------------------------------------- WirelessInterface_seqitem */ +static PyObject* WirelessInterface_seqitem(PyObject* self, int index) { + if(index >= 0 && index < WirelessInterfaceNumKeys()) return Py_BuildValue( + "s", WirelessInterfaceKeys[index] + ); + + else return NULL; +} + +/* ---------------------------------------------------------------------- WirelessInterface_Scan */ +static PyObject* WirelessInterface_Scan(wiface* self) { + iwreq wrq; + unsigned char* buffer = NULL; + int buflen = IW_SCAN_MAX_DATA; + iwrange range; + int has_range; + timeval tv; + int timeout = 10000000; + PyObject* scan_list = NULL; + + has_range = (iw_get_range_info(self->sock, self->ifname, &range) >= 0); + + tv.tv_sec = 0; + tv.tv_usec = 250000; + wrq.u.data.pointer = NULL; + wrq.u.data.flags = 0; + wrq.u.data.length = 0; + + if(iw_set_ext(self->sock, self->ifname, SIOCSIWSCAN, &wrq) < 0) { + if(errno != EPERM) { + PyErr_SetString(PyIWError, "Interface doesn't support scanning"); + + return NULL; + } + + tv.tv_usec = 0; + } + + timeout -= tv.tv_usec; + + while(1) { + fd_set rfds; + int last_fd; + int ret; + + FD_ZERO(&rfds); + last_fd = -1; + + ret = select(last_fd + 1, &rfds, NULL, NULL, &tv); + + if(ret < 0) { + if(errno == EAGAIN || errno == EINTR) continue; + + else { + PyErr_SetString(PyIWError, "Unknown scanning error"); + + return NULL; + } + } + + if(!ret) { + unsigned char* newbuf; + + realloc: + newbuf = realloc(buffer, buflen); + + if(!newbuf) { + if(buffer) free(buffer); + + PyErr_SetString(PyIWError, "Memory allocation failure in scan"); + + return NULL; + } + + buffer = newbuf; + + wrq.u.data.pointer = buffer; + wrq.u.data.flags = 0; + wrq.u.data.length = buflen; + + if(iw_get_ext(self->sock, self->ifname, SIOCGIWSCAN, &wrq) < 0) { + if((errno == E2BIG)) { + if(wrq.u.data.length > buflen) buflen = wrq.u.data.length; + else buflen *= 2; + + goto realloc; + } + + if(errno == EAGAIN) { + tv.tv_sec = 0; + tv.tv_usec = 100000; + timeout -= tv.tv_usec; + + if(timeout > 0) continue; + } + + free(buffer); + + PyErr_SetString(PyIWError, "Unable to read scan data"); + + return NULL; + } + + else break; + } + } + + if(wrq.u.data.length) { + iwevent iwe; + stream_descr stream; + int ret; + PyObject* scan_dict = NULL; + + scan_list = PyList_New(0); + + iw_init_event_stream(&stream, (char*)(buffer), wrq.u.data.length); + + do { + ret = iw_extract_event_stream(&stream, &iwe, range.we_version_compiled); + + if(ret > 0) { + wifacesd sd; + int sr = WirelessInterface_ScanItem(&iwe, &range, &sd); + + if(sr) { + int i; + + if(scan_dict) { + PyList_Append(scan_list, scan_dict); + Py_DECREF(scan_dict); + } + + scan_dict = PyDict_New(); + + for(i = 0; i < WirelessInterfaceNumKeys(); i++) { + PyMapping_SetItemString( + scan_dict, + WirelessInterfaceKeys[i], + Py_BuildValue("") + ); + } + } + + if(sd.num) { + int i; + + for(i = 0; i < sd.num; i++) { + PyMapping_SetItemString( + scan_dict, + WirelessInterfaceKeys[sd.keys[i]], + sd.objs[i] + ); + + Py_DECREF(sd.objs[i]); + } + } + } + } + + while(ret > 0); + + PyList_Append(scan_list, scan_dict); + Py_XDECREF(scan_dict); + } + + else return Py_BuildValue("[]"); + + free(buffer); + + return scan_list; +} + +/* ------------------------------------------------------------------ WirelessInterface_ScanItem */ +static int WirelessInterface_ScanItem(iwevent* event, iwrange* range, wifacesd* data) { + static char buf[128]; + + memset(data, 0, sizeof(wifacesd)); + + switch(event->cmd) { + case SIOCGIWAP: { + iw_ether_ntop( + (const struct ether_addr*)(event->u.ap_addr.sa_data), + buf + ); + + data->keys[0] = PYIW_KE_AP_MAC; + data->objs[0] = Py_BuildValue("s", buf); + data->num = 1; + + return 1; + } + + case SIOCGIWFREQ: { + double freq = iw_freq2float(&(event->u.freq)); + int channel; + + if(freq <= 14.0) channel = iw_channel_to_freq((int)(freq), &freq, range); + else channel = iw_freq_to_channel(freq, range); + + data->keys[0] = PYIW_KE_FREQUENCY; + data->keys[1] = PYIW_KE_CHANNEL; + data->objs[0] = Py_BuildValue("d", freq); + data->objs[1] = Py_BuildValue("i", channel); + data->num = 2; + + return 0; + } + + case SIOCGIWMODE: { + data->keys[0] = PYIW_KE_MODE; + data->objs[0] = Py_BuildValue("s", iw_operation_mode[event->u.mode]); + data->num = 1; + + return 0; + } + + case SIOCGIWNAME: { + data->keys[0] = PYIW_KE_PROTOCOL; + data->objs[0] = Py_BuildValue("s", event->u.name); + data->num = 1; + + return 0; + } + + case SIOCGIWESSID: { + memcpy(buf, event->u.essid.pointer, event->u.essid.length); + buf[event->u.essid.length] = 0x0; + + data->keys[0] = PYIW_KE_ESSID; + data->objs[0] = Py_BuildValue("s", buf); + data->num = 1; + + return 0; + } + + case SIOCGIWENCODE: { + PyObject* pybool; + + if(event->u.data.flags & IW_ENCODE_DISABLED) pybool = Py_False; + else pybool = Py_True; + + Py_INCREF(pybool); + + data->keys[0] = PYIW_KE_WEP; + data->objs[0] = pybool; + data->num = 1; + + return 0; + } + + case SIOCGIWRATE: { + data->keys[0] = PYIW_KE_BITRATE; + data->objs[0] = Py_BuildValue("i", event->u.bitrate.value); + data->num = 1; + + return 0; + } + + case IWEVQUAL: { + data->keys[0] = PYIW_KE_QUALITY; + data->objs[0] = Py_BuildValue("i", event->u.qual.qual); + data->num = 1; + + return 0; + } + + case IWEVGENIE: { + PyObject* pytrue = Py_True; + Py_INCREF(pytrue); + + data->keys[0] = PYIW_KE_WPA; + data->objs[0] = pytrue; + data->num = 1; + + return 0; + } + + case IWEVCUSTOM: { + memcpy(buf, event->u.data.pointer, event->u.data.length); + buf[event->u.data.length] = 0x0; + + if(strstr(buf, "wpa_ie")) { + PyObject* pytrue = Py_True; + Py_INCREF(pytrue); + + data->keys[0] = PYIW_KE_WPA; + data->objs[0] = pytrue; + data->num = 1; + } + + memset(buf, 0, sizeof(buf)); + } + + default: return 0; + } +} + +/* -------------------------------------------------------------------- Member/Method Structures */ +static PyMethodDef module_methods[] = { + { + "version", pyiw_version, METH_NOARGS, + "Returns the current PyIW version." + }, + { + "iw_version", pyiw_iw_version, METH_NOARGS, + "Returns the current Wireless Extnesions (libiw WE) version." + }, + { + "we_version", pyiw_we_version, METH_NOARGS, + "Returns the current Wireless Extensions (kernel-level WE) version." + }, + { NULL, NULL, 0, NULL } +}; + +static PyMethodDef WirelessInterface_methods[] = { + { + "Scan", (PyCFunction)(WirelessInterface_Scan), METH_NOARGS, + "This function will attempt to scan any local AP's and return a tuple\n" + "of objectes representing the data contained therein." + }, + { NULL, NULL, 0, NULL } +}; + +static PyMappingMethods WirelessInterface_mapping_methods = { + WirelessInterface_len, /* length */ + WirelessInterface_mapget, /* getitem */ + WirelessInterface_mapset /* setitem */ +}; + +static PySequenceMethods WirelessInterface_sequence_methods = { + WirelessInterface_len, /* sq_length */ + 0, /* sq_concat */ + 0, /* sq_repeat */ + WirelessInterface_seqitem, /* sq_item */ + 0, /* sq_slice */ + 0, /* sq_ass_item */ + 0, /* sq_ass_slice */ + 0, /* sq_contains */ + 0, /* sq_inplace_concat */ + 0 /* sq_inplace_repeat */ +}; + +/* -------------------------------------------------------------------- PyType_WirelessInterface */ +static PyTypeObject PyType_WirelessInterface = { + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ + "pyiw.WirelessInterface", /* tp_name */ + sizeof(WirelessInterface), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)(WirelessInterface_dealloc), /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + &WirelessInterface_sequence_methods, /* tp_as_sequence */ + &WirelessInterface_mapping_methods, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + WirelessInterface_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)(WirelessInterface_init), /* tp_init */ + 0, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ + 0, /* tp_mro */ + 0, /* tp_cache */ + 0, /* tp_subclasses */ + 0, /* tp_weaklist */ + 0 /* tp_del */ +}; + +/* ------------------------------------------------------------------------------------ initpyiw */ +PyMODINIT_FUNC initpyiw(void) { + PyObject* module; + + PyType_Ready(&PyType_WirelessInterface); + + module = Py_InitModule3("pyiw", module_methods, PYIW_DOC_STRING); + PyIWError = PyErr_NewException("pyiw.error", NULL, NULL); + + Py_INCREF(&PyType_WirelessInterface); + Py_INCREF(PyIWError); + + PyModule_AddObject(module, "WirelessInterface", (PyObject*)(&PyType_WirelessInterface)); + PyModule_AddObject(module, "error", PyIWError); +} + +static PyObject* pyiw_version(PyObject* u1, PyObject* u2) { + return Py_BuildValue("(iii)", + PYIW_VERSION_MAJOR, + PYIW_VERSION_MINOR, + PYIW_VERSION_BUGFIX + ); +} + +static PyObject* pyiw_iw_version(PyObject* u1, PyObject* u2) { + return Py_BuildValue("i", WE_VERSION); +} + +static PyObject* pyiw_we_version(PyObject* u1, PyObject* u2) { + return Py_BuildValue("i", iw_get_kernel_we_version()); +} diff --git a/staticlibiw/iwlib.h b/staticlibiw/iwlib.h new file mode 100644 index 0000000..c67ec82 --- /dev/null +++ b/staticlibiw/iwlib.h @@ -0,0 +1,596 @@ +/* + * Wireless Tools + * + * Jean II - HPLB 97->99 - HPL 99->04 + * + * Common header for the Wireless Extension library... + * + * This file is released under the GPL license. + * Copyright (c) 1997-2004 Jean Tourrilhes + */ + +#ifndef IWLIB_H +#define IWLIB_H + +/*#include "CHANGELOG.h"*/ + +/***************************** INCLUDES *****************************/ + +/* Standard headers */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* gethostbyname, getnetbyname */ +#include /* struct ether_addr */ +#include /* struct timeval */ +#include + +/* This is our header selection. Try to hide the mess and the misery :-( + * Don't look, you would go blind ;-) */ + +#ifndef LINUX_VERSION_CODE +#include +#endif + +/* Kernel headers 2.4.X + Glibc 2.2 - Mandrake 8.0, Debian 2.3, RH 7.1 + * Kernel headers 2.2.X + Glibc 2.2 - Slackware 8.0 */ +#if defined(__GLIBC__) \ + && __GLIBC__ == 2 \ + && __GLIBC_MINOR__ >= 2 \ + && LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) +#define HEADERS_GENERIC + +/* Kernel headers 2.4.X + Glibc 2.1 - Debian 2.2 upgraded, RH 7.0 + * Kernel headers 2.2.X + Glibc 2.1 - Debian 2.2, RH 6.1 */ +#elif defined(__GLIBC__) \ + && __GLIBC__ == 2 \ + && __GLIBC_MINOR__ == 1 \ + && LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) +#define HEADERS_GENERIC +#define HEADERS_KERNEL + +/* Unsupported combination */ +#else +#error "Your kernel/libc combination is not supported" +#endif + +#ifdef HEADERS_GENERIC +/* Proposed by Dr. Michael Rietz , 27.3.2 */ +#include /* For ARPHRD_ETHER */ +#include /* For AF_INET & struct sockaddr */ +#include /* For struct sockaddr_in */ +#include +#endif /* HEADERS_GENERIC */ + +/* Fixup to be able to include kernel includes in userspace. + * Basically, kill the sparse annotations... Jean II */ +#ifndef __user +#define __user +#endif + +#include /* for "caddr_t" et al */ + +#ifdef HEADERS_KERNEL +/* Traditionally we have used kernel headers, included in wireless.h */ +#include /* for "struct sockaddr" et al */ +#include /* for IFNAMSIZ and co... */ +#else /* !HEADERS_KERNEL */ +/* Glibc systems headers are supposedly less problematic than kernel ones */ +#include /* for "struct sockaddr" et al */ +#include /* for IFNAMSIZ and co... */ +#endif /* !HEADERS_KERNEL */ + +/* Private copy of Wireless extensions (in this directoty) */ +#include "wireless.h" + +/* Make gcc understant that when we say inline, we mean it. + * I really hate when the compiler is trying to be more clever than me, + * because in this case gcc is not able to figure out functions with a + * single call site, so not only I have to tag those functions inline + * by hand, but then it refuse to inline them properly. + * Total saving for iwevent : 150B = 0.7%. + * Fortunately, in gcc 3.4, they now automatically inline static functions + * with a single call site. Hurrah ! + * Jean II */ +#undef IW_GCC_HAS_BROKEN_INLINE +#if __GNUC__ == 3 +#if __GNUC_MINOR__ >= 1 && __GNUC_MINOR__ < 4 +#define IW_GCC_HAS_BROKEN_INLINE 1 +#endif /* __GNUC_MINOR__ */ +#endif /* __GNUC__ */ +/* However, gcc 4.0 has introduce a new "feature", when compiling with + * '-Os', it does not want to inline iw_ether_cmp() and friends. + * So, we need to fix inline again ! + * Jean II */ +#if __GNUC__ == 4 +#define IW_GCC_HAS_BROKEN_INLINE 1 +#endif /* __GNUC__ */ +/* Now, really fix the inline */ +#ifdef IW_GCC_HAS_BROKEN_INLINE +#ifdef inline +#undef inline +#endif /* inline */ +#define inline inline __attribute__((always_inline)) +#endif /* IW_GCC_HAS_BROKEN_INLINE */ + +#ifdef __cplusplus +extern "C" { +#endif + +/****************************** DEBUG ******************************/ + + +/************************ CONSTANTS & MACROS ************************/ + +/* Various versions information */ +/* Recommended Wireless Extension version */ +#define WE_VERSION 21 +/* Maximum forward compatibility built in this version of WT */ +#define WE_MAX_VERSION 21 +/* Version of Wireless Tools */ +#define WT_VERSION 29 + +/* Paths */ +#define PROC_NET_WIRELESS "/proc/net/wireless" +#define PROC_NET_DEV "/proc/net/dev" + +/* Some usefull constants */ +#define KILO 1e3 +#define MEGA 1e6 +#define GIGA 1e9 +/* For doing log10/exp10 without libm */ +#define LOG10_MAGIC 1.25892541179 + +/* Backward compatibility for network headers */ +#ifndef ARPHRD_IEEE80211 +#define ARPHRD_IEEE80211 801 /* IEEE 802.11 */ +#endif /* ARPHRD_IEEE80211 */ + +/****************************** TYPES ******************************/ + +/* Shortcuts */ +typedef struct iw_statistics iwstats; +typedef struct iw_range iwrange; +typedef struct iw_param iwparam; +typedef struct iw_freq iwfreq; +typedef struct iw_quality iwqual; +typedef struct iw_priv_args iwprivargs; +typedef struct sockaddr sockaddr; + +/* Structure for storing all wireless information for each device + * This is a cut down version of the one above, containing only + * the things *truly* needed to configure a card. + * Don't add other junk, I'll remove it... */ +typedef struct wireless_config +{ + char name[IFNAMSIZ + 1]; /* Wireless/protocol name */ + int has_nwid; + iwparam nwid; /* Network ID */ + int has_freq; + double freq; /* Frequency/channel */ + int freq_flags; + int has_key; + unsigned char key[IW_ENCODING_TOKEN_MAX]; /* Encoding key used */ + int key_size; /* Number of bytes */ + int key_flags; /* Various flags */ + int has_essid; + int essid_on; + char essid[IW_ESSID_MAX_SIZE + 1]; /* ESSID (extended network) */ + int has_mode; + int mode; /* Operation mode */ +} wireless_config; + +/* Structure for storing all wireless information for each device + * This is pretty exhaustive... */ +typedef struct wireless_info +{ + struct wireless_config b; /* Basic information */ + + int has_sens; + iwparam sens; /* sensitivity */ + int has_nickname; + char nickname[IW_ESSID_MAX_SIZE + 1]; /* NickName */ + int has_ap_addr; + sockaddr ap_addr; /* Access point address */ + int has_bitrate; + iwparam bitrate; /* Bit rate in bps */ + int has_rts; + iwparam rts; /* RTS threshold in bytes */ + int has_frag; + iwparam frag; /* Fragmentation threshold in bytes */ + int has_power; + iwparam power; /* Power management parameters */ + int has_txpower; + iwparam txpower; /* Transmit Power in dBm */ + int has_retry; + iwparam retry; /* Retry limit or lifetime */ + + /* Stats */ + iwstats stats; + int has_stats; + iwrange range; + int has_range; + + /* Auth params for WPA/802.1x/802.11i */ + int auth_key_mgmt; + int has_auth_key_mgmt; + int auth_cipher_pairwise; + int has_auth_cipher_pairwise; + int auth_cipher_group; + int has_auth_cipher_group; +} wireless_info; + +/* Structure for storing an entry of a wireless scan. + * This is only a subset of all possible information, the flexible + * structure of scan results make it impossible to capture all + * information in such a static structure. */ +typedef struct wireless_scan +{ + /* Linked list */ + struct wireless_scan * next; + + /* Cell identifiaction */ + int has_ap_addr; + sockaddr ap_addr; /* Access point address */ + + /* Other information */ + struct wireless_config b; /* Basic information */ + iwstats stats; /* Signal strength */ + int has_stats; +} wireless_scan; + +/* + * Context used for non-blocking scan. + */ +typedef struct wireless_scan_head +{ + wireless_scan * result; /* Result of the scan */ + int retry; /* Retry level */ +} wireless_scan_head; + +/* Structure used for parsing event streams, such as Wireless Events + * and scan results */ +typedef struct stream_descr +{ + char * end; /* End of the stream */ + char * current; /* Current event in stream of events */ + char * value; /* Current value in event */ +} stream_descr; + +/* Prototype for handling display of each single interface on the + * system - see iw_enum_devices() */ +typedef int (*iw_enum_handler)(int skfd, + char * ifname, + char * args[], + int count); + +/* Describe a modulation */ +typedef struct iw_modul_descr +{ + unsigned int mask; /* Modulation bitmask */ + char cmd[8]; /* Short name */ + char * verbose; /* Verbose description */ +} iw_modul_descr; + +/**************************** PROTOTYPES ****************************/ +/* + * All the functions in iwcommon.c + */ + +/* ---------------------- SOCKET SUBROUTINES -----------------------*/ +int + iw_sockets_open(void); +void + iw_enum_devices(int skfd, + iw_enum_handler fn, + char * args[], + int count); +/* --------------------- WIRELESS SUBROUTINES ----------------------*/ +int + iw_get_kernel_we_version(void); +int + iw_print_version_info(const char * toolname); +int + iw_get_range_info(int skfd, + const char * ifname, + iwrange * range); +int + iw_get_priv_info(int skfd, + const char * ifname, + iwprivargs ** ppriv); +int + iw_get_basic_config(int skfd, + const char * ifname, + wireless_config * info); +int + iw_set_basic_config(int skfd, + const char * ifname, + wireless_config * info); +/* --------------------- PROTOCOL SUBROUTINES --------------------- */ +int + iw_protocol_compare(const char * protocol1, + const char * protocol2); +/* -------------------- FREQUENCY SUBROUTINES --------------------- */ +void + iw_float2freq(double in, + iwfreq * out); +double + iw_freq2float(const iwfreq * in); +void + iw_print_freq_value(char * buffer, + int buflen, + double freq); +void + iw_print_freq(char * buffer, + int buflen, + double freq, + int channel, + int freq_flags); +int + iw_freq_to_channel(double freq, + const struct iw_range * range); +int + iw_channel_to_freq(int channel, + double * pfreq, + const struct iw_range * range); +void + iw_print_bitrate(char * buffer, + int buflen, + int bitrate); +/* ---------------------- POWER SUBROUTINES ----------------------- */ +int + iw_dbm2mwatt(int in); +int + iw_mwatt2dbm(int in); +void + iw_print_txpower(char * buffer, + int buflen, + struct iw_param * txpower); +/* -------------------- STATISTICS SUBROUTINES -------------------- */ +int + iw_get_stats(int skfd, + const char * ifname, + iwstats * stats, + const iwrange * range, + int has_range); +void + iw_print_stats(char * buffer, + int buflen, + const iwqual * qual, + const iwrange * range, + int has_range); +/* --------------------- ENCODING SUBROUTINES --------------------- */ +void + iw_print_key(char * buffer, + int buflen, + const unsigned char * key, + int key_size, + int key_flags); +int + iw_in_key(const char * input, + unsigned char * key); +int + iw_in_key_full(int skfd, + const char * ifname, + const char * input, + unsigned char * key, + __u16 * flags); +/* ----------------- POWER MANAGEMENT SUBROUTINES ----------------- */ +void + iw_print_pm_value(char * buffer, + int buflen, + int value, + int flags, + int we_version); +void + iw_print_pm_mode(char * buffer, + int buflen, + int flags); +/* --------------- RETRY LIMIT/LIFETIME SUBROUTINES --------------- */ +void + iw_print_retry_value(char * buffer, + int buflen, + int value, + int flags, + int we_version); +/* ----------------------- TIME SUBROUTINES ----------------------- */ +void + iw_print_timeval(char * buffer, + int buflen, + const struct timeval * time, + const struct timezone * tz); +/* --------------------- ADDRESS SUBROUTINES ---------------------- */ +int + iw_check_mac_addr_type(int skfd, + const char * ifname); +int + iw_check_if_addr_type(int skfd, + const char * ifname); +#if 0 +int + iw_check_addr_type(int skfd, + const char * ifname); +#endif +#if 0 +int + iw_get_mac_addr(int skfd, + const char * name, + struct ether_addr * eth, + unsigned short * ptype); +#endif +char * + iw_mac_ntop(const unsigned char * mac, + int maclen, + char * buf, + int buflen); +void + iw_ether_ntop(const struct ether_addr * eth, + char * buf); +char * + iw_sawap_ntop(const struct sockaddr * sap, + char * buf); +int + iw_mac_aton(const char * orig, + unsigned char * mac, + int macmax); +int + iw_ether_aton(const char* bufp, struct ether_addr* eth); +int + iw_in_inet(char *bufp, struct sockaddr *sap); +int + iw_in_addr(int skfd, + const char * ifname, + char * bufp, + struct sockaddr * sap); +/* ----------------------- MISC SUBROUTINES ------------------------ */ +int + iw_get_priv_size(int args); + +/* ---------------------- EVENT SUBROUTINES ---------------------- */ +void + iw_init_event_stream(struct stream_descr * stream, + char * data, + int len); +int + iw_extract_event_stream(struct stream_descr * stream, + struct iw_event * iwe, + int we_version); +/* --------------------- SCANNING SUBROUTINES --------------------- */ +int + iw_process_scan(int skfd, + char * ifname, + int we_version, + wireless_scan_head * context); +int + iw_scan(int skfd, + char * ifname, + int we_version, + wireless_scan_head * context); + +/**************************** VARIABLES ****************************/ + +/* Modes as human readable strings */ +extern const char * const iw_operation_mode[]; +#define IW_NUM_OPER_MODE 7 + +/* Modulations as human readable strings */ +extern const struct iw_modul_descr iw_modul_list[]; +#define IW_SIZE_MODUL_LIST 16 + +/************************* INLINE FUNTIONS *************************/ +/* + * Functions that are so simple that it's more efficient inlining them + */ + +/* + * Note : I've defined wrapper for the ioctl request so that + * it will be easier to migrate to other kernel API if needed + */ + +/*------------------------------------------------------------------*/ +/* + * Wrapper to push some Wireless Parameter in the driver + */ +static inline int +iw_set_ext(int skfd, /* Socket to the kernel */ + const char * ifname, /* Device name */ + int request, /* WE ID */ + struct iwreq * pwrq) /* Fixed part of the request */ +{ + /* Set device name */ + strncpy(pwrq->ifr_name, ifname, IFNAMSIZ); + /* Do the request */ + return(ioctl(skfd, request, pwrq)); +} + +/*------------------------------------------------------------------*/ +/* + * Wrapper to extract some Wireless Parameter out of the driver + */ +static inline int +iw_get_ext(int skfd, /* Socket to the kernel */ + const char * ifname, /* Device name */ + int request, /* WE ID */ + struct iwreq * pwrq) /* Fixed part of the request */ +{ + /* Set device name */ + strncpy(pwrq->ifr_name, ifname, IFNAMSIZ); + /* Do the request */ + return(ioctl(skfd, request, pwrq)); +} + +/*------------------------------------------------------------------*/ +/* + * Close the socket used for ioctl. + */ +static inline void +iw_sockets_close(int skfd) +{ + close(skfd); +} + +/*------------------------------------------------------------------*/ +/* + * Display an Ethernet Socket Address in readable format. + */ +static inline char * +iw_saether_ntop(const struct sockaddr *sap, char* bufp) +{ + iw_ether_ntop((const struct ether_addr *) sap->sa_data, bufp); + return bufp; +} +/*------------------------------------------------------------------*/ +/* + * Input an Ethernet Socket Address and convert to binary. + */ +static inline int +iw_saether_aton(const char *bufp, struct sockaddr *sap) +{ + sap->sa_family = ARPHRD_ETHER; + return iw_ether_aton(bufp, (struct ether_addr *) sap->sa_data); +} + +/*------------------------------------------------------------------*/ +/* + * Create an Ethernet broadcast address + */ +static inline void +iw_broad_ether(struct sockaddr *sap) +{ + sap->sa_family = ARPHRD_ETHER; + memset((char *) sap->sa_data, 0xFF, ETH_ALEN); +} + +/*------------------------------------------------------------------*/ +/* + * Create an Ethernet NULL address + */ +static inline void +iw_null_ether(struct sockaddr *sap) +{ + sap->sa_family = ARPHRD_ETHER; + memset((char *) sap->sa_data, 0x00, ETH_ALEN); +} + +/*------------------------------------------------------------------*/ +/* + * Compare two ethernet addresses + */ +static inline int +iw_ether_cmp(const struct ether_addr* eth1, const struct ether_addr* eth2) +{ + return memcmp(eth1, eth2, sizeof(*eth1)); +} + +#ifdef __cplusplus +} +#endif + +#endif /* IWLIB_H */ diff --git a/staticlibiw/libiw.a b/staticlibiw/libiw.a new file mode 100644 index 0000000..5223c17 Binary files /dev/null and b/staticlibiw/libiw.a differ diff --git a/staticlibiw/wireless.h b/staticlibiw/wireless.h new file mode 100644 index 0000000..5c16fb1 --- /dev/null +++ b/staticlibiw/wireless.h @@ -0,0 +1,1119 @@ +/* + * This file define a set of standard wireless extensions + * + * Version : 21 14.3.06 + * + * Authors : Jean Tourrilhes - HPL - + * Copyright (c) 1997-2005 Jean Tourrilhes, All Rights Reserved. + */ + +#ifndef _LINUX_WIRELESS_H +#define _LINUX_WIRELESS_H + +/************************** DOCUMENTATION **************************/ +/* + * Initial APIs (1996 -> onward) : + * ----------------------------- + * Basically, the wireless extensions are for now a set of standard ioctl + * call + /proc/net/wireless + * + * The entry /proc/net/wireless give statistics and information on the + * driver. + * This is better than having each driver having its entry because + * its centralised and we may remove the driver module safely. + * + * Ioctl are used to configure the driver and issue commands. This is + * better than command line options of insmod because we may want to + * change dynamically (while the driver is running) some parameters. + * + * The ioctl mechanimsm are copied from standard devices ioctl. + * We have the list of command plus a structure descibing the + * data exchanged... + * Note that to add these ioctl, I was obliged to modify : + * # net/core/dev.c (two place + add include) + * # net/ipv4/af_inet.c (one place + add include) + * + * /proc/net/wireless is a copy of /proc/net/dev. + * We have a structure for data passed from the driver to /proc/net/wireless + * Too add this, I've modified : + * # net/core/dev.c (two other places) + * # include/linux/netdevice.h (one place) + * # include/linux/proc_fs.h (one place) + * + * New driver API (2002 -> onward) : + * ------------------------------- + * This file is only concerned with the user space API and common definitions. + * The new driver API is defined and documented in : + * # include/net/iw_handler.h + * + * Note as well that /proc/net/wireless implementation has now moved in : + * # net/core/wireless.c + * + * Wireless Events (2002 -> onward) : + * -------------------------------- + * Events are defined at the end of this file, and implemented in : + * # net/core/wireless.c + * + * Other comments : + * -------------- + * Do not add here things that are redundant with other mechanisms + * (drivers init, ifconfig, /proc/net/dev, ...) and with are not + * wireless specific. + * + * These wireless extensions are not magic : each driver has to provide + * support for them... + * + * IMPORTANT NOTE : As everything in the kernel, this is very much a + * work in progress. Contact me if you have ideas of improvements... + */ + +/***************************** INCLUDES *****************************/ + +/* This header is used in user-space, therefore need to be sanitised + * for that purpose. Those includes are usually not compatible with glibc. + * To know which includes to use in user-space, check iwlib.h. */ +#ifdef __KERNEL__ +#include /* for "caddr_t" et al */ +#include /* for "struct sockaddr" et al */ +#include /* for IFNAMSIZ and co... */ +#endif /* __KERNEL__ */ + +/***************************** VERSION *****************************/ +/* + * This constant is used to know the availability of the wireless + * extensions and to know which version of wireless extensions it is + * (there is some stuff that will be added in the future...) + * I just plan to increment with each new version. + */ +#define WIRELESS_EXT 21 + +/* + * Changes : + * + * V2 to V3 + * -------- + * Alan Cox start some incompatibles changes. I've integrated a bit more. + * - Encryption renamed to Encode to avoid US regulation problems + * - Frequency changed from float to struct to avoid problems on old 386 + * + * V3 to V4 + * -------- + * - Add sensitivity + * + * V4 to V5 + * -------- + * - Missing encoding definitions in range + * - Access points stuff + * + * V5 to V6 + * -------- + * - 802.11 support (ESSID ioctls) + * + * V6 to V7 + * -------- + * - define IW_ESSID_MAX_SIZE and IW_MAX_AP + * + * V7 to V8 + * -------- + * - Changed my e-mail address + * - More 802.11 support (nickname, rate, rts, frag) + * - List index in frequencies + * + * V8 to V9 + * -------- + * - Support for 'mode of operation' (ad-hoc, managed...) + * - Support for unicast and multicast power saving + * - Change encoding to support larger tokens (>64 bits) + * - Updated iw_params (disable, flags) and use it for NWID + * - Extracted iw_point from iwreq for clarity + * + * V9 to V10 + * --------- + * - Add PM capability to range structure + * - Add PM modifier : MAX/MIN/RELATIVE + * - Add encoding option : IW_ENCODE_NOKEY + * - Add TxPower ioctls (work like TxRate) + * + * V10 to V11 + * ---------- + * - Add WE version in range (help backward/forward compatibility) + * - Add retry ioctls (work like PM) + * + * V11 to V12 + * ---------- + * - Add SIOCSIWSTATS to get /proc/net/wireless programatically + * - Add DEV PRIVATE IOCTL to avoid collisions in SIOCDEVPRIVATE space + * - Add new statistics (frag, retry, beacon) + * - Add average quality (for user space calibration) + * + * V12 to V13 + * ---------- + * - Document creation of new driver API. + * - Extract union iwreq_data from struct iwreq (for new driver API). + * - Rename SIOCSIWNAME as SIOCSIWCOMMIT + * + * V13 to V14 + * ---------- + * - Wireless Events support : define struct iw_event + * - Define additional specific event numbers + * - Add "addr" and "param" fields in union iwreq_data + * - AP scanning stuff (SIOCSIWSCAN and friends) + * + * V14 to V15 + * ---------- + * - Add IW_PRIV_TYPE_ADDR for struct sockaddr private arg + * - Make struct iw_freq signed (both m & e), add explicit padding + * - Add IWEVCUSTOM for driver specific event/scanning token + * - Add IW_MAX_GET_SPY for driver returning a lot of addresses + * - Add IW_TXPOW_RANGE for range of Tx Powers + * - Add IWEVREGISTERED & IWEVEXPIRED events for Access Points + * - Add IW_MODE_MONITOR for passive monitor + * + * V15 to V16 + * ---------- + * - Increase the number of bitrates in iw_range to 32 (for 802.11g) + * - Increase the number of frequencies in iw_range to 32 (for 802.11b+a) + * - Reshuffle struct iw_range for increases, add filler + * - Increase IW_MAX_AP to 64 for driver returning a lot of addresses + * - Remove IW_MAX_GET_SPY because conflict with enhanced spy support + * - Add SIOCSIWTHRSPY/SIOCGIWTHRSPY and "struct iw_thrspy" + * - Add IW_ENCODE_TEMP and iw_range->encoding_login_index + * + * V16 to V17 + * ---------- + * - Add flags to frequency -> auto/fixed + * - Document (struct iw_quality *)->updated, add new flags (INVALID) + * - Wireless Event capability in struct iw_range + * - Add support for relative TxPower (yick !) + * + * V17 to V18 (From Jouni Malinen ) + * ---------- + * - Add support for WPA/WPA2 + * - Add extended encoding configuration (SIOCSIWENCODEEXT and + * SIOCGIWENCODEEXT) + * - Add SIOCSIWGENIE/SIOCGIWGENIE + * - Add SIOCSIWMLME + * - Add SIOCSIWPMKSA + * - Add struct iw_range bit field for supported encoding capabilities + * - Add optional scan request parameters for SIOCSIWSCAN + * - Add SIOCSIWAUTH/SIOCGIWAUTH for setting authentication and WPA + * related parameters (extensible up to 4096 parameter values) + * - Add wireless events: IWEVGENIE, IWEVMICHAELMICFAILURE, + * IWEVASSOCREQIE, IWEVASSOCRESPIE, IWEVPMKIDCAND + * + * V18 to V19 + * ---------- + * - Remove (struct iw_point *)->pointer from events and streams + * - Remove header includes to help user space + * - Increase IW_ENCODING_TOKEN_MAX from 32 to 64 + * - Add IW_QUAL_ALL_UPDATED and IW_QUAL_ALL_INVALID macros + * - Add explicit flag to tell stats are in dBm : IW_QUAL_DBM + * - Add IW_IOCTL_IDX() and IW_EVENT_IDX() macros + * + * V20 to V21 + * ---------- + * - Remove (struct net_device *)->get_wireless_stats() + * - Change length in ESSID and NICK to strlen() instead of strlen()+1 + * - Add SIOCSIWMODUL/SIOCGIWMODUL for modulation setting + * - Add IW_RETRY_SHORT/IW_RETRY_LONG retry modifiers + * - Add IW_POWER_SAVING power type + * - Power/Retry relative values no longer * 100000 + * - Add bitrate flags for unicast/broadcast + */ + +/**************************** CONSTANTS ****************************/ + +/* -------------------------- IOCTL LIST -------------------------- */ + +/* Wireless Identification */ +#define SIOCSIWCOMMIT 0x8B00 /* Commit pending changes to driver */ +#define SIOCGIWNAME 0x8B01 /* get name == wireless protocol */ +/* SIOCGIWNAME is used to verify the presence of Wireless Extensions. + * Common values : "IEEE 802.11-DS", "IEEE 802.11-FH", "IEEE 802.11b"... + * Don't put the name of your driver there, it's useless. */ + +/* Basic operations */ +#define SIOCSIWNWID 0x8B02 /* set network id (pre-802.11) */ +#define SIOCGIWNWID 0x8B03 /* get network id (the cell) */ +#define SIOCSIWFREQ 0x8B04 /* set channel/frequency (Hz) */ +#define SIOCGIWFREQ 0x8B05 /* get channel/frequency (Hz) */ +#define SIOCSIWMODE 0x8B06 /* set operation mode */ +#define SIOCGIWMODE 0x8B07 /* get operation mode */ +#define SIOCSIWSENS 0x8B08 /* set sensitivity (dBm) */ +#define SIOCGIWSENS 0x8B09 /* get sensitivity (dBm) */ + +/* Informative stuff */ +#define SIOCSIWRANGE 0x8B0A /* Unused */ +#define SIOCGIWRANGE 0x8B0B /* Get range of parameters */ +#define SIOCSIWPRIV 0x8B0C /* Unused */ +#define SIOCGIWPRIV 0x8B0D /* get private ioctl interface info */ +#define SIOCSIWSTATS 0x8B0E /* Unused */ +#define SIOCGIWSTATS 0x8B0F /* Get /proc/net/wireless stats */ +/* SIOCGIWSTATS is strictly used between user space and the kernel, and + * is never passed to the driver (i.e. the driver will never see it). */ + +/* Spy support (statistics per MAC address - used for Mobile IP support) */ +#define SIOCSIWSPY 0x8B10 /* set spy addresses */ +#define SIOCGIWSPY 0x8B11 /* get spy info (quality of link) */ +#define SIOCSIWTHRSPY 0x8B12 /* set spy threshold (spy event) */ +#define SIOCGIWTHRSPY 0x8B13 /* get spy threshold */ + +/* Access Point manipulation */ +#define SIOCSIWAP 0x8B14 /* set access point MAC addresses */ +#define SIOCGIWAP 0x8B15 /* get access point MAC addresses */ +#define SIOCGIWAPLIST 0x8B17 /* Deprecated in favor of scanning */ +#define SIOCSIWSCAN 0x8B18 /* trigger scanning (list cells) */ +#define SIOCGIWSCAN 0x8B19 /* get scanning results */ + +/* 802.11 specific support */ +#define SIOCSIWESSID 0x8B1A /* set ESSID (network name) */ +#define SIOCGIWESSID 0x8B1B /* get ESSID */ +#define SIOCSIWNICKN 0x8B1C /* set node name/nickname */ +#define SIOCGIWNICKN 0x8B1D /* get node name/nickname */ +/* As the ESSID and NICKN are strings up to 32 bytes long, it doesn't fit + * within the 'iwreq' structure, so we need to use the 'data' member to + * point to a string in user space, like it is done for RANGE... */ + +/* Other parameters useful in 802.11 and some other devices */ +#define SIOCSIWRATE 0x8B20 /* set default bit rate (bps) */ +#define SIOCGIWRATE 0x8B21 /* get default bit rate (bps) */ +#define SIOCSIWRTS 0x8B22 /* set RTS/CTS threshold (bytes) */ +#define SIOCGIWRTS 0x8B23 /* get RTS/CTS threshold (bytes) */ +#define SIOCSIWFRAG 0x8B24 /* set fragmentation thr (bytes) */ +#define SIOCGIWFRAG 0x8B25 /* get fragmentation thr (bytes) */ +#define SIOCSIWTXPOW 0x8B26 /* set transmit power (dBm) */ +#define SIOCGIWTXPOW 0x8B27 /* get transmit power (dBm) */ +#define SIOCSIWRETRY 0x8B28 /* set retry limits and lifetime */ +#define SIOCGIWRETRY 0x8B29 /* get retry limits and lifetime */ + +/* Encoding stuff (scrambling, hardware security, WEP...) */ +#define SIOCSIWENCODE 0x8B2A /* set encoding token & mode */ +#define SIOCGIWENCODE 0x8B2B /* get encoding token & mode */ +/* Power saving stuff (power management, unicast and multicast) */ +#define SIOCSIWPOWER 0x8B2C /* set Power Management settings */ +#define SIOCGIWPOWER 0x8B2D /* get Power Management settings */ +/* Modulation bitmask */ +#define SIOCSIWMODUL 0x8B2E /* set Modulations settings */ +#define SIOCGIWMODUL 0x8B2F /* get Modulations settings */ + +/* WPA : Generic IEEE 802.11 informatiom element (e.g., for WPA/RSN/WMM). + * This ioctl uses struct iw_point and data buffer that includes IE id and len + * fields. More than one IE may be included in the request. Setting the generic + * IE to empty buffer (len=0) removes the generic IE from the driver. Drivers + * are allowed to generate their own WPA/RSN IEs, but in these cases, drivers + * are required to report the used IE as a wireless event, e.g., when + * associating with an AP. */ +#define SIOCSIWGENIE 0x8B30 /* set generic IE */ +#define SIOCGIWGENIE 0x8B31 /* get generic IE */ + +/* WPA : IEEE 802.11 MLME requests */ +#define SIOCSIWMLME 0x8B16 /* request MLME operation; uses + * struct iw_mlme */ +/* WPA : Authentication mode parameters */ +#define SIOCSIWAUTH 0x8B32 /* set authentication mode params */ +#define SIOCGIWAUTH 0x8B33 /* get authentication mode params */ + +/* WPA : Extended version of encoding configuration */ +#define SIOCSIWENCODEEXT 0x8B34 /* set encoding token & mode */ +#define SIOCGIWENCODEEXT 0x8B35 /* get encoding token & mode */ + +/* WPA2 : PMKSA cache management */ +#define SIOCSIWPMKSA 0x8B36 /* PMKSA cache operation */ + +/* -------------------- DEV PRIVATE IOCTL LIST -------------------- */ + +/* These 32 ioctl are wireless device private, for 16 commands. + * Each driver is free to use them for whatever purpose it chooses, + * however the driver *must* export the description of those ioctls + * with SIOCGIWPRIV and *must* use arguments as defined below. + * If you don't follow those rules, DaveM is going to hate you (reason : + * it make mixed 32/64bit operation impossible). + */ +#define SIOCIWFIRSTPRIV 0x8BE0 +#define SIOCIWLASTPRIV 0x8BFF +/* Previously, we were using SIOCDEVPRIVATE, but we now have our + * separate range because of collisions with other tools such as + * 'mii-tool'. + * We now have 32 commands, so a bit more space ;-). + * Also, all 'odd' commands are only usable by root and don't return the + * content of ifr/iwr to user (but you are not obliged to use the set/get + * convention, just use every other two command). More details in iwpriv.c. + * And I repeat : you are not forced to use them with iwpriv, but you + * must be compliant with it. + */ + +/* ------------------------- IOCTL STUFF ------------------------- */ + +/* The first and the last (range) */ +#define SIOCIWFIRST 0x8B00 +#define SIOCIWLAST SIOCIWLASTPRIV /* 0x8BFF */ +#define IW_IOCTL_IDX(cmd) ((cmd) - SIOCIWFIRST) + +/* Even : get (world access), odd : set (root access) */ +#define IW_IS_SET(cmd) (!((cmd) & 0x1)) +#define IW_IS_GET(cmd) ((cmd) & 0x1) + +/* ----------------------- WIRELESS EVENTS ----------------------- */ +/* Those are *NOT* ioctls, do not issue request on them !!! */ +/* Most events use the same identifier as ioctl requests */ + +#define IWEVTXDROP 0x8C00 /* Packet dropped to excessive retry */ +#define IWEVQUAL 0x8C01 /* Quality part of statistics (scan) */ +#define IWEVCUSTOM 0x8C02 /* Driver specific ascii string */ +#define IWEVREGISTERED 0x8C03 /* Discovered a new node (AP mode) */ +#define IWEVEXPIRED 0x8C04 /* Expired a node (AP mode) */ +#define IWEVGENIE 0x8C05 /* Generic IE (WPA, RSN, WMM, ..) + * (scan results); This includes id and + * length fields. One IWEVGENIE may + * contain more than one IE. Scan + * results may contain one or more + * IWEVGENIE events. */ +#define IWEVMICHAELMICFAILURE 0x8C06 /* Michael MIC failure + * (struct iw_michaelmicfailure) + */ +#define IWEVASSOCREQIE 0x8C07 /* IEs used in (Re)Association Request. + * The data includes id and length + * fields and may contain more than one + * IE. This event is required in + * Managed mode if the driver + * generates its own WPA/RSN IE. This + * should be sent just before + * IWEVREGISTERED event for the + * association. */ +#define IWEVASSOCRESPIE 0x8C08 /* IEs used in (Re)Association + * Response. The data includes id and + * length fields and may contain more + * than one IE. This may be sent + * between IWEVASSOCREQIE and + * IWEVREGISTERED events for the + * association. */ +#define IWEVPMKIDCAND 0x8C09 /* PMKID candidate for RSN + * pre-authentication + * (struct iw_pmkid_cand) */ + +#define IWEVFIRST 0x8C00 +#define IW_EVENT_IDX(cmd) ((cmd) - IWEVFIRST) + +/* ------------------------- PRIVATE INFO ------------------------- */ +/* + * The following is used with SIOCGIWPRIV. It allow a driver to define + * the interface (name, type of data) for its private ioctl. + * Privates ioctl are SIOCIWFIRSTPRIV -> SIOCIWLASTPRIV + */ + +#define IW_PRIV_TYPE_MASK 0x7000 /* Type of arguments */ +#define IW_PRIV_TYPE_NONE 0x0000 +#define IW_PRIV_TYPE_BYTE 0x1000 /* Char as number */ +#define IW_PRIV_TYPE_CHAR 0x2000 /* Char as character */ +#define IW_PRIV_TYPE_INT 0x4000 /* 32 bits int */ +#define IW_PRIV_TYPE_FLOAT 0x5000 /* struct iw_freq */ +#define IW_PRIV_TYPE_ADDR 0x6000 /* struct sockaddr */ + +#define IW_PRIV_SIZE_FIXED 0x0800 /* Variable or fixed number of args */ + +#define IW_PRIV_SIZE_MASK 0x07FF /* Max number of those args */ + +/* + * Note : if the number of args is fixed and the size < 16 octets, + * instead of passing a pointer we will put args in the iwreq struct... + */ + +/* ----------------------- OTHER CONSTANTS ----------------------- */ + +/* Maximum frequencies in the range struct */ +#define IW_MAX_FREQUENCIES 32 +/* Note : if you have something like 80 frequencies, + * don't increase this constant and don't fill the frequency list. + * The user will be able to set by channel anyway... */ + +/* Maximum bit rates in the range struct */ +#define IW_MAX_BITRATES 32 + +/* Maximum tx powers in the range struct */ +#define IW_MAX_TXPOWER 8 +/* Note : if you more than 8 TXPowers, just set the max and min or + * a few of them in the struct iw_range. */ + +/* Maximum of address that you may set with SPY */ +#define IW_MAX_SPY 8 + +/* Maximum of address that you may get in the + list of access points in range */ +#define IW_MAX_AP 64 + +/* Maximum size of the ESSID and NICKN strings */ +#define IW_ESSID_MAX_SIZE 32 + +/* Modes of operation */ +#define IW_MODE_AUTO 0 /* Let the driver decides */ +#define IW_MODE_ADHOC 1 /* Single cell network */ +#define IW_MODE_INFRA 2 /* Multi cell network, roaming, ... */ +#define IW_MODE_MASTER 3 /* Synchronisation master or Access Point */ +#define IW_MODE_REPEAT 4 /* Wireless Repeater (forwarder) */ +#define IW_MODE_SECOND 5 /* Secondary master/repeater (backup) */ +#define IW_MODE_MONITOR 6 /* Passive monitor (listen only) */ + +/* Statistics flags (bitmask in updated) */ +#define IW_QUAL_QUAL_UPDATED 0x01 /* Value was updated since last read */ +#define IW_QUAL_LEVEL_UPDATED 0x02 +#define IW_QUAL_NOISE_UPDATED 0x04 +#define IW_QUAL_ALL_UPDATED 0x07 +#define IW_QUAL_DBM 0x08 /* Level + Noise are dBm */ +#define IW_QUAL_QUAL_INVALID 0x10 /* Driver doesn't provide value */ +#define IW_QUAL_LEVEL_INVALID 0x20 +#define IW_QUAL_NOISE_INVALID 0x40 +#define IW_QUAL_ALL_INVALID 0x70 + +/* Frequency flags */ +#define IW_FREQ_AUTO 0x00 /* Let the driver decides */ +#define IW_FREQ_FIXED 0x01 /* Force a specific value */ + +/* Maximum number of size of encoding token available + * they are listed in the range structure */ +#define IW_MAX_ENCODING_SIZES 8 + +/* Maximum size of the encoding token in bytes */ +#define IW_ENCODING_TOKEN_MAX 64 /* 512 bits (for now) */ + +/* Flags for encoding (along with the token) */ +#define IW_ENCODE_INDEX 0x00FF /* Token index (if needed) */ +#define IW_ENCODE_FLAGS 0xFF00 /* Flags defined below */ +#define IW_ENCODE_MODE 0xF000 /* Modes defined below */ +#define IW_ENCODE_DISABLED 0x8000 /* Encoding disabled */ +#define IW_ENCODE_ENABLED 0x0000 /* Encoding enabled */ +#define IW_ENCODE_RESTRICTED 0x4000 /* Refuse non-encoded packets */ +#define IW_ENCODE_OPEN 0x2000 /* Accept non-encoded packets */ +#define IW_ENCODE_NOKEY 0x0800 /* Key is write only, so not present */ +#define IW_ENCODE_TEMP 0x0400 /* Temporary key */ + +/* Power management flags available (along with the value, if any) */ +#define IW_POWER_ON 0x0000 /* No details... */ +#define IW_POWER_TYPE 0xF000 /* Type of parameter */ +#define IW_POWER_PERIOD 0x1000 /* Value is a period/duration of */ +#define IW_POWER_TIMEOUT 0x2000 /* Value is a timeout (to go asleep) */ +#define IW_POWER_SAVING 0x4000 /* Value is relative (how aggressive)*/ +#define IW_POWER_MODE 0x0F00 /* Power Management mode */ +#define IW_POWER_UNICAST_R 0x0100 /* Receive only unicast messages */ +#define IW_POWER_MULTICAST_R 0x0200 /* Receive only multicast messages */ +#define IW_POWER_ALL_R 0x0300 /* Receive all messages though PM */ +#define IW_POWER_FORCE_S 0x0400 /* Force PM procedure for sending unicast */ +#define IW_POWER_REPEATER 0x0800 /* Repeat broadcast messages in PM period */ +#define IW_POWER_MODIFIER 0x000F /* Modify a parameter */ +#define IW_POWER_MIN 0x0001 /* Value is a minimum */ +#define IW_POWER_MAX 0x0002 /* Value is a maximum */ +#define IW_POWER_RELATIVE 0x0004 /* Value is not in seconds/ms/us */ + +/* Transmit Power flags available */ +#define IW_TXPOW_TYPE 0x00FF /* Type of value */ +#define IW_TXPOW_DBM 0x0000 /* Value is in dBm */ +#define IW_TXPOW_MWATT 0x0001 /* Value is in mW */ +#define IW_TXPOW_RELATIVE 0x0002 /* Value is in arbitrary units */ +#define IW_TXPOW_RANGE 0x1000 /* Range of value between min/max */ + +/* Retry limits and lifetime flags available */ +#define IW_RETRY_ON 0x0000 /* No details... */ +#define IW_RETRY_TYPE 0xF000 /* Type of parameter */ +#define IW_RETRY_LIMIT 0x1000 /* Maximum number of retries*/ +#define IW_RETRY_LIFETIME 0x2000 /* Maximum duration of retries in us */ +#define IW_RETRY_MODIFIER 0x00FF /* Modify a parameter */ +#define IW_RETRY_MIN 0x0001 /* Value is a minimum */ +#define IW_RETRY_MAX 0x0002 /* Value is a maximum */ +#define IW_RETRY_RELATIVE 0x0004 /* Value is not in seconds/ms/us */ +#define IW_RETRY_SHORT 0x0010 /* Value is for short packets */ +#define IW_RETRY_LONG 0x0020 /* Value is for long packets */ + +/* Scanning request flags */ +#define IW_SCAN_DEFAULT 0x0000 /* Default scan of the driver */ +#define IW_SCAN_ALL_ESSID 0x0001 /* Scan all ESSIDs */ +#define IW_SCAN_THIS_ESSID 0x0002 /* Scan only this ESSID */ +#define IW_SCAN_ALL_FREQ 0x0004 /* Scan all Frequencies */ +#define IW_SCAN_THIS_FREQ 0x0008 /* Scan only this Frequency */ +#define IW_SCAN_ALL_MODE 0x0010 /* Scan all Modes */ +#define IW_SCAN_THIS_MODE 0x0020 /* Scan only this Mode */ +#define IW_SCAN_ALL_RATE 0x0040 /* Scan all Bit-Rates */ +#define IW_SCAN_THIS_RATE 0x0080 /* Scan only this Bit-Rate */ +/* struct iw_scan_req scan_type */ +#define IW_SCAN_TYPE_ACTIVE 0 +#define IW_SCAN_TYPE_PASSIVE 1 +/* Maximum size of returned data */ +#define IW_SCAN_MAX_DATA 4096 /* In bytes */ + +/* Max number of char in custom event - use multiple of them if needed */ +#define IW_CUSTOM_MAX 256 /* In bytes */ + +/* Generic information element */ +#define IW_GENERIC_IE_MAX 1024 + +/* MLME requests (SIOCSIWMLME / struct iw_mlme) */ +#define IW_MLME_DEAUTH 0 +#define IW_MLME_DISASSOC 1 + +/* SIOCSIWAUTH/SIOCGIWAUTH struct iw_param flags */ +#define IW_AUTH_INDEX 0x0FFF +#define IW_AUTH_FLAGS 0xF000 +/* SIOCSIWAUTH/SIOCGIWAUTH parameters (0 .. 4095) + * (IW_AUTH_INDEX mask in struct iw_param flags; this is the index of the + * parameter that is being set/get to; value will be read/written to + * struct iw_param value field) */ +#define IW_AUTH_WPA_VERSION 0 +#define IW_AUTH_CIPHER_PAIRWISE 1 +#define IW_AUTH_CIPHER_GROUP 2 +#define IW_AUTH_KEY_MGMT 3 +#define IW_AUTH_TKIP_COUNTERMEASURES 4 +#define IW_AUTH_DROP_UNENCRYPTED 5 +#define IW_AUTH_80211_AUTH_ALG 6 +#define IW_AUTH_WPA_ENABLED 7 +#define IW_AUTH_RX_UNENCRYPTED_EAPOL 8 +#define IW_AUTH_ROAMING_CONTROL 9 +#define IW_AUTH_PRIVACY_INVOKED 10 + +/* IW_AUTH_WPA_VERSION values (bit field) */ +#define IW_AUTH_WPA_VERSION_DISABLED 0x00000001 +#define IW_AUTH_WPA_VERSION_WPA 0x00000002 +#define IW_AUTH_WPA_VERSION_WPA2 0x00000004 + +/* IW_AUTH_PAIRWISE_CIPHER and IW_AUTH_GROUP_CIPHER values (bit field) */ +#define IW_AUTH_CIPHER_NONE 0x00000001 +#define IW_AUTH_CIPHER_WEP40 0x00000002 +#define IW_AUTH_CIPHER_TKIP 0x00000004 +#define IW_AUTH_CIPHER_CCMP 0x00000008 +#define IW_AUTH_CIPHER_WEP104 0x00000010 + +/* IW_AUTH_KEY_MGMT values (bit field) */ +#define IW_AUTH_KEY_MGMT_802_1X 1 +#define IW_AUTH_KEY_MGMT_PSK 2 + +/* IW_AUTH_80211_AUTH_ALG values (bit field) */ +#define IW_AUTH_ALG_OPEN_SYSTEM 0x00000001 +#define IW_AUTH_ALG_SHARED_KEY 0x00000002 +#define IW_AUTH_ALG_LEAP 0x00000004 + +/* IW_AUTH_ROAMING_CONTROL values */ +#define IW_AUTH_ROAMING_ENABLE 0 /* driver/firmware based roaming */ +#define IW_AUTH_ROAMING_DISABLE 1 /* user space program used for roaming + * control */ + +/* SIOCSIWENCODEEXT definitions */ +#define IW_ENCODE_SEQ_MAX_SIZE 8 +/* struct iw_encode_ext ->alg */ +#define IW_ENCODE_ALG_NONE 0 +#define IW_ENCODE_ALG_WEP 1 +#define IW_ENCODE_ALG_TKIP 2 +#define IW_ENCODE_ALG_CCMP 3 +/* struct iw_encode_ext ->ext_flags */ +#define IW_ENCODE_EXT_TX_SEQ_VALID 0x00000001 +#define IW_ENCODE_EXT_RX_SEQ_VALID 0x00000002 +#define IW_ENCODE_EXT_GROUP_KEY 0x00000004 +#define IW_ENCODE_EXT_SET_TX_KEY 0x00000008 + +/* IWEVMICHAELMICFAILURE : struct iw_michaelmicfailure ->flags */ +#define IW_MICFAILURE_KEY_ID 0x00000003 /* Key ID 0..3 */ +#define IW_MICFAILURE_GROUP 0x00000004 +#define IW_MICFAILURE_PAIRWISE 0x00000008 +#define IW_MICFAILURE_STAKEY 0x00000010 +#define IW_MICFAILURE_COUNT 0x00000060 /* 1 or 2 (0 = count not supported) + */ + +/* Bit field values for enc_capa in struct iw_range */ +#define IW_ENC_CAPA_WPA 0x00000001 +#define IW_ENC_CAPA_WPA2 0x00000002 +#define IW_ENC_CAPA_CIPHER_TKIP 0x00000004 +#define IW_ENC_CAPA_CIPHER_CCMP 0x00000008 + +/* Event capability macros - in (struct iw_range *)->event_capa + * Because we have more than 32 possible events, we use an array of + * 32 bit bitmasks. Note : 32 bits = 0x20 = 2^5. */ +#define IW_EVENT_CAPA_BASE(cmd) ((cmd >= SIOCIWFIRSTPRIV) ? \ + (cmd - SIOCIWFIRSTPRIV + 0x60) : \ + (cmd - SIOCSIWCOMMIT)) +#define IW_EVENT_CAPA_INDEX(cmd) (IW_EVENT_CAPA_BASE(cmd) >> 5) +#define IW_EVENT_CAPA_MASK(cmd) (1 << (IW_EVENT_CAPA_BASE(cmd) & 0x1F)) +/* Event capability constants - event autogenerated by the kernel + * This list is valid for most 802.11 devices, customise as needed... */ +#define IW_EVENT_CAPA_K_0 (IW_EVENT_CAPA_MASK(0x8B04) | \ + IW_EVENT_CAPA_MASK(0x8B06) | \ + IW_EVENT_CAPA_MASK(0x8B1A)) +#define IW_EVENT_CAPA_K_1 (IW_EVENT_CAPA_MASK(0x8B2A)) +/* "Easy" macro to set events in iw_range (less efficient) */ +#define IW_EVENT_CAPA_SET(event_capa, cmd) (event_capa[IW_EVENT_CAPA_INDEX(cmd)] |= IW_EVENT_CAPA_MASK(cmd)) +#define IW_EVENT_CAPA_SET_KERNEL(event_capa) {event_capa[0] |= IW_EVENT_CAPA_K_0; event_capa[1] |= IW_EVENT_CAPA_K_1; } + +/* Modulations bitmasks */ +#define IW_MODUL_ALL 0x00000000 /* Everything supported */ +#define IW_MODUL_FH 0x00000001 /* Frequency Hopping */ +#define IW_MODUL_DS 0x00000002 /* Original Direct Sequence */ +#define IW_MODUL_CCK 0x00000004 /* 802.11b : 5.5 + 11 Mb/s */ +#define IW_MODUL_11B (IW_MODUL_DS | IW_MODUL_CCK) +#define IW_MODUL_PBCC 0x00000008 /* TI : 5.5 + 11 + 22 Mb/s */ +#define IW_MODUL_OFDM_A 0x00000010 /* 802.11a : 54 Mb/s */ +#define IW_MODUL_11A (IW_MODUL_OFDM_A) +#define IW_MODUL_11AB (IW_MODUL_11B | IW_MODUL_11A) +#define IW_MODUL_OFDM_G 0x00000020 /* 802.11g : 54 Mb/s */ +#define IW_MODUL_11G (IW_MODUL_11B | IW_MODUL_OFDM_G) +#define IW_MODUL_11AG (IW_MODUL_11G | IW_MODUL_11A) +#define IW_MODUL_TURBO 0x00000040 /* ATH : bonding, 108 Mb/s */ +/* In here we should define MIMO stuff. Later... */ +#define IW_MODUL_CUSTOM 0x40000000 /* Driver specific */ + +/* Bitrate flags available */ +#define IW_BITRATE_TYPE 0x00FF /* Type of value */ +#define IW_BITRATE_UNICAST 0x0001 /* Maximum/Fixed unicast bitrate */ +#define IW_BITRATE_BROADCAST 0x0002 /* Fixed broadcast bitrate */ + +/****************************** TYPES ******************************/ + +/* --------------------------- SUBTYPES --------------------------- */ +/* + * Generic format for most parameters that fit in an int + */ +struct iw_param +{ + __s32 value; /* The value of the parameter itself */ + __u8 fixed; /* Hardware should not use auto select */ + __u8 disabled; /* Disable the feature */ + __u16 flags; /* Various specifc flags (if any) */ +}; + +/* + * For all data larger than 16 octets, we need to use a + * pointer to memory allocated in user space. + */ +struct iw_point +{ + void __user *pointer; /* Pointer to the data (in user space) */ + __u16 length; /* number of fields or size in bytes */ + __u16 flags; /* Optional params */ +}; + +/* + * A frequency + * For numbers lower than 10^9, we encode the number in 'm' and + * set 'e' to 0 + * For number greater than 10^9, we divide it by the lowest power + * of 10 to get 'm' lower than 10^9, with 'm'= f / (10^'e')... + * The power of 10 is in 'e', the result of the division is in 'm'. + */ +struct iw_freq +{ + __s32 m; /* Mantissa */ + __s16 e; /* Exponent */ + __u8 i; /* List index (when in range struct) */ + __u8 flags; /* Flags (fixed/auto) */ +}; + +/* + * Quality of the link + */ +struct iw_quality +{ + __u8 qual; /* link quality (%retries, SNR, + %missed beacons or better...) */ + __u8 level; /* signal level (dBm) */ + __u8 noise; /* noise level (dBm) */ + __u8 updated; /* Flags to know if updated */ +}; + +/* + * Packet discarded in the wireless adapter due to + * "wireless" specific problems... + * Note : the list of counter and statistics in net_device_stats + * is already pretty exhaustive, and you should use that first. + * This is only additional stats... + */ +struct iw_discarded +{ + __u32 nwid; /* Rx : Wrong nwid/essid */ + __u32 code; /* Rx : Unable to code/decode (WEP) */ + __u32 fragment; /* Rx : Can't perform MAC reassembly */ + __u32 retries; /* Tx : Max MAC retries num reached */ + __u32 misc; /* Others cases */ +}; + +/* + * Packet/Time period missed in the wireless adapter due to + * "wireless" specific problems... + */ +struct iw_missed +{ + __u32 beacon; /* Missed beacons/superframe */ +}; + +/* + * Quality range (for spy threshold) + */ +struct iw_thrspy +{ + struct sockaddr addr; /* Source address (hw/mac) */ + struct iw_quality qual; /* Quality of the link */ + struct iw_quality low; /* Low threshold */ + struct iw_quality high; /* High threshold */ +}; + +/* + * Optional data for scan request + * + * Note: these optional parameters are controlling parameters for the + * scanning behavior, these do not apply to getting scan results + * (SIOCGIWSCAN). Drivers are expected to keep a local BSS table and + * provide a merged results with all BSSes even if the previous scan + * request limited scanning to a subset, e.g., by specifying an SSID. + * Especially, scan results are required to include an entry for the + * current BSS if the driver is in Managed mode and associated with an AP. + */ +struct iw_scan_req +{ + __u8 scan_type; /* IW_SCAN_TYPE_{ACTIVE,PASSIVE} */ + __u8 essid_len; + __u8 num_channels; /* num entries in channel_list; + * 0 = scan all allowed channels */ + __u8 flags; /* reserved as padding; use zero, this may + * be used in the future for adding flags + * to request different scan behavior */ + struct sockaddr bssid; /* ff:ff:ff:ff:ff:ff for broadcast BSSID or + * individual address of a specific BSS */ + + /* + * Use this ESSID if IW_SCAN_THIS_ESSID flag is used instead of using + * the current ESSID. This allows scan requests for specific ESSID + * without having to change the current ESSID and potentially breaking + * the current association. + */ + __u8 essid[IW_ESSID_MAX_SIZE]; + + /* + * Optional parameters for changing the default scanning behavior. + * These are based on the MLME-SCAN.request from IEEE Std 802.11. + * TU is 1.024 ms. If these are set to 0, driver is expected to use + * reasonable default values. min_channel_time defines the time that + * will be used to wait for the first reply on each channel. If no + * replies are received, next channel will be scanned after this. If + * replies are received, total time waited on the channel is defined by + * max_channel_time. + */ + __u32 min_channel_time; /* in TU */ + __u32 max_channel_time; /* in TU */ + + struct iw_freq channel_list[IW_MAX_FREQUENCIES]; +}; + +/* ------------------------- WPA SUPPORT ------------------------- */ + +/* + * Extended data structure for get/set encoding (this is used with + * SIOCSIWENCODEEXT/SIOCGIWENCODEEXT. struct iw_point and IW_ENCODE_* + * flags are used in the same way as with SIOCSIWENCODE/SIOCGIWENCODE and + * only the data contents changes (key data -> this structure, including + * key data). + * + * If the new key is the first group key, it will be set as the default + * TX key. Otherwise, default TX key index is only changed if + * IW_ENCODE_EXT_SET_TX_KEY flag is set. + * + * Key will be changed with SIOCSIWENCODEEXT in all cases except for + * special "change TX key index" operation which is indicated by setting + * key_len = 0 and ext_flags |= IW_ENCODE_EXT_SET_TX_KEY. + * + * tx_seq/rx_seq are only used when respective + * IW_ENCODE_EXT_{TX,RX}_SEQ_VALID flag is set in ext_flags. Normal + * TKIP/CCMP operation is to set RX seq with SIOCSIWENCODEEXT and start + * TX seq from zero whenever key is changed. SIOCGIWENCODEEXT is normally + * used only by an Authenticator (AP or an IBSS station) to get the + * current TX sequence number. Using TX_SEQ_VALID for SIOCSIWENCODEEXT and + * RX_SEQ_VALID for SIOCGIWENCODEEXT are optional, but can be useful for + * debugging/testing. + */ +struct iw_encode_ext +{ + __u32 ext_flags; /* IW_ENCODE_EXT_* */ + __u8 tx_seq[IW_ENCODE_SEQ_MAX_SIZE]; /* LSB first */ + __u8 rx_seq[IW_ENCODE_SEQ_MAX_SIZE]; /* LSB first */ + struct sockaddr addr; /* ff:ff:ff:ff:ff:ff for broadcast/multicast + * (group) keys or unicast address for + * individual keys */ + __u16 alg; /* IW_ENCODE_ALG_* */ + __u16 key_len; + __u8 key[0]; +}; + +/* SIOCSIWMLME data */ +struct iw_mlme +{ + __u16 cmd; /* IW_MLME_* */ + __u16 reason_code; + struct sockaddr addr; +}; + +/* SIOCSIWPMKSA data */ +#define IW_PMKSA_ADD 1 +#define IW_PMKSA_REMOVE 2 +#define IW_PMKSA_FLUSH 3 + +#define IW_PMKID_LEN 16 + +struct iw_pmksa +{ + __u32 cmd; /* IW_PMKSA_* */ + struct sockaddr bssid; + __u8 pmkid[IW_PMKID_LEN]; +}; + +/* IWEVMICHAELMICFAILURE data */ +struct iw_michaelmicfailure +{ + __u32 flags; + struct sockaddr src_addr; + __u8 tsc[IW_ENCODE_SEQ_MAX_SIZE]; /* LSB first */ +}; + +/* IWEVPMKIDCAND data */ +#define IW_PMKID_CAND_PREAUTH 0x00000001 /* RNS pre-authentication enabled */ +struct iw_pmkid_cand +{ + __u32 flags; /* IW_PMKID_CAND_* */ + __u32 index; /* the smaller the index, the higher the + * priority */ + struct sockaddr bssid; +}; + +/* ------------------------ WIRELESS STATS ------------------------ */ +/* + * Wireless statistics (used for /proc/net/wireless) + */ +struct iw_statistics +{ + __u16 status; /* Status + * - device dependent for now */ + + struct iw_quality qual; /* Quality of the link + * (instant/mean/max) */ + struct iw_discarded discard; /* Packet discarded counts */ + struct iw_missed miss; /* Packet missed counts */ +}; + +/* ------------------------ IOCTL REQUEST ------------------------ */ +/* + * This structure defines the payload of an ioctl, and is used + * below. + * + * Note that this structure should fit on the memory footprint + * of iwreq (which is the same as ifreq), which mean a max size of + * 16 octets = 128 bits. Warning, pointers might be 64 bits wide... + * You should check this when increasing the structures defined + * above in this file... + */ +union iwreq_data +{ + /* Config - generic */ + char name[IFNAMSIZ]; + /* Name : used to verify the presence of wireless extensions. + * Name of the protocol/provider... */ + + struct iw_point essid; /* Extended network name */ + struct iw_param nwid; /* network id (or domain - the cell) */ + struct iw_freq freq; /* frequency or channel : + * 0-1000 = channel + * > 1000 = frequency in Hz */ + + struct iw_param sens; /* signal level threshold */ + struct iw_param bitrate; /* default bit rate */ + struct iw_param txpower; /* default transmit power */ + struct iw_param rts; /* RTS threshold threshold */ + struct iw_param frag; /* Fragmentation threshold */ + __u32 mode; /* Operation mode */ + struct iw_param retry; /* Retry limits & lifetime */ + + struct iw_point encoding; /* Encoding stuff : tokens */ + struct iw_param power; /* PM duration/timeout */ + struct iw_quality qual; /* Quality part of statistics */ + + struct sockaddr ap_addr; /* Access point address */ + struct sockaddr addr; /* Destination address (hw/mac) */ + + struct iw_param param; /* Other small parameters */ + struct iw_point data; /* Other large parameters */ +}; + +/* + * The structure to exchange data for ioctl. + * This structure is the same as 'struct ifreq', but (re)defined for + * convenience... + * Do I need to remind you about structure size (32 octets) ? + */ +struct iwreq +{ + union + { + char ifrn_name[IFNAMSIZ]; /* if name, e.g. "eth0" */ + } ifr_ifrn; + + /* Data part (defined just above) */ + union iwreq_data u; +}; + +/* -------------------------- IOCTL DATA -------------------------- */ +/* + * For those ioctl which want to exchange mode data that what could + * fit in the above structure... + */ + +/* + * Range of parameters + */ + +struct iw_range +{ + /* Informative stuff (to choose between different interface) */ + __u32 throughput; /* To give an idea... */ + /* In theory this value should be the maximum benchmarked + * TCP/IP throughput, because with most of these devices the + * bit rate is meaningless (overhead an co) to estimate how + * fast the connection will go and pick the fastest one. + * I suggest people to play with Netperf or any benchmark... + */ + + /* NWID (or domain id) */ + __u32 min_nwid; /* Minimal NWID we are able to set */ + __u32 max_nwid; /* Maximal NWID we are able to set */ + + /* Old Frequency (backward compat - moved lower ) */ + __u16 old_num_channels; + __u8 old_num_frequency; + + /* Wireless event capability bitmasks */ + __u32 event_capa[6]; + + /* signal level threshold range */ + __s32 sensitivity; + + /* Quality of link & SNR stuff */ + /* Quality range (link, level, noise) + * If the quality is absolute, it will be in the range [0 ; max_qual], + * if the quality is dBm, it will be in the range [max_qual ; 0]. + * Don't forget that we use 8 bit arithmetics... */ + struct iw_quality max_qual; /* Quality of the link */ + /* This should contain the average/typical values of the quality + * indicator. This should be the threshold between a "good" and + * a "bad" link (example : monitor going from green to orange). + * Currently, user space apps like quality monitors don't have any + * way to calibrate the measurement. With this, they can split + * the range between 0 and max_qual in different quality level + * (using a geometric subdivision centered on the average). + * I expect that people doing the user space apps will feedback + * us on which value we need to put in each driver... */ + struct iw_quality avg_qual; /* Quality of the link */ + + /* Rates */ + __u8 num_bitrates; /* Number of entries in the list */ + __s32 bitrate[IW_MAX_BITRATES]; /* list, in bps */ + + /* RTS threshold */ + __s32 min_rts; /* Minimal RTS threshold */ + __s32 max_rts; /* Maximal RTS threshold */ + + /* Frag threshold */ + __s32 min_frag; /* Minimal frag threshold */ + __s32 max_frag; /* Maximal frag threshold */ + + /* Power Management duration & timeout */ + __s32 min_pmp; /* Minimal PM period */ + __s32 max_pmp; /* Maximal PM period */ + __s32 min_pmt; /* Minimal PM timeout */ + __s32 max_pmt; /* Maximal PM timeout */ + __u16 pmp_flags; /* How to decode max/min PM period */ + __u16 pmt_flags; /* How to decode max/min PM timeout */ + __u16 pm_capa; /* What PM options are supported */ + + /* Encoder stuff */ + __u16 encoding_size[IW_MAX_ENCODING_SIZES]; /* Different token sizes */ + __u8 num_encoding_sizes; /* Number of entry in the list */ + __u8 max_encoding_tokens; /* Max number of tokens */ + /* For drivers that need a "login/passwd" form */ + __u8 encoding_login_index; /* token index for login token */ + + /* Transmit power */ + __u16 txpower_capa; /* What options are supported */ + __u8 num_txpower; /* Number of entries in the list */ + __s32 txpower[IW_MAX_TXPOWER]; /* list, in bps */ + + /* Wireless Extension version info */ + __u8 we_version_compiled; /* Must be WIRELESS_EXT */ + __u8 we_version_source; /* Last update of source */ + + /* Retry limits and lifetime */ + __u16 retry_capa; /* What retry options are supported */ + __u16 retry_flags; /* How to decode max/min retry limit */ + __u16 r_time_flags; /* How to decode max/min retry life */ + __s32 min_retry; /* Minimal number of retries */ + __s32 max_retry; /* Maximal number of retries */ + __s32 min_r_time; /* Minimal retry lifetime */ + __s32 max_r_time; /* Maximal retry lifetime */ + + /* Frequency */ + __u16 num_channels; /* Number of channels [0; num - 1] */ + __u8 num_frequency; /* Number of entry in the list */ + struct iw_freq freq[IW_MAX_FREQUENCIES]; /* list */ + /* Note : this frequency list doesn't need to fit channel numbers, + * because each entry contain its channel index */ + + __u32 enc_capa; /* IW_ENC_CAPA_* bit field */ + + /* More power management stuff */ + __s32 min_pms; /* Minimal PM saving */ + __s32 max_pms; /* Maximal PM saving */ + __u16 pms_flags; /* How to decode max/min PM saving */ + + /* All available modulations for driver (hw may support less) */ + __s32 modul_capa; /* IW_MODUL_* bit field */ + + /* More bitrate stuff */ + __u32 bitrate_capa; /* Types of bitrates supported */ +}; + +/* + * Private ioctl interface information + */ + +struct iw_priv_args +{ + __u32 cmd; /* Number of the ioctl to issue */ + __u16 set_args; /* Type and number of args */ + __u16 get_args; /* Type and number of args */ + char name[IFNAMSIZ]; /* Name of the extension */ +}; + +/* ----------------------- WIRELESS EVENTS ----------------------- */ +/* + * Wireless events are carried through the rtnetlink socket to user + * space. They are encapsulated in the IFLA_WIRELESS field of + * a RTM_NEWLINK message. + */ + +/* + * A Wireless Event. Contains basically the same data as the ioctl... + */ +struct iw_event +{ + __u16 len; /* Real lenght of this stuff */ + __u16 cmd; /* Wireless IOCTL */ + union iwreq_data u; /* IOCTL fixed payload */ +}; + +/* Size of the Event prefix (including padding and alignement junk) */ +#define IW_EV_LCP_LEN (sizeof(struct iw_event) - sizeof(union iwreq_data)) +/* Size of the various events */ +#define IW_EV_CHAR_LEN (IW_EV_LCP_LEN + IFNAMSIZ) +#define IW_EV_UINT_LEN (IW_EV_LCP_LEN + sizeof(__u32)) +#define IW_EV_FREQ_LEN (IW_EV_LCP_LEN + sizeof(struct iw_freq)) +#define IW_EV_PARAM_LEN (IW_EV_LCP_LEN + sizeof(struct iw_param)) +#define IW_EV_ADDR_LEN (IW_EV_LCP_LEN + sizeof(struct sockaddr)) +#define IW_EV_QUAL_LEN (IW_EV_LCP_LEN + sizeof(struct iw_quality)) + +/* iw_point events are special. First, the payload (extra data) come at + * the end of the event, so they are bigger than IW_EV_POINT_LEN. Second, + * we omit the pointer, so start at an offset. */ +#define IW_EV_POINT_OFF (((char *) &(((struct iw_point *) NULL)->length)) - \ + (char *) NULL) +#define IW_EV_POINT_LEN (IW_EV_LCP_LEN + sizeof(struct iw_point) - \ + IW_EV_POINT_OFF) + +#endif /* _LINUX_WIRELESS_H */ diff --git a/test.py b/test.py new file mode 100755 index 0000000..a30a356 --- /dev/null +++ b/test.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python + +import sys +import time +import pyiw + +INTERFACE = "eth1" + +def PrintAllValues(iface): + for val in iface: + print "%-9s = %s" % (val, iface[val]) + +if __name__ == "__main__": + print "Using device:", INTERFACE, "\n" + print "Version [ PyIW ]:", pyiw.version() + print "Version [ libiw/WE ]:", pyiw.iw_version() + print "Version [ kernel/WE ]:", pyiw.we_version(), "\n" + + try: + iface = pyiw.WirelessInterface(INTERFACE) + + iface["essid"] = "01234567890123456789fasdfasdfas" + iface["channel"] = 1.0 + + for i in iface: + print i, "-", iface[i] + + except pyiw.error, error: + print "Error:", error + + sys.exit(1) + + print "\nScanning...\n" + + for net in iface.Scan(): + print net["essid"], "- WPA Active:", net["wpa"] diff --git a/welcome b/welcome deleted file mode 100644 index e69de29..0000000