├── .gitignore ├── LICENSE ├── README.md ├── VirtualMac80211.xcodeproj └── project.pbxproj └── VirtualMac80211 ├── AirportIOCTL.h ├── IO80211Controller.cpp ├── IO80211Controller.hpp ├── IO80211Interface.cpp ├── IO80211Interface.hpp ├── Info.plist ├── VirtualMac80211.cpp ├── VirtualMac80211.hpp └── apple ├── IOEthernetController.h ├── IOEthernetInterface.h ├── IONetworkController.h ├── IONetworkInterface.h ├── apple80211_ioctl.h └── apple80211_var.h /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | DerivedData 3 | build 4 | xcuserdata 5 | xcshareddata 6 | project.xcworkspace 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # VirtualMac80211 -------------------------------------------------------------------------------- /VirtualMac80211.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | F83F8FE024A8A0CE00E5E881 /* VirtualMac80211.hpp in Headers */ = {isa = PBXBuildFile; fileRef = F83F8FDF24A8A0CE00E5E881 /* VirtualMac80211.hpp */; }; 11 | F83F8FE224A8A0CE00E5E881 /* VirtualMac80211.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F83F8FE124A8A0CE00E5E881 /* VirtualMac80211.cpp */; }; 12 | F83F8FEA24A8A57A00E5E881 /* IO80211Interface.hpp in Headers */ = {isa = PBXBuildFile; fileRef = F83F8FE924A8A57A00E5E881 /* IO80211Interface.hpp */; }; 13 | F83F8FEC24A8A57F00E5E881 /* IO80211Interface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F83F8FEB24A8A57F00E5E881 /* IO80211Interface.cpp */; }; 14 | F83F8FEE24A8A59500E5E881 /* IO80211Controller.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F83F8FED24A8A59500E5E881 /* IO80211Controller.cpp */; }; 15 | F83F8FF024A8A59900E5E881 /* IO80211Controller.hpp in Headers */ = {isa = PBXBuildFile; fileRef = F83F8FEF24A8A59900E5E881 /* IO80211Controller.hpp */; }; 16 | F83F8FFA24A8A7D500E5E881 /* IONetworkInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = F83F8FF624A8A7D500E5E881 /* IONetworkInterface.h */; }; 17 | F83F8FFB24A8A7D500E5E881 /* IOEthernetController.h in Headers */ = {isa = PBXBuildFile; fileRef = F83F8FF724A8A7D500E5E881 /* IOEthernetController.h */; }; 18 | F83F8FFC24A8A7D500E5E881 /* IOEthernetInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = F83F8FF824A8A7D500E5E881 /* IOEthernetInterface.h */; }; 19 | F83F8FFD24A8A7D500E5E881 /* IONetworkController.h in Headers */ = {isa = PBXBuildFile; fileRef = F83F8FF924A8A7D500E5E881 /* IONetworkController.h */; }; 20 | F8DC0C3924A8DC1F005AB7A5 /* apple80211_ioctl.h in Headers */ = {isa = PBXBuildFile; fileRef = F8DC0C3824A8DC1F005AB7A5 /* apple80211_ioctl.h */; }; 21 | F8DC0C3B24A8DCD8005AB7A5 /* apple80211_var.h in Headers */ = {isa = PBXBuildFile; fileRef = F8DC0C3A24A8DCD8005AB7A5 /* apple80211_var.h */; }; 22 | F8DC0C3D24A8E66C005AB7A5 /* AirportIOCTL.h in Headers */ = {isa = PBXBuildFile; fileRef = F8DC0C3C24A8E66C005AB7A5 /* AirportIOCTL.h */; }; 23 | /* End PBXBuildFile section */ 24 | 25 | /* Begin PBXFileReference section */ 26 | F83F8FDC24A8A0CE00E5E881 /* VirtualMac80211.kext */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = VirtualMac80211.kext; sourceTree = BUILT_PRODUCTS_DIR; }; 27 | F83F8FDF24A8A0CE00E5E881 /* VirtualMac80211.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = VirtualMac80211.hpp; sourceTree = ""; }; 28 | F83F8FE124A8A0CE00E5E881 /* VirtualMac80211.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = VirtualMac80211.cpp; sourceTree = ""; }; 29 | F83F8FE324A8A0CE00E5E881 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 30 | F83F8FE924A8A57A00E5E881 /* IO80211Interface.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = IO80211Interface.hpp; sourceTree = ""; }; 31 | F83F8FEB24A8A57F00E5E881 /* IO80211Interface.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IO80211Interface.cpp; sourceTree = ""; }; 32 | F83F8FED24A8A59500E5E881 /* IO80211Controller.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IO80211Controller.cpp; sourceTree = ""; }; 33 | F83F8FEF24A8A59900E5E881 /* IO80211Controller.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = IO80211Controller.hpp; sourceTree = ""; }; 34 | F83F8FF624A8A7D500E5E881 /* IONetworkInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IONetworkInterface.h; sourceTree = ""; }; 35 | F83F8FF724A8A7D500E5E881 /* IOEthernetController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IOEthernetController.h; sourceTree = ""; }; 36 | F83F8FF824A8A7D500E5E881 /* IOEthernetInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IOEthernetInterface.h; sourceTree = ""; }; 37 | F83F8FF924A8A7D500E5E881 /* IONetworkController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IONetworkController.h; sourceTree = ""; }; 38 | F8DC0C3824A8DC1F005AB7A5 /* apple80211_ioctl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = apple80211_ioctl.h; sourceTree = ""; }; 39 | F8DC0C3A24A8DCD8005AB7A5 /* apple80211_var.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = apple80211_var.h; sourceTree = ""; }; 40 | F8DC0C3C24A8E66C005AB7A5 /* AirportIOCTL.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AirportIOCTL.h; sourceTree = ""; }; 41 | /* End PBXFileReference section */ 42 | 43 | /* Begin PBXFrameworksBuildPhase section */ 44 | F83F8FD924A8A0CE00E5E881 /* Frameworks */ = { 45 | isa = PBXFrameworksBuildPhase; 46 | buildActionMask = 2147483647; 47 | files = ( 48 | ); 49 | runOnlyForDeploymentPostprocessing = 0; 50 | }; 51 | /* End PBXFrameworksBuildPhase section */ 52 | 53 | /* Begin PBXGroup section */ 54 | F83F8FD224A8A0CD00E5E881 = { 55 | isa = PBXGroup; 56 | children = ( 57 | F83F8FDE24A8A0CE00E5E881 /* VirtualMac80211 */, 58 | F83F8FDD24A8A0CE00E5E881 /* Products */, 59 | ); 60 | sourceTree = ""; 61 | }; 62 | F83F8FDD24A8A0CE00E5E881 /* Products */ = { 63 | isa = PBXGroup; 64 | children = ( 65 | F83F8FDC24A8A0CE00E5E881 /* VirtualMac80211.kext */, 66 | ); 67 | name = Products; 68 | sourceTree = ""; 69 | }; 70 | F83F8FDE24A8A0CE00E5E881 /* VirtualMac80211 */ = { 71 | isa = PBXGroup; 72 | children = ( 73 | F83F8FF524A8A6FB00E5E881 /* apple */, 74 | F83F8FDF24A8A0CE00E5E881 /* VirtualMac80211.hpp */, 75 | F83F8FE124A8A0CE00E5E881 /* VirtualMac80211.cpp */, 76 | F83F8FE924A8A57A00E5E881 /* IO80211Interface.hpp */, 77 | F83F8FEB24A8A57F00E5E881 /* IO80211Interface.cpp */, 78 | F83F8FED24A8A59500E5E881 /* IO80211Controller.cpp */, 79 | F83F8FEF24A8A59900E5E881 /* IO80211Controller.hpp */, 80 | F8DC0C3C24A8E66C005AB7A5 /* AirportIOCTL.h */, 81 | F83F8FE324A8A0CE00E5E881 /* Info.plist */, 82 | ); 83 | path = VirtualMac80211; 84 | sourceTree = ""; 85 | }; 86 | F83F8FF524A8A6FB00E5E881 /* apple */ = { 87 | isa = PBXGroup; 88 | children = ( 89 | F83F8FF724A8A7D500E5E881 /* IOEthernetController.h */, 90 | F83F8FF824A8A7D500E5E881 /* IOEthernetInterface.h */, 91 | F83F8FF924A8A7D500E5E881 /* IONetworkController.h */, 92 | F83F8FF624A8A7D500E5E881 /* IONetworkInterface.h */, 93 | F8DC0C3824A8DC1F005AB7A5 /* apple80211_ioctl.h */, 94 | F8DC0C3A24A8DCD8005AB7A5 /* apple80211_var.h */, 95 | ); 96 | path = apple; 97 | sourceTree = ""; 98 | }; 99 | /* End PBXGroup section */ 100 | 101 | /* Begin PBXHeadersBuildPhase section */ 102 | F83F8FD724A8A0CE00E5E881 /* Headers */ = { 103 | isa = PBXHeadersBuildPhase; 104 | buildActionMask = 2147483647; 105 | files = ( 106 | F8DC0C3924A8DC1F005AB7A5 /* apple80211_ioctl.h in Headers */, 107 | F8DC0C3B24A8DCD8005AB7A5 /* apple80211_var.h in Headers */, 108 | F8DC0C3D24A8E66C005AB7A5 /* AirportIOCTL.h in Headers */, 109 | F83F8FE024A8A0CE00E5E881 /* VirtualMac80211.hpp in Headers */, 110 | F83F8FFA24A8A7D500E5E881 /* IONetworkInterface.h in Headers */, 111 | F83F8FF024A8A59900E5E881 /* IO80211Controller.hpp in Headers */, 112 | F83F8FFC24A8A7D500E5E881 /* IOEthernetInterface.h in Headers */, 113 | F83F8FFB24A8A7D500E5E881 /* IOEthernetController.h in Headers */, 114 | F83F8FFD24A8A7D500E5E881 /* IONetworkController.h in Headers */, 115 | F83F8FEA24A8A57A00E5E881 /* IO80211Interface.hpp in Headers */, 116 | ); 117 | runOnlyForDeploymentPostprocessing = 0; 118 | }; 119 | /* End PBXHeadersBuildPhase section */ 120 | 121 | /* Begin PBXNativeTarget section */ 122 | F83F8FDB24A8A0CE00E5E881 /* VirtualMac80211 */ = { 123 | isa = PBXNativeTarget; 124 | buildConfigurationList = F83F8FE624A8A0CE00E5E881 /* Build configuration list for PBXNativeTarget "VirtualMac80211" */; 125 | buildPhases = ( 126 | F83F8FD724A8A0CE00E5E881 /* Headers */, 127 | F83F8FD824A8A0CE00E5E881 /* Sources */, 128 | F83F8FD924A8A0CE00E5E881 /* Frameworks */, 129 | F83F8FDA24A8A0CE00E5E881 /* Resources */, 130 | ); 131 | buildRules = ( 132 | ); 133 | dependencies = ( 134 | ); 135 | name = VirtualMac80211; 136 | productName = VirtualMac80211; 137 | productReference = F83F8FDC24A8A0CE00E5E881 /* VirtualMac80211.kext */; 138 | productType = "com.apple.product-type.kernel-extension"; 139 | }; 140 | /* End PBXNativeTarget section */ 141 | 142 | /* Begin PBXProject section */ 143 | F83F8FD324A8A0CD00E5E881 /* Project object */ = { 144 | isa = PBXProject; 145 | attributes = { 146 | LastUpgradeCheck = 1110; 147 | ORGANIZATIONNAME = zxystd; 148 | TargetAttributes = { 149 | F83F8FDB24A8A0CE00E5E881 = { 150 | CreatedOnToolsVersion = 11.1; 151 | }; 152 | }; 153 | }; 154 | buildConfigurationList = F83F8FD624A8A0CD00E5E881 /* Build configuration list for PBXProject "VirtualMac80211" */; 155 | compatibilityVersion = "Xcode 9.3"; 156 | developmentRegion = en; 157 | hasScannedForEncodings = 0; 158 | knownRegions = ( 159 | en, 160 | Base, 161 | ); 162 | mainGroup = F83F8FD224A8A0CD00E5E881; 163 | productRefGroup = F83F8FDD24A8A0CE00E5E881 /* Products */; 164 | projectDirPath = ""; 165 | projectRoot = ""; 166 | targets = ( 167 | F83F8FDB24A8A0CE00E5E881 /* VirtualMac80211 */, 168 | ); 169 | }; 170 | /* End PBXProject section */ 171 | 172 | /* Begin PBXResourcesBuildPhase section */ 173 | F83F8FDA24A8A0CE00E5E881 /* Resources */ = { 174 | isa = PBXResourcesBuildPhase; 175 | buildActionMask = 2147483647; 176 | files = ( 177 | ); 178 | runOnlyForDeploymentPostprocessing = 0; 179 | }; 180 | /* End PBXResourcesBuildPhase section */ 181 | 182 | /* Begin PBXSourcesBuildPhase section */ 183 | F83F8FD824A8A0CE00E5E881 /* Sources */ = { 184 | isa = PBXSourcesBuildPhase; 185 | buildActionMask = 2147483647; 186 | files = ( 187 | F83F8FEC24A8A57F00E5E881 /* IO80211Interface.cpp in Sources */, 188 | F83F8FEE24A8A59500E5E881 /* IO80211Controller.cpp in Sources */, 189 | F83F8FE224A8A0CE00E5E881 /* VirtualMac80211.cpp in Sources */, 190 | ); 191 | runOnlyForDeploymentPostprocessing = 0; 192 | }; 193 | /* End PBXSourcesBuildPhase section */ 194 | 195 | /* Begin XCBuildConfiguration section */ 196 | F83F8FE424A8A0CE00E5E881 /* Debug */ = { 197 | isa = XCBuildConfiguration; 198 | buildSettings = { 199 | ALWAYS_SEARCH_USER_PATHS = NO; 200 | CLANG_ANALYZER_NONNULL = YES; 201 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 202 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 203 | CLANG_CXX_LIBRARY = "libc++"; 204 | CLANG_ENABLE_MODULES = YES; 205 | CLANG_ENABLE_OBJC_ARC = YES; 206 | CLANG_ENABLE_OBJC_WEAK = YES; 207 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 208 | CLANG_WARN_BOOL_CONVERSION = YES; 209 | CLANG_WARN_COMMA = YES; 210 | CLANG_WARN_CONSTANT_CONVERSION = YES; 211 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 212 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 213 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 214 | CLANG_WARN_EMPTY_BODY = YES; 215 | CLANG_WARN_ENUM_CONVERSION = YES; 216 | CLANG_WARN_INFINITE_RECURSION = YES; 217 | CLANG_WARN_INT_CONVERSION = YES; 218 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 219 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 220 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 221 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 222 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 223 | CLANG_WARN_STRICT_PROTOTYPES = YES; 224 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 225 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 226 | CLANG_WARN_UNREACHABLE_CODE = YES; 227 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 228 | COPY_PHASE_STRIP = NO; 229 | DEBUG_INFORMATION_FORMAT = dwarf; 230 | ENABLE_STRICT_OBJC_MSGSEND = YES; 231 | ENABLE_TESTABILITY = YES; 232 | GCC_C_LANGUAGE_STANDARD = gnu11; 233 | GCC_DYNAMIC_NO_PIC = NO; 234 | GCC_NO_COMMON_BLOCKS = YES; 235 | GCC_OPTIMIZATION_LEVEL = 0; 236 | GCC_PREPROCESSOR_DEFINITIONS = ( 237 | "DEBUG=1", 238 | "$(inherited)", 239 | ); 240 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 241 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 242 | GCC_WARN_UNDECLARED_SELECTOR = YES; 243 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 244 | GCC_WARN_UNUSED_FUNCTION = YES; 245 | GCC_WARN_UNUSED_VARIABLE = YES; 246 | MACOSX_DEPLOYMENT_TARGET = 10.15; 247 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 248 | MTL_FAST_MATH = YES; 249 | ONLY_ACTIVE_ARCH = YES; 250 | SDKROOT = macosx; 251 | }; 252 | name = Debug; 253 | }; 254 | F83F8FE524A8A0CE00E5E881 /* Release */ = { 255 | isa = XCBuildConfiguration; 256 | buildSettings = { 257 | ALWAYS_SEARCH_USER_PATHS = NO; 258 | CLANG_ANALYZER_NONNULL = YES; 259 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 260 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 261 | CLANG_CXX_LIBRARY = "libc++"; 262 | CLANG_ENABLE_MODULES = YES; 263 | CLANG_ENABLE_OBJC_ARC = YES; 264 | CLANG_ENABLE_OBJC_WEAK = YES; 265 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 266 | CLANG_WARN_BOOL_CONVERSION = YES; 267 | CLANG_WARN_COMMA = YES; 268 | CLANG_WARN_CONSTANT_CONVERSION = YES; 269 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 270 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 271 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 272 | CLANG_WARN_EMPTY_BODY = YES; 273 | CLANG_WARN_ENUM_CONVERSION = YES; 274 | CLANG_WARN_INFINITE_RECURSION = YES; 275 | CLANG_WARN_INT_CONVERSION = YES; 276 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 277 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 278 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 279 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 280 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 281 | CLANG_WARN_STRICT_PROTOTYPES = YES; 282 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 283 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 284 | CLANG_WARN_UNREACHABLE_CODE = YES; 285 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 286 | COPY_PHASE_STRIP = NO; 287 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 288 | ENABLE_NS_ASSERTIONS = NO; 289 | ENABLE_STRICT_OBJC_MSGSEND = YES; 290 | GCC_C_LANGUAGE_STANDARD = gnu11; 291 | GCC_NO_COMMON_BLOCKS = YES; 292 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 293 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 294 | GCC_WARN_UNDECLARED_SELECTOR = YES; 295 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 296 | GCC_WARN_UNUSED_FUNCTION = YES; 297 | GCC_WARN_UNUSED_VARIABLE = YES; 298 | MACOSX_DEPLOYMENT_TARGET = 10.15; 299 | MTL_ENABLE_DEBUG_INFO = NO; 300 | MTL_FAST_MATH = YES; 301 | SDKROOT = macosx; 302 | }; 303 | name = Release; 304 | }; 305 | F83F8FE724A8A0CE00E5E881 /* Debug */ = { 306 | isa = XCBuildConfiguration; 307 | buildSettings = { 308 | CODE_SIGN_STYLE = Automatic; 309 | COMBINE_HIDPI_IMAGES = YES; 310 | CURRENT_PROJECT_VERSION = 1.0.0d1; 311 | DEVELOPMENT_TEAM = ""; 312 | INFOPLIST_FILE = VirtualMac80211/Info.plist; 313 | MACOSX_DEPLOYMENT_TARGET = 10.12; 314 | MARKETING_VERSION = 1.0.0; 315 | MODULE_NAME = com.zxystd.VirtualMac80211; 316 | MODULE_VERSION = 1.0.0d1; 317 | PRODUCT_BUNDLE_IDENTIFIER = com.apple.iokit.VirtualMac80211; 318 | PRODUCT_NAME = "$(TARGET_NAME)"; 319 | SDKROOT = macosx; 320 | WRAPPER_EXTENSION = kext; 321 | }; 322 | name = Debug; 323 | }; 324 | F83F8FE824A8A0CE00E5E881 /* Release */ = { 325 | isa = XCBuildConfiguration; 326 | buildSettings = { 327 | CODE_SIGN_STYLE = Automatic; 328 | COMBINE_HIDPI_IMAGES = YES; 329 | CURRENT_PROJECT_VERSION = 1.0.0d1; 330 | DEVELOPMENT_TEAM = ""; 331 | INFOPLIST_FILE = VirtualMac80211/Info.plist; 332 | MACOSX_DEPLOYMENT_TARGET = 10.12; 333 | MARKETING_VERSION = 1.0.0; 334 | MODULE_NAME = com.zxystd.VirtualMac80211; 335 | MODULE_VERSION = 1.0.0d1; 336 | PRODUCT_BUNDLE_IDENTIFIER = com.apple.iokit.VirtualMac80211; 337 | PRODUCT_NAME = "$(TARGET_NAME)"; 338 | SDKROOT = macosx; 339 | WRAPPER_EXTENSION = kext; 340 | }; 341 | name = Release; 342 | }; 343 | /* End XCBuildConfiguration section */ 344 | 345 | /* Begin XCConfigurationList section */ 346 | F83F8FD624A8A0CD00E5E881 /* Build configuration list for PBXProject "VirtualMac80211" */ = { 347 | isa = XCConfigurationList; 348 | buildConfigurations = ( 349 | F83F8FE424A8A0CE00E5E881 /* Debug */, 350 | F83F8FE524A8A0CE00E5E881 /* Release */, 351 | ); 352 | defaultConfigurationIsVisible = 0; 353 | defaultConfigurationName = Release; 354 | }; 355 | F83F8FE624A8A0CE00E5E881 /* Build configuration list for PBXNativeTarget "VirtualMac80211" */ = { 356 | isa = XCConfigurationList; 357 | buildConfigurations = ( 358 | F83F8FE724A8A0CE00E5E881 /* Debug */, 359 | F83F8FE824A8A0CE00E5E881 /* Release */, 360 | ); 361 | defaultConfigurationIsVisible = 0; 362 | defaultConfigurationName = Release; 363 | }; 364 | /* End XCConfigurationList section */ 365 | }; 366 | rootObject = F83F8FD324A8A0CD00E5E881 /* Project object */; 367 | } 368 | -------------------------------------------------------------------------------- /VirtualMac80211/AirportIOCTL.h: -------------------------------------------------------------------------------- 1 | // 2 | // AirportIOCTL.h 3 | // VirtualMac80211 4 | // 5 | // Created by qcwap on 2020/6/28. 6 | // Copyright © 2020 zxystd. All rights reserved. 7 | // 8 | 9 | #ifndef AirportIOCTL_h 10 | #define AirportIOCTL_h 11 | 12 | #include "apple/IONetworkInterface.h" 13 | 14 | IOReturn sGetSSID(IONetworkInterface *inf, struct apple80211req *data); 15 | 16 | IOReturn sGetBSSID(IONetworkInterface *inf, struct apple80211req *data); 17 | 18 | IOReturn sGetPOWER(IONetworkInterface *inf, struct apple80211req *data); 19 | 20 | IOReturn sGetINT_MIT(IONetworkInterface *inf, struct apple80211req *data); 21 | 22 | IOReturn sGetAuthType(IONetworkInterface *inf, struct apple80211req *data); 23 | 24 | IOReturn sGetCardCapa(IONetworkInterface *inf, struct apple80211req *data); 25 | 26 | IOReturn sGetOpMode(IONetworkInterface *inf, struct apple80211req *data); 27 | 28 | IOReturn sGetPhyMode(IONetworkInterface *inf, struct apple80211req *data); 29 | 30 | IOReturn sGetRSSI(IONetworkInterface *inf, struct apple80211req *data); 31 | 32 | IOReturn sGetNoise(IONetworkInterface *inf, struct apple80211req *data); 33 | 34 | IOReturn sGetChannel(IONetworkInterface *inf, struct apple80211req *data); 35 | 36 | IOReturn sGetAuthType(IONetworkInterface *inf, struct apple80211req *data); 37 | 38 | IOReturn sGetRate(IONetworkInterface *inf, struct apple80211req *data); 39 | 40 | IOReturn sGetState(IONetworkInterface *inf, struct apple80211req *data); 41 | 42 | IOReturn sGetCountryCode(IONetworkInterface *inf, struct apple80211req *data); 43 | 44 | IOReturn sGetMCS(IONetworkInterface *inf, struct apple80211req *data); 45 | 46 | IOReturn sGetTxPower(IONetworkInterface *inf, struct apple80211req *data); 47 | 48 | IOReturn sGetPowerSave(IONetworkInterface *inf, struct apple80211req *data); 49 | 50 | IOReturn sGetProtMode(IONetworkInterface *inf, struct apple80211req *data); 51 | 52 | IOReturn sGetIntMit(IONetworkInterface *inf, struct apple80211req *data); 53 | 54 | IOReturn sGetSupportedChannels(IONetworkInterface *inf, struct apple80211req *data); 55 | 56 | IOReturn sGetHWSupportedChannels(IONetworkInterface *inf, struct apple80211req *data); 57 | 58 | IOReturn sGetVersion(IONetworkInterface *inf, struct apple80211req *data); 59 | 60 | IOReturn sGetScanResult(IONetworkInterface *inf, struct apple80211req *data); 61 | 62 | 63 | IOReturn sSetPOWER(IONetworkInterface *inf, struct apple80211req *data); 64 | 65 | IOReturn sSetScanRequest(IONetworkInterface *inf, struct apple80211req *data); 66 | 67 | IOReturn sSetScanRequestMultiple(IONetworkInterface *inf, struct apple80211req *data); 68 | 69 | IOReturn sSetScanCacheClear(IONetworkInterface *inf, struct apple80211req *data); 70 | 71 | #endif /* AirportIOCTL_h */ 72 | -------------------------------------------------------------------------------- /VirtualMac80211/IO80211Controller.cpp: -------------------------------------------------------------------------------- 1 | #include "IO80211Controller.hpp" 2 | #include "AirportIOCTL.h" 3 | 4 | OSDefineMetaClassAndAbstractStructors(IO80211Controller, IOEthernetController) 5 | 6 | IOReturn sGetPOWER(IONetworkInterface *inf, struct apple80211req *data) 7 | { 8 | IOReturn ret; 9 | struct apple80211_power_data pd; 10 | IO80211Controller *ctl = OSDynamicCast(IO80211Controller, inf->getController()); 11 | if (!ctl) { 12 | return kIOReturnError; 13 | } 14 | ret = ctl->getPOWER(OSDynamicCast(IO80211Interface, inf), &pd); 15 | if (ret == kIOReturnSuccess) { 16 | size_t len = sizeof(struct apple80211_power_data); 17 | if (data->req_len < sizeof(struct apple80211_power_data)) { 18 | len = data->req_len; 19 | } 20 | copyout(&pd, (user_addr_t)data->req_data, len); 21 | } 22 | return ret; 23 | } 24 | 25 | IOReturn sGetSSID(IONetworkInterface *inf, struct apple80211req *data) 26 | { 27 | IOReturn ret; 28 | struct apple80211_ssid_data pd; 29 | IO80211Controller *ctl = OSDynamicCast(IO80211Controller, inf->getController()); 30 | if (!ctl) { 31 | return kIOReturnError; 32 | } 33 | ret = ctl->getSSID(OSDynamicCast(IO80211Interface, inf), &pd); 34 | if (ret == kIOReturnSuccess) { 35 | if (data->req_len < pd.ssid_len) { 36 | data->req_len = pd.ssid_len; 37 | } 38 | copyout(pd.ssid_bytes, (user_addr_t)data->req_data, data->req_len); 39 | } 40 | return ret; 41 | } 42 | 43 | IOReturn sGetBSSID(IONetworkInterface *inf, struct apple80211req *data) 44 | { 45 | IOReturn ret; 46 | struct apple80211_bssid_data pd; 47 | IO80211Controller *ctl = OSDynamicCast(IO80211Controller, inf->getController()); 48 | if (!ctl) { 49 | return kIOReturnError; 50 | } 51 | ret = ctl->getBSSID(OSDynamicCast(IO80211Interface, inf), &pd); 52 | if (ret == kIOReturnSuccess) { 53 | data->req_len = 6; 54 | copyout(pd.bssid.octet, (user_addr_t)data->req_data, 6); 55 | } 56 | return ret; 57 | } 58 | 59 | IOReturn sGetCardCapa(IONetworkInterface *inf, struct apple80211req *data) 60 | { 61 | IOReturn ret; 62 | struct apple80211_capability_data pd; 63 | IO80211Controller *ctl = OSDynamicCast(IO80211Controller, inf->getController()); 64 | if (!ctl) { 65 | return kIOReturnError; 66 | } 67 | ret = ctl->getCARD_CAPABILITIES(OSDynamicCast(IO80211Interface, inf), &pd); 68 | if (ret == kIOReturnSuccess) { 69 | size_t len = sizeof(struct apple80211_capability_data) - sizeof(uint32_t); 70 | if (data->req_len < sizeof(struct apple80211_capability_data) - sizeof(uint32_t)) { 71 | len = data->req_len; 72 | } 73 | copyout(pd.capabilities, (user_addr_t)data->req_data, len); 74 | } 75 | return ret; 76 | } 77 | 78 | IOReturn sGetOpMode(IONetworkInterface *inf, struct apple80211req *data) 79 | { 80 | IOReturn ret; 81 | struct apple80211_opmode_data pd; 82 | IO80211Controller *ctl = OSDynamicCast(IO80211Controller, inf->getController()); 83 | if (!ctl) { 84 | return kIOReturnError; 85 | } 86 | ret = ctl->getOP_MODE(OSDynamicCast(IO80211Interface, inf), &pd); 87 | if (ret == kIOReturnSuccess) { 88 | data->req_val = pd.op_mode; 89 | } 90 | return ret; 91 | } 92 | 93 | IOReturn sGetPhyMode(IONetworkInterface *inf, struct apple80211req *data) 94 | { 95 | IOReturn ret; 96 | struct apple80211_phymode_data pd; 97 | IO80211Controller *ctl = OSDynamicCast(IO80211Controller, inf->getController()); 98 | if (!ctl) { 99 | return kIOReturnError; 100 | } 101 | ret = ctl->getPHY_MODE(OSDynamicCast(IO80211Interface, inf), &pd); 102 | if (ret == kIOReturnSuccess) { 103 | copyout(&pd, (user_addr_t)data->req_data, data->req_len); 104 | } 105 | return ret; 106 | } 107 | 108 | IOReturn sGetRSSI(IONetworkInterface *inf, struct apple80211req *data) 109 | { 110 | IOReturn ret; 111 | struct apple80211_rssi_data pd; 112 | IO80211Controller *ctl = OSDynamicCast(IO80211Controller, inf->getController()); 113 | if (!ctl) { 114 | return kIOReturnError; 115 | } 116 | ret = ctl->getRSSI(OSDynamicCast(IO80211Interface, inf), &pd); 117 | if (ret == kIOReturnSuccess) { 118 | copyout(&pd, (user_addr_t)data->req_data, data->req_len); 119 | } 120 | return ret; 121 | } 122 | 123 | IOReturn sGetNoise(IONetworkInterface *inf, struct apple80211req *data) 124 | { 125 | IOReturn ret; 126 | struct apple80211_noise_data pd; 127 | IO80211Controller *ctl = OSDynamicCast(IO80211Controller, inf->getController()); 128 | if (!ctl) { 129 | return kIOReturnError; 130 | } 131 | ret = ctl->getNOISE(OSDynamicCast(IO80211Interface, inf), &pd); 132 | if (ret == kIOReturnSuccess) { 133 | copyout(&pd, (user_addr_t)data->req_data, data->req_len); 134 | } 135 | return ret; 136 | } 137 | 138 | IOReturn sGetRate(IONetworkInterface *inf, struct apple80211req *data) 139 | { 140 | IOReturn ret; 141 | struct apple80211_rate_data pd; 142 | IO80211Controller *ctl = OSDynamicCast(IO80211Controller, inf->getController()); 143 | if (!ctl) { 144 | return kIOReturnError; 145 | } 146 | ret = ctl->getRATE(OSDynamicCast(IO80211Interface, inf), &pd); 147 | if (ret == kIOReturnSuccess) { 148 | copyout(&pd, (user_addr_t)data->req_data, data->req_len); 149 | } 150 | return ret; 151 | } 152 | 153 | IOReturn sGetChannel(IONetworkInterface *inf, struct apple80211req *data) 154 | { 155 | IOReturn ret; 156 | struct apple80211_channel_data pd; 157 | IO80211Controller *ctl = OSDynamicCast(IO80211Controller, inf->getController()); 158 | if (!ctl) { 159 | return kIOReturnError; 160 | } 161 | ret = ctl->getCHANNEL(OSDynamicCast(IO80211Interface, inf), &pd); 162 | if (ret == kIOReturnSuccess) { 163 | copyout(&pd, (user_addr_t)data->req_data, data->req_len); 164 | } 165 | return ret; 166 | } 167 | 168 | IOReturn sGetAuthType(IONetworkInterface *inf, struct apple80211req *data) 169 | { 170 | IOReturn ret; 171 | struct apple80211_authtype_data pd; 172 | IO80211Controller *ctl = OSDynamicCast(IO80211Controller, inf->getController()); 173 | if (!ctl) { 174 | return kIOReturnError; 175 | } 176 | ret = ctl->getAUTH_TYPE(OSDynamicCast(IO80211Interface, inf), &pd); 177 | if (ret == kIOReturnSuccess) { 178 | copyout(&pd, (user_addr_t)data->req_data, data->req_len); 179 | } 180 | return ret; 181 | } 182 | 183 | IOReturn sGetState(IONetworkInterface *inf, struct apple80211req *data) 184 | { 185 | IOReturn ret; 186 | struct apple80211_state_data pd; 187 | IO80211Controller *ctl = OSDynamicCast(IO80211Controller, inf->getController()); 188 | if (!ctl) { 189 | return kIOReturnError; 190 | } 191 | ret = ctl->getSTATE(OSDynamicCast(IO80211Interface, inf), &pd); 192 | if (ret == kIOReturnSuccess) { 193 | data->req_val = pd.state; 194 | } 195 | return ret; 196 | } 197 | 198 | IOReturn sGetCountryCode(IONetworkInterface *inf, struct apple80211req *data) 199 | { 200 | IOReturn ret; 201 | struct apple80211_country_code_data pd; 202 | IO80211Controller *ctl = OSDynamicCast(IO80211Controller, inf->getController()); 203 | if (!ctl) { 204 | return kIOReturnError; 205 | } 206 | ret = ctl->getCOUNTRY_CODE(OSDynamicCast(IO80211Interface, inf), &pd); 207 | if (ret == kIOReturnSuccess) { 208 | copyout(pd.cc, (user_addr_t)data->req_data, sizeof(pd.cc)); 209 | } 210 | return ret; 211 | } 212 | 213 | IOReturn sGetMCS(IONetworkInterface *inf, struct apple80211req *data) 214 | { 215 | IOReturn ret; 216 | struct apple80211_mcs_data pd; 217 | IO80211Controller *ctl = OSDynamicCast(IO80211Controller, inf->getController()); 218 | if (!ctl) { 219 | return kIOReturnError; 220 | } 221 | ret = ctl->getMCS(OSDynamicCast(IO80211Interface, inf), &pd); 222 | if (ret == kIOReturnSuccess) { 223 | copyout(&pd, (user_addr_t)data->req_data, data->req_len); 224 | } 225 | return ret; 226 | } 227 | 228 | IOReturn sGetTxPower(IONetworkInterface *inf, struct apple80211req *data) 229 | { 230 | IOReturn ret; 231 | struct apple80211_txpower_data pd; 232 | IO80211Controller *ctl = OSDynamicCast(IO80211Controller, inf->getController()); 233 | if (!ctl) { 234 | return kIOReturnError; 235 | } 236 | ret = ctl->getTXPOWER(OSDynamicCast(IO80211Interface, inf), &pd); 237 | if (ret == kIOReturnSuccess) { 238 | copyout(&pd, (user_addr_t)data->req_data, data->req_len); 239 | } 240 | return ret; 241 | } 242 | 243 | IOReturn sGetPowerSave(IONetworkInterface *inf, struct apple80211req *data) 244 | { 245 | IOReturn ret; 246 | struct apple80211_powersave_data pd; 247 | IO80211Controller *ctl = OSDynamicCast(IO80211Controller, inf->getController()); 248 | if (!ctl) { 249 | return kIOReturnError; 250 | } 251 | ret = ctl->getPOWERSAVE(OSDynamicCast(IO80211Interface, inf), &pd); 252 | if (ret == kIOReturnSuccess) { 253 | data->req_val = pd.powersave_level; 254 | } 255 | return ret; 256 | } 257 | 258 | IOReturn sGetProtMode(IONetworkInterface *inf, struct apple80211req *data) 259 | { 260 | IOReturn ret; 261 | struct apple80211_protmode_data pd; 262 | IO80211Controller *ctl = OSDynamicCast(IO80211Controller, inf->getController()); 263 | if (!ctl) { 264 | return kIOReturnError; 265 | } 266 | ret = ctl->getPROTMODE(OSDynamicCast(IO80211Interface, inf), &pd); 267 | if (ret == kIOReturnSuccess) { 268 | copyout(&pd, (user_addr_t)data->req_data, data->req_len); 269 | } 270 | return ret; 271 | } 272 | 273 | IOReturn sGetIntMit(IONetworkInterface *inf, struct apple80211req *data) 274 | { 275 | IOReturn ret; 276 | struct apple80211_intmit_data pd; 277 | IO80211Controller *ctl = OSDynamicCast(IO80211Controller, inf->getController()); 278 | if (!ctl) { 279 | return kIOReturnError; 280 | } 281 | ret = ctl->getINT_MIT(OSDynamicCast(IO80211Interface, inf), &pd); 282 | if (ret == kIOReturnSuccess) { 283 | data->req_val = pd.int_mit; 284 | } 285 | return ret; 286 | } 287 | 288 | IOReturn sGetSupportedChannels(IONetworkInterface *inf, struct apple80211req *data) 289 | { 290 | IOReturn ret; 291 | struct apple80211_sup_channel_data pd; 292 | IO80211Controller *ctl = OSDynamicCast(IO80211Controller, inf->getController()); 293 | if (!ctl) { 294 | return kIOReturnError; 295 | } 296 | ret = ctl->getSUPPORTED_CHANNELS(OSDynamicCast(IO80211Interface, inf), &pd); 297 | if (ret == kIOReturnSuccess) { 298 | data->req_len = min(data->req_len, sizeof(struct apple80211_sup_channel_data)); 299 | copyout(&pd, (user_addr_t)data->req_data, data->req_len); 300 | } 301 | return ret; 302 | } 303 | 304 | IOReturn sGetHWSupportedChannels(IONetworkInterface *inf, struct apple80211req *data) 305 | { 306 | IOReturn ret; 307 | struct apple80211_sup_channel_data pd; 308 | IO80211Controller *ctl = OSDynamicCast(IO80211Controller, inf->getController()); 309 | if (!ctl) { 310 | return kIOReturnError; 311 | } 312 | ret = ctl->getHW_SUPPORTED_CHANNELS(OSDynamicCast(IO80211Interface, inf), &pd); 313 | if (ret == kIOReturnSuccess) { 314 | data->req_len = min(data->req_len, sizeof(struct apple80211_sup_channel_data)); 315 | copyout(&pd, (user_addr_t)data->req_data, data->req_len); 316 | } 317 | return ret; 318 | } 319 | 320 | IOReturn sGetVersion(IONetworkInterface *inf, struct apple80211req *data) 321 | { 322 | IOReturn ret; 323 | struct apple80211_version_data pd; 324 | IO80211Controller *ctl = OSDynamicCast(IO80211Controller, inf->getController()); 325 | if (!ctl) { 326 | return kIOReturnError; 327 | } 328 | ret = ctl->getDRIVER_VERSION(OSDynamicCast(IO80211Interface, inf), &pd); 329 | if (ret == kIOReturnSuccess) { 330 | data->req_len = min(pd.string_len, sizeof(struct apple80211_version_data)); 331 | copyout((uint8_t *)&pd + offsetof(struct apple80211_version_data, string), (user_addr_t)data->req_data, min(pd.string_len, sizeof(pd.string))); 332 | } 333 | return ret; 334 | } 335 | 336 | IOReturn sGetScanResult(IONetworkInterface *inf, struct apple80211req *data) 337 | { 338 | IOReturn ret; 339 | struct apple80211_scan_result *sr; 340 | struct apple80211_scan_result *result; 341 | IO80211Controller *ctl = OSDynamicCast(IO80211Controller, inf->getController()); 342 | if (!ctl) { 343 | return kIOReturnError; 344 | } 345 | if (data->req_flag == 8) { 346 | if (data->req_len != sizeof(struct apple80211_scan_result)) { 347 | VMLog("%s Invalid req len %lld\n", __FUNCTION__, data->req_len); 348 | return kIOReturnBadArgument; 349 | } 350 | } else if (data->req_len != 144) { 351 | VMLog("%s Invalid req len %lld\n", __FUNCTION__, data->req_len); 352 | return kIOReturnBadArgument; 353 | } 354 | ret = ctl->getSCAN_RESULT(OSDynamicCast(IO80211Interface, inf), &sr); 355 | if (sr == NULL || ret != kIOReturnSuccess) { 356 | return ret; 357 | } 358 | result = (struct apple80211_scan_result *)IOMalloc(sizeof(struct apple80211_scan_result)); 359 | if (data->req_flag == 8) { 360 | if (copyin((user_addr_t)data->req_data, result, sizeof(struct apple80211_scan_result))) { 361 | VMLog("%s %d copy fail\n", __FUNCTION__, __LINE__); 362 | ret = kIOReturnIOError; 363 | goto freeNow; 364 | } 365 | result->version = sr->version; 366 | result->asr_channel.version = sr->asr_channel.version; 367 | result->asr_channel.channel = sr->asr_channel.channel; 368 | result->asr_channel.flags = sr->asr_channel.flags; 369 | result->asr_age = sr->asr_age; 370 | result->asr_beacon_int = sr->asr_beacon_int; 371 | result->asr_cap = sr->asr_cap; 372 | memcpy(result->asr_bssid, sr->asr_bssid, sizeof(sr->asr_bssid)); 373 | result->asr_ssid_len = sr->asr_ssid_len; 374 | memcpy(result->asr_ssid, sr->asr_ssid, sizeof(sr->asr_ssid)); 375 | result->asr_nrates = sr->asr_nrates; 376 | memcpy(result->asr_rates, sr->asr_rates, sizeof(sr->asr_rates)); 377 | result->asr_snr = sr->asr_snr; 378 | } else { 379 | if (copyin((user_addr_t)data->req_data, result, 144)) { 380 | VMLog("%s %d copy fail\n", __FUNCTION__, __LINE__); 381 | ret = kIOReturnIOError; 382 | goto freeNow; 383 | } 384 | result->version = sr->version; 385 | result->asr_channel.version = sr->asr_channel.version; 386 | result->asr_channel.channel = sr->asr_channel.channel; 387 | result->asr_channel.flags = sr->asr_channel.flags; 388 | result->asr_age = sr->asr_age; 389 | result->asr_beacon_int = sr->asr_beacon_int; 390 | result->asr_cap = sr->asr_cap; 391 | memcpy(result->asr_bssid, sr->asr_bssid, sizeof(sr->asr_bssid)); 392 | result->asr_ssid_len = sr->asr_ssid_len; 393 | memcpy(result->asr_ssid, sr->asr_ssid, sizeof(sr->asr_ssid)); 394 | result->asr_nrates = sr->asr_nrates; 395 | memcpy(result->asr_rates, sr->asr_rates, sizeof(sr->asr_rates)); 396 | result->asr_snr = sr->asr_snr; 397 | VMLog("%s %d Return result %d\n", __FUNCTION__, __LINE__, data->req_flag); 398 | } 399 | copyout(result, (user_addr_t)data->req_data, data->req_len); 400 | freeNow: 401 | IOFree(result, sizeof(struct apple80211_scan_result)); 402 | return ret; 403 | } 404 | 405 | IOReturn sSetPOWER(IONetworkInterface *inf, struct apple80211req *data) 406 | { 407 | IOReturn ret; 408 | struct apple80211_power_data pd; 409 | IO80211Controller *ctl = OSDynamicCast(IO80211Controller, inf->getController()); 410 | if (!ctl) { 411 | return kIOReturnError; 412 | } 413 | if (copyin((user_addr_t)data->req_data, &pd, sizeof(struct apple80211_power_data))) { 414 | return kIOReturnError; 415 | } 416 | ret = ctl->setPOWER(OSDynamicCast(IO80211Interface, inf), &pd); 417 | OSDynamicCast(IO80211Interface, inf)->postMessage(APPLE80211_M_POWER_CHANGED); 418 | return ret; 419 | } 420 | 421 | IOReturn sSetScanRequest(IONetworkInterface *inf, struct apple80211req *data) 422 | { 423 | struct apple80211_scan_data sd; 424 | 425 | IO80211Controller *ctl = OSDynamicCast(IO80211Controller, inf->getController()); 426 | if (!ctl) { 427 | return kIOReturnError; 428 | } 429 | bzero(&sd, sizeof(sd)); 430 | if (copyin((user_addr_t)data->req_data, &sd, sizeof(struct apple80211_scan_data))) { 431 | return kIOReturnError; 432 | }; 433 | return ctl->setSCAN_REQ(OSDynamicCast(IO80211Interface, inf), &sd); 434 | } 435 | 436 | IOReturn sSetScanRequestMultiple(IONetworkInterface *inf, struct apple80211req *data) 437 | { 438 | struct apple80211_scan_multiple_data sd; 439 | 440 | IO80211Controller *ctl = OSDynamicCast(IO80211Controller, inf->getController()); 441 | if (!ctl) { 442 | return kIOReturnError; 443 | } 444 | bzero(&sd, sizeof(sd)); 445 | if (copyin((user_addr_t)data->req_data, &sd, sizeof(struct apple80211_scan_multiple_data))) { 446 | return kIOReturnError; 447 | }; 448 | return ctl->setSCAN_REQ_MULTIPLE(OSDynamicCast(IO80211Interface, inf), &sd); 449 | } 450 | 451 | IOReturn sSetScanCacheClear(IONetworkInterface *inf, struct apple80211req *data) 452 | { 453 | IO80211Controller *ctl = OSDynamicCast(IO80211Controller, inf->getController()); 454 | if (!ctl) { 455 | return kIOReturnError; 456 | } 457 | return ctl->setSCANCACHE_CLEAR(OSDynamicCast(IO80211Interface, inf)); 458 | } 459 | 460 | bool IO80211Controller:: 461 | setLinkStatus(UInt32 status, const IONetworkMedium * activeMedium, UInt64 speed, OSData *data) 462 | { 463 | bool ret = IOEthernetController::setLinkStatus(status, activeMedium, speed, data); 464 | if (getNetworkInterface()) { 465 | if (status & kIONetworkLinkActive) { 466 | VMLog("AirPort: Link Up on %s.\n", getNetworkInterface()->getBSDName()); 467 | } else if (!(status & kIONetworkLinkNoNetworkChange)) { 468 | VMLog("AirPort: Link Down on %s.\n", getNetworkInterface()->getBSDName()); 469 | } 470 | getNetworkInterface()->postMessage(APPLE80211_M_LINK_CHANGED); 471 | getNetworkInterface()->postMessage(APPLE80211_M_SSID_CHANGED); 472 | getNetworkInterface()->postMessage(APPLE80211_M_BSSID_CHANGED); 473 | } 474 | return ret; 475 | } 476 | -------------------------------------------------------------------------------- /VirtualMac80211/IO80211Controller.hpp: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ifndef IO80211Controller_hpp 4 | #define IO80211Controller_hpp 5 | 6 | #include 7 | #include "IOEthernetController.h" 8 | #include "IO80211Interface.hpp" 9 | 10 | class IO80211Controller : public IOEthernetController { 11 | OSDeclareAbstractStructors(IO80211Controller) 12 | 13 | public: 14 | 15 | virtual IOReturn getSSID(IO80211Interface *interface, struct apple80211_ssid_data *sd) { 16 | return kIOReturnError; 17 | }; 18 | 19 | virtual IOReturn setSSID(IO80211Interface *interface, struct apple80211_ssid_data *sd) { 20 | return kIOReturnError; 21 | } 22 | 23 | virtual IOReturn getAUTH_TYPE(IO80211Interface *interface, struct apple80211_authtype_data *ad) { 24 | return kIOReturnError; 25 | } 26 | 27 | virtual IOReturn getCHANNEL(IO80211Interface *interface, 28 | struct apple80211_channel_data *cd) { 29 | return kIOReturnError; 30 | } 31 | 32 | virtual IOReturn getPROTMODE(IO80211Interface *interface, struct apple80211_protmode_data *pd) { 33 | return kIOReturnError; 34 | } 35 | 36 | virtual IOReturn getTXPOWER(IO80211Interface *interface, 37 | struct apple80211_txpower_data *txd) { 38 | return kIOReturnError; 39 | } 40 | 41 | virtual IOReturn getRATE(IO80211Interface* interface, 42 | struct apple80211_rate_data* rd) { 43 | return kIOReturnError; 44 | } 45 | 46 | virtual IOReturn getBSSID(IO80211Interface* interface, 47 | struct apple80211_bssid_data* bd) { 48 | return kIOReturnError; 49 | } 50 | 51 | virtual IOReturn setSCANCACHE_CLEAR(IO80211Interface *interface) { 52 | return kIOReturnSuccess; 53 | } 54 | 55 | virtual IOReturn setSCAN_REQ(IO80211Interface* interface, 56 | struct apple80211_scan_data* sd) { 57 | return kIOReturnError; 58 | } 59 | 60 | virtual IOReturn setSCAN_REQ_MULTIPLE(IO80211Interface* interface, 61 | struct apple80211_scan_multiple_data* sd) { 62 | return kIOReturnError; 63 | } 64 | 65 | virtual IOReturn getSCAN_RESULT(IO80211Interface* interface, 66 | apple80211_scan_result** sr) { 67 | return kIOReturnError; 68 | } 69 | 70 | virtual IOReturn getCARD_CAPABILITIES(IO80211Interface* interface, 71 | struct apple80211_capability_data* cd) { 72 | return kIOReturnError; 73 | } 74 | 75 | virtual IOReturn getSTATE(IO80211Interface* interface, 76 | struct apple80211_state_data* sd) { 77 | return kIOReturnError; 78 | } 79 | 80 | virtual IOReturn setSTATE(IO80211Interface* interface, 81 | struct apple80211_state_data* sd) { 82 | return kIOReturnError; 83 | } 84 | 85 | virtual IOReturn getPHY_MODE(IO80211Interface* interface, 86 | struct apple80211_phymode_data* pd) { 87 | return kIOReturnError; 88 | } 89 | 90 | virtual IOReturn getOP_MODE(IO80211Interface* interface, 91 | struct apple80211_opmode_data* od) { 92 | return kIOReturnError; 93 | } 94 | 95 | virtual IOReturn getRSSI(IO80211Interface* interface, 96 | struct apple80211_rssi_data* rd) { 97 | return kIOReturnError; 98 | } 99 | 100 | virtual IOReturn getNOISE(IO80211Interface* interface, 101 | struct apple80211_noise_data* nd) { 102 | return kIOReturnError; 103 | } 104 | 105 | virtual IOReturn getINT_MIT(IO80211Interface* interface, 106 | struct apple80211_intmit_data* imd) { 107 | return kIOReturnError; 108 | } 109 | 110 | virtual IOReturn getPOWER(IO80211Interface* interface, 111 | struct apple80211_power_data* pd) { 112 | return kIOReturnError; 113 | } 114 | 115 | virtual IOReturn setPOWER(IO80211Interface* interface, 116 | struct apple80211_power_data* pd) { 117 | return kIOReturnError; 118 | } 119 | 120 | virtual IOReturn getCOUNTRY_CODE(IO80211Interface* interface, 121 | struct apple80211_country_code_data* cd) { 122 | return kIOReturnError; 123 | } 124 | 125 | virtual IOReturn getMCS(IO80211Interface* interface, struct apple80211_mcs_data* md) { 126 | return kIOReturnError; 127 | } 128 | 129 | virtual IOReturn getPOWERSAVE(IO80211Interface* interface, struct apple80211_powersave_data *pd) { 130 | return kIOReturnError; 131 | } 132 | 133 | virtual IOReturn getSUPPORTED_CHANNELS(IO80211Interface* interface, struct apple80211_sup_channel_data *pd) { 134 | return kIOReturnError; 135 | } 136 | 137 | virtual IOReturn getHW_SUPPORTED_CHANNELS(IO80211Interface* interface, struct apple80211_sup_channel_data *pd) { 138 | return kIOReturnError; 139 | } 140 | 141 | virtual IOReturn getDRIVER_VERSION(IO80211Interface *interface, 142 | struct apple80211_version_data *hv) { 143 | return kIOReturnError; 144 | } 145 | 146 | virtual IOReturn getHARDWARE_VERSION(IO80211Interface *interface, 147 | struct apple80211_version_data *hv) { 148 | return kIOReturnError; 149 | } 150 | 151 | virtual IO80211Interface *getNetworkInterface() 152 | { 153 | return _netIf; 154 | } 155 | 156 | virtual bool attachInterface(IONetworkInterface ** interface, bool doRegister = true) override 157 | { 158 | if (IOEthernetController::attachInterface(interface, doRegister)) { 159 | _netIf = OSDynamicCast(IO80211Interface, *interface); 160 | return true; 161 | } 162 | return false; 163 | }; 164 | 165 | virtual void detachInterface(IONetworkInterface * interface, bool sync = false) override 166 | { 167 | IOEthernetController::detachInterface(interface, sync); 168 | _netIf = NULL; 169 | } 170 | 171 | virtual bool setLinkStatus( 172 | UInt32 status, 173 | const IONetworkMedium * activeMedium = 0, 174 | UInt64 speed = 0, 175 | OSData * data = 0) override; 176 | 177 | private: 178 | IO80211Interface *_netIf; 179 | }; 180 | 181 | #endif /* IO80211Controller_hpp */ 182 | -------------------------------------------------------------------------------- /VirtualMac80211/IO80211Interface.cpp: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include "IO80211Interface.hpp" 4 | #include 5 | extern "C" { 6 | #include 7 | } 8 | #include "AirportIOCTL.h" 9 | 10 | #define super IOEthernetInterface 11 | OSDefineMetaClassAndStructors( IO80211Interface, IOEthernetInterface ) 12 | 13 | bool IO80211Interface::init(IONetworkController *controller) 14 | { 15 | VMLog("%s\n", __FUNCTION__); 16 | if ( super::init(controller) == false ) 17 | return false; 18 | setInterfaceSubType(3); 19 | return true; 20 | } 21 | 22 | void IO80211Interface::free() 23 | { 24 | VMLog("%s\n", __FUNCTION__); 25 | super::free(); 26 | } 27 | 28 | SInt32 IO80211Interface::performCommand( IONetworkController * controller, 29 | unsigned long cmd, 30 | void * arg0, 31 | void * arg1 ) 32 | { 33 | // VMLog("%s cmd=%lu, arg0=%p, arg1=%p\n", __FUNCTION__, cmd, arg0, arg1); 34 | uint64_t v7; 35 | 36 | if ( controller == NULL ) return EINVAL; 37 | 38 | if (cmd <= 3223349704LL) { 39 | if (cmd != 2149607880LL) { 40 | v7 = 2150132168LL; 41 | goto label_6; 42 | } 43 | return controller->executeCommand( 44 | this, 45 | (IONetworkController::Action) 46 | &IO80211Interface::performGatedCommand, 47 | this, 48 | controller, 49 | &cmd, 50 | arg0, 51 | arg1 ); 52 | } 53 | if (cmd == 3223873993LL) { 54 | return controller->executeCommand( 55 | this, 56 | (IONetworkController::Action) 57 | &IO80211Interface::performGatedCommand, 58 | this, 59 | controller, 60 | &cmd, 61 | arg0, 62 | arg1 ); 63 | } 64 | v7 = 3223349705LL; 65 | label_6: 66 | if (cmd == v7) { 67 | return controller->executeCommand( 68 | this, 69 | (IONetworkController::Action) 70 | &IO80211Interface::performGatedCommand, 71 | this, 72 | controller, 73 | &cmd, 74 | arg0, 75 | arg1 ); 76 | } 77 | return super::performCommand(controller, cmd, arg0, arg1); 78 | } 79 | 80 | UInt64 IO80211Interface::IO80211InterfaceUserSpaceToKernelApple80211Request(void *arg, apple80211req *req, unsigned long ctl) 81 | { 82 | uint8_t *a1 = (uint8_t *)arg; 83 | uint8_t *req_ptr = (uint8_t*)req; 84 | if (a1 == NULL) { 85 | VMLog("%s a1==NULL\n", __FUNCTION__); 86 | return 0; 87 | } 88 | *(uint64_t*)(req_ptr + 8) = *((uint64_t*)((uint8_t*)a1 + 8)); 89 | *(uint64_t*)req_ptr = *(uint64_t*)a1; 90 | *(uint32_t*)(req_ptr + 0x10) = *((uint32_t*)((uint8_t*)a1 + 0x10)); 91 | *(uint32_t*)(req_ptr + 0x14) = *((uint32_t*)((uint8_t*)a1 + 0x14)); 92 | *(uint32_t*)(req_ptr + 0x18) = *((uint32_t*)((uint8_t*)a1 + 0x18)); 93 | if ( ctl != 3223873993LL && ctl != 2150132168LL ) { 94 | req->req_data = (void *)(uint64_t)(*((uint32_t*)((uint8_t*)a1 + 0x1C))); 95 | req->req_flag = 4; 96 | } else { 97 | req->req_data = (void *)*((uint64_t*)((uint8_t*)a1 + 0x20)); 98 | req->req_flag = 8; 99 | } 100 | // VMLog("%s %s req_len=%d req_val=%d req_type=%d req_flag=%d\n", __FUNCTION__, req->req_if_name, req->req_len, req->req_val, req->req_type, req->req_flag); 101 | return (UInt64)req->req_data; 102 | } 103 | 104 | int IO80211Interface::performGatedCommand(void * target, 105 | void * arg1_ctr, 106 | void * arg2_cmd, 107 | void * arg3_0, 108 | void * arg4_1) 109 | { 110 | // VMLog("%s\n", __FUNCTION__); 111 | apple80211req req; 112 | UInt64 method; 113 | IO80211Interface *that = (IO80211Interface *)target; 114 | if (!arg1_ctr) { 115 | return 22LL; 116 | } 117 | UInt64 cmd = *(UInt64 *)arg2_cmd; 118 | bzero(&req, sizeof(apple80211req)); 119 | that->IO80211InterfaceUserSpaceToKernelApple80211Request(arg4_1, &req, cmd); 120 | if ((cmd | 0x80000) == 2150132168LL) { 121 | method = IOCTL_SET; 122 | } else { 123 | method = IOCTL_GET; 124 | } 125 | return that->apple80211_ioctl(that, method, &req); 126 | } 127 | 128 | int IO80211Interface::apple80211_ioctl(IO80211Interface *netif, UInt64 method, apple80211req *a6) 129 | { 130 | // VMLog("%s\n", __FUNCTION__); 131 | if (method == IOCTL_GET) { 132 | return apple80211_ioctl_get(netif, a6); 133 | } else { 134 | return apple80211_ioctl_set(netif, a6); 135 | } 136 | } 137 | 138 | extern "C" { 139 | /* 140 | * Internal version of kev_msg_post. Allows posting Apple vendor code kernel 141 | * events. 142 | */ 143 | int kev_post_msg(struct kev_msg *event); 144 | } 145 | 146 | int IO80211InterfacePostMessage(const char *bsdName, unsigned int code, void *data, unsigned int len) 147 | { 148 | struct kev_msg kmsg = {0}; 149 | kmsg.vendor_code = KEV_VENDOR_APPLE; 150 | kmsg.kev_class = KEV_IEEE80211_CLASS; 151 | kmsg.kev_subclass = KEV_NETWORK_CLASS; 152 | kmsg.event_code = code; 153 | kmsg.dv[0].data_length = IFNAMSIZ; 154 | kmsg.dv[0].data_ptr = (void *)bsdName; 155 | if (len) { 156 | kmsg.dv[1].data_ptr = data; 157 | kmsg.dv[1].data_length = len; 158 | } 159 | 160 | return kev_post_msg(&kmsg); 161 | } 162 | 163 | const char *IO80211Interface::getBSDName() 164 | { 165 | if (bsdName[0] == 0) { 166 | snprintf(bsdName, IFNAMSIZ, "%s%u", ifnet_name(getIfnet()), ifnet_unit(getIfnet())); 167 | } 168 | return bsdName; 169 | } 170 | 171 | void IO80211Interface::postMessage(unsigned int code, void *data, uint32_t dataLen) 172 | { 173 | IO80211InterfacePostMessage(getBSDName(), code, data, dataLen); 174 | } 175 | 176 | int IO80211Interface::apple80211_ioctl_get(IO80211Interface *netif, apple80211req *req) 177 | { 178 | int ret; 179 | uint32_t index = req->req_type - 1; 180 | // VMLog("%s %d\n", __FUNCTION__, index); 181 | if (index > 0x160) { 182 | return 102; 183 | } 184 | ret = 102; 185 | switch (index) { 186 | case 0://ssid 187 | ret = sGetSSID(this, req); 188 | break; 189 | case 1://auth type 190 | ret = sGetAuthType(this, req); 191 | break; 192 | case 3://channel 193 | ret = sGetChannel(this, req); 194 | break; 195 | case 4://powersave 196 | ret = sGetPowerSave(this, req); 197 | break; 198 | case 5://protmode 199 | ret = sGetProtMode(this, req); 200 | break; 201 | case 6://tx power 202 | ret = sGetTxPower(this, req); 203 | break; 204 | case 7://rate 205 | ret = sGetRate(this, req); 206 | break; 207 | case 8://bssid 208 | ret = sGetBSSID(this, req); 209 | break; 210 | case 10://scan result 211 | ret = sGetScanResult(this, req); 212 | break; 213 | case 11://card capa 214 | ret = sGetCardCapa(this, req); 215 | break; 216 | case 12://state req 217 | ret = sGetState(this, req); 218 | break; 219 | case 13://phy mode 220 | ret = sGetPhyMode(this, req); 221 | break; 222 | case 14://op mode 223 | ret = sGetOpMode(this, req); 224 | break; 225 | case 15://rssi 226 | ret = sGetRSSI(this, req); 227 | break; 228 | case 16://noise 229 | ret = sGetNoise(this, req); 230 | break; 231 | case 17://int mit 232 | ret = sGetIntMit(this, req); 233 | break; 234 | case 18://power 235 | ret = sGetPOWER(this, req); 236 | break; 237 | // case 20://association result 238 | // 239 | // break; 240 | case 26://supported channels 241 | ret = sGetSupportedChannels(this, req); 242 | break; 243 | case 42: 244 | ret = sGetVersion(this, req); 245 | break; 246 | case 50://country code 247 | ret = sGetCountryCode(this, req); 248 | break; 249 | case 56://mcs 250 | ret = sGetMCS(this, req); 251 | break; 252 | case 95://vir if role 253 | ret = 6; 254 | break; 255 | case 194://ROAMING 256 | ret = kIOReturnError; 257 | break; 258 | case 215://roam profile 259 | ret = kIOReturnError; 260 | break; 261 | case 253: 262 | ret = sGetHWSupportedChannels(this, req); 263 | break; 264 | case 352: 265 | ret = 6; 266 | break; 267 | 268 | default: 269 | VMLog("%s unhandle ioctl index=%d\n", __FUNCTION__, index); 270 | break; 271 | } 272 | return ret; 273 | } 274 | 275 | int IO80211Interface::apple80211_ioctl_set(IO80211Interface *netif, apple80211req *req) 276 | { 277 | int ret; 278 | uint32_t index = req->req_type - 1; 279 | // VMLog("%s %d\n", __FUNCTION__, index); 280 | if (index > 0x160) { 281 | return 102; 282 | } 283 | ret = 102; 284 | switch (index) { 285 | case 0: 286 | 287 | break; 288 | // case 4://setPowerSave 289 | // break; 290 | case 9: //scan req 291 | ret = sSetScanRequest(this, req); 292 | break; 293 | case 18://power 294 | ret = sSetPOWER(this, req); 295 | break; 296 | case 85://setScanRequestMultiple 297 | ret = sSetScanRequestMultiple(this, req); 298 | break; 299 | case 89://setScanCacheClear 300 | ret = sSetScanCacheClear(this, req); 301 | break; 302 | case 93://setVirtualInterfaceCreate 303 | ret = kIOReturnError; 304 | break; 305 | case 215://roam profile 306 | ret = kIOReturnSuccess; 307 | break; 308 | 309 | default: 310 | VMLog("%s unhandle ioctl index=%d\n", __FUNCTION__, index); 311 | break; 312 | } 313 | return ret; 314 | } 315 | -------------------------------------------------------------------------------- /VirtualMac80211/IO80211Interface.hpp: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ifndef ItlNetworkInterface_hpp 4 | #define ItlNetworkInterface_hpp 5 | 6 | #include "IOEthernetInterface.h" 7 | #include "apple/apple80211_ioctl.h" 8 | 9 | #define VMLog(fmt, x...)\ 10 | do\ 11 | {\ 12 | IOLog("%s: " fmt, "VM80211", ##x);\ 13 | }while(0) 14 | 15 | typedef int apple80211_postMessage_tlv_types; 16 | 17 | class IO80211Interface : public IOEthernetInterface 18 | { 19 | OSDeclareDefaultStructors( IO80211Interface ) 20 | 21 | public: 22 | virtual bool init( IONetworkController * controller ) APPLE_KEXT_OVERRIDE; 23 | 24 | void postMessage(unsigned int code, void *data = NULL, uint32_t dataLen = 0); 25 | 26 | const char *getBSDName(); 27 | 28 | protected: 29 | 30 | virtual void free() APPLE_KEXT_OVERRIDE; 31 | 32 | virtual SInt32 performCommand(IONetworkController * controller, 33 | unsigned long cmd, 34 | void * arg0, 35 | void * arg1) APPLE_KEXT_OVERRIDE; 36 | 37 | static int performGatedCommand(void *, void *, void *, void *, void *); 38 | 39 | UInt64 IO80211InterfaceUserSpaceToKernelApple80211Request(void *arg, apple80211req *req, unsigned long ctl); 40 | 41 | int apple80211_ioctl(IO80211Interface *netif, UInt64 method, apple80211req *a6); 42 | 43 | int apple80211_ioctl_set(IO80211Interface *netif, apple80211req *a6); 44 | 45 | int apple80211_ioctl_get(IO80211Interface *netif, apple80211req *a6); 46 | 47 | private: 48 | char bsdName[IFNAMSIZ]; 49 | }; 50 | 51 | #endif /* ItlNetworkInterface_hpp */ 52 | -------------------------------------------------------------------------------- /VirtualMac80211/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleGetInfoString 10 | 12.0, Copyright © 2005-2016 Apple Inc. All rights reserved. 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 19 | CFBundleShortVersionString 20 | $(MARKETING_VERSION) 21 | CFBundleVersion 22 | 1 23 | IOKitPersonalities 24 | 25 | VirtualMac80211 26 | 27 | CFBundleIdentifier 28 | com.apple.iokit.VirtualMac80211 29 | IOClass 30 | VirtualMac80211 31 | IOMatchCategory 32 | IODefaultMatchCategory 33 | IOPCIPrimaryMatch 34 | 0x00008086&0x0000ffff 35 | IOProbeScore 36 | 2000 37 | IOProviderClass 38 | IOPCIDevice 39 | 40 | VirtualMac80211_USB 41 | 42 | CFBundleIdentifier 43 | com.apple.iokit.VirtualMac80211 44 | IOClass 45 | VirtualMac80211 46 | IOMatchCategory 47 | VirtualMac80211 48 | IOProviderClass 49 | IOUSBHostDevice 50 | idProduct 51 | 30209 52 | idVendor 53 | 5263 54 | 55 | 56 | NSHumanReadableCopyright 57 | Copyright © 2020 zxystd. All rights reserved. 58 | OSBundleLibraries 59 | 60 | com.apple.iokit.IONetworkingFamily 61 | 3.2 62 | com.apple.iokit.IOUSBHostFamily 63 | 1.2 64 | com.apple.kpi.bsd 65 | 16.7 66 | com.apple.kpi.iokit 67 | 16.7 68 | com.apple.kpi.libkern 69 | 16.7 70 | com.apple.kpi.mach 71 | 16.7 72 | com.apple.kpi.private 73 | 16.7 74 | com.apple.kpi.unsupported 75 | 16.7 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /VirtualMac80211/VirtualMac80211.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "VirtualMac80211.hpp" 3 | #include 4 | 5 | #include 6 | 7 | #define super IO80211Controller 8 | OSDefineMetaClassAndStructors(VirtualMac80211, IO80211Controller) 9 | 10 | bool VirtualMac80211::init(OSDictionary *properties) { 11 | VMLog("Driver init()"); 12 | return super::init(properties); 13 | } 14 | 15 | void VirtualMac80211::free() { 16 | VMLog("Driver free()"); 17 | super::free(); 18 | } 19 | 20 | IOService* VirtualMac80211::probe(IOService* provider, SInt32 *score) { 21 | VMLog("Driver probe"); 22 | if (vmAirportInstance != NULL) { 23 | VMLog("Can't support 2 instances - bye...\n"); 24 | return NULL; 25 | } 26 | super::probe(provider, score); 27 | vmAirportInstance = this; 28 | return this; 29 | } 30 | 31 | bool VirtualMac80211::start(IOService *provider) { 32 | VMLog("Driver start"); 33 | if (!super::start(provider)) { 34 | VMLog("Super start call failed!"); 35 | releaseAll(); 36 | return false; 37 | } 38 | scanResult = NULL; 39 | const IONetworkMedium *primaryMedium; 40 | if (!createMediumTables(&primaryMedium) || 41 | !setCurrentMedium(primaryMedium)) { 42 | releaseAll(); 43 | return false; 44 | } 45 | if (!attachInterface((IONetworkInterface **)&fNetIf)) { 46 | VMLog("attachInterface failed!"); 47 | releaseAll(); 48 | return false; 49 | } 50 | scanSource = IOTimerEventSource::timerEventSource(this, &fakeScanDone); 51 | getWorkLoop()->addEventSource(scanSource); 52 | registerService(); 53 | return true; 54 | } 55 | 56 | void VirtualMac80211::fakeScanDone(OSObject *owner, IOTimerEventSource *sender) 57 | { 58 | VirtualMac80211 *that = (VirtualMac80211 *)owner; 59 | that->fNetIf->postMessage(APPLE80211_M_SCAN_DONE); 60 | that->fNetIf->postMessage(APPLE80211_M_SCAN_CACHE_UPDATED); 61 | } 62 | 63 | void VirtualMac80211::stop(IOService *provider) { 64 | VMLog("Driver stop"); 65 | super::stop(provider); 66 | if (scanResult) { 67 | if (scanResult->asr_ie_len && scanResult->asr_ie_data) { 68 | IOFree(scanResult->asr_ie_data, scanResult->asr_ie_len); 69 | scanResult->asr_ie_data = NULL; 70 | scanResult->asr_ie_len = 0; 71 | } 72 | IOFree(scanResult, sizeof(struct apple80211_scan_result)); 73 | scanResult = NULL; 74 | } 75 | detachInterface(fNetIf); 76 | fNetIf->release(); 77 | } 78 | 79 | bool VirtualMac80211::createMediumTables(const IONetworkMedium **primary) 80 | { 81 | IONetworkMedium *medium; 82 | 83 | OSDictionary *mediumDict = OSDictionary::withCapacity(1); 84 | if (mediumDict == NULL) { 85 | VMLog("Cannot allocate OSDictionary\n"); 86 | return false; 87 | } 88 | 89 | medium = IONetworkMedium::medium(0x80, 11000000); 90 | IONetworkMedium::addMedium(mediumDict, medium); 91 | medium->release(); 92 | if (primary) { 93 | *primary = medium; 94 | } 95 | 96 | bool result = publishMediumDictionary(mediumDict); 97 | if (!result) { 98 | VMLog("Cannot publish medium dictionary!\n"); 99 | } 100 | 101 | mediumDict->release(); 102 | return result; 103 | } 104 | 105 | bool VirtualMac80211::setupUserClient() 106 | { 107 | setProperty("IOUserClientClass", "ItlNetworkUserClient"); 108 | return true; 109 | } 110 | 111 | void VirtualMac80211::releaseAll() 112 | { 113 | VMLog("%s\n", __FUNCTION__); 114 | } 115 | 116 | bool VirtualMac80211::configureInterface(IONetworkInterface *netif) { 117 | IONetworkData *nd; 118 | 119 | VMLog("%s\n", __FUNCTION__); 120 | if (super::configureInterface(netif) == false) { 121 | VMLog("super failed\n"); 122 | return false; 123 | } 124 | 125 | nd = netif->getNetworkData(kIONetworkStatsKey); 126 | if (!nd || !(fpNetStats = (IONetworkStats *)nd->getBuffer())) { 127 | VMLog("network statistics buffer unavailable?\n"); 128 | return false; 129 | } 130 | 131 | return true; 132 | } 133 | 134 | IONetworkInterface * VirtualMac80211::createInterface() 135 | { 136 | IO80211Interface * netif = new IO80211Interface; 137 | 138 | if ( netif && ( netif->init( this ) == false ) ) 139 | { 140 | netif->release(); 141 | netif = 0; 142 | } 143 | return netif; 144 | } 145 | 146 | IOReturn VirtualMac80211::disable(IONetworkInterface *netif) 147 | { 148 | super::disable(netif); 149 | scanSource->disable(); 150 | setLinkStatus(kIONetworkLinkValid); 151 | return kIOReturnSuccess; 152 | } 153 | 154 | IOReturn VirtualMac80211::enable(IONetworkInterface *netif) 155 | { 156 | super::enable(netif); 157 | scanSource->enable(); 158 | setLinkStatus(kIONetworkLinkValid); 159 | return kIOReturnSuccess; 160 | } 161 | 162 | IOReturn VirtualMac80211::getHardwareAddress(IOEthernetAddress *addrP) { 163 | addrP->bytes[0] = 0x12; 164 | addrP->bytes[1] = 0x22; 165 | addrP->bytes[2] = 0x32; 166 | addrP->bytes[3] = 0x42; 167 | addrP->bytes[4] = 0x52; 168 | addrP->bytes[5] = 0x62; 169 | return kIOReturnSuccess; 170 | } 171 | 172 | UInt32 VirtualMac80211::outputPacket(mbuf_t m, void *param) 173 | { 174 | // VMLog("%s len=%d\n", __FUNCTION__, mbuf_pkthdr_len(m)); 175 | freePacket(m); 176 | return kIOReturnOutputSuccess; 177 | } 178 | 179 | IOReturn VirtualMac80211::setPromiscuousMode(IOEnetPromiscuousMode mode) { 180 | return kIOReturnSuccess; 181 | } 182 | 183 | IOReturn VirtualMac80211::setMulticastMode(IOEnetMulticastMode mode) { 184 | return kIOReturnSuccess; 185 | } 186 | 187 | IOReturn VirtualMac80211::setMulticastList(IOEthernetAddress* addr, UInt32 len) { 188 | return kIOReturnSuccess; 189 | } 190 | 191 | IOReturn VirtualMac80211::getPOWER(IO80211Interface *interface, 192 | struct apple80211_power_data *pd) 193 | { 194 | pd->version = APPLE80211_VERSION; 195 | pd->num_radios = 1; 196 | pd->power_state[0] = power_state; 197 | return kIOReturnSuccess; 198 | } 199 | 200 | IOReturn VirtualMac80211::setPOWER(IO80211Interface *interface, 201 | struct apple80211_power_data *pd) 202 | { 203 | if (pd->num_radios > 0) { 204 | power_state = (pd->power_state[0]); 205 | } 206 | 207 | return kIOReturnSuccess; 208 | } 209 | 210 | IOReturn VirtualMac80211::getCARD_CAPABILITIES(IO80211Interface *interface, 211 | struct apple80211_capability_data *cd) 212 | { 213 | cd->version = APPLE80211_VERSION; 214 | cd->capabilities[0] = 0xEB; 215 | cd->capabilities[1] = 0x7E; 216 | cd->capabilities[2] = 0xFF; 217 | cd->capabilities[5] |= 8; 218 | cd->capabilities[3] |= 2; 219 | cd->capabilities[4] |= 1; 220 | cd->capabilities[6] |= 8; 221 | cd->capabilities[8] |= 8;//dfs white list 222 | cd->capabilities[3] |= 0x21; 223 | cd->capabilities[4] |= 0x80; 224 | cd->capabilities[5] |= 4; 225 | cd->capabilities[2] |= 0xC0; 226 | cd->capabilities[6] |= 0x84; 227 | cd->capabilities[3] |= 8; 228 | cd->capabilities[4] |= 0xAC; 229 | cd->capabilities[6] |= 1; 230 | cd->capabilities[7] |= 4; 231 | cd->capabilities[5] |= 0x80;//isCntryDefaultSupported 232 | cd->capabilities[7] |= 0x80; 233 | cd->capabilities[8] |= 0x40; 234 | cd->capabilities[9] |= 8; 235 | cd->capabilities[9] |= 0x28; 236 | return kIOReturnSuccess; 237 | } 238 | 239 | IOReturn VirtualMac80211::getOP_MODE(IO80211Interface *interface, 240 | struct apple80211_opmode_data *od) 241 | { 242 | od->version = APPLE80211_VERSION; 243 | od->op_mode = APPLE80211_M_STA; 244 | return kIOReturnSuccess; 245 | } 246 | 247 | IOReturn VirtualMac80211::getPHY_MODE(IO80211Interface *interface, 248 | struct apple80211_phymode_data *pd) 249 | { 250 | pd->version = APPLE80211_VERSION; 251 | pd->phy_mode = APPLE80211_MODE_11A 252 | | APPLE80211_MODE_11B 253 | | APPLE80211_MODE_11G 254 | | APPLE80211_MODE_11N 255 | | APPLE80211_MODE_11AC; 256 | 257 | return kIOReturnSuccess; 258 | } 259 | 260 | IOReturn VirtualMac80211::getRSSI(IO80211Interface *interface, 261 | struct apple80211_rssi_data *rd) 262 | { 263 | if (curState == APPLE80211_S_RUN) { 264 | memset(rd, 0, sizeof(*rd)); 265 | rd->version = APPLE80211_VERSION; 266 | rd->num_radios = 1; 267 | rd->rssi_unit = APPLE80211_UNIT_DBM; 268 | rd->rssi[0] = rd->aggregate_rssi 269 | = rd->rssi_ext[0] 270 | = rd->aggregate_rssi_ext 271 | = -101; 272 | return kIOReturnSuccess; 273 | } 274 | return kIOReturnError; 275 | } 276 | 277 | IOReturn VirtualMac80211::getNOISE(IO80211Interface *interface, 278 | struct apple80211_noise_data *nd) 279 | { 280 | if (curState == APPLE80211_S_RUN) { 281 | memset(nd, 0, sizeof(*nd)); 282 | nd->version = APPLE80211_VERSION; 283 | nd->num_radios = 1; 284 | nd->noise_unit = APPLE80211_UNIT_DBM; 285 | nd->noise[0] = nd->aggregate_noise 286 | = nd->noise_ext[0] 287 | = nd->aggregate_noise_ext 288 | = -100; 289 | return kIOReturnSuccess; 290 | } 291 | return kIOReturnError; 292 | } 293 | 294 | const uint8_t fake_bssid[] = { 0x64, 0x7C, 0x34, 0x5C, 0x1C, 0x40 }; 295 | 296 | IOReturn VirtualMac80211::getBSSID(IO80211Interface *interface, 297 | struct apple80211_bssid_data *bd) 298 | { 299 | if (curState == APPLE80211_S_RUN) { 300 | memset(bd, 0, sizeof(*bd)); 301 | bd->version = APPLE80211_VERSION; 302 | bd->bssid.octet[0] = fake_bssid[0]; 303 | bd->bssid.octet[1] = fake_bssid[1]; 304 | bd->bssid.octet[2] = fake_bssid[2]; 305 | bd->bssid.octet[3] = fake_bssid[3]; 306 | bd->bssid.octet[4] = fake_bssid[4]; 307 | bd->bssid.octet[5] = fake_bssid[5]; 308 | return kIOReturnSuccess; 309 | } 310 | return kIOReturnError; 311 | } 312 | 313 | IOReturn VirtualMac80211::getRATE(IO80211Interface *interface, struct apple80211_rate_data *rd) 314 | { 315 | if (curState == APPLE80211_S_RUN) { 316 | memset(rd, 0, sizeof(*rd)); 317 | rd->version = APPLE80211_VERSION; 318 | rd->num_radios = 1; 319 | rd->rate[0] = 20; 320 | return kIOReturnSuccess; 321 | } 322 | return kIOReturnError; 323 | } 324 | 325 | IOReturn VirtualMac80211::getAUTH_TYPE( 326 | IO80211Interface *interface, struct apple80211_authtype_data *ad) 327 | { 328 | if (isAssociating) { 329 | ad->version = APPLE80211_VERSION; 330 | ad->authtype_lower = APPLE80211_AUTHTYPE_OPEN; 331 | ad->authtype_upper = 8; 332 | return kIOReturnSuccess; 333 | } 334 | return kIOReturnError; 335 | } 336 | 337 | const char *fake_ssid = "UPC5424297"; 338 | 339 | IOReturn VirtualMac80211::getSSID(IO80211Interface *interface, 340 | struct apple80211_ssid_data *sd) 341 | { 342 | if (curState == APPLE80211_S_RUN) { 343 | memset(sd, 0, sizeof(*sd)); 344 | sd->version = APPLE80211_VERSION; 345 | memcpy(sd->ssid_bytes, fake_ssid, strlen(fake_ssid)); 346 | sd->ssid_len = strlen(fake_ssid); 347 | return kIOReturnSuccess; 348 | } 349 | return kIOReturnError; 350 | } 351 | 352 | IOReturn VirtualMac80211::getSTATE(IO80211Interface *interface, 353 | struct apple80211_state_data *sd) 354 | { 355 | sd->version = APPLE80211_VERSION; 356 | sd->state = curState; 357 | return kIOReturnSuccess; 358 | } 359 | 360 | IOReturn VirtualMac80211::getCOUNTRY_CODE(IO80211Interface *interface, 361 | struct apple80211_country_code_data *cd) 362 | { 363 | cd->version = APPLE80211_VERSION; 364 | strncpy((char*)cd->cc, "CN", sizeof(cd->cc)); 365 | return kIOReturnSuccess; 366 | } 367 | 368 | IOReturn VirtualMac80211::getMCS(IO80211Interface* interface, struct apple80211_mcs_data* md) 369 | { 370 | if (curState == APPLE80211_S_RUN) { 371 | md->version = APPLE80211_VERSION; 372 | md->index = APPLE80211_MCS_INDEX_AUTO; 373 | return kIOReturnSuccess; 374 | } 375 | return kIOReturnError; 376 | } 377 | 378 | IOReturn VirtualMac80211::getTXPOWER(IO80211Interface *interface, 379 | struct apple80211_txpower_data *txd) 380 | { 381 | if (curState == APPLE80211_S_RUN) { 382 | memset(txd, 0, sizeof(*txd)); 383 | txd->version = APPLE80211_VERSION; 384 | txd->txpower = 100; 385 | txd->txpower_unit = APPLE80211_UNIT_PERCENT; 386 | return kIOReturnSuccess; 387 | } 388 | return kIOReturnError; 389 | } 390 | 391 | IOReturn VirtualMac80211::getPROTMODE( 392 | IO80211Interface *interface, struct apple80211_protmode_data *pd) 393 | { 394 | if (curState == APPLE80211_S_RUN) { 395 | memset(pd, 0, sizeof(*pd)); 396 | pd->version = APPLE80211_VERSION; 397 | pd->threshold = 0; 398 | pd->protmode = 0; 399 | return kIOReturnSuccess; 400 | } 401 | return kIOReturnError; 402 | } 403 | 404 | IOReturn VirtualMac80211::getPOWERSAVE(IO80211Interface *interface, struct apple80211_powersave_data *pd) 405 | { 406 | pd->version = APPLE80211_VERSION; 407 | pd->powersave_level = APPLE80211_POWERSAVE_MODE_DISABLED; 408 | return kIOReturnSuccess; 409 | } 410 | 411 | IOReturn VirtualMac80211::getINT_MIT( 412 | IO80211Interface *interface, struct apple80211_intmit_data *imd) 413 | { 414 | imd->version = APPLE80211_VERSION; 415 | imd->int_mit = APPLE80211_INT_MIT_AUTO; 416 | return kIOReturnSuccess; 417 | } 418 | 419 | IOReturn VirtualMac80211:: 420 | getSUPPORTED_CHANNELS(IO80211Interface *interface, struct apple80211_sup_channel_data *ad) 421 | { 422 | ad->version = APPLE80211_VERSION; 423 | ad->num_channels = 0; 424 | for (int i = 0; i < 14; i++) { 425 | ad->supported_channels[ad->num_channels++].channel = (i + 1); 426 | ad->supported_channels[ad->num_channels].flags = APPLE80211_C_FLAG_2GHZ; 427 | } 428 | return kIOReturnSuccess; 429 | } 430 | 431 | IOReturn VirtualMac80211:: 432 | getHW_SUPPORTED_CHANNELS(IO80211Interface *interface, struct apple80211_sup_channel_data *ad) 433 | { 434 | ad->version = APPLE80211_VERSION; 435 | ad->num_channels = 0; 436 | for (int i = 0; i < 14; i++) { 437 | ad->supported_channels[ad->num_channels++].channel = (i + 1); 438 | ad->supported_channels[ad->num_channels].flags = APPLE80211_C_FLAG_2GHZ; 439 | } 440 | return kIOReturnSuccess; 441 | } 442 | 443 | IOReturn VirtualMac80211:: 444 | getDRIVER_VERSION(IO80211Interface *interface, 445 | struct apple80211_version_data *hv) 446 | { 447 | hv->version = APPLE80211_VERSION; 448 | snprintf(hv->string, sizeof(hv->string), "RTL008: %s fw: %s", "1.0.0", "RTL"); 449 | hv->string_len = strlen(hv->string); 450 | return kIOReturnSuccess; 451 | } 452 | 453 | IOReturn VirtualMac80211:: 454 | setSCANCACHE_CLEAR(IO80211Interface *interface) 455 | { 456 | VMLog("%s\n", __FUNCTION__); 457 | if (scanResult) { 458 | if (scanResult->asr_ie_len && scanResult->asr_ie_data) { 459 | IOFree(scanResult->asr_ie_data, scanResult->asr_ie_len); 460 | scanResult->asr_ie_data = NULL; 461 | scanResult->asr_ie_len = 0; 462 | } 463 | IOFree(scanResult, sizeof(struct apple80211_scan_result)); 464 | scanResult = NULL; 465 | } 466 | return kIOReturnSuccess; 467 | } 468 | 469 | IOReturn VirtualMac80211:: 470 | setSCAN_REQ(IO80211Interface *interface, struct apple80211_scan_data *sd) 471 | { 472 | VMLog("%s Type: %u BSS Type: %u PHY Mode: %u Dwell time: %u Rest time: %u Num channels: %u SSID: %s\n", 473 | __FUNCTION__, 474 | sd->scan_type, 475 | sd->bss_type, 476 | sd->phy_mode, 477 | sd->dwell_time, 478 | sd->rest_time, 479 | sd->num_channels, 480 | sd->ssid); 481 | if (waitingForScanResult) { 482 | return kIOReturnError; 483 | } 484 | curState = APPLE80211_S_SCAN; 485 | if (interface && scanSource) { 486 | scanSource->setTimeoutMS(200); 487 | scanSource->enable(); 488 | } 489 | waitingForScanResult = true; 490 | return kIOReturnSuccess; 491 | } 492 | 493 | IOReturn VirtualMac80211:: 494 | setSCAN_REQ_MULTIPLE(IO80211Interface *interface, struct apple80211_scan_multiple_data *sd) 495 | { 496 | int i; 497 | VMLog("%s Type: %u SSID Count: %u BSSID Count: %u PHY Mode: %u Dwell time: %u Rest time: %u Num channels: %u Unk: %u\n", 498 | __FUNCTION__, 499 | sd->scan_type, 500 | sd->ssid_count, 501 | sd->bssid_count, 502 | sd->phy_mode, 503 | sd->dwell_time, 504 | sd->rest_time, 505 | sd->num_channels, 506 | sd->unk_2); 507 | for (i = 0; i < sd->ssid_count; i++) { 508 | VMLog("%s index=%d ssid=%s ssid_len=%d\n", __FUNCTION__, i, sd->ssids[i].ssid_bytes, sd->ssids[i].ssid_len); 509 | } 510 | if (waitingForScanResult) { 511 | return kIOReturnError; 512 | } 513 | if (interface && scanSource) { 514 | scanSource->setTimeoutMS(200); 515 | scanSource->enable(); 516 | } 517 | waitingForScanResult = true; 518 | return kIOReturnSuccess; 519 | } 520 | 521 | const apple80211_channel fake_channel = { 522 | .version = APPLE80211_VERSION, 523 | .channel = 1, 524 | .flags = APPLE80211_C_FLAG_2GHZ 525 | }; 526 | 527 | // This string contains information elements from beacon frame that I captured via Wireshark 528 | const char beacon_ie[] = "\x00\x0a\x55" \ 529 | "\x50\x43\x35\x34\x32\x34\x32\x39\x37\x01\x08\x82\x84\x8b\x96\x0c" \ 530 | "\x12\x18\x24\x03\x01\x01\x05\x04\x00\x01\x00\x00\x07\x06\x43\x5a" \ 531 | "\x20\x01\x0d\x14\x2a\x01\x04\x32\x04\x30\x48\x60\x6c\x2d\x1a\xad" \ 532 | "\x01\x1b\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" \ 533 | "\x00\x00\x00\x04\x06\xe6\xe7\x0d\x00\x3d\x16\x01\x00\x17\x00\x00" \ 534 | "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" \ 535 | "\x00\x4a\x0e\x14\x00\x0a\x00\x2c\x01\xc8\x00\x14\x00\x05\x00\x19" \ 536 | "\x00\x7f\x01\x01\xdd\x18\x00\x50\xf2\x02\x01\x01\x80\x00\x03\xa4" \ 537 | "\x00\x00\x27\xa4\x00\x00\x42\x43\x5e\x00\x62\x32\x2f\x00\xdd\x09" \ 538 | "\x00\x03\x7f\x01\x01\x00\x00\xff\x7f\x30\x18\x01\x00\x00\x0f\xac" \ 539 | "\x02\x02\x00\x00\x0f\xac\x04\x00\x0f\xac\x02\x01\x00\x00\x0f\xac" \ 540 | "\x02\x00\x00\xdd\x1a\x00\x50\xf2\x01\x01\x00\x00\x50\xf2\x02\x02" \ 541 | "\x00\x00\x50\xf2\x04\x00\x50\xf2\x02\x01\x00\x00\x50\xf2\x02\xdd" \ 542 | "\x22\x00\x50\xf2\x04\x10\x4a\x00\x01\x10\x10\x44\x00\x01\x02\x10" \ 543 | "\x57\x00\x01\x01\x10\x3c\x00\x01\x01\x10\x49\x00\x06\x00\x37\x2a" \ 544 | "\x00\x01\x20"; 545 | 546 | IOReturn VirtualMac80211:: 547 | getSCAN_RESULT(IO80211Interface *interface, 548 | struct apple80211_scan_result **sr) { 549 | 550 | if (!waitingForScanResult) { 551 | return 0xe0820446; 552 | } 553 | 554 | struct apple80211_scan_result* result; 555 | 556 | if (scanResult) { 557 | result = scanResult; 558 | } else { 559 | result = (struct apple80211_scan_result*)IOMalloc(sizeof(struct apple80211_scan_result)); 560 | bzero(result, sizeof(*result)); 561 | result->version = APPLE80211_VERSION; 562 | 563 | result->asr_channel = fake_channel; 564 | 565 | result->asr_noise = -101; 566 | // result->asr_snr = 60; 567 | result->asr_rssi = -73; 568 | result->asr_beacon_int = 100; 569 | 570 | result->asr_cap = 0x411; 571 | 572 | result->asr_age = 0; 573 | 574 | memcpy(result->asr_bssid, fake_bssid, sizeof(fake_bssid)); 575 | 576 | result->asr_nrates = 1; 577 | result->asr_rates[0] = 54; 578 | 579 | strncpy((char*)result->asr_ssid, fake_ssid, sizeof(result->asr_ssid)); 580 | result->asr_ssid_len = strlen(fake_ssid); 581 | 582 | result->asr_ie_len = 246; 583 | result->asr_ie_data = IOMalloc(result->asr_ie_len); 584 | memcpy(result->asr_ie_data, beacon_ie, result->asr_ie_len); 585 | scanResult = result; 586 | } 587 | 588 | *sr = result; 589 | 590 | waitingForScanResult = false; 591 | 592 | return kIOReturnSuccess; 593 | } 594 | 595 | IOReturn VirtualMac80211:: 596 | getHARDWARE_VERSION(IO80211Interface *interface, 597 | struct apple80211_version_data *hv) 598 | { 599 | hv->version = APPLE80211_VERSION; 600 | strncpy(hv->string, "RTL", sizeof(hv->string)); 601 | hv->string_len = strlen("RTL"); 602 | return kIOReturnSuccess; 603 | } 604 | 605 | const OSString* VirtualMac80211::newVendorString() const { 606 | return OSString::withCString("Apple"); 607 | } 608 | 609 | const OSString* VirtualMac80211::newModelString() const { 610 | return OSString::withCString("Intel Wiress Card"); 611 | } 612 | 613 | const OSString* VirtualMac80211::newRevisionString() const { 614 | return OSString::withCString("1.0.0d"); 615 | } 616 | -------------------------------------------------------------------------------- /VirtualMac80211/VirtualMac80211.hpp: -------------------------------------------------------------------------------- 1 | #include "IO80211Interface.hpp" 2 | #include "IO80211Controller.hpp" 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | void *vmAirportInstance; 10 | 11 | class VirtualMac80211 : public IO80211Controller { 12 | OSDeclareDefaultStructors(VirtualMac80211) 13 | 14 | public: 15 | bool init(OSDictionary *properties) override; 16 | void free() override; 17 | IOService* probe(IOService* provider, SInt32* score) override; 18 | bool start(IOService *provider) override; 19 | void stop(IOService *provider) override; 20 | IOReturn getHardwareAddress(IOEthernetAddress* addrP) override; 21 | IOReturn enable(IONetworkInterface *netif) override; 22 | IOReturn disable(IONetworkInterface *netif) override; 23 | UInt32 outputPacket(mbuf_t, void * param) override; 24 | IOReturn setPromiscuousMode(IOEnetPromiscuousMode mode) override; 25 | IOReturn setMulticastMode(IOEnetMulticastMode mode) override; 26 | IOReturn setMulticastList(IOEthernetAddress* addr, UInt32 len) override; 27 | bool configureInterface(IONetworkInterface *netif) override; 28 | virtual IONetworkInterface * createInterface() override; 29 | virtual const OSString* newVendorString() const override; 30 | virtual const OSString* newModelString() const override; 31 | virtual const OSString* newRevisionString() const override; 32 | 33 | bool setupUserClient(); 34 | bool createMediumTables(const IONetworkMedium **primary); 35 | 36 | void releaseAll(); 37 | 38 | virtual IOReturn getPOWER(IO80211Interface *interface, struct apple80211_power_data *pd) override; 39 | 40 | virtual IOReturn setPOWER(IO80211Interface *interface, struct apple80211_power_data *pd) override; 41 | 42 | virtual IOReturn getCARD_CAPABILITIES(IO80211Interface *interface, struct apple80211_capability_data *cd) override; 43 | 44 | virtual IOReturn getOP_MODE(IO80211Interface *interface, struct apple80211_opmode_data *od) override; 45 | 46 | virtual IOReturn getPHY_MODE(IO80211Interface *interface, struct apple80211_phymode_data *pd) override; 47 | 48 | virtual IOReturn getRSSI(IO80211Interface *interface, struct apple80211_rssi_data *rd) override; 49 | 50 | virtual IOReturn getNOISE(IO80211Interface *interface, struct apple80211_noise_data *nd) override; 51 | 52 | virtual IOReturn getBSSID(IO80211Interface *interface, struct apple80211_bssid_data *bd) override; 53 | 54 | virtual IOReturn getRATE(IO80211Interface *interface, struct apple80211_rate_data *rd) override; 55 | 56 | virtual IOReturn getAUTH_TYPE(IO80211Interface *interface, struct apple80211_authtype_data *ad) override; 57 | 58 | virtual IOReturn getSSID(IO80211Interface *interface, struct apple80211_ssid_data *sd) override; 59 | 60 | virtual IOReturn getSTATE(IO80211Interface *interface, struct apple80211_state_data *sd) override; 61 | 62 | virtual IOReturn getCOUNTRY_CODE(IO80211Interface *interface, struct apple80211_country_code_data *cd) override; 63 | 64 | virtual IOReturn getMCS(IO80211Interface *interface, struct apple80211_mcs_data *md) override; 65 | 66 | virtual IOReturn getTXPOWER(IO80211Interface *interface, struct apple80211_txpower_data *txd) override; 67 | 68 | virtual IOReturn getPROTMODE(IO80211Interface *interface, struct apple80211_protmode_data *pd) override; 69 | 70 | virtual IOReturn getPOWERSAVE(IO80211Interface *interface, struct apple80211_powersave_data *pd) override; 71 | 72 | virtual IOReturn getINT_MIT(IO80211Interface *interface, struct apple80211_intmit_data *imd) override; 73 | 74 | virtual IOReturn getSUPPORTED_CHANNELS(IO80211Interface *interface, struct apple80211_sup_channel_data *ad) override; 75 | 76 | virtual IOReturn getHW_SUPPORTED_CHANNELS(IO80211Interface *interface, struct apple80211_sup_channel_data *ad) override; 77 | 78 | virtual IOReturn getDRIVER_VERSION(IO80211Interface *interface, 79 | struct apple80211_version_data *hv) override; 80 | 81 | virtual IOReturn getHARDWARE_VERSION(IO80211Interface *interface, 82 | struct apple80211_version_data *hv) override; 83 | static void fakeScanDone(OSObject *owner, IOTimerEventSource *sender); 84 | virtual IOReturn setSCAN_REQ(IO80211Interface *interface, struct apple80211_scan_data *sd) override; 85 | virtual IOReturn setSCAN_REQ_MULTIPLE(IO80211Interface *interface, struct apple80211_scan_multiple_data *sd) override; 86 | virtual IOReturn setSCANCACHE_CLEAR(IO80211Interface *interface) override; 87 | virtual IOReturn getSCAN_RESULT(IO80211Interface *interface, apple80211_scan_result **sr) override; 88 | 89 | public: 90 | uint8_t power_state; 91 | bool isAssociating; 92 | uint8_t curState; 93 | bool scanEnd; 94 | 95 | protected: 96 | IO80211Interface *fNetIf; 97 | IONetworkStats *fpNetStats; 98 | struct apple80211_scan_result *scanResult; 99 | 100 | private: 101 | IOTimerEventSource *scanSource; 102 | bool waitingForScanResult; 103 | }; 104 | -------------------------------------------------------------------------------- /VirtualMac80211/apple/IOEthernetController.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1998-2008 Apple Inc. All rights reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * The contents of this file constitute Original Code as defined in and 7 | * are subject to the Apple Public Source License Version 1.1 (the 8 | * "License"). You may not use this file except in compliance with the 9 | * License. Please obtain a copy of the License at 10 | * http://www.apple.com/publicsource and read it before using this file. 11 | * 12 | * This Original Code and all software distributed under the License are 13 | * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER 14 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 15 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the 17 | * License for the specific language governing rights and limitations 18 | * under the License. 19 | * 20 | * @APPLE_LICENSE_HEADER_END@ 21 | */ 22 | 23 | #ifndef _IOETHERNETCONTROLLER_H 24 | #define _IOETHERNETCONTROLLER_H 25 | 26 | #include "IONetworkController.h" 27 | 28 | /*! @defined kIOEthernetControllerClass 29 | @abstract kIOEthernetControllerClass is the name of the 30 | IOEthernetController class. */ 31 | 32 | #define kIOEthernetControllerClass "IOEthernetController" 33 | 34 | /*! @defined kIOEthernetAddressSize 35 | @abstract The number of bytes in an Ethernet hardware address. */ 36 | 37 | #define kIOEthernetAddressSize 6 38 | 39 | /*! @defined kIOEthernetMaxPacketSize 40 | @abstract The maximum size of an Ethernet packet, including 41 | the FCS bytes. */ 42 | 43 | #define kIOEthernetMaxPacketSize 1518 44 | 45 | /*! @defined kIOEthernetMinPacketSize 46 | @abstract The minimum size of an Ethernet packet, including 47 | the FCS bytes. */ 48 | 49 | #define kIOEthernetMinPacketSize 64 50 | 51 | /*! @defined kIOEthernetCRCSize 52 | @abstract The size in bytes of the 32-bit CRC value appended 53 | to the end of each Ethernet frame. */ 54 | 55 | #define kIOEthernetCRCSize 4 56 | 57 | /*! @defined kIOEthernetWakeOnLANFilterGroup 58 | @abstract kIOEthernetWakeOnLANFilterGroup describes the name assigned 59 | to the Ethernet Wake-On-LAN filter group. This group represents 60 | wake filters that are supported by the controller. */ 61 | 62 | #define kIOEthernetWakeOnLANFilterGroup "IOEthernetWakeOnLANFilterGroup" 63 | 64 | /*! @defined kIOEthernetDisabledWakeOnLANFilterGroup 65 | @abstract kIOEthernetDisabledWakeOnLANFilterGroup describes the name 66 | assigned to the disabled Ethernet Wake-On-LAN filter group. This 67 | group represents wake filters that are currently disabled. 68 | Membership in this group is dynamic. */ 69 | 70 | #define kIOEthernetDisabledWakeOnLANFilterGroup \ 71 | "IOEthernetDisabledWakeOnLANFilterGroup" 72 | 73 | /*! @enum Wake On LAN Filters 74 | @abstract All filters in the Wake-on-LAN filter group. 75 | @discussion Each filter listed will respond to a network event that 76 | will trigger a system wake-up. 77 | @constant kIOEthernetWakeOnMagicPacket Reception of a Magic Packet. 78 | @constant kIOEthernetWakeOnPacketAddressMatch Reception of a packet 79 | which passes through any of the address filtering mechanisms based 80 | on its destination Ethernet address. This may include unicast, 81 | broadcast, or multicast addresses depending on the current state 82 | and setting of the corresponding packet filters. */ 83 | 84 | enum { 85 | kIOEthernetWakeOnMagicPacket = 0x00000001, 86 | kIOEthernetWakeOnPacketAddressMatch = 0x00000002 87 | }; 88 | 89 | #ifdef KERNEL 90 | #ifdef __cplusplus 91 | 92 | struct IOEthernetAddress { 93 | UInt8 bytes[kIOEthernetAddressSize]; 94 | }; 95 | 96 | /*! @const gIOEthernetWakeOnLANFilterGroup 97 | @discussion gIOEthernetWakeOnLANFilterGroup is an OSSymbol object 98 | that contains the name of the Ethernet Wake-on-LAN filter group 99 | defined by kIOEthernetWakeOnLANFilterGroup. */ 100 | 101 | extern const OSSymbol * gIOEthernetWakeOnLANFilterGroup; 102 | 103 | /*! @const gIOEthernetDisabledWakeOnLANFilterGroup 104 | @discussion gIOEthernetDisabledWakeOnLANFilterGroup is an OSSymbol object 105 | that contains the name of the disabled Ethernet Wake-on-LAN filter group 106 | defined by kIOEthernetDisabledWakeOnLANFilterGroup. */ 107 | 108 | extern const OSSymbol * gIOEthernetDisabledWakeOnLANFilterGroup; 109 | 110 | /*! @class IOEthernetController 111 | @abstract Abstract superclass for Ethernet controllers. 112 | @discussion Ethernet controller drivers should subclass IOEthernetController, and implement 113 | or override the hardware specific methods to create an Ethernet driver. 114 | An interface object (an IOEthernetInterface instance) must be 115 | instantiated by the driver, through attachInterface(), to connect 116 | the controller driver to the data link layer. 117 | */ 118 | 119 | class IOEthernetController : public IONetworkController 120 | { 121 | OSDeclareAbstractStructors( IOEthernetController ) 122 | 123 | protected: 124 | struct ExpansionData { }; 125 | /*! @var reserved 126 | Reserved for future use. (Internal use only) */ 127 | ExpansionData * _reserved; 128 | 129 | 130 | public: 131 | 132 | /*! @function initialize 133 | @abstract IOEthernetController class initializer. 134 | @discussion Creates global OSSymbol objects that are used as keys. */ 135 | 136 | static void initialize(); 137 | 138 | /*! @function init 139 | @abstract Initializes an IOEthernetController object. 140 | @param properties A dictionary object containing a property table 141 | associated with this instance. 142 | @result Returns true on success, false otherwise. 143 | */ 144 | 145 | virtual bool init(OSDictionary * properties); 146 | 147 | /*! @function getPacketFilters 148 | @abstract Gets the set of packet filters supported by the Ethernet 149 | controller in the given filter group. 150 | @discussion The default implementation of the abstract method inherited 151 | from IONetworkController. When the filter group specified is 152 | gIONetworkFilterGroup, then this method will return a value formed by 153 | a bitwise OR of kIOPacketFilterUnicast, kIOPacketFilterBroadcast, 154 | kIOPacketFilterMulticast, kIOPacketFilterPromiscuous. Otherwise, the 155 | return value will be set to zero (0). Subclasses must override this 156 | method if their filtering capability differs from what is reported by 157 | this default implementation. This method is called from the workloop 158 | context, and the result is published to the I/O Kit Registry. 159 | @param group The name of the filter group. 160 | @param filters Pointer to the mask of supported filters returned by 161 | this method. 162 | @result Returns kIOReturnSuccess. Drivers that override this 163 | method must return kIOReturnSuccess to indicate success, or an error 164 | return code otherwise. 165 | */ 166 | 167 | virtual IOReturn getPacketFilters(const OSSymbol * group, 168 | UInt32 * filters) const; 169 | 170 | /*! @function enablePacketFilter 171 | @abstract Enables one of the supported packet filters from the 172 | given filter group. 173 | @discussion The default implementation of the abstract method inherited 174 | from IONetworkController. This method will call setMulticastMode() or 175 | setPromiscuousMode() when the multicast or the promiscuous filter is to be 176 | enabled. Requests to disable the Unicast or Broadcast filters are handled 177 | silently, without informing the subclass. Subclasses can override this 178 | method to change this default behavior, or to extend it to handle 179 | additional filter types or filter groups. This method call is synchronized 180 | by the workloop's gate. 181 | @param group The name of the filter group containing the filter to be 182 | enabled. 183 | @param aFilter The filter to enable. 184 | @param enabledFilters All filters currently enabled by the client. 185 | @param options Optional flags for the enable request. 186 | @result Returns the value returned by setMulticastMode() or setPromiscuousMode() if 187 | either of those two methods are called. Returns kIOReturnSuccess if the filter 188 | specified is kIOPacketFilterUnicast or kIOPacketFilterBroadcast. 189 | Returns kIOReturnUnsupported if the filter group specified is not 190 | gIONetworkFilterGroup. 191 | */ 192 | 193 | virtual IOReturn enablePacketFilter(const OSSymbol * group, 194 | UInt32 aFilter, 195 | UInt32 enabledFilters, 196 | IOOptionBits options = 0); 197 | 198 | /*! @function disablePacketFilter 199 | @abstract Disables a packet filter that is currently enabled from the 200 | given filter group. 201 | @discussion The default implementation of the abstract method inherited 202 | from IONetworkController. This method will call setMulticastMode() or 203 | setPromiscuousMode() when the multicast or the promiscuous filter is to be 204 | disabled. Requests to disable the Unicast or Broadcast filters are handled 205 | silently, without informing the subclass. Subclasses can override this 206 | method to change this default behavior, or to extend it to handle 207 | additional filter types or filter groups. This method call is synchronized 208 | by the workloop's gate. 209 | @param group The name of the filter group containing the filter to be 210 | disabled. 211 | @param aFilter The filter to disable. 212 | @param enabledFilters All filters currently enabled by the client. 213 | @param options Optional flags for the disable request. 214 | @result Returns the value returned by setMulticastMode() or setPromiscuousMode() if 215 | either of those two methods are called. Returns kIOReturnSuccess if the filter 216 | specified is kIOPacketFilterUnicast or kIOPacketFilterBroadcast. 217 | Returns kIOReturnUnsupported if the filter group specified is not 218 | gIONetworkFilterGroup. 219 | */ 220 | 221 | virtual IOReturn disablePacketFilter(const OSSymbol * group, 222 | UInt32 aFilter, 223 | UInt32 enabledFilters, 224 | IOOptionBits options = 0); 225 | 226 | /*! @function getHardwareAddress 227 | @abstract Gets the Ethernet controller's station address. 228 | @discussion The default implementation of the abstract method inherited 229 | from IONetworkController. This method will call the overloaded form 230 | IOEthernetController::getHardwareAddress() that subclasses are expected 231 | to override. 232 | @param addr The buffer where the controller's hardware address should 233 | be written. 234 | @param inOutAddrBytes The size of the address buffer provided by the 235 | client, and replaced by this method with the actual size of 236 | the hardware address in bytes. 237 | @result Returns kIOReturnSuccess on success, or an error otherwise. 238 | */ 239 | 240 | virtual IOReturn getHardwareAddress(void * addr, 241 | UInt32 * inOutAddrBytes); 242 | 243 | /*! @function setHardwareAddress 244 | @abstract Sets or changes the station address used by the Ethernet 245 | controller. 246 | @discussion The default implementation of the abstract method inherited 247 | from IONetworkController. This method will call the overloaded form 248 | IOEthernetController::setHardwareAddress() that subclasses are expected 249 | to override. 250 | @param addr The buffer containing the hardware address provided by 251 | the client. 252 | @param addrBytes The size of the address buffer provided by the 253 | client in bytes. 254 | @result Returns kIOReturnSuccess on success, or an error otherwise. 255 | */ 256 | 257 | virtual IOReturn setHardwareAddress(const void * addr, 258 | UInt32 addrBytes); 259 | 260 | /*! @function getMaxPacketSize 261 | @abstract Gets the maximum packet size supported by the Ethernet 262 | controller, including the frame header and FCS. 263 | @param maxSize Pointer to the return value. 264 | @result Returns kIOReturnSuccess on success, or an error code otherwise. 265 | */ 266 | 267 | virtual IOReturn getMaxPacketSize(UInt32 * maxSize) const; 268 | 269 | /*! @function getMinPacketSize 270 | @abstract Gets the minimum packet size supported by the Ethernet 271 | controller, including the frame header and FCS. 272 | @param minSize Pointer to the return value. 273 | @result Returns kIOReturnSuccess on success, or an error code otherwise. 274 | */ 275 | 276 | virtual IOReturn getMinPacketSize(UInt32 * minSize) const; 277 | 278 | /*! @function getPacketFilters 279 | @abstract Gets the set of packet filters supported by the Ethernet 280 | controller in the network filter group. 281 | @param filters Pointer to the return value containing a mask of 282 | supported filters. 283 | @result Returns kIOReturnSuccess. Drivers that override this 284 | method must return kIOReturnSuccess to indicate success, or an error 285 | return code otherwise. 286 | */ 287 | 288 | virtual IOReturn getPacketFilters(UInt32 * filters) const; 289 | 290 | /*! @function getHardwareAddress 291 | @abstract Gets the Ethernet controller's permanent station address. 292 | @discussion Ethernet drivers must implement this method, by reading the 293 | address from hardware and writing it to the buffer provided. This method 294 | is called from the workloop context. 295 | @param addrP Pointer to an IOEthernetAddress where the hardware address 296 | should be returned. 297 | @result Returns kIOReturnSuccess on success, or an error return code otherwise. 298 | */ 299 | 300 | virtual IOReturn getHardwareAddress(IOEthernetAddress * addrP) = 0; 301 | 302 | /*! @function setHardwareAddress 303 | @abstract Sets or changes the station address used by the Ethernet 304 | controller. 305 | @discussion This method is called in response to a client command to 306 | change the station address used by the Ethernet controller. Implementation 307 | of this method is optional. This method is called from the workloop context. 308 | @param addrP Pointer to an IOEthernetAddress containing the new station 309 | address. 310 | @result The default implementation will always return kIOReturnUnsupported. 311 | If overridden, drivers must return kIOReturnSuccess on success, or an error 312 | return code otherwise. 313 | */ 314 | 315 | virtual IOReturn setHardwareAddress(const IOEthernetAddress * addrP); 316 | 317 | /*! @function setMulticastMode 318 | @abstract Enables or disables multicast mode. 319 | @discussion Called by enablePacketFilter() or disablePacketFilter() 320 | when there is a change in the activation state of the multicast filter 321 | identified by kIOPacketFilterMulticast. This method is called from the 322 | workloop context. 323 | @param active True to enable multicast mode, false to disable it. 324 | @result Returns kIOReturnUnsupported. If overridden, drivers must return 325 | kIOReturnSuccess on success, or an error return code otherwise. 326 | */ 327 | 328 | virtual IOReturn setMulticastMode(bool active); 329 | 330 | /*! @function setMulticastList 331 | @abstract Sets the list of multicast addresses a multicast filter 332 | should use to match against the destination address of an incoming frame. 333 | @discussion This method sets the list of multicast addresses that the multicast filter 334 | should use to match against the destination address of an incoming frame. 335 | The frame should be accepted when a match occurs. Called when the multicast group membership of an interface 336 | object is changed. Drivers that support kIOPacketFilterMulticast should 337 | override this method and update the hardware multicast filter using the 338 | list of Ethernet addresses provided. Perfect multicast filtering is 339 | preferred if supported by the hardware, in order to reduce the number of 340 | unwanted packets received. If the number of multicast addresses in the 341 | list exceeds what the hardware is capable of supporting, or if perfect 342 | filtering is not supported, then ideally the hardware should be programmed 343 | to perform imperfect filtering, through some form of hash filtering 344 | mechanism. Only as a last resort should the driver enable reception of 345 | all multicast packets to satisfy this request. This method is called 346 | from the workloop context, and only if the driver reports 347 | kIOPacketFilterMulticast support in getPacketFilters(). 348 | @param addrs An array of Ethernet addresses. This argument must be 349 | ignored if the count argument is 0. 350 | @param count The number of Ethernet addresses in the list. This value 351 | will be zero when the list becomes empty. 352 | @result Returns kIOReturnUnsupported. Drivers must return kIOReturnSuccess to 353 | indicate success, or an error return code otherwise. 354 | */ 355 | 356 | virtual IOReturn setMulticastList(IOEthernetAddress * addrs, 357 | UInt32 count); 358 | 359 | /*! @function setPromiscuousMode 360 | @abstract Enables or disables promiscuous mode. 361 | @discussion Called by enablePacketFilter() or disablePacketFilter() 362 | when there is a change in the activation state of the promiscuous 363 | filter identified by kIOPacketFilterPromiscuous. This method is 364 | called from the workloop context. 365 | @param active True to enable promiscuous mode, false to disable it. 366 | @result Returns kIOReturnUnsupported. If overridden, drivers must return 367 | kIOReturnSuccess on success, or an error return code otherwise. 368 | */ 369 | 370 | virtual IOReturn setPromiscuousMode(bool active); 371 | 372 | /*! @function setWakeOnMagicPacket 373 | @abstract Enables or disables the wake on Magic Packet support. 374 | @discussion Called by enablePacketFilter() or disablePacketFilter() 375 | when there is a change in the activation state of the Wake-on-LAN 376 | filter identified by kIOEthernetWakeOnMagicPacket. This method is 377 | called from the workloop context. 378 | @param active True to enable support for system wake on reception 379 | of a Magic Packet, false to disable it. 380 | @result Returns kIOReturnUnsupported. If overridden, drivers must return 381 | kIOReturnSuccess on success, or an error return code otherwise. 382 | */ 383 | 384 | virtual IOReturn setWakeOnMagicPacket(bool active); 385 | 386 | protected: 387 | 388 | /*! @function createInterface 389 | @abstract Creates an IOEthernetInterface object. 390 | @discussion This method allocates and returns a new IOEthernetInterface instance. 391 | A subclass of IONetworkController must implement this method and return 392 | a matching interface object. The implementation in IOEthernetController 393 | will return an IOEthernetInterface object. Subclasses of 394 | IOEthernetController, such as Ethernet controller drivers, will have 395 | little reason to override this implementation. 396 | @result Returns a newly allocated and initialized IOEthernetInterface object. 397 | */ 398 | 399 | virtual IONetworkInterface * createInterface(); 400 | 401 | /*! @function free 402 | @abstract Frees the IOEthernetController instance. 403 | @discussion This method releases resources, and is 404 | then followed by a call to super::free(). */ 405 | 406 | virtual void free(); 407 | 408 | /*! @function publishProperties 409 | @abstract Publishes Ethernet controller properties and capabilities. 410 | @discussion This method publishes Ethernet controller properties to the property 411 | table. For instance, getHardwareAddress() is called to fetch the 412 | hardware address, and the address is then published to the property 413 | table. This method call is synchronized by the workloop's gate, 414 | and must never be called directly by subclasses. 415 | @result Returns true if all properties and capabilities were discovered, 416 | and published successfully, false otherwise. Returning false will 417 | prevent client objects from attaching to the Ethernet controller 418 | since a property that a client relies upon may be missing. 419 | */ 420 | 421 | virtual bool publishProperties(); 422 | 423 | OSMetaClassDeclareReservedUsed( IOEthernetController, 0); 424 | 425 | /*! @function getVlanTagDemand 426 | @abstract Fetch the demand for hardware vlan tag stuffing 427 | for the given packet before it is transmitted on the network. 428 | @discussion A network controller that can insert 802.1Q vlan tags for output 429 | packets must call this method to obtain vlan tag information that it must 430 | insert into the given output packet. 431 | @param m A mbuf containing a packet that may require vlan tag stuffing. 432 | @param vlanTag After calling, the low order 16 bits contain the 802.1Q priority and 433 | vlan ID tag in host order. The hi-order 16 bits are currently unused and should be ignored. 434 | @result true if vlanTag has been set and should be used. 435 | false if no vlan tag stuffing is required for this packet. */ 436 | 437 | virtual bool getVlanTagDemand(mbuf_t m, UInt32 *vlanTag); 438 | 439 | OSMetaClassDeclareReservedUsed( IOEthernetController, 1); 440 | 441 | /*! @function setVlanTag 442 | @abstract Encode a received packet with the vlan tag result reported 443 | by the hardware. 444 | @discussion A network controller that can strip 802.1Q vlan tag information for a 445 | received packet should call this method to encode the result on the 446 | packet, before passing it up towards the protocol stacks. 447 | @param m A mbuf containing a packet that has had its 802.1q vlan tag stripped by 448 | the hardware. 449 | @param vlanTag A value in host order that contains the 802.1q vlan tag and priority 450 | in the low order 16 bits. The hi order word is currently unused and should be set to 0. */ 451 | 452 | virtual void setVlanTag(mbuf_t m, UInt32 vlanTag); 453 | 454 | // Virtual function padding 455 | OSMetaClassDeclareReservedUnused( IOEthernetController, 2); 456 | OSMetaClassDeclareReservedUnused( IOEthernetController, 3); 457 | OSMetaClassDeclareReservedUnused( IOEthernetController, 4); 458 | OSMetaClassDeclareReservedUnused( IOEthernetController, 5); 459 | OSMetaClassDeclareReservedUnused( IOEthernetController, 6); 460 | OSMetaClassDeclareReservedUnused( IOEthernetController, 7); 461 | OSMetaClassDeclareReservedUnused( IOEthernetController, 8); 462 | OSMetaClassDeclareReservedUnused( IOEthernetController, 9); 463 | OSMetaClassDeclareReservedUnused( IOEthernetController, 10); 464 | OSMetaClassDeclareReservedUnused( IOEthernetController, 11); 465 | OSMetaClassDeclareReservedUnused( IOEthernetController, 12); 466 | OSMetaClassDeclareReservedUnused( IOEthernetController, 13); 467 | OSMetaClassDeclareReservedUnused( IOEthernetController, 14); 468 | OSMetaClassDeclareReservedUnused( IOEthernetController, 15); 469 | OSMetaClassDeclareReservedUnused( IOEthernetController, 16); 470 | OSMetaClassDeclareReservedUnused( IOEthernetController, 17); 471 | OSMetaClassDeclareReservedUnused( IOEthernetController, 18); 472 | OSMetaClassDeclareReservedUnused( IOEthernetController, 19); 473 | OSMetaClassDeclareReservedUnused( IOEthernetController, 20); 474 | OSMetaClassDeclareReservedUnused( IOEthernetController, 21); 475 | OSMetaClassDeclareReservedUnused( IOEthernetController, 22); 476 | OSMetaClassDeclareReservedUnused( IOEthernetController, 23); 477 | OSMetaClassDeclareReservedUnused( IOEthernetController, 24); 478 | OSMetaClassDeclareReservedUnused( IOEthernetController, 25); 479 | OSMetaClassDeclareReservedUnused( IOEthernetController, 26); 480 | OSMetaClassDeclareReservedUnused( IOEthernetController, 27); 481 | OSMetaClassDeclareReservedUnused( IOEthernetController, 28); 482 | OSMetaClassDeclareReservedUnused( IOEthernetController, 29); 483 | OSMetaClassDeclareReservedUnused( IOEthernetController, 30); 484 | OSMetaClassDeclareReservedUnused( IOEthernetController, 31); 485 | }; 486 | 487 | /* 488 | * FIXME: remove this. 489 | */ 490 | enum { 491 | kIOEnetPromiscuousModeOff = false, 492 | kIOEnetPromiscuousModeOn = true, 493 | kIOEnetPromiscuousModeAll = true, 494 | kIOEnetMulticastModeOff = false, 495 | kIOEnetMulticastModeFilter = true 496 | }; 497 | typedef bool IOEnetPromiscuousMode; 498 | typedef bool IOEnetMulticastMode; 499 | 500 | #endif /* __cplusplus */ 501 | #endif /* KERNEL */ 502 | #endif /* !_IOETHERNETCONTROLLER_H */ 503 | -------------------------------------------------------------------------------- /VirtualMac80211/apple/IOEthernetInterface.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1998-2008 Apple Inc. All rights reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * The contents of this file constitute Original Code as defined in and 7 | * are subject to the Apple Public Source License Version 1.1 (the 8 | * "License"). You may not use this file except in compliance with the 9 | * License. Please obtain a copy of the License at 10 | * http://www.apple.com/publicsource and read it before using this file. 11 | * 12 | * This Original Code and all software distributed under the License are 13 | * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER 14 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 15 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the 17 | * License for the specific language governing rights and limitations 18 | * under the License. 19 | * 20 | * @APPLE_LICENSE_HEADER_END@ 21 | */ 22 | 23 | #ifndef _IOETHERNETINTERFACE_H 24 | #define _IOETHERNETINTERFACE_H 25 | 26 | /*! @defined kIOEthernetInterfaceClass 27 | @abstract The name of the 28 | IOEthernetInterface class. 29 | */ 30 | 31 | #define kIOEthernetInterfaceClass "IOEthernetInterface" 32 | 33 | /*! @defined kIOActivePacketFilters 34 | @abstract A property of IOEthernetInterface objects. 35 | @discussion The kIOActivePacketFilters property has an OSDictionary value that describes the current 36 | set of packet filters that have been successfully activated. Each 37 | entry in the dictionary is a key/value pair consisting of the filter 38 | group name, and an OSNumber describing the set of active filters for 39 | that group. Entries in this dictionary will mirror those in 40 | kIORequiredPacketFilters if the controller has reported success for 41 | all filter change requests from the IOEthernetInterface object. 42 | */ 43 | 44 | #define kIOActivePacketFilters "IOActivePacketFilters" 45 | 46 | /*! @defined kIORequiredPacketFilters 47 | @abstract A property of IOEthernetInterface objects. 48 | @discussion The kIORequiredPacketFilters property has an OSDictionary value that describes the current 49 | set of required packet filters. Each entry in the dictionary is a 50 | key/value pair consisting of the filter group name, and an OSNumber 51 | describing the set of required filters for that group. 52 | */ 53 | 54 | #define kIORequiredPacketFilters "IORequiredPacketFilters" 55 | 56 | /*! @defined kIOMulticastAddressList 57 | @abstract A property of IOEthernetInterface objects. 58 | @discussion The kIOMulticastAddressList property is an OSData object that describes the 59 | list of multicast addresses that are being used by the 60 | controller to match against the destination address of an 61 | incoming frame. 62 | */ 63 | 64 | #define kIOMulticastAddressList "IOMulticastAddressList" 65 | #define kIOMulticastFilterData kIOMulticastAddressList 66 | 67 | #ifdef KERNEL 68 | #ifdef __cplusplus 69 | 70 | #include "IONetworkInterface.h" 71 | #include "IOEthernetController.h" 72 | #include 73 | 74 | /*! @class IOEthernetInterface 75 | @abstract The Ethernet interface object. 76 | @discussion An Ethernet controller driver, 77 | that is a subclass of IOEthernetController, will instantiate an object 78 | of this class when the driver calls the attachInterface() method. 79 | This interface object will then vend an Ethernet interface to DLIL, 80 | and manage the connection between the controller driver and the upper 81 | networking layers. Drivers will seldom need to subclass 82 | IOEthernetInterface. 83 | */ 84 | 85 | class IOEthernetInterface : public IONetworkInterface 86 | { 87 | OSDeclareDefaultStructors( IOEthernetInterface ) 88 | 89 | private: 90 | thread_call_t _inputEventThreadCall; // inputEvent() thread call 91 | UInt32 _mcAddrCount; // # of multicast addresses 92 | bool _ctrEnabled; // Is controller enabled? 93 | OSDictionary * _supportedFilters; // Controller's supported filters 94 | OSDictionary * _requiredFilters; // The required filters 95 | OSDictionary * _activeFilters; // Currently active filters 96 | bool _controllerLostPower; // true if controller is unusable 97 | 98 | struct ExpansionData { 99 | UInt32 altMTU; // track the physical mtu of controller 100 | UInt32 publishedFeatureID; // id for published wake packet 101 | uint32_t supportedWakeFilters; // bitmask of supported wake filters 102 | OSNumber * disabledWakeFilters; // OSNumber of disabled wake filters 103 | uint64_t wompEnabledAssertionID; 104 | }; 105 | /*! @var reserved 106 | Reserved for future use. (Internal use only) */ 107 | ExpansionData * _reserved; 108 | 109 | 110 | IOReturn enableController(IONetworkController * ctr); 111 | IOReturn setupMulticastFilter(IONetworkController * ctr); 112 | 113 | UInt32 getFilters(const OSDictionary * dict, 114 | const OSSymbol * group); 115 | 116 | bool setFilters(OSDictionary * dict, 117 | const OSSymbol * group, 118 | UInt32 filters); 119 | 120 | IOReturn disableFilter(IONetworkController * ctr, 121 | const OSSymbol * group, 122 | UInt32 filter, 123 | IOOptionBits options = 0); 124 | 125 | IOReturn enableFilter(IONetworkController * ctr, 126 | const OSSymbol * group, 127 | UInt32 filter, 128 | IOOptionBits options = 0); 129 | 130 | int syncSIOCSIFFLAGS(IONetworkController * ctr); 131 | int syncSIOCSIFADDR(IONetworkController * ctr); 132 | int syncSIOCADDMULTI(IONetworkController * ctr); 133 | int syncSIOCDELMULTI(IONetworkController * ctr); 134 | int syncSIOCSIFMTU(IONetworkController * ctr, struct ifreq * ifr, bool); 135 | int syncSIOCGIFDEVMTU(IONetworkController * ctr, struct ifreq * ifr); 136 | int syncSIOCSIFLLADDR(IONetworkController * ctr, const char * lladdr, int len); 137 | void _fixupVlanPacket(mbuf_t, u_int16_t, int); 138 | void reportInterfaceWakeFlags(IONetworkController * ctr); 139 | 140 | static void handleEthernetInputEvent(thread_call_param_t param0, thread_call_param_t param1); 141 | static int performGatedCommand(void *, void *, void *, void *, void *); 142 | static IOReturn enableFilter_Wrapper( 143 | IOEthernetInterface *, IONetworkController *, const OSSymbol *, UInt32 , IOOptionBits); 144 | 145 | public: 146 | 147 | /*! @function init 148 | @abstract Initializes an IOEthernetInterface instance. 149 | @discussion Instance variables are initialized, and an arpcom 150 | structure is allocated. 151 | @param controller A network controller object that will service 152 | the interface object being initialized. 153 | @result Returns true on success, false otherwise. 154 | */ 155 | 156 | virtual bool init( IONetworkController * controller ); 157 | 158 | /*! @function getNamePrefix 159 | @abstract Returns a string containing the prefix to use when 160 | creating a BSD name for this interface. 161 | @discussion The BSD name for each interface object is created by 162 | concatenating a string returned by this method, with an unique 163 | unit number assigned by IONetworkStack. 164 | @result Returns a pointer to a constant C string "en". Therefore, Ethernet 165 | interfaces will be registered with BSD as en0, en1, etc. 166 | */ 167 | 168 | virtual const char * getNamePrefix() const; 169 | 170 | protected: 171 | 172 | /*! @function free 173 | @abstract Frees the IOEthernetInterface instance. 174 | @discussion The memory allocated for the arpcom structure is released, 175 | followed by a call to super::free(). 176 | */ 177 | 178 | virtual void free(); 179 | 180 | /*! @function performCommand 181 | @abstract Handles an ioctl command sent to the Ethernet interface. 182 | @discussion This method handles socket ioctl commands sent to the Ethernet 183 | interface from DLIL. Commands recognized and processed by this method are 184 | SIOCSIFADDR, SIOCSIFFLAGS, SIOCADDMULTI, and SIOCDELMULTI. Other commands 185 | are passed to the superclass. 186 | @param controller The controller object. 187 | @param cmd The ioctl command code. 188 | @param arg0 Command argument 0. Generally a pointer to an ifnet structure 189 | associated with the interface. 190 | @param arg1 Command argument 1. 191 | @result Returns a BSD return value defined in bsd/sys/errno.h. 192 | */ 193 | 194 | virtual SInt32 performCommand(IONetworkController * controller, 195 | unsigned long cmd, 196 | void * arg0, 197 | void * arg1); 198 | 199 | /*! @function controllerDidOpen 200 | @abstract A notification that the interface has opened the network 201 | controller. 202 | @discussion This method will be called by IONetworkInterface after a 203 | network controller has accepted an open from this interface object. 204 | IOEthernetInterface will first call the implementation in its 205 | superclass, then inspect the controller through properties published 206 | in the registry. This method is called with the arbitration lock held. 207 | @param controller The controller object that was opened. 208 | @result Returns true on success, false otherwise. Returning false will 209 | cause the controller to be closed, and any pending client opens to be 210 | rejected. 211 | */ 212 | 213 | virtual bool controllerDidOpen(IONetworkController * controller); 214 | 215 | /*! @function controllerWillClose 216 | @abstract A notification that the interface will close the network 217 | controller. 218 | @discussion This method will simply call super to propagate the method 219 | call. This method is called with the arbitration lock held. 220 | @param controller The controller that is about to be closed. 221 | */ 222 | 223 | virtual void controllerWillClose(IONetworkController * controller); 224 | 225 | 226 | /*! @function controllerWillChangePowerState 227 | @abstract Handles a notification that the network controller 228 | servicing this interface object is about to transition to a new power state. 229 | @discussion If the controller is about to transition to an unusable state, 230 | and it is currently enabled, then the disable() method on the controller is 231 | called. 232 | @param controller The network controller object. 233 | @param flags Flags that describe the capability of the controller in the new 234 | power state. 235 | @param stateNumber An index to a state in the network controller's 236 | power state array that the controller is switching to. 237 | @param policyMaker A reference to the network controller's policy-maker, 238 | and is also the originator of this notification. 239 | @result Always returns kIOReturnSuccess. 240 | */ 241 | 242 | virtual IOReturn controllerWillChangePowerState( 243 | IONetworkController * controller, 244 | IOPMPowerFlags flags, 245 | UInt32 stateNumber, 246 | IOService * policyMaker); 247 | 248 | /*! @function controllerDidChangePowerState 249 | @abstract Handles a notification that the network controller servicing 250 | this interface object has transitioned to a new power state. 251 | @discussion If the controller did transition to a usable state, and it was 252 | previously disabled due to a previous power change, then it is re-enabled. 253 | @param controller The network controller object. 254 | @param flags Flags that describe the capability of the controller in the new 255 | power state. 256 | @param stateNumber An index to a state in the network controller's 257 | power state array that the controller has switched to. 258 | @param policyMaker A reference to the network controller's policy-maker, 259 | and is also the originator of this notification. 260 | @result Always returns kIOReturnSuccess. 261 | */ 262 | 263 | virtual IOReturn controllerDidChangePowerState( 264 | IONetworkController * controller, 265 | IOPMPowerFlags flags, 266 | UInt32 stateNumber, 267 | IOService * policyMaker); 268 | 269 | public: 270 | /* Override IONetworkInterface::willTerminate() */ 271 | 272 | virtual bool willTerminate( IOService * provider, 273 | IOOptionBits options ); 274 | 275 | /* Override IONetworkInterface::attachToDataLinkLayer() */ 276 | 277 | virtual IOReturn attachToDataLinkLayer( IOOptionBits options, 278 | void * parameter ); 279 | 280 | /* Override IONetworkInterface::inputEvent() */ 281 | 282 | virtual bool inputEvent( UInt32 type, void * data ); 283 | 284 | protected: 285 | virtual void feedPacketInputTap(mbuf_t); 286 | virtual void feedPacketOutputTap(mbuf_t); 287 | virtual bool initIfnetParams(struct ifnet_init_params *params); 288 | 289 | public: 290 | // Virtual function padding 291 | OSMetaClassDeclareReservedUnused( IOEthernetInterface, 0); 292 | OSMetaClassDeclareReservedUnused( IOEthernetInterface, 1); 293 | OSMetaClassDeclareReservedUnused( IOEthernetInterface, 2); 294 | OSMetaClassDeclareReservedUnused( IOEthernetInterface, 3); 295 | OSMetaClassDeclareReservedUnused( IOEthernetInterface, 4); 296 | OSMetaClassDeclareReservedUnused( IOEthernetInterface, 5); 297 | OSMetaClassDeclareReservedUnused( IOEthernetInterface, 6); 298 | OSMetaClassDeclareReservedUnused( IOEthernetInterface, 7); 299 | OSMetaClassDeclareReservedUnused( IOEthernetInterface, 8); 300 | OSMetaClassDeclareReservedUnused( IOEthernetInterface, 9); 301 | OSMetaClassDeclareReservedUnused( IOEthernetInterface, 10); 302 | OSMetaClassDeclareReservedUnused( IOEthernetInterface, 11); 303 | OSMetaClassDeclareReservedUnused( IOEthernetInterface, 12); 304 | OSMetaClassDeclareReservedUnused( IOEthernetInterface, 13); 305 | OSMetaClassDeclareReservedUnused( IOEthernetInterface, 14); 306 | OSMetaClassDeclareReservedUnused( IOEthernetInterface, 15); 307 | }; 308 | 309 | #endif /* __cplusplus */ 310 | #endif /* KERNEL */ 311 | #endif /* !_IOETHERNETINTERFACE_H */ 312 | -------------------------------------------------------------------------------- /VirtualMac80211/apple/apple80211_ioctl.h: -------------------------------------------------------------------------------- 1 | // 2 | // apple80211_ioctl.h 3 | // VirtualMac80211 4 | // 5 | // Created by qcwap on 2020/6/28. 6 | // Copyright © 2020 zxystd. All rights reserved. 7 | // 8 | 9 | #ifndef apple80211_ioctl_h 10 | #define apple80211_ioctl_h 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include "apple80211_var.h" 18 | 19 | #define IOCTL_GET 3224398281LL 20 | #define IOCTL_SET 2150656456LL 21 | 22 | #define IFNAMSIZ 16 23 | 24 | struct apple80211req 25 | { 26 | char req_if_name[IFNAMSIZ]; 27 | uint32_t req_type; 28 | uint32_t req_val; 29 | uint64_t req_len; 30 | void *req_data; 31 | uint32_t req_flag; 32 | }; 33 | 34 | #define APPLE80211_VERSION 1 35 | 36 | struct apple80211_ssid_data 37 | { 38 | u_int32_t version; 39 | u_int32_t ssid_len; 40 | u_int8_t ssid_bytes[APPLE80211_MAX_SSID_LEN]; 41 | } __packed; 42 | 43 | struct apple80211_channel_data 44 | { 45 | u_int32_t version; 46 | struct apple80211_channel channel; 47 | } __packed; 48 | 49 | struct apple80211_bssid_data 50 | { 51 | u_int32_t version; 52 | struct ether_addr bssid; 53 | } __packed; 54 | 55 | struct apple80211_cipher_key 56 | { 57 | u_int32_t version; 58 | uint8_t type; 59 | uint8_t flags; 60 | } __packed; 61 | 62 | struct apple80211_capability_data 63 | { 64 | u_int32_t version; 65 | u_int8_t capabilities[11]; 66 | } __packed; 67 | 68 | struct apple80211_state_data 69 | { 70 | u_int32_t version; 71 | u_int32_t state; 72 | } __packed; 73 | 74 | struct apple80211_rssi_data 75 | { 76 | u_int32_t version; 77 | u_int32_t num_radios; 78 | u_int32_t rssi_unit; 79 | int32_t rssi[APPLE80211_MAX_RADIO]; // control channel 80 | int32_t aggregate_rssi; // aggregate control channel rssi 81 | int32_t rssi_ext[APPLE80211_MAX_RADIO]; // extension channel rssi 82 | int32_t aggregate_rssi_ext; // aggregate extension channel rssi 83 | } __packed; 84 | 85 | struct apple80211_power_data 86 | { 87 | u_int32_t version; 88 | u_int32_t num_radios; 89 | u_int32_t power_state[APPLE80211_MAX_RADIO]; 90 | } __packed; 91 | 92 | struct apple80211_assoc_result_data 93 | { 94 | u_int32_t version; 95 | u_int32_t result; 96 | } __packed; 97 | 98 | struct apple80211_assoc_status_data 99 | { 100 | u_int32_t version; 101 | u_int32_t status; 102 | } __packed; 103 | 104 | struct apple80211_rate_data 105 | { 106 | u_int32_t version; 107 | u_int32_t num_radios; 108 | u_int32_t rate[APPLE80211_MAX_RADIO]; 109 | } __packed; 110 | 111 | struct apple80211_status_dev_data 112 | { 113 | u_int32_t version; 114 | u_int8_t dev_name[MAXPATHLEN]; 115 | } __packed; 116 | 117 | struct apple80211_powersave_data 118 | { 119 | u_int32_t version; 120 | u_int32_t powersave_level; 121 | } __packed; 122 | 123 | struct apple80211_protmode_data 124 | { 125 | u_int32_t version; 126 | u_int32_t protmode; 127 | u_int32_t threshold; // bytes 128 | } __packed; 129 | 130 | struct apple80211_txpower_data 131 | { 132 | u_int32_t version; 133 | u_int32_t txpower_unit; 134 | int32_t txpower; 135 | } __packed; 136 | 137 | struct apple80211_phymode_data 138 | { 139 | u_int32_t version; 140 | u_int32_t phy_mode; // vector of supported phy modes 141 | u_int32_t active_phy_mode; // current active phy mode 142 | } __packed; 143 | 144 | struct apple80211_opmode_data 145 | { 146 | u_int32_t version; 147 | u_int32_t op_mode; 148 | } __packed; 149 | 150 | struct apple80211_noise_data 151 | { 152 | u_int32_t version; 153 | u_int32_t num_radios; 154 | u_int32_t noise_unit; 155 | int32_t noise[APPLE80211_MAX_RADIO]; // control channel 156 | int32_t aggregate_noise; // aggregate control channel noise 157 | int32_t noise_ext[APPLE80211_MAX_RADIO]; // extension channel noise 158 | int32_t aggregate_noise_ext; // aggregate extension channel noise 159 | } __packed; 160 | 161 | struct apple80211_intmit_data 162 | { 163 | u_int32_t version; 164 | u_int32_t int_mit; 165 | } __packed; 166 | 167 | struct apple80211_authtype_data 168 | { 169 | u_int32_t version; 170 | u_int32_t authtype_lower; // apple80211_authtype_lower 171 | u_int32_t authtype_upper; // apple80211_authtype_upper 172 | } __packed; 173 | 174 | struct apple80211_sup_channel_data 175 | { 176 | u_int32_t version; 177 | u_int32_t num_channels; 178 | struct apple80211_channel supported_channels[APPLE80211_MAX_CHANNELS]; 179 | } __packed; 180 | 181 | 182 | struct apple80211_roam_threshold_data 183 | { 184 | u_int32_t threshold; 185 | u_int32_t count; 186 | } __packed; 187 | 188 | struct apple80211_locale_data 189 | { 190 | u_int32_t version; 191 | u_int32_t locale; 192 | } __packed; 193 | 194 | struct apple80211_scan_data 195 | { 196 | u_int32_t version; 197 | u_int32_t bss_type; // apple80211_apmode 198 | struct ether_addr bssid; // target BSSID 199 | u_int32_t ssid_len; // length of the SSID 200 | u_int8_t ssid[APPLE80211_MAX_SSID_LEN]; // direct scan ssid or AirDrop scan ssid like "Air-xxxx" 201 | u_int32_t scan_type; // apple80211_scan_type 202 | u_int32_t phy_mode; // apple80211_phymode vector 203 | u_int16_t dwell_time; // time to spend on each channel (ms) 204 | u_int32_t rest_time; // time between scanning each channel (ms) 205 | u_int32_t num_channels; // 0 if not passing in channels 206 | struct apple80211_channel channels[APPLE80211_MAX_CHANNELS]; // channel list 207 | }; 208 | 209 | struct apple80211_scan_multiple_data 210 | { 211 | uint32_t version; 212 | uint32_t three; 213 | uint32_t ssid_count; 214 | apple80211_ssid_data ssids[16]; 215 | uint32_t bssid_count; 216 | ether_addr bssids[16]; 217 | uint32_t scan_type; 218 | uint32_t phy_mode; 219 | uint32_t dwell_time; 220 | uint32_t rest_time; 221 | uint32_t num_channels; 222 | struct apple80211_channel channels[128]; 223 | uint16_t unk_2; 224 | }; 225 | 226 | struct apple80211_apmode_data 227 | { 228 | u_int32_t version; 229 | u_int32_t apmode; 230 | } __packed; 231 | 232 | struct apple80211_assoc_data 233 | { 234 | u_int32_t version; 235 | u_int16_t ad_mode; // apple80211_apmode 236 | u_int16_t ad_auth_lower; // apple80211_authtype_lower 237 | u_int16_t ad_auth_upper; // apple80211_authtype_upper 238 | u_int32_t ad_ssid_len; 239 | u_int8_t ad_ssid[ APPLE80211_MAX_SSID_LEN ]; 240 | struct ether_addr ad_bssid; // prefer over ssid if not zeroed 241 | struct apple80211_key ad_key; 242 | u_int16_t ad_rsn_ie_len; 243 | u_int8_t ad_rsn_ie[ APPLE80211_MAX_RSN_IE_LEN ]; 244 | u_int32_t ad_flags; // apple80211_assoc_flags 245 | } __packed; 246 | 247 | struct apple80211_deauth_data 248 | { 249 | u_int32_t version; 250 | u_int32_t deauth_reason; // reason code 251 | struct ether_addr deauth_ea; // BSSID of AP 252 | } __packed; 253 | 254 | struct apple80211_countermeasures_data 255 | { 256 | u_int32_t version; 257 | u_int32_t enabled; 258 | } __packed; 259 | 260 | struct apple80211_frag_threshold_data 261 | { 262 | u_int32_t version; 263 | u_int32_t threshold; // bytes 264 | } __packed; 265 | 266 | struct apple80211_rate_set_data 267 | { 268 | u_int32_t version; 269 | u_int16_t num_rates; 270 | struct apple80211_rate rates[APPLE80211_MAX_RATES]; 271 | } __packed; 272 | 273 | struct apple80211_short_slot_data 274 | { 275 | u_int32_t version; 276 | u_int8_t mode; 277 | } __packed; 278 | 279 | struct apple80211_retry_limit_data 280 | { 281 | u_int32_t version; 282 | u_int32_t limit; 283 | } __packed; 284 | 285 | struct apple80211_antenna_data 286 | { 287 | u_int32_t version; 288 | u_int32_t num_radios; 289 | int32_t antenna_index[APPLE80211_MAX_RADIO]; 290 | } __packed; 291 | 292 | struct apple80211_dtim_int_data 293 | { 294 | u_int32_t version; 295 | u_int32_t interval; 296 | } __packed; 297 | 298 | struct apple80211_sta_data 299 | { 300 | u_int32_t version; 301 | u_int32_t num_stations; 302 | struct apple80211_station station_list[APPLE80211_MAX_STATIONS]; 303 | } __packed; 304 | 305 | struct apple80211_version_data 306 | { 307 | u_int32_t version; 308 | u_int16_t string_len; 309 | char string[APPLE80211_MAX_VERSION_LEN]; 310 | } __packed; 311 | 312 | struct apple80211_rom_data 313 | { 314 | u_int32_t version; 315 | u_int32_t rom_len; 316 | u_int8_t rom[1]; // variable length 317 | } __packed; 318 | 319 | struct apple80211_rand_data 320 | { 321 | u_int32_t version; 322 | u_int32_t rand; 323 | } __packed; 324 | 325 | struct apple80211_rsn_ie_data 326 | { 327 | u_int32_t version; 328 | u_int16_t len; 329 | u_int8_t ie[ APPLE80211_MAX_RSN_IE_LEN ]; 330 | } __packed; 331 | 332 | struct apple80211_ap_ie_data 333 | { 334 | u_int32_t version; 335 | u_int32_t len; 336 | u_int8_t *ie_data; 337 | } __packed; 338 | 339 | struct apple80211_stats_data 340 | { 341 | u_int32_t version; 342 | u_int32_t tx_frame_count; 343 | u_int32_t tx_errors; 344 | u_int32_t rx_frame_count; 345 | u_int32_t rx_errors; 346 | } __packed; 347 | 348 | struct apple80211_country_code_data 349 | { 350 | u_int32_t version; 351 | u_int8_t cc[APPLE80211_MAX_CC_LEN]; 352 | } __packed; 353 | 354 | struct apple80211_last_rx_pkt_data 355 | { 356 | u_int32_t version; 357 | u_int32_t rate; 358 | int32_t rssi; 359 | u_int32_t num_streams; // number of spatial streams 360 | struct ether_addr sa; // source address 361 | } __packed; 362 | 363 | struct apple80211_radio_info_data 364 | { 365 | u_int32_t version; 366 | u_int32_t count; // number of rf chains 367 | } __packed; 368 | 369 | struct apple80211_guard_interval_data 370 | { 371 | u_int32_t version; 372 | u_int32_t interval; // apple80211_guard_interval 373 | } __packed; 374 | 375 | struct apple80211_mcs_data 376 | { 377 | u_int32_t version; 378 | u_int32_t index; // 0 to APPLE80211_MAX_MCS_INDEX 379 | } __packed; 380 | 381 | struct apple80211_rifs_data 382 | { 383 | u_int32_t version; 384 | u_int32_t enabled; 385 | } __packed; 386 | 387 | struct apple80211_ldpc_data 388 | { 389 | u_int32_t version; 390 | u_int32_t enabled; 391 | } __packed; 392 | 393 | struct apple80211_msdu_data 394 | { 395 | u_int32_t version; 396 | u_int32_t max_length; // 3839 or 7935 bytes 397 | } __packed; 398 | 399 | struct apple80211_mpdu_data 400 | { 401 | u_int32_t version; 402 | u_int32_t max_factor; // 0 - APPLE80211_MAX_MPDU_FACTOR 403 | u_int32_t max_density; // 0 - APPLE80211_MAX_MPDU_DENSITY 404 | } __packed; 405 | 406 | struct apple80211_block_ack_data 407 | { 408 | u_int32_t version; 409 | u_int8_t ba_enabled; // block ack enabled 410 | u_int8_t immediate_ba_enabled; // immediate block ack enabled 411 | u_int8_t cbba_enabled; // compressed bitmap block ack enabled 412 | u_int8_t implicit_ba_enabled; // implicit block ack enabled 413 | } __packed; 414 | 415 | struct apple80211_pls_data 416 | { 417 | u_int32_t version; 418 | u_int32_t enabled; // phy level spoofing enabled 419 | } __packed; 420 | 421 | struct apple80211_psmp_data 422 | { 423 | u_int32_t version; 424 | u_int32_t enabled; 425 | } __packed; 426 | 427 | struct apple80211_physubmode_data 428 | { 429 | u_int32_t version; 430 | u_int32_t phy_mode; // one apple80211_phymode 431 | u_int32_t phy_submode; // one apple80211_physubmode 432 | u_int32_t flags; // apple80211_channel_flag vector 433 | } __packed; 434 | 435 | struct apple80211_mcs_index_set_data 436 | { 437 | u_int32_t version; 438 | u_int8_t mcs_set_map[APPLE80211_MAP_SIZE( APPLE80211_MAX_MCS_INDEX + 1 )]; 439 | } __packed; 440 | 441 | struct apple80211_wow_parameter_data 442 | { 443 | u_int32_t version; 444 | u_int8_t wake_cond_map[APPLE80211_MAP_SIZE( APPLE80211_MAX_WAKE_COND + 1 )]; 445 | u_int32_t beacon_loss_time; 446 | u_int32_t pattern_count; 447 | struct apple80211_wow_pattern patterns[APPLE80211_MAX_WOW_PATTERNS]; 448 | } __packed; 449 | 450 | struct apple80211_40mhz_intolerant_data 451 | { 452 | u_int32_t version; 453 | u_int32_t enabled; // bit enabled or not 454 | } __packed; 455 | 456 | #endif /* apple80211_ioctl_h */ 457 | -------------------------------------------------------------------------------- /VirtualMac80211/apple/apple80211_var.h: -------------------------------------------------------------------------------- 1 | // 2 | // apple80211_var.h 3 | // VirtualMac80211 4 | // 5 | // Created by qcwap on 2020/6/28. 6 | // Copyright © 2020 zxystd. All rights reserved. 7 | // 8 | 9 | #ifndef apple80211_var_h 10 | #define apple80211_var_h 11 | 12 | #define __packed __attribute__((packed)) 13 | 14 | // Sizes and limits 15 | #define APPLE80211_ADDR_LEN 6 16 | #define APPLE80211_MAX_RATES 15 17 | #define APPLE80211_MAX_SSID_LEN 32 18 | #define APPLE80211_MAX_ANTENNAE 4 19 | #define APPLE80211_MAX_RADIO 4 20 | #define APPLE80211_MAX_CHANNELS 128 21 | #define APPLE80211_MAX_STATIONS 128 22 | #define APPLE80211_MAX_VERSION_LEN 256 23 | #define APPLE80211_MAX_ROM_SIZE 32768 // 32 KB 24 | #define APPLE80211_MAX_RSN_IE_LEN 257 // 255 + type and length bytes 25 | #define APPLE80211_MAX_CC_LEN 3 26 | #define APPLE80211_MAX_MCS_INDEX 76 27 | #define APPLE80211_MAX_MPDU_FACTOR 3 28 | #define APPLE80211_MAX_MPDU_DENSITY 7 29 | #define APPLE80211_MAX_WOW_PAT_LEN 1500 // Max wake on wireless pattern length 30 | #define APPLE80211_MAX_WOW_PATTERNS 12 // Arbitrary..this can change 31 | 32 | #define APPLE80211_MAP_SIZE( _bits ) (roundup( _bits, NBBY )/NBBY) 33 | 34 | enum apple80211_phymode { 35 | APPLE80211_MODE_UNKNOWN = 0, 36 | APPLE80211_MODE_AUTO = 0x1, // autoselect 37 | APPLE80211_MODE_11A = 2 << (1 - 1), // 5GHz, OFDM 38 | APPLE80211_MODE_11B = 2 << (2 - 1), // 2GHz, CCK 39 | APPLE80211_MODE_11G = 2 << (3 - 1), // 2GHz, OFDM 40 | APPLE80211_MODE_11N = 2 << (4 - 1), // 2GHz/5GHz, OFDM 41 | APPLE80211_MODE_TURBO_A = 2 << (5 - 1), // 5GHz, OFDM, 2x clock 42 | APPLE80211_MODE_TURBO_G = 2 << (6 - 1), // 2GHz, OFDM, 2x clock 43 | APPLE80211_MODE_11AC = 2 << (7 - 1), 44 | }; 45 | 46 | enum apple80211_physubmode { 47 | APPLE80211_SUBMODE_UNKNOWN = 0x0, 48 | APPLE80211_SUBMODE_11N_AUTO = 0x1, // 11n mode determined by AP capabilities 49 | APPLE80211_SUBMODE_11N_LEGACY = 0x2, // legacy 50 | APPLE80211_SUBMODE_11N_LEGACY_DUP = 0x4, // legacy duplicate 51 | APPLE80211_SUBMODE_11N_HT = 0x8, // high throughput 52 | APPLE80211_SUBMODE_11N_HT_DUP = 0x10, // high throughput duplicate 53 | APPLE80211_SUBMODE_11N_GF = 0x20, // green field 54 | }; 55 | 56 | // flags 57 | enum apple80211_opmode { 58 | APPLE80211_M_NONE = 0x0, 59 | APPLE80211_M_STA = 0x1, // infrastructure station 60 | APPLE80211_M_IBSS = 0x2, // IBSS (adhoc) station 61 | APPLE80211_M_AHDEMO = 0x4, // Old lucent compatible adhoc demo 62 | APPLE80211_M_HOSTAP = 0x8, // Software Access Point 63 | APPLE80211_M_MONITOR = 0x10 // Monitor mode 64 | }; 65 | 66 | enum apple80211_apmode { 67 | APPLE80211_AP_MODE_UNKNOWN = 0, 68 | APPLE80211_AP_MODE_IBSS = 1, // IBSS (adhoc) station 69 | APPLE80211_AP_MODE_INFRA = 2, // Access Point 70 | APPLE80211_AP_MODE_ANY = 3, // Any supported mode 71 | }; 72 | 73 | enum apple80211_state { 74 | APPLE80211_S_INIT = 0, // default state 75 | APPLE80211_S_SCAN = 1, // scanning 76 | APPLE80211_S_AUTH = 2, // try to authenticate 77 | APPLE80211_S_ASSOC = 3, // try to assoc 78 | APPLE80211_S_RUN = 4, // associated 79 | }; 80 | 81 | enum apple80211_protmode { 82 | APPLE80211_PROTMODE_OFF = 0, // no protection 83 | APPLE80211_PROTMODE_AUTO = 1, // auto 84 | APPLE80211_PROTMODE_CTS = 2, // CTS to self 85 | APPLE80211_PROTMODE_RTSCTS = 3, // RTS-CTS 86 | APPLE80211_PROTMODE_DUAL_CTS = 4, // dual CTS 87 | }; 88 | 89 | enum apple80211_cipher_type { 90 | APPLE80211_CIPHER_NONE = 0, // open network 91 | APPLE80211_CIPHER_WEP_40 = 1, // 40 bit WEP 92 | APPLE80211_CIPHER_WEP_104 = 2, // 104 bit WEP 93 | APPLE80211_CIPHER_TKIP = 3, // TKIP (WPA) 94 | APPLE80211_CIPHER_AES_OCB = 4, // AES (OCB) 95 | APPLE80211_CIPHER_AES_CCM = 5, // AES (CCM) 96 | APPLE80211_CIPHER_PMK = 6, // PMK 97 | APPLE80211_CIPHER_PMKSA = 7, // PMK obtained from pre-authentication 98 | }; 99 | 100 | enum apple80211_cipher_key_type 101 | { 102 | APPLE80211_CIPHER_KEY_TYPE_UNICAST = 0, // unicast cipher key 103 | APPLE80211_CIPHER_KEY_TYPE_MULTICAST = 1 // multicast cipher key 104 | }; 105 | 106 | // Low level 802.11 authentication types 107 | 108 | enum apple80211_authtype_lower 109 | { 110 | APPLE80211_AUTHTYPE_OPEN = 1, // open 111 | APPLE80211_AUTHTYPE_SHARED = 2, // shared key 112 | APPLE80211_AUTHTYPE_CISCO = 3, // cisco net eap 113 | }; 114 | 115 | // Higher level authentication used after 802.11 association complete 116 | 117 | enum apple80211_authtype_upper 118 | { 119 | APPLE80211_AUTHTYPE_NONE = 0, // No upper auth 120 | APPLE80211_AUTHTYPE_WPA = 1, // WPA 121 | APPLE80211_AUTHTYPE_WPA_PSK = 2, // WPA PSK 122 | APPLE80211_AUTHTYPE_WPA2 = 3, // WPA2 123 | APPLE80211_AUTHTYPE_WPA2_PSK = 4, // WPA2 PSK 124 | APPLE80211_AUTHTYPE_LEAP = 5, // LEAP 125 | APPLE80211_AUTHTYPE_8021X = 6, // 802.1x 126 | APPLE80211_AUTHTYPE_WPS = 7, // WiFi Protected Setup 127 | }; 128 | 129 | // Unify association status code and deauth reason codes into a single enum describing 130 | // common error conditions 131 | enum apple80211_associate_result 132 | { 133 | APPLE80211_RESULT_UNAVAILABLE = 0, // No association/authentication result ready 134 | APPLE80211_RESULT_SUCCESS = 1, // APPLE80211_STATUS_SUCCESS and no deauth 135 | APPLE80211_RESULT_UNSPECIFIED_FAILURE = 2, // APPLE80211_STATUS_UNSPECIFIED_FAILURE 136 | APPLE80211_RESULT_UNSUPPORTED_CAPAPBILITIES = 3, // APPLE80211_STATUS_UNSUPPORTED_CAPABILITIES 137 | APPLE80211_RESULT_REASSOCIATION_DENIED = 4, // APPLE80211_STATUS_REASSOCIATION_DENIED 138 | APPLE80211_RESULT_ASSOCIATION_DENIED = 5, // APPLE80211_STATUS_ASSOCIATION_DENIED 139 | APPLE80211_RESULT_AUTH_ALG_UNSUPPORTED = 6, // APPLE80211_STATUS_AUTH_ALG_UNSUPPORTED 140 | APPLE80211_RESULT_INVALID_AUTH_SEQ_NUM = 7, // APPLE80211_STATUS_INVALID_AUTH_SEQ_NUM 141 | APPLE80211_RESULT_CHALLENGE_FAILURE = 8, // APPLE80211_STATUS_CHALLENGE_FAILURE 142 | APPLE80211_RESULT_TIMEOUT = 9, // APPLE80211_STATUS_TIMEOUT 143 | APPLE80211_RESULT_AP_FULL = 10, // APPLE80211_STATUS_AP_FULL 144 | APPLE80211_RESULT_UNSUPPORTED_RATE_SET = 11, // APPLE80211_STATUS_UNSUPPORTED_RATE_SET 145 | APPLE80211_RESULT_SHORT_SLOT_UNSUPPORTED = 12, // APPLE80211_STATUS_SHORT_SLOT_UNSUPPORTED 146 | APPLE80211_RESULT_DSSS_OFDM_UNSUPPORTED = 13, // APPLE80211_STATUS_DSSS_OFDM_UNSUPPORTED 147 | APPLE80211_RESULT_INVALID_IE = 14, // APPLE80211_STATUS_INVALID_IE 148 | APPLE80211_RESULT_INVALID_GROUP_CIPHER = 15, // APPLE80211_STATUS_INVALID_GROUP_CIPHER 149 | APPLE80211_RESULT_INVALID_PAIRWISE_CIPHER = 16, // APPLE80211_STATUS_INVALID_PAIRWISE_CIPHER 150 | APPLE80211_RESULT_INVALID_AKMP = 17, // APPLE80211_STATUS_INVALID_AKMP 151 | APPLE80211_RESULT_UNSUPPORTED_RSN_VERSION = 18, // APPLE80211_STATUS_UNSUPPORTED_RSN_VERSION 152 | APPLE80211_RESULT_INVALID_RSN_CAPABILITIES = 19, // APPLE80211_STATUS_INVALID_RSN_CAPABILITIES 153 | APPLE80211_RESULT_CIPHER_SUITE_REJECTED = 20, // APPLE80211_STATUS_CIPHER_SUIT_REJECTED 154 | APPLE80211_RESULT_INVALID_PMK = 21, // APPLE80211_REASON_PREV_AUTH_EXPIRED received 155 | APPLE80211_RESULT_SUPPLICANT_TIMEOUT = 22, // RSNSupplicant did not finish handshake 156 | APPLE80211_RESULT_UNKNOWN = 0xffff // Unrecognized error condition 157 | }; 158 | 159 | enum apple80211_unit 160 | { 161 | APPLE80211_UNIT_DBM = 0, // dBm 162 | APPLE80211_UNIT_MW = 1, // milliwatts 163 | APPLE80211_UNIT_PERCENT = 2, // value expressed as a percentage 164 | }; 165 | 166 | enum apple80211_power_state 167 | { 168 | APPLE80211_POWER_OFF = 0, // Chain disabled 169 | APPLE80211_POWER_ON = 1, // Chain powered on for tx and rx 170 | APPLE80211_POWER_TX = 2, // Chain powered on for tx only 171 | APPLE80211_POWER_RX = 3, // Chain powered on for rx only 172 | }; 173 | 174 | enum apple80211_locale 175 | { 176 | APPLE80211_LOCALE_UNKNOWN = 0, 177 | APPLE80211_LOCALE_FCC = 1, 178 | APPLE80211_LOCALE_ETSI = 2, 179 | APPLE80211_LOCALE_JAPAN = 3, 180 | APPLE80211_LOCALE_KOREA = 4, 181 | APPLE80211_LOCALE_APAC = 5, 182 | APPLE80211_LOCALE_ROW = 6, 183 | }; 184 | 185 | enum apple80211_scan_type 186 | { 187 | APPLE80211_SCAN_TYPE_NONE = 0, 188 | APPLE80211_SCAN_TYPE_ACTIVE = 1, 189 | APPLE80211_SCAN_TYPE_PASSIVE = 2, 190 | APPLE80211_SCAN_TYPE_FAST = 3, // Ok to return cached scan results 191 | APPLE80211_SCAN_TYPE_BACKGROUND = 4, // Initiate background scanning 192 | }; 193 | 194 | enum apple80211_int_mit { 195 | APPLE80211_INT_MIT_OFF = 0, 196 | APPLE80211_INT_MIT_AUTO = 1, 197 | }; 198 | 199 | enum apple80211_channel_flag 200 | { 201 | APPLE80211_C_FLAG_NONE = 0x0, // no flags 202 | APPLE80211_C_FLAG_10MHZ = 0x1, // 10 MHz wide 203 | APPLE80211_C_FLAG_20MHZ = 0x2, // 20 MHz wide 204 | APPLE80211_C_FLAG_40MHZ = 0x4, // 40 MHz wide 205 | APPLE80211_C_FLAG_2GHZ = 0x8, // 2.4 GHz 206 | APPLE80211_C_FLAG_5GHZ = 0x10, // 5 GHz 207 | APPLE80211_C_FLAG_IBSS = 0x20, // IBSS supported 208 | APPLE80211_C_FLAG_HOST_AP = 0x40, // HOST AP mode supported 209 | APPLE80211_C_FLAG_ACTIVE = 0x80, // active scanning supported 210 | APPLE80211_C_FLAG_DFS = 0x100, // DFS required 211 | APPLE80211_C_FLAG_EXT_ABV = 0x200, // If 40 Mhz, extension channel above. 212 | // If this flag is not set, then the 213 | // extension channel is below. 214 | APPLE80211_C_FLAG_80MHZ = 0x400, // comex 215 | }; 216 | 217 | enum apple80211_rate_flag 218 | { 219 | APPLE80211_RATE_FLAG_NONE = 0x0, // no flags 220 | APPLE80211_RATE_FLAG_BASIC = 0x1, // basic rate 221 | APPLE80211_RATE_FLAG_HT = 0x2, // HT rate computed from MCS index 222 | }; 223 | 224 | enum apple80211_short_slot_mode 225 | { 226 | APPLE80211_SHORT_SLOT_MODE_AUTO = 1, // Default behavior 227 | APPLE80211_SHORT_SLOT_MODE_LONG = 2, // long - short slot timing mode 228 | APPLE80211_SHORT_SLOT_MODE_SHORT = 3, // short - short slot timing mode 229 | }; 230 | 231 | enum apple80211_powersave_mode 232 | { 233 | // Standard modes 234 | APPLE80211_POWERSAVE_MODE_DISABLED = 0, 235 | APPLE80211_POWERSAVE_MODE_80211 = 1, 236 | APPLE80211_POWERSAVE_MODE_VENDOR = 2, // Vendor specific mode, there should be 237 | // more general apple modes in the future. 238 | // Vendor modes also likely require more info. 239 | // Mimo modes 240 | APPLE80211_POWERSAVE_MODE_MIMO_STATIC = 3, 241 | APPLE80211_POWERSAVE_MODE_MIMO_DYNAMIC = 4, 242 | APPLE80211_POWERSAVE_MODE_MIMO_MIMO = 5, 243 | 244 | // WOW 245 | APPLE80211_POWERSAVE_MODE_WOW = 6, 246 | 247 | // Vendor specific powersave mode, throughput is maximized 248 | APPLE80211_POWERSAVE_MODE_MAX_THROUGHPUT = 7, 249 | 250 | // Vendor specific powersave mode, power savings are maximized, possibly 251 | // at the expense of throughput/latency. 252 | APPLE80211_POWERSAVE_MODE_MAX_POWERSAVE = 8, 253 | }; 254 | 255 | enum apple80211_debug_flag 256 | { 257 | APPLE80211_DEBUG_FLAG_NONE = 0x0, // No logging 258 | APPLE80211_DEBUG_FLAG_INFORMATIVE = 0x1, // Log "interesting" events 259 | APPLE80211_DEBUG_FLAG_ERROR = 0x2, // Log errors 260 | APPLE80211_DEBUG_FLAG_RSN = 0x4, // Full RSN supplicant logging 261 | APPLE80211_DEBUG_FLAG_SCAN = 0x8, // Scan events and information 262 | }; 263 | 264 | enum apple80211_guard_interval 265 | { 266 | APPLE80211_GI_SHORT = 400, // ns 267 | APPLE80211_GI_LONG = 800, // ns 268 | }; 269 | 270 | #define APPLE80211_RSC_LEN 8 271 | #define APPLE80211_KEY_BUFF_LEN 64 272 | 273 | #define APPLE80211_KEY_FLAG_UNICAST 0x1 274 | #define APPLE80211_KEY_FLAG_MULTICAST 0x2 275 | #define APPLE80211_KEY_FLAG_TX 0x4 276 | #define APPLE80211_KEY_FLAG_RX 0x8 277 | 278 | struct apple80211_key 279 | { 280 | u_int32_t version; 281 | u_int32_t key_len; 282 | u_int32_t key_cipher_type; // apple80211_cipher_type 283 | u_int16_t key_flags; 284 | u_int16_t key_index; 285 | u_int8_t key[ APPLE80211_KEY_BUFF_LEN ]; 286 | u_int32_t key_rsc_len; 287 | u_int8_t key_rsc[ APPLE80211_RSC_LEN ]; // receive sequence counter 288 | struct ether_addr key_ea; // key applies to this bssid 289 | uint32_t unk_1; 290 | uint8_t unk_2[16]; 291 | uint32_t unk_3; 292 | uint8_t unk_4[16]; 293 | uint8_t unk_5[8]; 294 | 295 | }; 296 | 297 | // Changing this affects any structure that contains a channel 298 | struct apple80211_channel 299 | { 300 | u_int32_t version; 301 | u_int32_t channel; // channel number 302 | u_int32_t flags; // apple80211_channel_flag vector 303 | }; 304 | 305 | struct apple80211_rate 306 | { 307 | u_int32_t version; 308 | u_int32_t rate; // rate mbps 309 | u_int32_t flags; // apple80211_rate_flag vector 310 | }; 311 | 312 | // Probe response capability flags, IEEE 7.3.1.4 313 | #define APPLE80211_CAPINFO_ESS 0x0001 314 | #define APPLE80211_CAPINFO_IBSS 0x0002 315 | #define APPLE80211_CAPINFO_CF_POLLABLE 0x0004 316 | #define APPLE80211_CAPINFO_CF_POLLREQ 0x0008 317 | #define APPLE80211_CAPINFO_PRIVACY 0x0010 318 | #define APPLE80211_CAPINFO_SHORT_PREAMBLE 0x0020 319 | #define APPLE80211_CAPINFO_PBCC 0x0040 320 | #define APPLE80211_CAPINFO_AGILITY 0x0080 321 | // 0x0100, 0x0200 reserved 322 | #define APPLE80211_CAPINFO_SHORT_SLOT_TIME 0x0400 323 | // 0x0800, 0x1000 reserved 324 | #define APPLE80211_CAPINFO_DSSS_OFDM 0X2000 325 | // 0x4000, 0x8000 reserved 326 | 327 | // Reason codes IEEE 7.3.1.7 328 | #define APPLE80211_REASON_UNSPECIFIED 1 329 | #define APPLE80211_REASON_PREV_AUTH_EXPIRED 2 330 | #define APPLE80211_REASON_AUTH_LEAVING 3 331 | #define APPLE80211_REASON_INACTIVE 4 332 | #define APPLE80211_REASON_AP_OVERLOAD 5 333 | #define APPLE80211_REASON_NOT_AUTHED 6 334 | #define APPLE80211_REASON_NOT_ASSOCED 7 335 | #define APPLE80211_REASON_ASSOC_LEAVING 8 336 | #define APPLE80211_REASON_ASSOC_NOT_AUTHED 9 337 | #define APPLE80211_REASON_POWER_CAP 10 338 | #define APPLE80211_REASON_SUPPORTED_CHANS 11 339 | 340 | #define APPLE80211_REASON_INVALID_IE 13 341 | #define APPLE80211_REASON_MIC_FAILURE 14 342 | #define APPLE80211_REASON_4_WAY_TIMEOUT 15 343 | #define APPLE80211_REASON_GROUP_KEY_TIMEOUT 16 344 | #define APPLE80211_REASON_DIFF_IE 17 345 | #define APPLE80211_REASON_INVALID_GROUP_KEY 18 346 | #define APPLE80211_REASON_INVALID_PAIR_KEY 19 347 | #define APPLE80211_REASON_INVALID_AKMP 20 348 | #define APPLE80211_REASON_UNSUPP_RSN_VER 21 349 | #define APPLE80211_REASON_INVALID_RSN_CAPS 22 350 | #define APPLE80211_REASON_8021X_AUTH_FAILED 23 351 | 352 | // Status codes IEEE 7.3.1.9 353 | #define APPLE80211_STATUS_SUCCESS 0 354 | #define APPLE80211_STATUS_UNSPECIFIED_FAILURE 1 355 | // 2-9 reserved 356 | #define APPLE80211_STATUS_UNSUPPORTED_CAPABILITIES 10 357 | #define APPLE80211_STATUS_REASSOCIATION_DENIED 11 358 | #define APPLE80211_STATUS_ASSOCIATION_DENIED 12 359 | #define APPLE80211_STATUS_AUTH_ALG_UNSUPPORTED 13 360 | #define APPLE80211_STATUS_INVALID_AUTH_SEQ_NUM 14 361 | #define APPLE80211_STATUS_CHALLENGE_FAILURE 15 362 | #define APPLE80211_STATUS_TIMEOUT 16 363 | #define APPLE80211_STATUS_AP_FULL 17 364 | #define APPLE80211_STATUS_UNSUPPORTED_RATE_SET 18 365 | // 22-24 reserved 366 | #define APPLE80211_STATUS_SHORT_SLOT_UNSUPPORTED 25 367 | #define APPLE80211_STATUS_DSSS_OFDM_UNSUPPORTED 26 368 | // 27-39 reserved 369 | #define APPLE80211_STATUS_INVALID_IE 40 370 | #define APPLE80211_STATUS_INVALID_GROUP_CIPHER 41 371 | #define APPLE80211_STATUS_INVALID_PAIRWISE_CIPHER 42 372 | #define APPLE80211_STATUS_INVALID_AKMP 43 373 | #define APPLE80211_STATUS_UNSUPPORTED_RSN_VERSION 44 374 | #define APPLE80211_STATUS_INVALID_RSN_CAPABILITIES 45 375 | #define APPLE80211_STATUS_CIPHER_SUITE_REJECTED 46 376 | // 47 - 65535 reserved 377 | #define APPLE80211_STATUS_UNAVAILABLE 0xffff 378 | 379 | // If mcs index is set to APPLE80211_MCS_INDEX_AUTO, the interface 380 | // should go to auto rate selection, and abandon any previously 381 | // configured static MCS indices 382 | #define APPLE80211_MCS_INDEX_AUTO 0xffffffff 383 | 384 | /* 385 | DSCP TOS/Traffic class values for WME access categories taken from 386 | WiFi WMM Test Plan v 1.3.1 Appendix C. 387 | 388 | TOS/Traffic class field looks like: 389 | 390 | 0 1 2 3 4 5 6 7 391 | +---+---+---+---+---+---+---+---+ 392 | | DSCP | ECN | 393 | +---+---+---+---+---+---+---+---+ 394 | 395 | These bits are numbered according to rfc 2474, but might be misleading. 396 | It looks like bit 0 is actually the high order bit. 397 | */ 398 | 399 | #define APPLE80211_DSCP_WME_BE 0x00 400 | #define APPLE80211_DSCP_WME_BK 0x08 401 | #define APPLE80211_DSCP_WME_VI 0x28 402 | #define APPLE80211_DSCP_WME_VO 0x38 403 | 404 | // Access category values set in the mbuf 405 | #define APPLE80211_WME_AC_BE 0 406 | #define APPLE80211_WME_AC_BK 1 407 | #define APPLE80211_WME_AC_VI 2 408 | #define APPLE80211_WME_AC_VO 3 409 | 410 | // Working within the limitations of the kpi mbuf routines, the receive interface pointer 411 | // is the best place to put this for now since it is not used on the output path. The mbuf 412 | // kpi doesn't allow us to access unused flags, or I would put the WME AC in there like 413 | // everyone else. 414 | 415 | #define APPLE80211_MBUF_SET_WME_AC( m, ac ) mbuf_pkthdr_setrcvif( m, (ifnet_t)ac ) 416 | #define APPLE80211_MBUF_WME_AC( m ) (int)mbuf_pkthdr_rcvif( m ) 417 | 418 | // FIXME: seems that rates array starts at 0x24, immediately after 419 | struct apple80211_scan_result 420 | { 421 | u_int32_t version; // 0x00 - 0x03 422 | apple80211_channel asr_channel; // 0x04 - 0x0f 423 | 424 | int16_t asr_unk; // 0x10 - 0x11 425 | 426 | int16_t asr_noise; // 0x12 - 0x13 427 | int16_t asr_snr; // 0x14 - 0x15 428 | int16_t asr_rssi; // 0x16 - 0x17 429 | int16_t asr_beacon_int; // 0x18 - 0x19 430 | 431 | int16_t asr_cap; // 0x1a - 0x1b (capabilities) 432 | 433 | u_int8_t asr_bssid[ APPLE80211_ADDR_LEN ]; // 0x1c 0x1d 0x1e 0x1f 0x20 0x21 434 | u_int8_t asr_nrates; // 0x22 435 | u_int8_t asr_nr_unk; // 0x23 436 | u_int32_t asr_rates[ APPLE80211_MAX_RATES ]; // 0x24 - 0x5f 437 | u_int8_t asr_ssid_len; // 0x60 438 | u_int8_t asr_ssid[ APPLE80211_MAX_SSID_LEN ]; // 0x61 - 0x80 439 | int16_t unk; 440 | uint8_t unk2; 441 | u_int32_t asr_age; // (ms) non-zero for cached scan result // 0x84 442 | 443 | u_int16_t unk3; 444 | int16_t asr_ie_len; 445 | uint32_t asr_unk3; 446 | void* asr_ie_data; 447 | } __attribute__((packed)); 448 | 449 | struct apple80211_scan_result_v12 450 | { 451 | u_int32_t version; // 0x00 - 0x03 452 | apple80211_channel asr_channel; // 0x04 - 0x0f 453 | 454 | int16_t asr_unk; // 0x10 - 0x11 455 | 456 | int16_t asr_noise; // 0x12 - 0x13 457 | int16_t asr_snr; // 0x14 - 0x15 458 | int16_t asr_rssi; // 0x16 - 0x17 459 | int16_t asr_beacon_int; // 0x18 - 0x19 460 | 461 | int16_t asr_cap; // 0x1a - 0x1b (capabilities) 462 | 463 | u_int8_t asr_bssid[ APPLE80211_ADDR_LEN ]; // 0x1c 0x1d 0x1e 0x1f 0x20 0x21 464 | u_int8_t asr_nrates; // 0x22 465 | u_int8_t asr_nr_unk; // 0x23 466 | u_int32_t asr_rates[ APPLE80211_MAX_RATES ]; // 0x24 - 0x5f 467 | u_int8_t asr_ssid_len; // 0x60 468 | u_int8_t asr_ssid[ APPLE80211_MAX_SSID_LEN ]; // 0x61 - 0x80 469 | int16_t unk; 470 | uint8_t unk2; 471 | u_int32_t asr_age; // (ms) non-zero for cached scan result // 0x84 472 | 473 | u_int16_t unk3; 474 | int16_t asr_ie_len; 475 | uint8_t asr_ie_data[1024]; 476 | } __attribute__((packed)); 477 | 478 | static_assert(sizeof(struct apple80211_scan_result_v12) == 1164, "bbb"); 479 | 480 | static_assert(__offsetof(struct apple80211_scan_result_v12, asr_channel) == 4, "aaa"); 481 | static_assert(__offsetof(struct apple80211_scan_result_v12, asr_noise) == 0x12, "aaa"); 482 | static_assert(__offsetof(struct apple80211_scan_result_v12, asr_rssi) == 0x16, "aaa"); 483 | static_assert(__offsetof(struct apple80211_scan_result_v12, asr_beacon_int) == 0x18, "aaa"); 484 | static_assert(__offsetof(struct apple80211_scan_result_v12, asr_cap) == 0x1A, "aaa"); 485 | static_assert(__offsetof(struct apple80211_scan_result_v12, asr_bssid) == 0x1C, "aaa"); 486 | static_assert(__offsetof(struct apple80211_scan_result_v12, asr_rates) == 0x24, "aaa"); 487 | static_assert(__offsetof(struct apple80211_scan_result_v12, asr_ssid_len) == 0x60, "aaa"); 488 | static_assert(__offsetof(struct apple80211_scan_result_v12, asr_ssid) == 0x61, "aaa"); 489 | static_assert(__offsetof(struct apple80211_scan_result_v12, asr_age) == 0x84, "aaa"); 490 | static_assert(__offsetof(struct apple80211_scan_result_v12, asr_ie_len) == 0x8A, "aaa"); 491 | static_assert(__offsetof(struct apple80211_scan_result_v12, asr_ie_data) == 0x8C, "aaa"); 492 | 493 | struct apple80211_network_data 494 | { 495 | u_int32_t version; 496 | u_int16_t nd_mode; // apple80211_apmode 497 | u_int16_t nd_auth_lower; // apple80211_authtype_lower 498 | u_int16_t nd_auth_upper; // apple80211_authtype_upper 499 | struct apple80211_channel nd_channel; 500 | u_int32_t nd_ssid_len; 501 | u_int8_t nd_ssid[ APPLE80211_MAX_SSID_LEN ]; 502 | struct apple80211_key nd_key; 503 | u_int32_t nd_ie_len; 504 | void *nd_ie_data; 505 | } __packed; 506 | 507 | #define APPLE80211_NETWORK_DATA_MAX_IE_LEN 1024 508 | 509 | // As hostap support improves, this will grow 510 | struct apple80211_station 511 | { 512 | u_int32_t version; 513 | struct ether_addr sta_mac; 514 | int32_t sta_rssi; 515 | } __packed; 516 | 517 | // WOW structures and defines 518 | 519 | struct apple80211_wow_pattern 520 | { 521 | size_t len; 522 | u_int8_t * pattern; 523 | } __packed; 524 | 525 | enum apple80211_wake_condition 526 | { 527 | APPLE80211_WAKE_COND_MAGIC_PATTERN = 0, 528 | APPLE80211_WAKE_COND_NET_PATTERN = 1, 529 | APPLE80211_WAKE_COND_DISASSOCIATED = 2, 530 | APPLE80211_WAKE_COND_DEAUTHED = 3, 531 | APPLE80211_WAKE_COND_RETROGRADE_TSF = 4, 532 | APPLE80211_WAKE_COND_BEACON_LOSS = 5, 533 | }; 534 | 535 | #define APPLE80211_MAX_WAKE_COND 5 536 | 537 | enum apple80211_card_capability 538 | { 539 | APPLE80211_CAP_WEP = 0, // CAPABILITY: WEP available 540 | APPLE80211_CAP_TKIP = 1, // CAPABILITY: TKIP available 541 | APPLE80211_CAP_AES = 2, // CAPABILITY: AES OCB avail 542 | APPLE80211_CAP_AES_CCM = 3, // CAPABILITY: AES CCM avail 543 | APPLE80211_CAP_CKIP = 4, // CAPABILITY: CKIP available 544 | APPLE80211_CAP_IBSS = 5, // CAPABILITY: IBSS available 545 | APPLE80211_CAP_PMGT = 6, // CAPABILITY: Power mgmt 546 | APPLE80211_CAP_HOSTAP = 7, // CAPABILITY: HOSTAP avail 547 | APPLE80211_CAP_TXPMGT = 8, // CAPABILITY: tx power mgmt 548 | APPLE80211_CAP_SHSLOT = 9, // CAPABILITY: short slottime 549 | APPLE80211_CAP_SHPREAMBLE = 10, // CAPABILITY: short preamble 550 | APPLE80211_CAP_MONITOR = 11, // CAPABILITY: monitor mode 551 | APPLE80211_CAP_TKIPMIC = 12, // CAPABILITY: TKIP MIC avail 552 | APPLE80211_CAP_WPA1 = 13, // CAPABILITY: WPA1 avail 553 | APPLE80211_CAP_WPA2 = 14, // CAPABILITY: WPA2 avail 554 | APPLE80211_CAP_WPA = 15, // CAPABILITY: WPA1+WPA2 avail 555 | APPLE80211_CAP_BURST = 16, // CAPABILITY: frame bursting 556 | APPLE80211_CAP_WME = 17, // CAPABILITY: WME avail 557 | APPLE80211_CAP_SHORT_GI_40MHZ = 18, // CAPABILITY: Short guard interval in 40 MHz 558 | APPLE80211_CAP_SHORT_GI_20MHZ = 19, // CAPABILITY: Short guard interval in 20 MHz 559 | APPLE80211_CAP_WOW = 20, // CAPABILITY: Wake on wireless 560 | APPLE80211_CAP_TSN = 21, // CAPABILITY: WPA with WEP group key 561 | }; 562 | #define APPLE80211_CAP_MAX 21 563 | 564 | enum apple80211_assoc_flags { 565 | APPLE80211_ASSOC_F_CLOSED = 1, // flag: scan was directed, needed to remember closed networks 566 | }; 567 | 568 | // Kernel messages 569 | 570 | struct apple80211_status_msg_hdr 571 | { 572 | u_int32_t msg_type; // type of message 573 | u_int32_t msg_len; // length of data (not including msg_type and msg_len) 574 | 575 | // data follows 576 | } __packed; 577 | 578 | #define APPLE80211_M_MAX_LEN 2048 579 | 580 | #define APPLE80211_M_POWER_CHANGED 1 581 | #define APPLE80211_M_SSID_CHANGED 2 582 | #define APPLE80211_M_BSSID_CHANGED 3 583 | #define APPLE80211_M_LINK_CHANGED 4 584 | #define APPLE80211_M_MIC_ERROR_UCAST 5 585 | #define APPLE80211_M_MIC_ERROR_MCAST 6 586 | #define APPLE80211_M_INT_MIT_CHANGED 7 587 | #define APPLE80211_M_MODE_CHANGED 8 588 | #define APPLE80211_M_ASSOC_DONE 9 589 | #define APPLE80211_M_SCAN_DONE 10 590 | #define APPLE80211_M_COUNTRY_CODE_CHANGED 11 591 | #define APPLE80211_M_STA_ARRIVE 12 592 | #define APPLE80211_M_STA_LEAVE 13 593 | #define APPLE80211_M_SCAN_CACHE_UPDATED 15 594 | 595 | #define APPLE80211_M_MAX 13 596 | #define APPLE80211_M_BUFF_SIZE APPLE80211_MAP_SIZE( APPLE80211_M_MAX ) 597 | 598 | // Registry Information 599 | #define APPLE80211_REGKEY_HARDWARE_VERSION "IO80211HardwareVersion" 600 | //#define APPLE80211_REG_FIRMWARE_VERSION "IO80211FirmwareVersion" 601 | #define APPLE80211_REGKEY_DRIVER_VERSION "IO80211DriverVersion" 602 | #define APPLE80211_REGKEY_LOCALE "IO80211Locale" 603 | #define APPLE80211_REGKEY_SSID "IO80211SSID" 604 | #define APPLE80211_REGKEY_CHANNEL "IO80211Channel" 605 | #define APPLE80211_REGKEY_EXT_CHANNEL "IO80211ExtensionChannel" 606 | #define APPLE80211_REGKEY_BAND "IO80211Band" 607 | #define APPLE80211_BAND_2GHZ "2 GHz" 608 | #define APPLE80211_BAND_5GHZ "5 GHz" 609 | #define APPLE80211_REGKEY_COUNTRY_CODE "IO80211CountryCode" 610 | 611 | // Userland messages 612 | #define APPLE80211_M_RSN_AUTH_SUCCESS 254 613 | #define APPLE80211_M_RSN_AUTH_SUCCESS_TEMPLATE "com.apple.rsn.%s.auth.success" // string is interface name 614 | 615 | #define APPLE80211_M_RSN_AUTH_TIMEOUT 255 616 | #define APPLE80211_M_RSN_AUTH_TIMEOUT_TEMPLATE "com.apple.rsn.%s.auth.timeout" // string is interface name 617 | 618 | #define APPLE80211_M_RSN_MSG_MAX 2 619 | 620 | #endif /* apple80211_var_h */ 621 | --------------------------------------------------------------------------------