Add a fork of tap-windows from OpenVPN, will be customized.

This commit is contained in:
Adam Ierymenko 2013-08-15 15:52:52 -04:00
parent b23748aa5a
commit d7bd3e37cb
40 changed files with 7658 additions and 0 deletions

40
windows-tap/COPYING Normal file
View File

@ -0,0 +1,40 @@
TAP-Win32/TAP-Win64 Driver license:
-----------------------------------
This device driver was inspired by the CIPE-Win32 driver by
Damion K. Wilson.
The source and object code of the TAP-Win32/TAP-Win64 driver
is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., and is released under
the GPL version 2.
NSIS License:
-------------
Copyright (C) 2002-2003 Joost Verburg
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute
it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented;
you must not claim that you wrote the original software.
If you use this software in a product, an acknowledgment in the
product documentation would be appreciated but is not required.
2. Altered versions must be plainly marked as such,
and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any distribution.
GNU Public License (GPL)
------------------------
TAP-Win32 distributions are licensed under the GPL version 2 (see
COPYRIGHT.GPL).
In the Windows binary distribution of OpenVPN, the
GPL is reproduced below.

339
windows-tap/COPYRIGHT.GPL Normal file
View File

@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

49
windows-tap/_build.bat Normal file
View File

@ -0,0 +1,49 @@
@echo off
rem TAP-Windows -- A kernel driver to provide virtual tap
rem device functionality on Windows.
rem
rem Copyright (C) 2012 Alon Bar-Lev <alon.barlev@gmail.com>
rem
rem This program is free software; you can redistribute it and/or modify
rem it under the terms of the GNU General Public License as published by
rem the Free Software Foundation; either version 2 of the License, or
rem (at your option) any later version.
rem
rem This program is distributed in the hope that it will be useful,
rem but WITHOUT ANY WARRANTY; without even the implied warranty of
rem MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
rem GNU General Public License for more details.
rem
rem You should have received a copy of the GNU General Public License
rem along with this program (see the file COPYING included with this
rem distribution); if not, write to the Free Software Foundation, Inc.,
rem 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
setlocal enableextensions enabledelayedexpansion
set root=%cd%
set myos=%1
set myprofile=%2
set mymode=fre
echo Building %myos%-%myprofile%-%mymode%
call "%DDK%\bin\setenv" %DDK% %mymode% %myprofile% %myos% no_oacr
if errorlevel 1 goto error
cd /d %root%
cd src
nmake
if errorlevel 1 goto error
set rc=0
goto end
:error
echo FAIL %myos%-%myprofile%-%mymode%
set rc=1
goto end
:end
endlocal

55
windows-tap/build.bat Normal file
View File

@ -0,0 +1,55 @@
@echo off
rem TAP-Windows -- A kernel driver to provide virtual tap
rem device functionality on Windows.
rem
rem Copyright (C) 2012 Alon Bar-Lev <alon.barlev@gmail.com>
rem
rem This program is free software; you can redistribute it and/or modify
rem it under the terms of the GNU General Public License as published by
rem the Free Software Foundation; either version 2 of the License, or
rem (at your option) any later version.
rem
rem This program is distributed in the hope that it will be useful,
rem but WITHOUT ANY WARRANTY; without even the implied warranty of
rem MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
rem GNU General Public License for more details.
rem
rem You should have received a copy of the GNU General Public License
rem along with this program (see the file COPYING included with this
rem distribution); if not, write to the Free Software Foundation, Inc.,
rem 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
cd /d %0\..
if not exist config-env.bat (
echo please run configure
exit /b 1
)
setlocal
call config-env.bat
for /d %%d in (src\obj*) do rmdir /q /s %%d > nul 2>&1
for %%f in (src\amd64\*.sys src\i386\*.sys) do del /s %%f > nul 2>&1
cmd /c _build WXP x86
if errorlevel 1 goto error
cmd /c _build WIN7 x64
if errorlevel 1 goto error
call installer\build
set rc=0
goto end
:error
echo FAIL
set rc=1
goto end
:end
endlocal
exit /b %rc%

View File

@ -0,0 +1,32 @@
-----BEGIN CERTIFICATE-----
MIIFmjCCA4KgAwIBAgIKYRmT5AAAAAAAHDANBgkqhkiG9w0BAQUFADB/MQswCQYD
VQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEe
MBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSkwJwYDVQQDEyBNaWNyb3Nv
ZnQgQ29kZSBWZXJpZmljYXRpb24gUm9vdDAeFw0xMTAyMjIxOTI1MTdaFw0yMTAy
MjIxOTM1MTdaMIHKMQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIElu
Yy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShj
KSAyMDA2IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkx
RTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlm
aWNhdGlvbiBBdXRob3JpdHkgLSBHNTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
AQoCggEBAK8kCAgpejWeYAyq50s7Ttx8vDxFHLsr4P4pAvlXCKNkhRUn9fGtyDGJ
XSLoKqqmQrOP+LlVt7G3S7P+j34HV+zvQ9tmYhVhz2ANpNje+ODDYgg9VBPrScpZ
VIUm5SuPG5/r9aGRwjNJ2ENjalJL0o/ocFFN0Ylpe8dw9rPcEnTbe11LVtOWvxV3
obD0oiXyrxySZxjl9AYE75C55ADk3Tq1Gf8CuvQ87uCL6zeL7PTXrPL28D2v3XWR
MxkdHEDLdCQZIZPZFP6sKlLHj9UESeSNY0eIPGmDy/5HvSt+T8WVrg6d1NFDwGdz
4xQIfuU/n3O4MwrPXT80h5aK7lPoJRUCAwEAAaOByzCByDARBgNVHSAECjAIMAYG
BFUdIAAwDwYDVR0TAQH/BAUwAwEB/zALBgNVHQ8EBAMCAYYwHQYDVR0OBBYEFH/T
ZafC3ey78DAJ80M5+gKvMzEzMB8GA1UdIwQYMBaAFGL7CiFbf0NuEdoJVFBr9dKW
cfGeMFUGA1UdHwROMEwwSqBIoEaGRGh0dHA6Ly9jcmwubWljcm9zb2Z0LmNvbS9w
a2kvY3JsL3Byb2R1Y3RzL01pY3Jvc29mdENvZGVWZXJpZlJvb3QuY3JsMA0GCSqG
SIb3DQEBBQUAA4ICAQCBKoIWjDRnK+UD6zR7jKKjUIr0VYbxHoyOrn3uAxnOcpUY
SK1iEf0g/T9HBgFa4uBvjBUsTjxqUGwLNqPPeg2cQrxc+BnVYONp5uIjQWeMaIN2
K4+Toyq1f75Z+6nJsiaPyqLzghuYPpGVJ5eGYe5bXQdrzYao4mWAqOIV4rK+IwVq
ugzzR5NNrKSMB3k5wGESOgUNiaPsn1eJhPvsynxHZhSR2LYPGV3muEqsvEfIcUOW
5jIgpdx3hv0844tx23ubA/y3HTJk6xZSoEOj+i6tWZJOfMfyM0JIOFE6fDjHGyQi
KEAeGkYfF9sY9/AnNWy4Y9nNuWRdK6Ve78YptPLH+CHMBLpX/QG2q8Zn+efTmX/0
9SL6cvX9/zocQjqh+YAYpe6NHNRmnkUB/qru//sXjzD38c0pxZ3stdVJAD2FuMu7
kzonaknAMK5myfcjKDJ2+aSDVshIzlqWqqDMDMR/tI6Xr23jVCfDn4bA1uRzCJcF
29BUYl4DSMLVn3+nZozQnbBP1NOYX0t6yX+yKVLQEoDHD1S2HmfNxqBsEQOE00h1
5yr+sDtuCjqma3aZBaPxd2hhMxRHBvxTf1K9khRcSiRqZ4yvjZCq0PZ5IRuTJnzD
zh69iDiSrkXGGWpJULMF+K5ZN4pqJQOUsVmBUOi6g4C3IzX0drlnHVkYrSCNlA==
-----END CERTIFICATE-----

View File

@ -0,0 +1,118 @@
/*
* msvc-generate.js - string transformation
*
* Copyright (C) 2008-2012 Alon Bar-Lev <alon.barlev@gmail.com>
*
* BSD License
* ============
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* o Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* o Neither the name of the Alon Bar-Lev nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
var ForReading = 1;
var fso = new ActiveXObject("Scripting.FileSystemObject");
var input = "nul";
var output = "nul";
var files = new Array();
var env = new Array();
function initialize() {
for (var i=0;i<WScript.Arguments.length;i++) {
var arg = WScript.Arguments(i);
if (arg.match(/^--input=(.*)$/)) {
input=RegExp.$1;
}
else if (arg.match(/^--output=(.*)$/)) {
output=RegExp.$1;
}
else if (arg.match(/^--config=(.*)$/)) {
files.push(RegExp.$1);
}
else if (arg.match(/^--var=([^=]*)=(.*)$/)) {
env[RegExp.$1] = RegExp.$2;
}
}
}
function process_config(vars, file) {
try {
var fin = fso.OpenTextFile(file, ForReading);
while (!fin.AtEndOfStream) {
var content = fin.ReadLine();
if (content.match(/^[ \t]*define\(\[(.*)\],[ \t]*\[(.*)\]\)[ \t]*/)) {
vars[RegExp.$1] = RegExp.$2;
}
}
}
catch(e) {
throw new Error(1, "Cannot process '" + file + "'.");
}
}
function process_file(vars, input, output) {
var fin = fso.OpenTextFile(input, ForReading);
var fout = fso.CreateTextFile(output);
var content = fin.ReadAll();
for (var i in vars) {
content = content.replace(new RegExp("@"+i+"@", "g"), vars[i]);
}
fout.Write(content);
}
function build_vars() {
var vars = new Array();
for (var f in files) {
process_config(vars, files[f]);
}
for (var e in env) {
vars[e] = env[e];
}
return vars;
}
function main() {
try {
initialize();
var vars = build_vars();
process_file(
vars,
input,
output
);
WScript.Quit(0);
}
catch(e) {
WScript.Echo("ERROR: when procssing " + output + ": " + e.description);
WScript.Quit(1);
}
}
main();

View File

@ -0,0 +1,54 @@
/*
* unix2dos.js - a simple unix2dos implementation in jscript.
*
* Copyright (C) 2008-2012 Alon Bar-Lev <alon.barlev@gmail.com>
*
* BSD License
* ============
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* o Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* o Neither the name of the Alon Bar-Lev nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
var ForReading = 1;
try {
var fso = new ActiveXObject("Scripting.FileSystemObject");
for (var i=0;i<WScript.Arguments.length;i++) {
var file = WScript.Arguments(i);
var tmp = file+".tmp";
var fin = fso.OpenTextFile(file, ForReading);
var fout = fso.CreateTextFile(tmp);
fout.Write(fin.ReadAll().replace(/\n/g, "\r\n"));
fin.Close();
fout.Close();
fso.DeleteFile(file);
fso.MoveFile(tmp, file);
}
WScript.Quit(0);
}
catch(e) {
WScript.Echo("ERROR: " + e.description);
WScript.Quit(1);
}

View File

@ -0,0 +1,2 @@
define([INF_PROVIDER_SUFFIX], [, NTamd64])
define([INF_SECTION_SUFFIX], [.NTamd64])

View File

@ -0,0 +1,2 @@
define([INF_PROVIDER_SUFFIX], [])
define([INF_SECTION_SUFFIX], [])

74
windows-tap/build/zip.js Normal file
View File

@ -0,0 +1,74 @@
/*
* zip.js - a simple zip implementation in jscript.
*
* Copyright (C) 2008-2012 Alon Bar-Lev <alon.barlev@gmail.com>
*
* BSD License
* ============
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* o Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* o Neither the name of the Alon Bar-Lev nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
var ForReading = 0;
var ForWriting = 1;
var fso = new ActiveXObject("Scripting.FileSystemObject");
function zip(source, destination) {
try {
var f = OpenTextFile(destination, ForReading);
f.Close();
}
catch(e) {
var f = fso.CreateTextFile(destination, ForWriting);
var zipheader = "PK" + String.fromCharCode(5) + String.fromCharCode(6);
for (var i=0;i<18;i++) {
zipheader += String.fromCharCode(0);
}
f.Write(zipheader);
f.Close();
}
var shell = new ActiveXObject("Shell.Application");
var source = shell.NameSpace(fso.GetAbsolutePathName(source));
var destination = shell.NameSpace(fso.GetAbsolutePathName(destination));
destination.CopyHere(source.Items(), 4);
while(source.Items().Count != destination.Items().Count) {
WScript.Sleep(1000);
}
}
var index = 0;
var source = WScript.Arguments(index++);
var destination = WScript.Arguments(index++);
try {
zip(source, destination);
WScript.Quit(0);
}
catch(e) {
WScript.Echo("ERROR: Cannot zip '" + destination + "'.");
WScript.Quit(1);
}

View File

@ -0,0 +1,15 @@
set DDK=@DDK@
set DEVCON32=@DEVCON32@
set DEVCON64=@DEVCON64@
set DEVCON_BASENAME=@DEVCON_BASENAME@
set SIGNTOOL=@SIGNTOOL@
set MAKENSIS=@MAKENSIS@
set CODESIGN_PKCS12=@CODESIGN_PKCS12@
set CODESIGN_PASS=@CODESIGN_PASS@
set CODESIGN_CROSS=@CODESIGN_CROSS@
set CODESIGN_TIMESTAMP=@CODESIGN_TIMESTAMP@
set CODESIGN_ISTEST=@CODESIGN_ISTEST@
set PRODUCT_TAP_WIN_COMPONENT_ID=@PRODUCT_TAP_WIN_COMPONENT_ID@
set PRODUCT_NAME=@PRODUCT_NAME@
set PRODUCT_VERSION=@PRODUCT_VERSION@
set OUTDIR=@OUTDIR@

94
windows-tap/configure.bat Normal file
View File

@ -0,0 +1,94 @@
@echo off
rem TAP-Windows -- A kernel driver to provide virtual tap
rem device functionality on Windows.
rem
rem Copyright (C) 2012 Alon Bar-Lev <alon.barlev@gmail.com>
rem
rem This program is free software; you can redistribute it and/or modify
rem it under the terms of the GNU General Public License as published by
rem the Free Software Foundation; either version 2 of the License, or
rem (at your option) any later version.
rem
rem This program is distributed in the hope that it will be useful,
rem but WITHOUT ANY WARRANTY; without even the implied warranty of
rem MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
rem GNU General Public License for more details.
rem
rem You should have received a copy of the GNU General Public License
rem along with this program (see the file COPYING included with this
rem distribution); if not, write to the Free Software Foundation, Inc.,
rem 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
cd /d %0\..
if "%1"=="--help" (
echo %0
echo Environment:
echo DDK DDK home
echo SIGNTOOL signtool, default from DDK
echo DEVCON32 devcon, default from DDK
echo DEVCON64 devcon, default from DDK
echo MAKENSIS nullsoft installer
echo CODESIGN_PKCS12 Code sign PKCS#12 optional
echo CODESIGN_PASS Code sign password
echo CODESIGN_CROSS Cross certificate to be used
echo CODESIGN_TIMESTAMP Timestamp URL
echo CODESIGN_ISTEST If yes, use test certificate
echo OUTDIR Output directory
exit /b 1
)
setlocal
if "%DDK%"=="" for /d %%f in (c:\WINDDK\*) do set DDK=%%f
if "%DDK%"=="" (
echo cannot find ddk
goto error
)
if "%SIGNTOOL%"=="" set SIGNTOOL=%DDK%\bin\x86\signtool.exe
if "%DEVCON32%"=="" set DEVCON32=%DDK%\tools\devcon\i386\devcon.exe
if "%DEVCON64%"=="" set DEVCON64=%DDK%\tools\devcon\amd64\devcon.exe
for /f %%f in ("%DEVCON32%") do set DEVCON_BASENAME=%%~nf%%~xf
if "%MAKENSIS%"=="" for /d %%f in ("%ProgramFiles%\NSIS" "%ProgramFiles(x86)%\NSIS") do if exist "%%f" set MAKENSIS=%%~f
if "%MAKENSIS%"=="" (
echo cannot find nsis
goto error
)
if "%CODESIGN_CROSS%"=="" set CODESIGN_CROSS=%cd%\build\MSCV-VSClass3.cer
if "%CODESIGN_TIMESTAMP%"=="" set CODESIGN_TIMESTAMP=http://timestamp.verisign.com/scripts/timestamp.dll
if "%OUTDIR%"=="" set OUTDIR=%cd%
set msvcg_args=cscript //nologo build/msvc-generate.js --config=version.m4
if exist config-local.m4 set msvcg_args=%msvcg_args% --config=config-local.m4
set msvcg_args=%msvcg_args% --var=DDK="%DDK%" --var=MAKENSIS="%MAKENSIS%" --var=SIGNTOOL="%SIGNTOOL%" --var=DEVCON32="%DEVCON32%" --var=DEVCON64="%DEVCON64%" --var=DEVCON_BASENAME="%DEVCON_BASENAME%" --var=EXTRA_C_DEFINES="%EXTRA_C_DEFINES%" --var=CODESIGN_PKCS12="%CODESIGN_PKCS12%" --var=CODESIGN_PASS="%CODESIGN_PASS%" --var=CODESIGN_CROSS="%CODESIGN_CROSS%" --var=CODESIGN_TIMESTAMP="%CODESIGN_TIMESTAMP%" --var=CODESIGN_ISTEST="%CODESIGN_ISTEST%" --var=OUTDIR="%OUTDIR%"
for %%f in (config-env.bat src\SOURCES src\config.h) do (
%msvcg_args% --input=%%f.in --output=%%f
if errorlevel 1 goto error
)
for %%a in (i386 amd64) do (
mkdir src\%%a > nul 2>&1
%msvcg_args% --config=build\vars.%%a.m4 --input=src\OemWin2k.inf.in --output=src\%%a\OemWin2k.inf
if errorlevel 1 goto error
)
set rc=0
goto end
:error
echo FAILED
set rc=1
goto end
:end
endlocal
exit /b %rc%

View File

@ -0,0 +1,95 @@
@echo off
rem TAP-Windows -- A kernel driver to provide virtual tap
rem device functionality on Windows.
rem
rem Copyright (C) 2012 Alon Bar-Lev <alon.barlev@gmail.com>
rem
rem This program is free software; you can redistribute it and/or modify
rem it under the terms of the GNU General Public License as published by
rem the Free Software Foundation; either version 2 of the License, or
rem (at your option) any later version.
rem
rem This program is distributed in the hope that it will be useful,
rem but WITHOUT ANY WARRANTY; without even the implied warranty of
rem MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
rem GNU General Public License for more details.
rem
rem You should have received a copy of the GNU General Public License
rem along with this program (see the file COPYING included with this
rem distribution); if not, write to the Free Software Foundation, Inc.,
rem 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
setlocal
set wd=%cd%
cd %0\..
if "%MAKENSIS%"=="" call ..\config-env.bat
if "%OUTDIR%"=="" set OUTDIR=.
set OUTPUT=%OUTDIR%\tap-windows-%PRODUCT_VERSION%
set TAP_ROOT=tmp\image\tap-windows-%PRODUCT_VERSION%
set SIGNTOOL_CMD="%SIGNTOOL%" sign /v /p "%CODESIGN_PASS%" /f "%CODESIGN_PKCS12%"
set SIGNTOOL_CMD_DRIVERS=%SIGNTOOL_CMD%
if "%CODESIGN_ISTEST%" NEQ "yes" (
set SIGNTOOL_CMD=%SIGNTOOL_CMD% /t "%CODESIGN_TIMESTAMP%"
set SIGNTOOL_CMD_DRIVERS=%SIGNTOOL_CMD% /ac "%CODESIGN_CROSS%"
)
del "%OUTPUT%.*" > nul 2>&1
rmdir /q /s tmp > nul 2>&1
mkdir %TAP_ROOT%\include
copy ..\src\tap-windows.h %TAP_ROOT%\include
if errorlevel 1 goto error
mkdir %TAP_ROOT%\i386
copy ..\src\i386\* %TAP_ROOT%\i386
if errorlevel 1 goto error
mkdir %TAP_ROOT%\amd64
copy ..\src\amd64\* %TAP_ROOT%\amd64
if errorlevel 1 goto error
type ..\COPYING > %TAP_ROOT%\license.txt
type ..\COPYRIGHT.GPL >> %TAP_ROOT%\license.txt
cscript //nologo ..\build\unix2dos.js %TAP_ROOT%\license.txt
if errorlevel 1 goto error
"%DDK%\bin\selfsign\inf2cat" /driver:%TAP_ROOT%\i386 /os:XP_X86,Vista_X86,7_X86,Server2003_X86,Server2008_X86
"%DDK%\bin\selfsign\inf2cat" /driver:%TAP_ROOT%\amd64 /os:XP_X64,Vista_X64,7_X64,Server2003_X64,Server2008_X64,Server2008R2_X64
if not "%CODESIGN_PKCS12%"=="" (
for %%a in (i386 amd64) do (
%SIGNTOOL_CMD_DRIVERS% "%TAP_ROOT%\%%a\%PRODUCT_TAP_WIN_COMPONENT_ID%.sys"
if errorlevel 1 goto error
%SIGNTOOL_CMD_DRIVERS% "%TAP_ROOT%\%%a\%PRODUCT_TAP_WIN_COMPONENT_ID%.cat"
if errorlevel 1 goto error
)
)
cscript //nologo ..\build\zip.js tmp\image "%OUTPUT%.zip"
if errorlevel 1 goto error
"%MAKENSIS%\makensis" -DDEVCON32="%DEVCON32%" -DDEVCON64="%DEVCON64%" -DDEVCON_BASENAME="%DEVCON_BASENAME%" -DPRODUCT_TAP_WIN_COMPONENT_ID="%PRODUCT_TAP_WIN_COMPONENT_ID%" -DPRODUCT_NAME="%PRODUCT_NAME%" -DPRODUCT_VERSION="%PRODUCT_VERSION%" -DOUTPUT="%OUTPUT%.exe" -DIMAGE="%TAP_ROOT%" tap-windows.nsi
if errorlevel 1 goto error
if not "%CODESIGN_PKCS12%"=="" (
%SIGNTOOL_CMD% "%OUTPUT%.exe"
if errorlevel 1 goto error
)
set rc=0
goto end
:error
echo FATAL
set rc=1
goto end
:end
cd %wd%
endlocal
exit /b %rc%

BIN
windows-tap/installer/icon.ico Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

View File

@ -0,0 +1,317 @@
; ****************************************************************************
; * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. *
; * Copyright (C) 2012 Alon Bar-Lev <alon.barlev@gmail.com> *
; * This program is free software; you can redistribute it and/or modify *
; * it under the terms of the GNU General Public License version 2 *
; * as published by the Free Software Foundation. *
; ****************************************************************************
; TAP-Windows install script for Windows, using NSIS
SetCompressor lzma
!include "MUI.nsh"
!include "StrFunc.nsh"
!include "x64.nsh"
!define MULTIUSER_EXECUTIONLEVEL Admin
!include "MultiUser.nsh"
!include FileFunc.nsh
!insertmacro GetParameters
!insertmacro GetOptions
${StrLoc}
;--------------------------------
;Configuration
;General
OutFile "${OUTPUT}"
ShowInstDetails show
ShowUninstDetails show
;Remember install folder
InstallDirRegKey HKLM "SOFTWARE\${PRODUCT_NAME}" ""
;--------------------------------
;Modern UI Configuration
Name "${PRODUCT_NAME} ${PRODUCT_VERSION}"
!define MUI_WELCOMEPAGE_TEXT "This wizard will guide you through the installation of ${PRODUCT_NAME}, a kernel driver to provide virtual tap device functionality on Windows originally written by James Yonan.\r\n\r\nNote that the Windows version of ${PRODUCT_NAME} will only run on Windows XP or later.\r\n\r\n\r\n"
!define MUI_COMPONENTSPAGE_TEXT_TOP "Select the components to install/upgrade. Stop any ${PRODUCT_NAME} processes or the ${PRODUCT_NAME} service if it is running. All DLLs are installed locally."
!define MUI_COMPONENTSPAGE_SMALLDESC
!define MUI_FINISHPAGE_NOAUTOCLOSE
!define MUI_ABORTWARNING
!define MUI_ICON "icon.ico"
!define MUI_UNICON "icon.ico"
!define MUI_HEADERIMAGE
!define MUI_HEADERIMAGE_BITMAP "install-whirl.bmp"
!define MUI_UNFINISHPAGE_NOAUTOCLOSE
!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_LICENSE "${IMAGE}\license.txt"
!insertmacro MUI_PAGE_COMPONENTS
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_INSTFILES
!insertmacro MUI_UNPAGE_FINISH
;--------------------------------
;Languages
!insertmacro MUI_LANGUAGE "English"
;--------------------------------
;Language Strings
LangString DESC_SecTAP ${LANG_ENGLISH} "Install/Upgrade the TAP virtual device driver. Will not interfere with CIPE."
LangString DESC_SecTAPUtilities ${LANG_ENGLISH} "Install the TAP Utilities."
LangString DESC_SecTAPSDK ${LANG_ENGLISH} "Install the TAP SDK."
;--------------------------------
;Reserve Files
;Things that need to be extracted on first (keep these lines before any File command!)
;Only useful for BZIP2 compression
ReserveFile "install-whirl.bmp"
;--------------------------------
;Macros
!macro SelectByParameter SECT PARAMETER DEFAULT
${GetOptions} $R0 "/${PARAMETER}=" $0
${If} ${DEFAULT} == 0
${If} $0 == 1
!insertmacro SelectSection ${SECT}
${EndIf}
${Else}
${If} $0 != 0
!insertmacro SelectSection ${SECT}
${EndIf}
${EndIf}
!macroend
;--------------------------------
;Installer Sections
Section /o "TAP Virtual Ethernet Adapter" SecTAP
SetOverwrite on
${If} ${RunningX64}
DetailPrint "We are running on a 64-bit system."
SetOutPath "$INSTDIR\bin"
File "${DEVCON64}"
SetOutPath "$INSTDIR\driver"
File "${IMAGE}\amd64\OemWin2k.inf"
File "${IMAGE}\amd64\${PRODUCT_TAP_WIN_COMPONENT_ID}.cat"
File "${IMAGE}\amd64\${PRODUCT_TAP_WIN_COMPONENT_ID}.sys"
${Else}
DetailPrint "We are running on a 32-bit system."
SetOutPath "$INSTDIR\bin"
File "${DEVCON32}"
SetOutPath "$INSTDIR\driver"
File "${IMAGE}\i386\OemWin2k.inf"
File "${IMAGE}\i386\${PRODUCT_TAP_WIN_COMPONENT_ID}.cat"
File "${IMAGE}\i386\${PRODUCT_TAP_WIN_COMPONENT_ID}.sys"
${EndIf}
SectionEnd
Section /o "TAP Utilities" SecTAPUtilities
SetOverwrite on
# Delete previous start menu
RMDir /r "$SMPROGRAMS\${PRODUCT_NAME}"
FileOpen $R0 "$INSTDIR\bin\addtap.bat" w
FileWrite $R0 "rem Add a new TAP virtual ethernet adapter$\r$\n"
FileWrite $R0 '"$INSTDIR\bin\${DEVCON_BASENAME}" install "$INSTDIR\driver\OemWin2k.inf" ${PRODUCT_TAP_WIN_COMPONENT_ID}$\r$\n'
FileWrite $R0 "pause$\r$\n"
FileClose $R0
FileOpen $R0 "$INSTDIR\bin\deltapall.bat" w
FileWrite $R0 "echo WARNING: this script will delete ALL TAP virtual adapters (use the device manager to delete adapters one at a time)$\r$\n"
FileWrite $R0 "pause$\r$\n"
FileWrite $R0 '"$INSTDIR\bin\${DEVCON_BASENAME}" remove ${PRODUCT_TAP_WIN_COMPONENT_ID}$\r$\n'
FileWrite $R0 "pause$\r$\n"
FileClose $R0
; Create shortcuts
CreateDirectory "$SMPROGRAMS\${PRODUCT_NAME}\Utilities"
CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\Utilities\Add a new TAP virtual ethernet adapter.lnk" "$INSTDIR\bin\addtap.bat" ""
CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\Utilities\Delete ALL TAP virtual ethernet adapters.lnk" "$INSTDIR\bin\deltapall.bat" ""
SectionEnd
Section /o "TAP SDK" SecTAPSDK
SetOverwrite on
SetOutPath "$INSTDIR\include"
File "${IMAGE}\include\tap-windows.h"
SectionEnd
Function .onInit
${GetParameters} $R0
ClearErrors
!insertmacro SelectByParameter ${SecTAP} SELECT_TAP 1
!insertmacro SelectByParameter ${SecTAPUtilities} SELECT_UTILITIES 0
!insertmacro SelectByParameter ${SecTAPSDK} SELECT_SDK 0
!insertmacro MULTIUSER_INIT
SetShellVarContext all
${If} ${RunningX64}
SetRegView 64
StrCpy $INSTDIR "$PROGRAMFILES64\${PRODUCT_NAME}"
${Else}
StrCpy $INSTDIR "$PROGRAMFILES\${PRODUCT_NAME}"
${EndIf}
FunctionEnd
;--------------------------------
;Dependencies
Function .onSelChange
${If} ${SectionIsSelected} ${SecTAPUtilities}
!insertmacro SelectSection ${SecTAP}
${EndIf}
FunctionEnd
;--------------------
;Post-install section
Section -post
SetOverwrite on
; Store README, license, icon
SetOverwrite on
SetOutPath $INSTDIR
File "${IMAGE}\license.txt"
File "icon.ico"
${If} ${SectionIsSelected} ${SecTAP}
;
; install/upgrade TAP driver if selected, using devcon
;
; TAP install/update was selected.
; Should we install or update?
; If tapinstall error occurred, $R5 will
; be nonzero.
IntOp $R5 0 & 0
nsExec::ExecToStack '"$INSTDIR\bin\${DEVCON_BASENAME}" hwids ${PRODUCT_TAP_WIN_COMPONENT_ID}'
Pop $R0 # return value/error/timeout
IntOp $R5 $R5 | $R0
DetailPrint "${DEVCON_BASENAME} hwids returned: $R0"
; If tapinstall output string contains "${PRODUCT_TAP_WIN_COMPONENT_ID}" we assume
; that TAP device has been previously installed,
; therefore we will update, not install.
Push "${PRODUCT_TAP_WIN_COMPONENT_ID}"
Push ">"
Call StrLoc
Pop $R0
${If} $R5 == 0
${If} $R0 == ""
StrCpy $R1 "install"
${Else}
StrCpy $R1 "update"
${EndIf}
DetailPrint "TAP $R1 (${PRODUCT_TAP_WIN_COMPONENT_ID}) (May require confirmation)"
nsExec::ExecToLog '"$INSTDIR\bin\${DEVCON_BASENAME}" $R1 "$INSTDIR\driver\OemWin2k.inf" ${PRODUCT_TAP_WIN_COMPONENT_ID}'
Pop $R0 # return value/error/timeout
${If} $R0 == ""
IntOp $R0 0 & 0
SetRebootFlag true
DetailPrint "REBOOT flag set"
${EndIf}
IntOp $R5 $R5 | $R0
DetailPrint "${DEVCON_BASENAME} returned: $R0"
${EndIf}
DetailPrint "${DEVCON_BASENAME} cumulative status: $R5"
${If} $R5 != 0
MessageBox MB_OK "An error occurred installing the TAP device driver."
${EndIf}
; Store install folder in registry
WriteRegStr HKLM SOFTWARE\${PRODUCT_NAME} "" $INSTDIR
${EndIf}
; Create uninstaller
WriteUninstaller "$INSTDIR\Uninstall.exe"
; Show up in Add/Remove programs
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "DisplayName" "${PRODUCT_NAME} ${PRODUCT_VERSION}"
WriteRegExpandStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "UninstallString" "$INSTDIR\Uninstall.exe"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "DisplayIcon" "$INSTDIR\icon.ico"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "DisplayVersion" "${PRODUCT_VERSION}"
; Advise a reboot
;Messagebox MB_OK "IMPORTANT: Rebooting the system is advised in order to finalize TAP driver installation/upgrade (this is an informational message only, pressing OK will not reboot)."
SectionEnd
;--------------------------------
;Descriptions
!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
!insertmacro MUI_DESCRIPTION_TEXT ${SecTAP} $(DESC_SecTAP)
!insertmacro MUI_DESCRIPTION_TEXT ${SecTAPUtilities} $(DESC_SecTAPUtilities)
!insertmacro MUI_DESCRIPTION_TEXT ${SecTAPSDK} $(DESC_SecTAPSDK)
!insertmacro MUI_FUNCTION_DESCRIPTION_END
;--------------------------------
;Uninstaller Section
Function un.onInit
ClearErrors
!insertmacro MULTIUSER_UNINIT
SetShellVarContext all
${If} ${RunningX64}
SetRegView 64
${EndIf}
FunctionEnd
Section "Uninstall"
DetailPrint "TAP REMOVE"
nsExec::ExecToLog '"$INSTDIR\bin\${DEVCON_BASENAME}" remove ${PRODUCT_TAP_WIN_COMPONENT_ID}'
Pop $R0 # return value/error/timeout
DetailPrint "${DEVCON_BASENAME} remove returned: $R0"
Delete "$INSTDIR\bin\${DEVCON_BASENAME}"
Delete "$INSTDIR\bin\addtap.bat"
Delete "$INSTDIR\bin\deltapall.bat"
Delete "$INSTDIR\driver\OemWin2k.inf"
Delete "$INSTDIR\driver\${PRODUCT_TAP_WIN_COMPONENT_ID}.cat"
Delete "$INSTDIR\driver\${PRODUCT_TAP_WIN_COMPONENT_ID}.sys"
Delete "$INSTDIR\include\tap-windows.h"
Delete "$INSTDIR\icon.ico"
Delete "$INSTDIR\license.txt"
Delete "$INSTDIR\Uninstall.exe"
RMDir "$INSTDIR\bin"
RMDir "$INSTDIR\driver"
RMDir "$INSTDIR\include"
RMDir "$INSTDIR"
RMDir /r "$SMPROGRAMS\${PRODUCT_NAME}"
DeleteRegKey HKLM "SOFTWARE\${PRODUCT_NAME}"
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"
SectionEnd

6
windows-tap/src/MAKEFILE Executable file
View File

@ -0,0 +1,6 @@
#
# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
# file to this component. This file merely indirects to the real make file
# that is shared by all the components of NT OS/2
#
!INCLUDE $(NTMAKEENV)\makefile.def

187
windows-tap/src/OemWin2k.inf.in Executable file
View File

@ -0,0 +1,187 @@
; ****************************************************************************
; * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. *
; * This program is free software; you can redistribute it and/or modify *
; * it under the terms of the GNU General Public License version 2 *
; * as published by the Free Software Foundation. *
; ****************************************************************************
; SYNTAX CHECKER
; cd \WINDDK\3790\tools\chkinf
; chkinf c:\src\openvpn\tap-win32\i386\oemwin2k.inf
; OUTPUT -> file:///c:/WINDDK/3790/tools/chkinf/htm/c%23+src+openvpn+tap-win32+i386+__OemWin2k.htm
; INSTALL/REMOVE DRIVER
; tapinstall install OemWin2k.inf TAP0901
; tapinstall update OemWin2k.inf TAP0901
; tapinstall remove TAP0901
;*********************************************************
; Note to Developers:
;
; If you are bundling the TAP-Windows driver with your app,
; you should try to rename it in such a way that it will
; not collide with other instances of TAP-Windows defined
; by other apps. Multiple versions of the TAP-Windows
; driver, each installed by different apps, can coexist
; on the same machine if you follow these guidelines.
; NOTE: these instructions assume you are editing the
; generated OemWin2k.inf file, not the source
; OemWin2k.inf.in file which is preprocessed by winconfig
; and uses macro definitions from settings.in.
;
; (1) Rename all tapXXXX instances in this file to
; something different (use at least 5 characters
; for this name!)
; (2) Change the "!define TAP" definition in openvpn.nsi
; to match what you changed tapXXXX to.
; (3) Change TARGETNAME in SOURCES to match what you
; changed tapXXXX to.
; (4) Change TAP_COMPONENT_ID in common.h to match what
; you changed tapXXXX to.
; (5) Change SZDEPENDENCIES in service.h to match what
; you changed tapXXXX to.
; (6) Change DeviceDescription and Provider strings.
; (7) Change PRODUCT_TAP_WIN_DEVICE_DESCRIPTION in constants.h to what you
; set DeviceDescription to.
;
;*********************************************************
[Version]
Signature = "$Windows NT$"
CatalogFile = @PRODUCT_TAP_WIN_COMPONENT_ID@.cat
ClassGUID = {4d36e972-e325-11ce-bfc1-08002be10318}
Provider = %Provider%
Class = Net
; This version number should match the version
; number given in SOURCES.
DriverVer=@PRODUCT_TAP_WIN_RELDATE@,@PRODUCT_TAP_WIN_MAJOR@.00.00.@PRODUCT_TAP_WIN_MINOR@
[Strings]
DeviceDescription = "@PRODUCT_TAP_WIN_DEVICE_DESCRIPTION@"
Provider = "@PRODUCT_TAP_WIN_PROVIDER@"
;----------------------------------------------------------------
; Manufacturer + Product Section (Done)
;----------------------------------------------------------------
[Manufacturer]
%Provider% = @PRODUCT_TAP_WIN_COMPONENT_ID@@INF_PROVIDER_SUFFIX@
[@PRODUCT_TAP_WIN_COMPONENT_ID@@INF_SECTION_SUFFIX@]
%DeviceDescription% = @PRODUCT_TAP_WIN_COMPONENT_ID@.ndi, @PRODUCT_TAP_WIN_COMPONENT_ID@
;---------------------------------------------------------------
; Driver Section (Done)
;---------------------------------------------------------------
;----------------- Characteristics ------------
; NCF_PHYSICAL = 0x04
; NCF_VIRTUAL = 0x01
; NCF_SOFTWARE_ENUMERATED = 0x02
; NCF_HIDDEN = 0x08
; NCF_NO_SERVICE = 0x10
; NCF_HAS_UI = 0x80
;----------------- Characteristics ------------
[@PRODUCT_TAP_WIN_COMPONENT_ID@.ndi]
CopyFiles = @PRODUCT_TAP_WIN_COMPONENT_ID@.driver, @PRODUCT_TAP_WIN_COMPONENT_ID@.files
AddReg = @PRODUCT_TAP_WIN_COMPONENT_ID@.reg
AddReg = @PRODUCT_TAP_WIN_COMPONENT_ID@.params.reg
Characteristics = @PRODUCT_TAP_WIN_CHARACTERISTICS@
[@PRODUCT_TAP_WIN_COMPONENT_ID@.ndi.Services]
AddService = @PRODUCT_TAP_WIN_COMPONENT_ID@, 2, @PRODUCT_TAP_WIN_COMPONENT_ID@.service
[@PRODUCT_TAP_WIN_COMPONENT_ID@.reg]
HKR, Ndi, Service, 0, "@PRODUCT_TAP_WIN_COMPONENT_ID@"
HKR, Ndi\Interfaces, UpperRange, 0, "ndis5"
HKR, Ndi\Interfaces, LowerRange, 0, "ethernet"
HKR, , Manufacturer, 0, "%Provider%"
HKR, , ProductName, 0, "%DeviceDescription%"
[@PRODUCT_TAP_WIN_COMPONENT_ID@.params.reg]
HKR, Ndi\params\MTU, ParamDesc, 0, "MTU"
HKR, Ndi\params\MTU, Type, 0, "int"
HKR, Ndi\params\MTU, Default, 0, "1500"
HKR, Ndi\params\MTU, Optional, 0, "0"
HKR, Ndi\params\MTU, Min, 0, "100"
HKR, Ndi\params\MTU, Max, 0, "1500"
HKR, Ndi\params\MTU, Step, 0, "1"
HKR, Ndi\params\MediaStatus, ParamDesc, 0, "Media Status"
HKR, Ndi\params\MediaStatus, Type, 0, "enum"
HKR, Ndi\params\MediaStatus, Default, 0, "0"
HKR, Ndi\params\MediaStatus, Optional, 0, "0"
HKR, Ndi\params\MediaStatus\enum, "0", 0, "Application Controlled"
HKR, Ndi\params\MediaStatus\enum, "1", 0, "Always Connected"
HKR, Ndi\params\MAC, ParamDesc, 0, "MAC Address"
HKR, Ndi\params\MAC, Type, 0, "edit"
HKR, Ndi\params\MAC, Optional, 0, "1"
HKR, Ndi\params\AllowNonAdmin, ParamDesc, 0, "Non-Admin Access"
HKR, Ndi\params\AllowNonAdmin, Type, 0, "enum"
HKR, Ndi\params\AllowNonAdmin, Default, 0, "1"
HKR, Ndi\params\AllowNonAdmin, Optional, 0, "0"
HKR, Ndi\params\AllowNonAdmin\enum, "0", 0, "Not Allowed"
HKR, Ndi\params\AllowNonAdmin\enum, "1", 0, "Allowed"
;----------------------------------------------------------------
; Service Section
;----------------------------------------------------------------
;---------- Service Type -------------
; SERVICE_KERNEL_DRIVER = 0x01
; SERVICE_WIN32_OWN_PROCESS = 0x10
;---------- Service Type -------------
;---------- Start Mode ---------------
; SERVICE_BOOT_START = 0x0
; SERVICE_SYSTEM_START = 0x1
; SERVICE_AUTO_START = 0x2
; SERVICE_DEMAND_START = 0x3
; SERVICE_DISABLED = 0x4
;---------- Start Mode ---------------
[@PRODUCT_TAP_WIN_COMPONENT_ID@.service]
DisplayName = %DeviceDescription%
ServiceType = 1
StartType = 3
ErrorControl = 1
LoadOrderGroup = NDIS
ServiceBinary = %12%\@PRODUCT_TAP_WIN_COMPONENT_ID@.sys
;-----------------------------------------------------------------
; File Installation
;-----------------------------------------------------------------
;----------------- Copy Flags ------------
; COPYFLG_NOSKIP = 0x02
; COPYFLG_NOVERSIONCHECK = 0x04
;----------------- Copy Flags ------------
; SourceDisksNames
; diskid = description[, [tagfile] [, <unused>, subdir]]
; 1 = "Intel Driver Disk 1",e100bex.sys,,
[SourceDisksNames]
1 = %DeviceDescription%, @PRODUCT_TAP_WIN_COMPONENT_ID@.sys
; SourceDisksFiles
; filename_on_source = diskID[, [subdir][, size]]
; e100bex.sys = 1,, ; on distribution disk 1
[SourceDisksFiles]
@PRODUCT_TAP_WIN_COMPONENT_ID@.sys = 1
[DestinationDirs]
@PRODUCT_TAP_WIN_COMPONENT_ID@.files = 11
@PRODUCT_TAP_WIN_COMPONENT_ID@.driver = 12
[@PRODUCT_TAP_WIN_COMPONENT_ID@.files]
; TapPanel.cpl,,,6 ; COPYFLG_NOSKIP | COPYFLG_NOVERSIONCHECK
; cipsrvr.exe,,,6 ; COPYFLG_NOSKIP | COPYFLG_NOVERSIONCHECK
[@PRODUCT_TAP_WIN_COMPONENT_ID@.driver]
@PRODUCT_TAP_WIN_COMPONENT_ID@.sys,,,6 ; COPYFLG_NOSKIP | COPYFLG_NOVERSIONCHECK
;---------------------------------------------------------------
; End
;---------------------------------------------------------------

65
windows-tap/src/SOURCES.in Executable file
View File

@ -0,0 +1,65 @@
# Build TAP-Windows driver.
# Build Command: build -cef
MAJORCOMP=ntos
MINORCOMP=ndis
TARGETNAME=@PRODUCT_TAP_WIN_COMPONENT_ID@
TARGETTYPE=DRIVER
TARGETPATH=.
TARGETLIBS=$(DDK_LIB_PATH)\ndis.lib $(DDK_LIB_PATH)\ntstrsafe.lib
INCLUDES=$(DDK_INCLUDE_PATH) ..
# The TAP version numbers here must be >=
# PRODUCT_TAP_WIN32_MIN_x values defined in version.m4
C_DEFINES=
C_DEFINES=$(C_DEFINES) @EXTRA_C_DEFINES@
C_DEFINES=$(C_DEFINES) -DTAP_DRIVER_MAJOR_VERSION=@PRODUCT_TAP_WIN_MAJOR@
C_DEFINES=$(C_DEFINES) -DTAP_DRIVER_MINOR_VERSION=@PRODUCT_TAP_WIN_MINOR@
# Produce the same symbolic information for both free & checked builds.
# This will allow us to perform full source-level debugging on both
# builds without affecting the free build's performance.
!IF "$(DDKBUILDENV)" != "chk"
NTDEBUGTYPE=both
USE_PDB=1
!ELSE
NTDEBUGTYPE=both
USE_PDB=1
!ENDIF
# Set compiler optimizations:
# /Ox - Full optimization enabled
# /Os - favor speed over size when optimizing
# /Od - Disable all optimizations
# /Oi - Enable optimization for intrinsic functions
# /Fc - Generate mixed assembler/source code files
#
# For both checked and free builds, make sure that any intrinsic
# functions are compiled correctly. To do this, ensure that /Oi
# is selected for both free and checked builds. There is a bug in
# VC++ 6.0 (at least through SP4) where, if you specify any
# intrinsic functions in your code with "#pragma intrinsic" but
# you don't have the /Oi optimization enabled, neither a call
# to the function, nor the intrinsic inline version of the function
# will end up in your object code. This bug only applies to free
# builds, but just to be safe we'll make sure that the flag is
# enabled for all builds.
!IF "$(DDKBUILDENV)" != "chk"
MSC_OPTIMIZATION=/Ox /Oi /Fc
!ELSE
MSC_OPTIMIZATION=/Od /Oi /Fc
!ENDIF
# Generate a linker map file just in case we need one for debugging
LINKER_FLAGS=$(LINKER_FLAGS) /INCREMENTAL:NO /MAP /MAPINFO:EXPORTS
# Generate a browser information file for use in IDE development
#BROWSER_INFO=1
#BROWSERFILE=$(TARGETNAME).BSC -n
# Abort compilation on warnings by adding /WX
MSC_WARNING_LEVEL=/W3
SOURCES=tapdrvr.c resource.rc

View File

@ -0,0 +1,9 @@
#define PRODUCT_NAME "@PRODUCT_NAME@"
#define PRODUCT_VERSION "@PRODUCT_VERSION@"
#define PRODUCT_VERSION_RESOURCE @PRODUCT_VERSION_RESOURCE@
#define PRODUCT_TAP_WIN_COMPONENT_ID "@PRODUCT_TAP_WIN_COMPONENT_ID@"
#define PRODUCT_TAP_WIN_MAJOR @PRODUCT_TAP_WIN_MAJOR@
#define PRODUCT_TAP_WIN_MINOR @PRODUCT_TAP_WIN_MINOR@
#define PRODUCT_TAP_WIN_PROVIDER "@PRODUCT_TAP_WIN_PROVIDER@"
#define PRODUCT_TAP_WIN_DEVICE_DESCRIPTION "@PRODUCT_TAP_WIN_DEVICE_DESCRIPTION@"
#define PRODUCT_TAP_WIN_RELDATE "@PRODUCT_TAP_WIN_RELDATE@"

52
windows-tap/src/constants.h Executable file
View File

@ -0,0 +1,52 @@
/*
* TAP-Windows -- A kernel driver to provide virtual tap
* device functionality on Windows.
*
* This code was inspired by the CIPE-Win32 driver by Damion K. Wilson.
*
* This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc.,
* and is released under the GPL version 2 (see below).
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program (see the file COPYING included with this
* distribution); if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
//====================================================================
// Product and Version public settings
//====================================================================
#define PRODUCT_STRING PRODUCT_TAP_DEVICE_DESCRIPTION
#define TAP_NDIS_MAJOR_VERSION 5
#define TAP_NDIS_MINOR_VERSION 0
//===========================================================
// Driver constants
//===========================================================
#define ETHERNET_HEADER_SIZE (sizeof (ETH_HEADER))
#define ETHERNET_MTU 1500
#define ETHERNET_PACKET_SIZE (ETHERNET_MTU + ETHERNET_HEADER_SIZE)
#define DEFAULT_PACKET_LOOKAHEAD (ETHERNET_PACKET_SIZE)
#define NIC_MAX_MCAST_LIST 32 // Max length of multicast address list
#define MINIMUM_MTU 576 // USE TCP Minimum MTU
#define MAXIMUM_MTU 65536 // IP maximum MTU
#define PACKET_QUEUE_SIZE 64 // tap -> userspace queue size
#define IRP_QUEUE_SIZE 16 // max number of simultaneous i/o operations from userspace
#define INJECT_QUEUE_SIZE 16 // DHCP/ARP -> tap injection queue
#define TAP_LITTLE_ENDIAN // affects ntohs, htonl, etc. functions

599
windows-tap/src/dhcp.c Executable file
View File

@ -0,0 +1,599 @@
/*
* TAP-Windows -- A kernel driver to provide virtual tap
* device functionality on Windows.
*
* This code was inspired by the CIPE-Win32 driver by Damion K. Wilson.
*
* This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc.,
* and is released under the GPL version 2 (see below).
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program (see the file COPYING included with this
* distribution); if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
//=========================
// Code to set DHCP options
//=========================
VOID
SetDHCPOpt (DHCPMsg *m, void *data, unsigned int len)
{
if (!m->overflow)
{
if (m->optlen + len <= DHCP_OPTIONS_BUFFER_SIZE)
{
if (len)
{
NdisMoveMemory (m->msg.options + m->optlen, data, len);
m->optlen += len;
}
}
else
{
m->overflow = TRUE;
}
}
}
VOID
SetDHCPOpt0 (DHCPMsg *msg, int type)
{
DHCPOPT0 opt;
opt.type = (UCHAR) type;
SetDHCPOpt (msg, &opt, sizeof (opt));
}
VOID
SetDHCPOpt8 (DHCPMsg *msg, int type, ULONG data)
{
DHCPOPT8 opt;
opt.type = (UCHAR) type;
opt.len = sizeof (opt.data);
opt.data = (UCHAR) data;
SetDHCPOpt (msg, &opt, sizeof (opt));
}
VOID
SetDHCPOpt32 (DHCPMsg *msg, int type, ULONG data)
{
DHCPOPT32 opt;
opt.type = (UCHAR) type;
opt.len = sizeof (opt.data);
opt.data = data;
SetDHCPOpt (msg, &opt, sizeof (opt));
}
//==============
// Checksum code
//==============
USHORT
ip_checksum (const UCHAR *buf, const int len_ip_header)
{
USHORT word16;
ULONG sum = 0;
int i;
// make 16 bit words out of every two adjacent 8 bit words in the packet
// and add them up
for (i = 0; i < len_ip_header - 1; i += 2) {
word16 = ((buf[i] << 8) & 0xFF00) + (buf[i+1] & 0xFF);
sum += (ULONG) word16;
}
// take only 16 bits out of the 32 bit sum and add up the carries
while (sum >> 16)
sum = (sum & 0xFFFF) + (sum >> 16);
// one's complement the result
return ((USHORT) ~sum);
}
USHORT
udp_checksum (const UCHAR *buf,
const int len_udp,
const UCHAR *src_addr,
const UCHAR *dest_addr)
{
USHORT word16;
ULONG sum = 0;
int i;
// make 16 bit words out of every two adjacent 8 bit words and
// calculate the sum of all 16 bit words
for (i = 0; i < len_udp; i += 2){
word16 = ((buf[i] << 8) & 0xFF00) + ((i + 1 < len_udp) ? (buf[i+1] & 0xFF) : 0);
sum += word16;
}
// add the UDP pseudo header which contains the IP source and destination addresses
for (i = 0; i < 4; i += 2){
word16 =((src_addr[i] << 8) & 0xFF00) + (src_addr[i+1] & 0xFF);
sum += word16;
}
for (i = 0; i < 4; i += 2){
word16 =((dest_addr[i] << 8) & 0xFF00) + (dest_addr[i+1] & 0xFF);
sum += word16;
}
// the protocol number and the length of the UDP packet
sum += (USHORT) IPPROTO_UDP + (USHORT) len_udp;
// keep only the last 16 bits of the 32 bit calculated sum and add the carries
while (sum >> 16)
sum = (sum & 0xFFFF) + (sum >> 16);
// Take the one's complement of sum
return ((USHORT) ~sum);
}
//================================
// Set IP and UDP packet checksums
//================================
VOID
SetChecksumDHCPMsg (DHCPMsg *m)
{
// Set IP checksum
m->msg.pre.ip.check = htons (ip_checksum ((UCHAR *) &m->msg.pre.ip, sizeof (IPHDR)));
// Set UDP Checksum
m->msg.pre.udp.check = htons (udp_checksum ((UCHAR *) &m->msg.pre.udp,
sizeof (UDPHDR) + sizeof (DHCP) + m->optlen,
(UCHAR *)&m->msg.pre.ip.saddr,
(UCHAR *)&m->msg.pre.ip.daddr));
}
//===================
// DHCP message tests
//===================
int
GetDHCPMessageType (const DHCP *dhcp, const int optlen)
{
const UCHAR *p = (UCHAR *) (dhcp + 1);
int i;
for (i = 0; i < optlen; ++i)
{
const UCHAR type = p[i];
const int room = optlen - i - 1;
if (type == DHCP_END) // didn't find what we were looking for
return -1;
else if (type == DHCP_PAD) // no-operation
;
else if (type == DHCP_MSG_TYPE) // what we are looking for
{
if (room >= 2)
{
if (p[i+1] == 1) // message length should be 1
return p[i+2]; // return message type
}
return -1;
}
else // some other message
{
if (room >= 1)
{
const int len = p[i+1]; // get message length
i += (len + 1); // advance to next message
}
}
}
return -1;
}
BOOLEAN
DHCPMessageOurs (const TapAdapterPointer p_Adapter,
const ETH_HEADER *eth,
const IPHDR *ip,
const UDPHDR *udp,
const DHCP *dhcp)
{
// Must be UDPv4 protocol
if (!(eth->proto == htons (ETH_P_IP) && ip->protocol == IPPROTO_UDP))
return FALSE;
// Source MAC must be our adapter
if (!MAC_EQUAL (eth->src, p_Adapter->m_MAC))
return FALSE;
// Dest MAC must be either broadcast or our virtual DHCP server
if (!(MAC_EQUAL (eth->dest, p_Adapter->m_MAC_Broadcast)
|| MAC_EQUAL (eth->dest, p_Adapter->m_dhcp_server_mac)))
return FALSE;
// Port numbers must be correct
if (!(udp->dest == htons (BOOTPS_PORT)
&& udp->source == htons (BOOTPC_PORT)))
return FALSE;
// Hardware address must be MAC addr sized
if (!(dhcp->hlen == sizeof (MACADDR)))
return FALSE;
// Hardware address must match our adapter
if (!MAC_EQUAL (eth->src, dhcp->chaddr))
return FALSE;
return TRUE;
}
//=====================================================
// Build all of DHCP packet except for DHCP options.
// Assume that *p has been zeroed before we are called.
//=====================================================
VOID
BuildDHCPPre (const TapAdapterPointer a,
DHCPPre *p,
const ETH_HEADER *eth,
const IPHDR *ip,
const UDPHDR *udp,
const DHCP *dhcp,
const int optlen,
const int type)
{
// Should we broadcast or direct to a specific MAC / IP address?
const BOOLEAN broadcast = (type == DHCPNAK
|| MAC_EQUAL (eth->dest, a->m_MAC_Broadcast));
// Build ethernet header
COPY_MAC (p->eth.src, a->m_dhcp_server_mac);
if (broadcast)
COPY_MAC (p->eth.dest, a->m_MAC_Broadcast);
else
COPY_MAC (p->eth.dest, eth->src);
p->eth.proto = htons (ETH_P_IP);
// Build IP header
p->ip.version_len = (4 << 4) | (sizeof (IPHDR) >> 2);
p->ip.tos = 0;
p->ip.tot_len = htons (sizeof (IPHDR) + sizeof (UDPHDR) + sizeof (DHCP) + optlen);
p->ip.id = 0;
p->ip.frag_off = 0;
p->ip.ttl = 16;
p->ip.protocol = IPPROTO_UDP;
p->ip.check = 0;
p->ip.saddr = a->m_dhcp_server_ip;
if (broadcast)
p->ip.daddr = ~0;
else
p->ip.daddr = a->m_dhcp_addr;
// Build UDP header
p->udp.source = htons (BOOTPS_PORT);
p->udp.dest = htons (BOOTPC_PORT);
p->udp.len = htons (sizeof (UDPHDR) + sizeof (DHCP) + optlen);
p->udp.check = 0;
// Build DHCP response
p->dhcp.op = BOOTREPLY;
p->dhcp.htype = 1;
p->dhcp.hlen = sizeof (MACADDR);
p->dhcp.hops = 0;
p->dhcp.xid = dhcp->xid;
p->dhcp.secs = 0;
p->dhcp.flags = 0;
p->dhcp.ciaddr = 0;
if (type == DHCPNAK)
p->dhcp.yiaddr = 0;
else
p->dhcp.yiaddr = a->m_dhcp_addr;
p->dhcp.siaddr = a->m_dhcp_server_ip;
p->dhcp.giaddr = 0;
COPY_MAC (p->dhcp.chaddr, eth->src);
p->dhcp.magic = htonl (0x63825363);
}
//=============================
// Build specific DHCP messages
//=============================
VOID
SendDHCPMsg (const TapAdapterPointer a,
const int type,
const ETH_HEADER *eth,
const IPHDR *ip,
const UDPHDR *udp,
const DHCP *dhcp)
{
DHCPMsg *pkt;
if (!(type == DHCPOFFER || type == DHCPACK || type == DHCPNAK))
{
DEBUGP (("[TAP] SendDHCPMsg: Bad DHCP type: %d\n", type));
return;
}
pkt = (DHCPMsg *) MemAlloc (sizeof (DHCPMsg), TRUE);
if (pkt)
{
//-----------------------
// Build DHCP options
//-----------------------
// Message Type
SetDHCPOpt8 (pkt, DHCP_MSG_TYPE, type);
// Server ID
SetDHCPOpt32 (pkt, DHCP_SERVER_ID, a->m_dhcp_server_ip);
if (type == DHCPOFFER || type == DHCPACK)
{
// Lease Time
SetDHCPOpt32 (pkt, DHCP_LEASE_TIME, htonl (a->m_dhcp_lease_time));
// Netmask
SetDHCPOpt32 (pkt, DHCP_NETMASK, a->m_dhcp_netmask);
// Other user-defined options
SetDHCPOpt (pkt,
a->m_dhcp_user_supplied_options_buffer,
a->m_dhcp_user_supplied_options_buffer_len);
}
// End
SetDHCPOpt0 (pkt, DHCP_END);
if (!DHCPMSG_OVERFLOW (pkt))
{
// The initial part of the DHCP message (not including options) gets built here
BuildDHCPPre (a,
&pkt->msg.pre,
eth,
ip,
udp,
dhcp,
DHCPMSG_LEN_OPT (pkt),
type);
SetChecksumDHCPMsg (pkt);
DUMP_PACKET ("DHCPMsg",
DHCPMSG_BUF (pkt),
DHCPMSG_LEN_FULL (pkt));
// Return DHCP response to kernel
InjectPacketDeferred (a,
DHCPMSG_BUF (pkt),
DHCPMSG_LEN_FULL (pkt));
}
else
{
DEBUGP (("[TAP] SendDHCPMsg: DHCP buffer overflow\n"));
}
MemFree (pkt, sizeof (DHCPMsg));
}
}
//===================================================================
// Handle a BOOTPS packet produced by the local system to
// resolve the address/netmask of this adapter.
// If we are in TAP_WIN_IOCTL_CONFIG_DHCP_MASQ mode, reply
// to the message. Return TRUE if we processed the passed
// message, so that downstream stages can ignore it.
//===================================================================
BOOLEAN
ProcessDHCP (TapAdapterPointer p_Adapter,
const ETH_HEADER *eth,
const IPHDR *ip,
const UDPHDR *udp,
const DHCP *dhcp,
int optlen)
{
int msg_type;
// Sanity check IP header
if (!(ntohs (ip->tot_len) == sizeof (IPHDR) + sizeof (UDPHDR) + sizeof (DHCP) + optlen
&& (ntohs (ip->frag_off) & IP_OFFMASK) == 0))
return TRUE;
// Does this message belong to us?
if (!DHCPMessageOurs (p_Adapter, eth, ip, udp, dhcp))
return FALSE;
msg_type = GetDHCPMessageType (dhcp, optlen);
// Drop non-BOOTREQUEST messages
if (dhcp->op != BOOTREQUEST)
return TRUE;
// Drop any messages except DHCPDISCOVER or DHCPREQUEST
if (!(msg_type == DHCPDISCOVER || msg_type == DHCPREQUEST))
return TRUE;
// Should we reply with DHCPOFFER, DHCPACK, or DHCPNAK?
if (msg_type == DHCPREQUEST
&& ((dhcp->ciaddr && dhcp->ciaddr != p_Adapter->m_dhcp_addr)
|| !p_Adapter->m_dhcp_received_discover
|| p_Adapter->m_dhcp_bad_requests >= BAD_DHCPREQUEST_NAK_THRESHOLD))
SendDHCPMsg (p_Adapter,
DHCPNAK,
eth, ip, udp, dhcp);
else
SendDHCPMsg (p_Adapter,
(msg_type == DHCPDISCOVER ? DHCPOFFER : DHCPACK),
eth, ip, udp, dhcp);
// Remember if we received a DHCPDISCOVER
if (msg_type == DHCPDISCOVER)
p_Adapter->m_dhcp_received_discover = TRUE;
// Is this a bad DHCPREQUEST?
if (msg_type == DHCPREQUEST && dhcp->ciaddr && dhcp->ciaddr != p_Adapter->m_dhcp_addr)
++p_Adapter->m_dhcp_bad_requests;
return TRUE;
}
#if DBG
const char *
message_op_text (int op)
{
switch (op)
{
case BOOTREQUEST:
return "BOOTREQUEST";
case BOOTREPLY:
return "BOOTREPLY";
default:
return "???";
}
}
const char *
message_type_text (int type)
{
switch (type)
{
case DHCPDISCOVER:
return "DHCPDISCOVER";
case DHCPOFFER:
return "DHCPOFFER";
case DHCPREQUEST:
return "DHCPREQUEST";
case DHCPDECLINE:
return "DHCPDECLINE";
case DHCPACK:
return "DHCPACK";
case DHCPNAK:
return "DHCPNAK";
case DHCPRELEASE:
return "DHCPRELEASE";
case DHCPINFORM:
return "DHCPINFORM";
default:
return "???";
}
}
const char *
port_name (int port)
{
switch (port)
{
case BOOTPS_PORT:
return "BOOTPS";
case BOOTPC_PORT:
return "BOOTPC";
default:
return "unknown";
}
}
VOID
DumpDHCP (const ETH_HEADER *eth,
const IPHDR *ip,
const UDPHDR *udp,
const DHCP *dhcp,
const int optlen)
{
DEBUGP ((" %s", message_op_text (dhcp->op)));
DEBUGP ((" %s ", message_type_text (GetDHCPMessageType (dhcp, optlen))));
PrIP (ip->saddr);
DEBUGP ((":%s[", port_name (ntohs (udp->source))));
PrMac (eth->src);
DEBUGP (("] -> "));
PrIP (ip->daddr);
DEBUGP ((":%s[", port_name (ntohs (udp->dest))));
PrMac (eth->dest);
DEBUGP (("]"));
if (dhcp->ciaddr)
{
DEBUGP ((" ci="));
PrIP (dhcp->ciaddr);
}
if (dhcp->yiaddr)
{
DEBUGP ((" yi="));
PrIP (dhcp->yiaddr);
}
if (dhcp->siaddr)
{
DEBUGP ((" si="));
PrIP (dhcp->siaddr);
}
if (dhcp->hlen == sizeof (MACADDR))
{
DEBUGP ((" ch="));
PrMac (dhcp->chaddr);
}
DEBUGP ((" xid=0x%08x", ntohl (dhcp->xid)));
if (ntohl (dhcp->magic) != 0x63825363)
DEBUGP ((" ma=0x%08x", ntohl (dhcp->magic)));
if (dhcp->htype != 1)
DEBUGP ((" htype=%d", dhcp->htype));
if (dhcp->hops)
DEBUGP ((" hops=%d", dhcp->hops));
if (ntohs (dhcp->secs))
DEBUGP ((" secs=%d", ntohs (dhcp->secs)));
if (ntohs (dhcp->flags))
DEBUGP ((" flags=0x%04x", ntohs (dhcp->flags)));
// extra stuff
if (ip->version_len != 0x45)
DEBUGP ((" vl=0x%02x", ip->version_len));
if (ntohs (ip->tot_len) != sizeof (IPHDR) + sizeof (UDPHDR) + sizeof (DHCP) + optlen)
DEBUGP ((" tl=%d", ntohs (ip->tot_len)));
if (ntohs (udp->len) != sizeof (UDPHDR) + sizeof (DHCP) + optlen)
DEBUGP ((" ul=%d", ntohs (udp->len)));
if (ip->tos)
DEBUGP ((" tos=0x%02x", ip->tos));
if (ntohs (ip->id))
DEBUGP ((" id=0x%04x", ntohs (ip->id)));
if (ntohs (ip->frag_off))
DEBUGP ((" frag_off=0x%04x", ntohs (ip->frag_off)));
DEBUGP ((" ttl=%d", ip->ttl));
DEBUGP ((" ic=0x%04x [0x%04x]", ntohs (ip->check),
ip_checksum ((UCHAR*)ip, sizeof (IPHDR))));
DEBUGP ((" uc=0x%04x [0x%04x/%d]", ntohs (udp->check),
udp_checksum ((UCHAR *) udp,
sizeof (UDPHDR) + sizeof (DHCP) + optlen,
(UCHAR *) &ip->saddr,
(UCHAR *) &ip->daddr),
optlen));
// Options
{
const UCHAR *opt = (UCHAR *) (dhcp + 1);
int i;
DEBUGP ((" OPT"));
for (i = 0; i < optlen; ++i)
{
const UCHAR data = opt[i];
DEBUGP ((".%d", data));
}
}
}
#endif /* DBG */

164
windows-tap/src/dhcp.h Executable file
View File

@ -0,0 +1,164 @@
/*
* TAP-Windows -- A kernel driver to provide virtual tap
* device functionality on Windows.
*
* This code was inspired by the CIPE-Win32 driver by Damion K. Wilson.
*
* This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc.,
* and is released under the GPL version 2 (see below).
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program (see the file COPYING included with this
* distribution); if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#pragma pack(1)
//===================================================
// How many bad DHCPREQUESTs do we receive before we
// return a NAK?
//
// A bad DHCPREQUEST is defined to be one where the
// requestor doesn't know its IP address.
//===================================================
#define BAD_DHCPREQUEST_NAK_THRESHOLD 3
//==============================================
// Maximum number of DHCP options bytes supplied
//==============================================
#define DHCP_USER_SUPPLIED_OPTIONS_BUFFER_SIZE 256
#define DHCP_OPTIONS_BUFFER_SIZE 256
//===================================
// UDP port numbers of DHCP messages.
//===================================
#define BOOTPS_PORT 67
#define BOOTPC_PORT 68
//===========================
// The DHCP message structure
//===========================
typedef struct {
# define BOOTREQUEST 1
# define BOOTREPLY 2
UCHAR op; /* message op */
UCHAR htype; /* hardware address type (e.g. '1' = 10Mb Ethernet) */
UCHAR hlen; /* hardware address length (e.g. '6' for 10Mb Ethernet) */
UCHAR hops; /* client sets to 0, may be used by relay agents */
ULONG xid; /* transaction ID, chosen by client */
USHORT secs; /* seconds since request process began, set by client */
USHORT flags;
ULONG ciaddr; /* client IP address, client sets if known */
ULONG yiaddr; /* 'your' IP address -- server's response to client */
ULONG siaddr; /* server IP address */
ULONG giaddr; /* relay agent IP address */
UCHAR chaddr[16]; /* client hardware address */
UCHAR sname[64]; /* optional server host name */
UCHAR file[128]; /* boot file name */
ULONG magic; /* must be 0x63825363 (network order) */
} DHCP;
typedef struct {
ETH_HEADER eth;
IPHDR ip;
UDPHDR udp;
DHCP dhcp;
} DHCPPre;
typedef struct {
DHCPPre pre;
UCHAR options[DHCP_OPTIONS_BUFFER_SIZE];
} DHCPFull;
typedef struct {
unsigned int optlen;
BOOLEAN overflow;
DHCPFull msg;
} DHCPMsg;
//===================
// Macros for DHCPMSG
//===================
#define DHCPMSG_LEN_BASE(p) (sizeof (DHCPPre))
#define DHCPMSG_LEN_OPT(p) ((p)->optlen)
#define DHCPMSG_LEN_FULL(p) (DHCPMSG_LEN_BASE(p) + DHCPMSG_LEN_OPT(p))
#define DHCPMSG_BUF(p) ((UCHAR*) &(p)->msg)
#define DHCPMSG_OVERFLOW(p) ((p)->overflow)
//========================================
// structs to hold individual DHCP options
//========================================
typedef struct {
UCHAR type;
} DHCPOPT0;
typedef struct {
UCHAR type;
UCHAR len;
UCHAR data;
} DHCPOPT8;
typedef struct {
UCHAR type;
UCHAR len;
ULONG data;
} DHCPOPT32;
#pragma pack()
//==================
// DHCP Option types
//==================
#define DHCP_MSG_TYPE 53 /* message type (u8) */
#define DHCP_PARM_REQ 55 /* parameter request list: c1 (u8), ... */
#define DHCP_CLIENT_ID 61 /* client ID: type (u8), i1 (u8), ... */
#define DHCP_IP 50 /* requested IP addr (u32) */
#define DHCP_NETMASK 1 /* subnet mask (u32) */
#define DHCP_LEASE_TIME 51 /* lease time sec (u32) */
#define DHCP_RENEW_TIME 58 /* renewal time sec (u32) */
#define DHCP_REBIND_TIME 59 /* rebind time sec (u32) */
#define DHCP_SERVER_ID 54 /* server ID: IP addr (u32) */
#define DHCP_PAD 0
#define DHCP_END 255
//====================
// DHCP Messages types
//====================
#define DHCPDISCOVER 1
#define DHCPOFFER 2
#define DHCPREQUEST 3
#define DHCPDECLINE 4
#define DHCPACK 5
#define DHCPNAK 6
#define DHCPRELEASE 7
#define DHCPINFORM 8
#if DBG
VOID
DumpDHCP (const ETH_HEADER *eth,
const IPHDR *ip,
const UDPHDR *udp,
const DHCP *dhcp,
const int optlen);
#endif

35
windows-tap/src/endian.h Executable file
View File

@ -0,0 +1,35 @@
/*
* TAP-Windows -- A kernel driver to provide virtual tap
* device functionality on Windows.
*
* This code was inspired by the CIPE-Win32 driver by Damion K. Wilson.
*
* This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc.,
* and is released under the GPL version 2 (see below).
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program (see the file COPYING included with this
* distribution); if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifdef TAP_LITTLE_ENDIAN
#define ntohs(x) RtlUshortByteSwap(x)
#define htons(x) RtlUshortByteSwap(x)
#define ntohl(x) RtlUlongByteSwap(x)
#define htonl(x) RtlUlongByteSwap(x)
#else
#define ntohs(x) ((USHORT)(x))
#define htons(x) ((USHORT)(x))
#define ntohl(x) ((ULONG)(x))
#define htonl(x) ((ULONG)(x))
#endif

385
windows-tap/src/error.c Executable file
View File

@ -0,0 +1,385 @@
/*
* TAP-Windows -- A kernel driver to provide virtual tap
* device functionality on Windows.
*
* This code was inspired by the CIPE-Win32 driver by Damion K. Wilson.
*
* This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc.,
* and is released under the GPL version 2 (see below).
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program (see the file COPYING included with this
* distribution); if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
//-----------------
// DEBUGGING OUTPUT
//-----------------
const char *g_LastErrorFilename;
int g_LastErrorLineNumber;
#if DBG
DebugOutput g_Debug;
BOOLEAN
NewlineExists (const char *str, int len)
{
while (len-- > 0)
{
const char c = *str++;
if (c == '\n')
return TRUE;
else if (c == '\0')
break;
}
return FALSE;
}
VOID
MyDebugInit (unsigned int bufsiz)
{
NdisZeroMemory (&g_Debug, sizeof (g_Debug));
g_Debug.text = (char *) MemAlloc (bufsiz, FALSE);
if (g_Debug.text)
g_Debug.capacity = bufsiz;
}
VOID
MyDebugFree ()
{
if (g_Debug.text)
MemFree (g_Debug.text, g_Debug.capacity);
NdisZeroMemory (&g_Debug, sizeof (g_Debug));
}
VOID
MyDebugPrint (const unsigned char* format, ...)
{
if (g_Debug.text && g_Debug.capacity > 0 && CAN_WE_PRINT)
{
BOOLEAN owned;
ACQUIRE_MUTEX_ADAPTIVE (&g_Debug.lock, owned);
if (owned)
{
const int remaining = (int)g_Debug.capacity - (int)g_Debug.out;
if (remaining > 0)
{
va_list args;
NTSTATUS status;
char *end;
#ifdef DBG_PRINT
va_start (args, format);
vDbgPrintEx (DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, format, args);
va_end (args);
#endif
va_start (args, format);
status = RtlStringCchVPrintfExA (g_Debug.text + g_Debug.out,
remaining,
&end,
NULL,
STRSAFE_NO_TRUNCATION | STRSAFE_IGNORE_NULLS,
format,
args);
va_end (args);
va_start (args, format);
vDbgPrintEx(DPFLTR_IHVDRIVER_ID , 1, format, args);
va_end (args);
if (status == STATUS_SUCCESS)
g_Debug.out = (unsigned int) (end - g_Debug.text);
else
g_Debug.error = TRUE;
}
else
g_Debug.error = TRUE;
RELEASE_MUTEX (&g_Debug.lock);
}
else
g_Debug.error = TRUE;
}
}
BOOLEAN
GetDebugLine (char *buf, const int len)
{
static const char *truncated = "[OUTPUT TRUNCATED]\n";
BOOLEAN ret = FALSE;
NdisZeroMemory (buf, len);
if (g_Debug.text && g_Debug.capacity > 0)
{
BOOLEAN owned;
ACQUIRE_MUTEX_ADAPTIVE (&g_Debug.lock, owned);
if (owned)
{
int i = 0;
if (g_Debug.error || NewlineExists (g_Debug.text + g_Debug.in, (int)g_Debug.out - (int)g_Debug.in))
{
while (i < (len - 1) && g_Debug.in < g_Debug.out)
{
const char c = g_Debug.text[g_Debug.in++];
if (c == '\n')
break;
buf[i++] = c;
}
if (i < len)
buf[i] = '\0';
}
if (!i)
{
if (g_Debug.in == g_Debug.out)
{
g_Debug.in = g_Debug.out = 0;
if (g_Debug.error)
{
const unsigned int tlen = strlen (truncated);
if (tlen < g_Debug.capacity)
{
NdisMoveMemory (g_Debug.text, truncated, tlen+1);
g_Debug.out = tlen;
}
g_Debug.error = FALSE;
}
}
}
else
ret = TRUE;
RELEASE_MUTEX (&g_Debug.lock);
}
}
return ret;
}
VOID
MyAssert (const unsigned char *file, int line)
{
DEBUGP (("MYASSERT failed %s/%d\n", file, line));
KeBugCheckEx (0x0F00BABA,
(ULONG_PTR) line,
(ULONG_PTR) 0,
(ULONG_PTR) 0,
(ULONG_PTR) 0);
}
VOID
PrMac (const MACADDR mac)
{
DEBUGP (("%x:%x:%x:%x:%x:%x",
mac[0], mac[1], mac[2],
mac[3], mac[4], mac[5]));
}
VOID
PrIP (IPADDR ip_addr)
{
const unsigned char *ip = (const unsigned char *) &ip_addr;
DEBUGP (("%d.%d.%d.%d",
ip[0], ip[1], ip[2], ip[3]));
}
const char *
PrIPProto (int proto)
{
switch (proto)
{
case IPPROTO_UDP:
return "UDP";
case IPPROTO_TCP:
return "TCP";
case IPPROTO_ICMP:
return "ICMP";
case IPPROTO_IGMP:
return "IGMP";
default:
return "???";
}
}
VOID
DumpARP (const char *prefix, const ARP_PACKET *arp)
{
DEBUGP (("%s ARP src=", prefix));
PrMac (arp->m_MAC_Source);
DEBUGP ((" dest="));
PrMac (arp->m_MAC_Destination);
DEBUGP ((" OP=0x%04x",
(int)ntohs(arp->m_ARP_Operation)));
DEBUGP ((" M=0x%04x(%d)",
(int)ntohs(arp->m_MAC_AddressType),
(int)arp->m_MAC_AddressSize));
DEBUGP ((" P=0x%04x(%d)",
(int)ntohs(arp->m_PROTO_AddressType),
(int)arp->m_PROTO_AddressSize));
DEBUGP ((" MacSrc="));
PrMac (arp->m_ARP_MAC_Source);
DEBUGP ((" MacDest="));
PrMac (arp->m_ARP_MAC_Destination);
DEBUGP ((" IPSrc="));
PrIP (arp->m_ARP_IP_Source);
DEBUGP ((" IPDest="));
PrIP (arp->m_ARP_IP_Destination);
DEBUGP (("\n"));
}
struct ethpayload {
ETH_HEADER eth;
UCHAR payload[DEFAULT_PACKET_LOOKAHEAD];
};
VOID
DumpPacket2 (const char *prefix,
const ETH_HEADER *eth,
const unsigned char *data,
unsigned int len)
{
struct ethpayload *ep = (struct ethpayload *) MemAlloc (sizeof (struct ethpayload), TRUE);
if (ep)
{
if (len > DEFAULT_PACKET_LOOKAHEAD)
len = DEFAULT_PACKET_LOOKAHEAD;
ep->eth = *eth;
NdisMoveMemory (ep->payload, data, len);
DumpPacket (prefix, (unsigned char *) ep, sizeof (ETH_HEADER) + len);
MemFree (ep, sizeof (struct ethpayload));
}
}
VOID
DumpPacket (const char *prefix,
const unsigned char *data,
unsigned int len)
{
const ETH_HEADER *eth = (const ETH_HEADER *) data;
const IPHDR *ip = (const IPHDR *) (data + sizeof (ETH_HEADER));
if (len < sizeof (ETH_HEADER))
{
DEBUGP (("%s TRUNCATED PACKET LEN=%d\n", prefix, len));
return;
}
// ARP Packet?
if (len >= sizeof (ARP_PACKET) && eth->proto == htons (ETH_P_ARP))
{
DumpARP (prefix, (const ARP_PACKET *) data);
return;
}
// IPv4 packet?
if (len >= (sizeof (IPHDR) + sizeof (ETH_HEADER))
&& eth->proto == htons (ETH_P_IP)
&& IPH_GET_VER (ip->version_len) == 4)
{
const int hlen = IPH_GET_LEN (ip->version_len);
const int blen = len - sizeof (ETH_HEADER);
BOOLEAN did = FALSE;
DEBUGP (("%s IPv4 %s[%d]", prefix, PrIPProto (ip->protocol), len));
if (!(ntohs (ip->tot_len) == blen && hlen <= blen))
{
DEBUGP ((" XXX"));
return;
}
// TCP packet?
if (ip->protocol == IPPROTO_TCP
&& blen - hlen >= (sizeof (TCPHDR)))
{
const TCPHDR *tcp = (TCPHDR *) (data + sizeof (ETH_HEADER) + hlen);
DEBUGP ((" "));
PrIP (ip->saddr);
DEBUGP ((":%d", ntohs (tcp->source)));
DEBUGP ((" -> "));
PrIP (ip->daddr);
DEBUGP ((":%d", ntohs (tcp->dest)));
did = TRUE;
}
// UDP packet?
else if ((ntohs (ip->frag_off) & IP_OFFMASK) == 0
&& ip->protocol == IPPROTO_UDP
&& blen - hlen >= (sizeof (UDPHDR)))
{
const UDPHDR *udp = (UDPHDR *) (data + sizeof (ETH_HEADER) + hlen);
// DHCP packet?
if ((udp->dest == htons (BOOTPC_PORT) || udp->dest == htons (BOOTPS_PORT))
&& blen - hlen >= (sizeof (UDPHDR) + sizeof (DHCP)))
{
const DHCP *dhcp = (DHCP *) (data
+ hlen
+ sizeof (ETH_HEADER)
+ sizeof (UDPHDR));
int optlen = len
- sizeof (ETH_HEADER)
- hlen
- sizeof (UDPHDR)
- sizeof (DHCP);
if (optlen < 0)
optlen = 0;
DumpDHCP (eth, ip, udp, dhcp, optlen);
did = TRUE;
}
if (!did)
{
DEBUGP ((" "));
PrIP (ip->saddr);
DEBUGP ((":%d", ntohs (udp->source)));
DEBUGP ((" -> "));
PrIP (ip->daddr);
DEBUGP ((":%d", ntohs (udp->dest)));
did = TRUE;
}
}
if (!did)
{
DEBUGP ((" ipproto=%d ", ip->protocol));
PrIP (ip->saddr);
DEBUGP ((" -> "));
PrIP (ip->daddr);
}
DEBUGP (("\n"));
return;
}
{
DEBUGP (("%s ??? src=", prefix));
PrMac (eth->src);
DEBUGP ((" dest="));
PrMac (eth->dest);
DEBUGP ((" proto=0x%04x len=%d\n",
(int) ntohs(eth->proto),
len));
}
}
#endif

88
windows-tap/src/error.h Executable file
View File

@ -0,0 +1,88 @@
/*
* TAP-Windows -- A kernel driver to provide virtual tap
* device functionality on Windows.
*
* This code was inspired by the CIPE-Win32 driver by Damion K. Wilson.
*
* This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc.,
* and is released under the GPL version 2 (see below).
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program (see the file COPYING included with this
* distribution); if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
//-----------------
// DEBUGGING OUTPUT
//-----------------
#define NOTE_ERROR() \
{ \
g_LastErrorFilename = __FILE__; \
g_LastErrorLineNumber = __LINE__; \
}
#if DBG
typedef struct {
unsigned int in;
unsigned int out;
unsigned int capacity;
char *text;
BOOLEAN error;
MUTEX lock;
} DebugOutput;
VOID MyDebugPrint (const unsigned char* format, ...);
VOID MyAssert (const unsigned char *file, int line);
VOID DumpPacket (const char *prefix,
const unsigned char *data,
unsigned int len);
VOID DumpPacket2 (const char *prefix,
const ETH_HEADER *eth,
const unsigned char *data,
unsigned int len);
#define CAN_WE_PRINT (DEBUGP_AT_DISPATCH || KeGetCurrentIrql () < DISPATCH_LEVEL)
#if ALSO_DBGPRINT
#define DEBUGP(fmt) { MyDebugPrint fmt; if (CAN_WE_PRINT) DbgPrint fmt; }
#else
#define DEBUGP(fmt) { MyDebugPrint fmt; }
#endif
#define MYASSERT(exp) \
{ \
if (!(exp)) \
{ \
MyAssert(__FILE__, __LINE__); \
} \
}
#define DUMP_PACKET(prefix, data, len) \
DumpPacket (prefix, data, len)
#define DUMP_PACKET2(prefix, eth, data, len) \
DumpPacket2 (prefix, eth, data, len)
#else
#define DEBUGP(fmt)
#define MYASSERT(exp)
#define DUMP_PACKET(prefix, data, len)
#define DUMP_PACKET2(prefix, eth, data, len)
#endif

69
windows-tap/src/hexdump.c Executable file
View File

@ -0,0 +1,69 @@
/*
* TAP-Windows -- A kernel driver to provide virtual tap
* device functionality on Windows.
*
* This code was inspired by the CIPE-Win32 driver by Damion K. Wilson.
*
* This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc.,
* and is released under the GPL version 2 (see below).
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program (see the file COPYING included with this
* distribution); if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifdef __cplusplus
extern "C" {
#endif
#include "hexdump.h"
#ifndef NDIS_MINIPORT_DRIVER
VOID (*DbgMessage)(char *p_Format, ...) = DisplayDebugString;
VOID DisplayDebugString (char *p_Format, ...)
{
static char l_Buffer [4096];
va_list l_ArgumentList;
va_start (l_ArgumentList, p_Format);
vsprintf (l_Buffer, p_Format, l_ArgumentList);
va_end (l_ArgumentList);
OutputDebugStringA (l_Buffer);
}
#endif
VOID HexDump (unsigned char *p_Buffer, unsigned long p_Size)
{
unsigned long l_Index, l_Idx;
unsigned char l_Row [17];
for (l_Index = l_Row [16] = 0; l_Index < p_Size || l_Index % 16; ++l_Index)
{
if (l_Index % 16 == 0)
DEBUGP (("%05x ", l_Index));
DEBUGP (("%02x ", l_Row [l_Index % 16] = (l_Index < p_Size ? p_Buffer [l_Index] : 0)));
l_Row [l_Index % 16] = IfPrint (l_Row [l_Index % 16]);
if ((l_Index + 1) % 16 == 0)
DEBUGP ((" %s\n", l_Row));
}
DEBUGP (("\n"));
}
#ifdef __cplusplus
}
#endif

63
windows-tap/src/hexdump.h Executable file
View File

@ -0,0 +1,63 @@
/*
* TAP-Windows -- A kernel driver to provide virtual tap
* device functionality on Windows.
*
* This code was inspired by the CIPE-Win32 driver by Damion K. Wilson.
*
* This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc.,
* and is released under the GPL version 2 (see below).
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program (see the file COPYING included with this
* distribution); if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef HEXDUMP_DEFINED
#define HEXDUMP_DEFINED
#ifdef __cplusplus
extern "C" {
#endif
//=====================================================================================
// Debug Routines
//=====================================================================================
#ifndef NDIS_MINIPORT_DRIVER
# include <stdio.h>
# include <ctype.h>
# include <windows.h>
# include <winnt.h>
# include <memory.h>
# ifndef DEBUGP
# define DEBUGP(fmt) { DbgMessage fmt; }
# endif
extern VOID (*DbgMessage)(char *p_Format, ...);
VOID DisplayDebugString (char *p_Format, ...);
#endif
//===================================================================================
// Reporting / Debugging
//===================================================================================
#define IfPrint(c) (c >= 32 && c < 127 ? c : '.')
VOID HexDump (unsigned char *p_Buffer, unsigned long p_Size);
#ifdef __cplusplus
}
#endif
#endif

241
windows-tap/src/instance.c Executable file
View File

@ -0,0 +1,241 @@
/*
* TAP-Windows -- A kernel driver to provide virtual tap
* device functionality on Windows.
*
* This code was inspired by the CIPE-Win32 driver by Damion K. Wilson.
*
* This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc.,
* and is released under the GPL version 2 (see below).
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program (see the file COPYING included with this
* distribution); if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#define INSTANCE_KEY(a) ((PVOID)((a)->m_Extension.m_TapDevice))
#define N_INSTANCE_BUCKETS 256
typedef struct _INSTANCE {
struct _INSTANCE *next;
TapAdapterPointer m_Adapter;
} INSTANCE;
typedef struct {
INSTANCE *list;
MUTEX lock;
} INSTANCE_BUCKET;
typedef struct {
INSTANCE_BUCKET buckets[N_INSTANCE_BUCKETS];
} INSTANCE_HASH;
INSTANCE_HASH *g_InstanceHash = NULL;
// must return a hash >= 0 and < N_INSTANCE_BUCKETS
int
InstanceHashValue (PVOID addr)
{
UCHAR *p = (UCHAR *) &addr;
if (sizeof (addr) == 4)
return p[0] ^ p[1] ^ p[2] ^ p[3];
else if (sizeof (addr) == 8)
return p[0] ^ p[1] ^ p[2] ^ p[3] ^ p[4] ^ p[5] ^ p[6] ^ p[7];
else
{
MYASSERT (0);
}
}
BOOLEAN
InitInstanceList (VOID)
{
MYASSERT (g_InstanceHash == NULL);
g_InstanceHash = MemAlloc (sizeof (INSTANCE_HASH), TRUE);
if (g_InstanceHash)
{
int i;
for (i = 0; i < N_INSTANCE_BUCKETS; ++i)
INIT_MUTEX (&g_InstanceHash->buckets[i].lock);
return TRUE;
}
else
return FALSE;
}
int
NInstances (VOID)
{
int i, n = 0;
if (g_InstanceHash)
{
for (i = 0; i < N_INSTANCE_BUCKETS; ++i)
{
BOOLEAN got_lock;
INSTANCE_BUCKET *ib = &g_InstanceHash->buckets[i];
ACQUIRE_MUTEX_ADAPTIVE (&ib->lock, got_lock);
if (got_lock)
{
INSTANCE *current;
for (current = ib->list; current != NULL; current = current->next)
++n;
RELEASE_MUTEX (&ib->lock);
}
else
return -1;
}
}
return n;
}
int
InstanceMaxBucketSize (VOID)
{
int i, n = 0;
if (g_InstanceHash)
{
for (i = 0; i < N_INSTANCE_BUCKETS; ++i)
{
BOOLEAN got_lock;
int bucket_size = 0;
INSTANCE_BUCKET *ib = &g_InstanceHash->buckets[i];
ACQUIRE_MUTEX_ADAPTIVE (&ib->lock, got_lock);
if (got_lock)
{
INSTANCE *current;
for (current = ib->list; current != NULL; current = current->next)
++bucket_size;
if (bucket_size > n)
n = bucket_size;
RELEASE_MUTEX (&ib->lock);
}
else
return -1;
}
}
return n;
}
VOID
FreeInstanceList (VOID)
{
if (g_InstanceHash)
{
MYASSERT (NInstances() == 0);
MemFree (g_InstanceHash, sizeof (INSTANCE_HASH));
g_InstanceHash = NULL;
}
}
BOOLEAN
AddAdapterToInstanceList (TapAdapterPointer p_Adapter)
{
BOOLEAN got_lock;
BOOLEAN ret = FALSE;
const int hash = InstanceHashValue(INSTANCE_KEY(p_Adapter));
INSTANCE_BUCKET *ib = &g_InstanceHash->buckets[hash];
DEBUGP (("[TAP] AddAdapterToInstanceList hash=%d\n", hash));
ACQUIRE_MUTEX_ADAPTIVE (&ib->lock, got_lock);
if (got_lock)
{
INSTANCE *i = MemAlloc (sizeof (INSTANCE), FALSE);
if (i)
{
MYASSERT (p_Adapter);
i->m_Adapter = p_Adapter;
i->next = ib->list;
ib->list = i;
ret = TRUE;
}
RELEASE_MUTEX (&ib->lock);
}
return ret;
}
BOOLEAN
RemoveAdapterFromInstanceList (TapAdapterPointer p_Adapter)
{
BOOLEAN got_lock;
BOOLEAN ret = FALSE;
INSTANCE_BUCKET *ib = &g_InstanceHash->buckets[InstanceHashValue(INSTANCE_KEY(p_Adapter))];
ACQUIRE_MUTEX_ADAPTIVE (&ib->lock, got_lock);
if (got_lock)
{
INSTANCE *current, *prev=NULL;
for (current = ib->list; current != NULL; current = current->next)
{
if (current->m_Adapter == p_Adapter) // found match
{
if (prev)
prev->next = current->next;
else
ib->list = current->next;
MemFree (current->m_Adapter, sizeof (TapAdapter));
MemFree (current, sizeof (INSTANCE));
ret = TRUE;
break;
}
prev = current;
}
RELEASE_MUTEX (&ib->lock);
}
return ret;
}
TapAdapterPointer
LookupAdapterInInstanceList (PDEVICE_OBJECT p_DeviceObject)
{
BOOLEAN got_lock;
TapAdapterPointer ret = NULL;
INSTANCE_BUCKET *ib = &g_InstanceHash->buckets[InstanceHashValue((PVOID)p_DeviceObject)];
ACQUIRE_MUTEX_ADAPTIVE (&ib->lock, got_lock);
if (got_lock)
{
INSTANCE *current, *prev=NULL;
for (current = ib->list; current != NULL; current = current->next)
{
if (p_DeviceObject == INSTANCE_KEY (current->m_Adapter)) // found match
{
// move it to head of list
if (prev)
{
prev->next = current->next;
current->next = ib->list;
ib->list = current;
}
ret = ib->list->m_Adapter;
break;
}
prev = current;
}
RELEASE_MUTEX (&ib->lock);
}
return ret;
}

75
windows-tap/src/lock.h Executable file
View File

@ -0,0 +1,75 @@
/*
* TAP-Windows -- A kernel driver to provide virtual tap
* device functionality on Windows.
*
* This code was inspired by the CIPE-Win32 driver by Damion K. Wilson.
*
* This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc.,
* and is released under the GPL version 2 (see below).
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program (see the file COPYING included with this
* distribution); if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
typedef struct
{
volatile long count;
} MUTEX;
#define MUTEX_SLEEP_TIME 10000 // microseconds
#define INIT_MUTEX(m) { (m)->count = 0; }
#define ACQUIRE_MUTEX_BLOCKING(m) \
{ \
while (NdisInterlockedIncrement (&((m)->count)) != 1) \
{ \
NdisInterlockedDecrement(&((m)->count)); \
NdisMSleep(MUTEX_SLEEP_TIME); \
} \
}
#define RELEASE_MUTEX(m) \
{ \
NdisInterlockedDecrement(&((m)->count)); \
}
#define ACQUIRE_MUTEX_NONBLOCKING(m, result) \
{ \
if (NdisInterlockedIncrement (&((m)->count)) != 1) \
{ \
NdisInterlockedDecrement(&((m)->count)); \
result = FALSE; \
} \
else \
{ \
result = TRUE; \
} \
}
#define ACQUIRE_MUTEX_ADAPTIVE(m, result) \
{ \
result = TRUE; \
while (NdisInterlockedIncrement (&((m)->count)) != 1) \
{ \
NdisInterlockedDecrement(&((m)->count)); \
if (KeGetCurrentIrql () < DISPATCH_LEVEL) \
NdisMSleep(MUTEX_SLEEP_TIME); \
else \
{ \
result = FALSE; \
break; \
} \
} \
}

154
windows-tap/src/macinfo.c Executable file
View File

@ -0,0 +1,154 @@
/*
* TAP-Windows -- A kernel driver to provide virtual tap
* device functionality on Windows.
*
* This code was inspired by the CIPE-Win32 driver by Damion K. Wilson.
*
* This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc.,
* and is released under the GPL version 2 (see below).
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program (see the file COPYING included with this
* distribution); if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "macinfo.h"
int
HexStringToDecimalInt (const int p_Character)
{
int l_Value = 0;
if (p_Character >= 'A' && p_Character <= 'F')
l_Value = (p_Character - 'A') + 10;
else if (p_Character >= 'a' && p_Character <= 'f')
l_Value = (p_Character - 'a') + 10;
else if (p_Character >= '0' && p_Character <= '9')
l_Value = p_Character - '0';
return l_Value;
}
BOOLEAN
ParseMAC (MACADDR dest, const char *src)
{
int c;
int mac_index = 0;
BOOLEAN high_digit = FALSE;
int delim_action = 1;
MYASSERT (src);
MYASSERT (dest);
CLEAR_MAC (dest);
while (c = *src++)
{
if (IsMacDelimiter (c))
{
mac_index += delim_action;
high_digit = FALSE;
delim_action = 1;
}
else if (IsHexDigit (c))
{
const int digit = HexStringToDecimalInt (c);
if (mac_index < sizeof (MACADDR))
{
if (!high_digit)
{
dest[mac_index] = (char)(digit);
high_digit = TRUE;
delim_action = 1;
}
else
{
dest[mac_index] = (char)(dest[mac_index] * 16 + digit);
++mac_index;
high_digit = FALSE;
delim_action = 0;
}
}
else
return FALSE;
}
else
return FALSE;
}
return (mac_index + delim_action) >= sizeof (MACADDR);
}
/*
* Generate a MAC using the GUID in the adapter name.
*
* The mac is constructed as 00:FF:xx:xx:xx:xx where
* the Xs are taken from the first 32 bits of the GUID in the
* adapter name. This is similar to the Linux 2.4 tap MAC
* generator, except linux uses 32 random bits for the Xs.
*
* In general, this solution is reasonable for most
* applications except for very large bridged TAP networks,
* where the probability of address collisions becomes more
* than infintesimal.
*
* Using the well-known "birthday paradox", on a 1000 node
* network the probability of collision would be
* 0.000116292153. On a 10,000 node network, the probability
* of collision would be 0.01157288998621678766.
*/
VOID GenerateRandomMac (MACADDR mac, const unsigned char *adapter_name)
{
unsigned const char *cp = adapter_name;
unsigned char c;
unsigned int i = 2;
unsigned int byte = 0;
int brace = 0;
int state = 0;
CLEAR_MAC (mac);
mac[0] = 0x00;
mac[1] = 0xFF;
while (c = *cp++)
{
if (i >= sizeof (MACADDR))
break;
if (c == '{')
brace = 1;
if (IsHexDigit (c) && brace)
{
const unsigned int digit = HexStringToDecimalInt (c);
if (state)
{
byte <<= 4;
byte |= digit;
mac[i++] = (unsigned char) byte;
state = 0;
}
else
{
byte = digit;
state = 1;
}
}
}
}
VOID GenerateRelatedMAC (MACADDR dest, const MACADDR src, const int delta)
{
COPY_MAC (dest, src);
dest[2] += (UCHAR) delta;
}

38
windows-tap/src/macinfo.h Executable file
View File

@ -0,0 +1,38 @@
/*
* TAP-Windows -- A kernel driver to provide virtual tap
* device functionality on Windows.
*
* This code was inspired by the CIPE-Win32 driver by Damion K. Wilson.
*
* This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc.,
* and is released under the GPL version 2 (see below).
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program (see the file COPYING included with this
* distribution); if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MacInfoDefined
#define MacInfoDefined
//===================================================================================
// Macros
//===================================================================================
#define IsMacDelimiter(a) (a == ':' || a == '-' || a == '.')
#define IsHexDigit(c) ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'))
#define COPY_MAC(dest, src) NdisMoveMemory ((dest), (src), sizeof (MACADDR))
#define CLEAR_MAC(dest) NdisZeroMemory ((dest), sizeof (MACADDR))
#define MAC_EQUAL(a,b) (memcmp ((a), (b), sizeof (MACADDR)) == 0)
#endif

186
windows-tap/src/mem.c Executable file
View File

@ -0,0 +1,186 @@
/*
* TAP-Windows -- A kernel driver to provide virtual tap
* device functionality on Windows.
*
* This code was inspired by the CIPE-Win32 driver by Damion K. Wilson.
*
* This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc.,
* and is released under the GPL version 2 (see below).
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program (see the file COPYING included with this
* distribution); if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
//------------------
// Memory Management
//------------------
PVOID
MemAlloc (ULONG p_Size, BOOLEAN zero)
{
PVOID l_Return = NULL;
if (p_Size)
{
__try
{
if (NdisAllocateMemoryWithTag (&l_Return, p_Size, 'APAT')
== NDIS_STATUS_SUCCESS)
{
if (zero)
NdisZeroMemory (l_Return, p_Size);
}
else
l_Return = NULL;
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
l_Return = NULL;
}
}
return l_Return;
}
VOID
MemFree (PVOID p_Addr, ULONG p_Size)
{
if (p_Addr && p_Size)
{
__try
{
#if DBG
NdisZeroMemory (p_Addr, p_Size);
#endif
NdisFreeMemory (p_Addr, p_Size, 0);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
}
}
}
/*
* Circular queue management routines.
*/
#define QUEUE_BYTE_ALLOCATION(size) \
(sizeof (Queue) + (size * sizeof (PVOID)))
#define QUEUE_ADD_INDEX(var, inc) \
{ \
var += inc; \
if (var >= q->capacity) \
var -= q->capacity; \
MYASSERT (var < q->capacity); \
}
#define QUEUE_SANITY_CHECK() \
MYASSERT (q != NULL && q->base < q->capacity && q->size <= q->capacity)
#define QueueCount(q) (q->size)
#define UPDATE_MAX_SIZE() \
{ \
if (q->size > q->max_size) \
q->max_size = q->size; \
}
Queue *
QueueInit (ULONG capacity)
{
Queue *q;
MYASSERT (capacity > 0);
q = (Queue *) MemAlloc (QUEUE_BYTE_ALLOCATION (capacity), TRUE);
if (!q)
return NULL;
q->base = q->size = 0;
q->capacity = capacity;
q->max_size = 0;
return q;
}
VOID
QueueFree (Queue *q)
{
if (q)
{
QUEUE_SANITY_CHECK ();
MemFree (q, QUEUE_BYTE_ALLOCATION (q->capacity));
}
}
PVOID
QueuePush (Queue *q, PVOID item)
{
ULONG dest;
QUEUE_SANITY_CHECK ();
if (q->size == q->capacity)
return NULL;
dest = q->base;
QUEUE_ADD_INDEX (dest, q->size);
q->data[dest] = item;
++q->size;
UPDATE_MAX_SIZE();
return item;
}
PVOID
QueuePop (Queue *q)
{
ULONG oldbase;
QUEUE_SANITY_CHECK ();
if (!q->size)
return NULL;
oldbase = q->base;
QUEUE_ADD_INDEX (q->base, 1);
--q->size;
UPDATE_MAX_SIZE();
return q->data[oldbase];
}
PVOID
QueueExtract (Queue *q, PVOID item)
{
ULONG src, dest, count, n;
QUEUE_SANITY_CHECK ();
n = 0;
src = dest = q->base;
count = q->size;
while (count--)
{
if (item == q->data[src])
{
++n;
--q->size;
}
else
{
q->data[dest] = q->data[src];
QUEUE_ADD_INDEX (dest, 1);
}
QUEUE_ADD_INDEX (src, 1);
}
if (n)
return item;
else
return NULL;
}
#undef QUEUE_BYTE_ALLOCATION
#undef QUEUE_ADD_INDEX
#undef QUEUE_SANITY_CHECK
#undef UPDATE_MAX_SIZE

224
windows-tap/src/proto.h Executable file
View File

@ -0,0 +1,224 @@
/*
* TAP-Windows -- A kernel driver to provide virtual tap
* device functionality on Windows.
*
* This code was inspired by the CIPE-Win32 driver by Damion K. Wilson.
*
* This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc.,
* and is released under the GPL version 2 (see below).
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program (see the file COPYING included with this
* distribution); if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
//============================================================
// MAC address, Ethernet header, and ARP
//============================================================
#pragma pack(1)
#define IP_HEADER_SIZE 20
#define IPV6_HEADER_SIZE 40
typedef unsigned char MACADDR [6];
typedef unsigned long IPADDR;
typedef unsigned char IPV6ADDR [16];
//-----------------
// Ethernet address
//-----------------
typedef struct {
MACADDR addr;
} ETH_ADDR;
typedef struct {
ETH_ADDR list[NIC_MAX_MCAST_LIST];
} MC_LIST;
//----------------
// Ethernet header
//----------------
typedef struct
{
MACADDR dest; /* destination eth addr */
MACADDR src; /* source ether addr */
# define ETH_P_IP 0x0800 /* IPv4 protocol */
# define ETH_P_IPV6 0x86DD /* IPv6 protocol */
# define ETH_P_ARP 0x0806 /* ARP protocol */
USHORT proto; /* packet type ID field */
} ETH_HEADER, *PETH_HEADER;
//----------------
// ARP packet
//----------------
typedef struct
{
MACADDR m_MAC_Destination; // Reverse these two
MACADDR m_MAC_Source; // to answer ARP requests
USHORT m_Proto; // 0x0806
# define MAC_ADDR_TYPE 0x0001
USHORT m_MAC_AddressType; // 0x0001
USHORT m_PROTO_AddressType; // 0x0800
UCHAR m_MAC_AddressSize; // 0x06
UCHAR m_PROTO_AddressSize; // 0x04
# define ARP_REQUEST 0x0001
# define ARP_REPLY 0x0002
USHORT m_ARP_Operation; // 0x0001 for ARP request, 0x0002 for ARP reply
MACADDR m_ARP_MAC_Source;
IPADDR m_ARP_IP_Source;
MACADDR m_ARP_MAC_Destination;
IPADDR m_ARP_IP_Destination;
}
ARP_PACKET, *PARP_PACKET;
//----------
// IP Header
//----------
typedef struct {
# define IPH_GET_VER(v) (((v) >> 4) & 0x0F)
# define IPH_GET_LEN(v) (((v) & 0x0F) << 2)
UCHAR version_len;
UCHAR tos;
USHORT tot_len;
USHORT id;
# define IP_OFFMASK 0x1fff
USHORT frag_off;
UCHAR ttl;
# define IPPROTO_UDP 17 /* UDP protocol */
# define IPPROTO_TCP 6 /* TCP protocol */
# define IPPROTO_ICMP 1 /* ICMP protocol */
# define IPPROTO_IGMP 2 /* IGMP protocol */
UCHAR protocol;
USHORT check;
ULONG saddr;
ULONG daddr;
/* The options start here. */
} IPHDR;
//-----------
// UDP header
//-----------
typedef struct {
USHORT source;
USHORT dest;
USHORT len;
USHORT check;
} UDPHDR;
//--------------------------
// TCP header, per RFC 793.
//--------------------------
typedef struct {
USHORT source; /* source port */
USHORT dest; /* destination port */
ULONG seq; /* sequence number */
ULONG ack_seq; /* acknowledgement number */
# define TCPH_GET_DOFF(d) (((d) & 0xF0) >> 2)
UCHAR doff_res;
# define TCPH_FIN_MASK (1<<0)
# define TCPH_SYN_MASK (1<<1)
# define TCPH_RST_MASK (1<<2)
# define TCPH_PSH_MASK (1<<3)
# define TCPH_ACK_MASK (1<<4)
# define TCPH_URG_MASK (1<<5)
# define TCPH_ECE_MASK (1<<6)
# define TCPH_CWR_MASK (1<<7)
UCHAR flags;
USHORT window;
USHORT check;
USHORT urg_ptr;
} TCPHDR;
#define TCPOPT_EOL 0
#define TCPOPT_NOP 1
#define TCPOPT_MAXSEG 2
#define TCPOLEN_MAXSEG 4
//------------
// IPv6 Header
//------------
typedef struct {
UCHAR version_prio;
UCHAR flow_lbl[3];
USHORT payload_len;
# define IPPROTO_ICMPV6 0x3a /* ICMP protocol v6 */
UCHAR nexthdr;
UCHAR hop_limit;
IPV6ADDR saddr;
IPV6ADDR daddr;
} IPV6HDR;
//--------------------------------------------
// IPCMPv6 NS/NA Packets (RFC4443 and RFC4861)
//--------------------------------------------
// Neighbor Solictiation - RFC 4861, 4.3
// (this is just the ICMPv6 part of the packet)
typedef struct {
UCHAR type;
# define ICMPV6_TYPE_NS 135 // neighbour solicitation
UCHAR code;
# define ICMPV6_CODE_0 0 // no specific sub-code for NS/NA
USHORT checksum;
ULONG reserved;
IPV6ADDR target_addr;
} ICMPV6_NS;
// Neighbor Advertisement - RFC 4861, 4.4 + 4.6/4.6.1
// (this is just the ICMPv6 payload)
typedef struct {
UCHAR type;
# define ICMPV6_TYPE_NA 136 // neighbour advertisement
UCHAR code;
# define ICMPV6_CODE_0 0 // no specific sub-code for NS/NA
USHORT checksum;
UCHAR rso_bits; // Router(0), Solicited(2), Ovrrd(4)
UCHAR reserved[3];
IPV6ADDR target_addr;
// always include "Target Link-layer Address" option (RFC 4861 4.6.1)
UCHAR opt_type;
#define ICMPV6_OPTION_TLLA 2
UCHAR opt_length;
#define ICMPV6_LENGTH_TLLA 1 // multiplied by 8 -> 1 = 8 bytes
MACADDR target_macaddr;
} ICMPV6_NA;
// this is the complete packet with Ethernet and IPv6 headers
typedef struct {
ETH_HEADER eth;
IPV6HDR ipv6;
ICMPV6_NA icmpv6;
} ICMPV6_NA_PKT;
#pragma pack()

260
windows-tap/src/prototypes.h Executable file
View File

@ -0,0 +1,260 @@
/*
* TAP-Windows -- A kernel driver to provide virtual tap
* device functionality on Windows.
*
* This code was inspired by the CIPE-Win32 driver by Damion K. Wilson.
*
* This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc.,
* and is released under the GPL version 2 (see below).
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program (see the file COPYING included with this
* distribution); if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef TAP_PROTOTYPES_DEFINED
#define TAP_PROTOTYPES_DEFINED
NTSTATUS DriverEntry
(
IN PDRIVER_OBJECT p_DriverObject,
IN PUNICODE_STRING p_RegistryPath
);
VOID TapDriverUnload
(
IN PDRIVER_OBJECT p_DriverObject
);
NDIS_STATUS AdapterCreate
(
OUT PNDIS_STATUS p_ErrorStatus,
OUT PUINT p_MediaIndex,
IN PNDIS_MEDIUM p_Media,
IN UINT p_MediaCount,
IN NDIS_HANDLE p_AdapterHandle,
IN NDIS_HANDLE p_ConfigurationHandle
);
VOID AdapterHalt
(
IN NDIS_HANDLE p_AdapterContext
);
VOID AdapterFreeResources
(
TapAdapterPointer p_Adapter
);
NDIS_STATUS AdapterReset
(
OUT PBOOLEAN p_AddressingReset,
IN NDIS_HANDLE p_AdapterContext
);
NDIS_STATUS AdapterQuery
(
IN NDIS_HANDLE p_AdapterContext,
IN NDIS_OID p_OID,
IN PVOID p_Buffer,
IN ULONG p_BufferLength,
OUT PULONG p_BytesWritten,
OUT PULONG p_BytesNeeded
);
NDIS_STATUS AdapterModify
(
IN NDIS_HANDLE p_AdapterContext,
IN NDIS_OID p_OID,
IN PVOID p_Buffer,
IN ULONG p_BufferLength,
OUT PULONG p_BytesRead,
OUT PULONG p_BytesNeeded
);
NDIS_STATUS AdapterTransmit
(
IN NDIS_HANDLE p_AdapterContext,
IN PNDIS_PACKET p_Packet,
IN UINT p_Flags
);
NDIS_STATUS AdapterReceive
(
OUT PNDIS_PACKET p_Packet,
OUT PUINT p_Transferred,
IN NDIS_HANDLE p_AdapterContext,
IN NDIS_HANDLE p_ReceiveContext,
IN UINT p_Offset,
IN UINT p_ToTransfer
);
NTSTATUS TapDeviceHook
(
IN PDEVICE_OBJECT p_DeviceObject,
IN PIRP p_IRP
);
NDIS_STATUS CreateTapDevice
(
TapExtensionPointer p_Extension,
const char *p_Name
);
VOID DestroyTapDevice
(
TapExtensionPointer p_Extension
);
VOID TapDeviceFreeResources
(
TapExtensionPointer p_Extension
);
NTSTATUS CompleteIRP
(
IN PIRP p_IRP,
IN TapPacketPointer p_PacketBuffer,
IN CCHAR PriorityBoost
);
VOID CancelIRPCallback
(
IN PDEVICE_OBJECT p_DeviceObject,
IN PIRP p_IRP
);
VOID CancelIRP
(
TapExtensionPointer p_Extension,
IN PIRP p_IRP,
BOOLEAN callback
);
VOID FlushQueues
(
TapExtensionPointer p_Extension
);
VOID ResetTapAdapterState
(
TapAdapterPointer p_Adapter
);
BOOLEAN ProcessARP
(
TapAdapterPointer p_Adapter,
const PARP_PACKET src,
const IPADDR adapter_ip,
const IPADDR ip_network,
const IPADDR ip_netmask,
const MACADDR mac
);
VOID SetMediaStatus
(
TapAdapterPointer p_Adapter,
BOOLEAN state
);
VOID InjectPacketDeferred
(
TapAdapterPointer p_Adapter,
UCHAR *packet,
const unsigned int len
);
VOID InjectPacketNow
(
TapAdapterPointer p_Adapter,
UCHAR *packet,
const unsigned int len
);
// for KDEFERRED_ROUTINE and Static Driver Verifier
//#include <wdm.h>
//KDEFERRED_ROUTINE InjectPacketDpc;
VOID InjectPacketDpc
(
KDPC *Dpc,
PVOID DeferredContext,
PVOID SystemArgument1,
PVOID SystemArgument2
);
VOID CheckIfDhcpAndTunMode
(
TapAdapterPointer p_Adapter
);
VOID HookDispatchFunctions();
#if ENABLE_NONADMIN
#if defined(DDKVER_MAJOR) && DDKVER_MAJOR < 5600
/*
* Better solution for use on Vista DDK, but possibly not compatible with
* earlier DDKs:
*
* Eliminate the definition of SECURITY_DESCRIPTOR (and even ZwSetSecurityObject),
* and at the top of tapdrv.c change:
*
* #include <ndis.h>
* #include <ntstrsafe.h>
* #include <ntddk.h>
*
* To
*
* #include <ntifs.h>
* #include <ndis.h>
* #include <ntstrsafe.h>
*/
typedef struct _SECURITY_DESCRIPTOR {
unsigned char opaque[64];
} SECURITY_DESCRIPTOR;
NTSYSAPI
NTSTATUS
NTAPI
ZwSetSecurityObject (
IN HANDLE Handle,
IN SECURITY_INFORMATION SecurityInformation,
IN PSECURITY_DESCRIPTOR SecurityDescriptor);
#endif
VOID AllowNonAdmin (TapExtensionPointer p_Extension);
#endif
struct WIN2K_NDIS_MINIPORT_BLOCK
{
unsigned char opaque[16];
UNICODE_STRING MiniportName; // how mini-port refers to us
};
#if PACKET_TRUNCATION_CHECK
VOID IPv4PacketSizeVerify
(
const UCHAR *data,
ULONG length,
BOOLEAN tun,
const char *prefix,
LONG *counter
);
#endif
#endif

62
windows-tap/src/resource.rc Executable file
View File

@ -0,0 +1,62 @@
#include <windows.h>
#include <ntverp.h>
#include "config.h"
#undef VER_PRODUCTVERSION
#undef VER_PRODUCTVERSION_STR
#undef VER_COMPANYNAME_STR
#undef VER_PRODUCTNAME_STR
/* VER_FILETYPE, VER_FILESUBTYPE, VER_FILEDESCRIPTION_STR
* and VER_INTERNALNAME_STR must be defined before including COMMON.VER
* The strings don't need a '\0', since common.ver has them.
*/
#define VER_FILETYPE VFT_DRV
/* possible values: VFT_UNKNOWN
VFT_APP
VFT_DLL
VFT_DRV
VFT_FONT
VFT_VXD
VFT_STATIC_LIB
*/
#define VER_FILESUBTYPE VFT2_DRV_NETWORK
/* possible values VFT2_UNKNOWN
VFT2_DRV_PRINTER
VFT2_DRV_KEYBOARD
VFT2_DRV_LANGUAGE
VFT2_DRV_DISPLAY
VFT2_DRV_MOUSE
VFT2_DRV_NETWORK
VFT2_DRV_SYSTEM
VFT2_DRV_INSTALLABLE
VFT2_DRV_SOUND
VFT2_DRV_COMM
*/
#define VER_COMPANYNAME_STR "The OpenVPN Project"
#define VER_FILEDESCRIPTION_STR "TAP-Windows Virtual Network Driver"
#define VER_ORIGINALFILENAME_STR PRODUCT_TAP_WIN_COMPONENT_ID ".sys"
#define VER_LEGALCOPYRIGHT_YEARS "2003-2010"
#define VER_LEGALCOPYRIGHT_STR "OpenVPN Technologies, Inc."
#define VER_PRODUCTNAME_STR VER_FILEDESCRIPTION_STR
#define VER_PRODUCTVERSION PRODUCT_TAP_WIN_MAJOR,00,00,PRODUCT_TAP_WIN_MINOR
#define XSTR(s) STR(s)
#define STR(s) #s
#define VSTRING PRODUCT_VERSION " " XSTR(PRODUCT_TAP_WIN_MAJOR) "/" XSTR(PRODUCT_TAP_WIN_MINOR)
#ifdef DBG
#define VER_PRODUCTVERSION_STR VSTRING " (DEBUG)"
#else
#define VER_PRODUCTVERSION_STR VSTRING
#endif
#define VER_INTERNALNAME_STR VER_ORIGINALFILENAME_STR
#include "common.ver"

74
windows-tap/src/tap-windows.h Executable file
View File

@ -0,0 +1,74 @@
/*
* TAP-Windows -- A kernel driver to provide virtual tap
* device functionality on Windows.
*
* This code was inspired by the CIPE-Win32 driver by Damion K. Wilson.
*
* This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc.,
* and is released under the GPL version 2 (see below).
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program (see the file COPYING included with this
* distribution); if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __TAP_WIN_H
#define __TAP_WIN_H
/*
* =============
* TAP IOCTLs
* =============
*/
#define TAP_WIN_CONTROL_CODE(request,method) \
CTL_CODE (FILE_DEVICE_UNKNOWN, request, method, FILE_ANY_ACCESS)
/* Present in 8.1 */
#define TAP_WIN_IOCTL_GET_MAC TAP_WIN_CONTROL_CODE (1, METHOD_BUFFERED)
#define TAP_WIN_IOCTL_GET_VERSION TAP_WIN_CONTROL_CODE (2, METHOD_BUFFERED)
#define TAP_WIN_IOCTL_GET_MTU TAP_WIN_CONTROL_CODE (3, METHOD_BUFFERED)
#define TAP_WIN_IOCTL_GET_INFO TAP_WIN_CONTROL_CODE (4, METHOD_BUFFERED)
#define TAP_WIN_IOCTL_CONFIG_POINT_TO_POINT TAP_WIN_CONTROL_CODE (5, METHOD_BUFFERED)
#define TAP_WIN_IOCTL_SET_MEDIA_STATUS TAP_WIN_CONTROL_CODE (6, METHOD_BUFFERED)
#define TAP_WIN_IOCTL_CONFIG_DHCP_MASQ TAP_WIN_CONTROL_CODE (7, METHOD_BUFFERED)
#define TAP_WIN_IOCTL_GET_LOG_LINE TAP_WIN_CONTROL_CODE (8, METHOD_BUFFERED)
#define TAP_WIN_IOCTL_CONFIG_DHCP_SET_OPT TAP_WIN_CONTROL_CODE (9, METHOD_BUFFERED)
/* Added in 8.2 */
/* obsoletes TAP_WIN_IOCTL_CONFIG_POINT_TO_POINT */
#define TAP_WIN_IOCTL_CONFIG_TUN TAP_WIN_CONTROL_CODE (10, METHOD_BUFFERED)
/*
* =================
* Registry keys
* =================
*/
#define ADAPTER_KEY "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}"
#define NETWORK_CONNECTIONS_KEY "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}"
/*
* ======================
* Filesystem prefixes
* ======================
*/
#define USERMODEDEVICEDIR "\\\\.\\Global\\"
#define SYSDEVICEDIR "\\Device\\"
#define USERDEVICEDIR "\\DosDevices\\Global\\"
#define TAP_WIN_SUFFIX ".tap"
#endif

3147
windows-tap/src/tapdrvr.c Executable file

File diff suppressed because it is too large Load Diff

178
windows-tap/src/types.h Executable file
View File

@ -0,0 +1,178 @@
/*
* TAP-Windows -- A kernel driver to provide virtual tap
* device functionality on Windows.
*
* This code was inspired by the CIPE-Win32 driver by Damion K. Wilson.
*
* This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc.,
* and is released under the GPL version 2 (see below).
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program (see the file COPYING included with this
* distribution); if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef TAP_TYPES_DEFINED
#define TAP_TYPES_DEFINED
typedef struct _Queue
{
ULONG base;
ULONG size;
ULONG capacity;
ULONG max_size;
PVOID data[];
} Queue;
typedef struct _TapAdapter;
typedef struct _TapPacket;
typedef union _TapAdapterQuery
{
NDIS_HARDWARE_STATUS m_HardwareStatus;
NDIS_MEDIUM m_Medium;
NDIS_PHYSICAL_MEDIUM m_PhysicalMedium;
UCHAR m_MacAddress [6];
UCHAR m_Buffer [256];
ULONG m_Long;
USHORT m_Short;
UCHAR m_Byte;
}
TapAdapterQuery, *TapAdapterQueryPointer;
typedef struct _TapExtension
{
// TAP device object and packet queues
Queue *m_PacketQueue, *m_IrpQueue;
PDEVICE_OBJECT m_TapDevice;
NDIS_HANDLE m_TapDeviceHandle;
ULONG m_TapOpens;
// Used to lock packet queues
NDIS_SPIN_LOCK m_QueueLock;
BOOLEAN m_AllocatedSpinlocks;
// Used to bracket open/close
// state changes.
MUTEX m_OpenCloseMutex;
// True if device has been permanently halted
BOOLEAN m_Halt;
// TAP device name
unsigned char *m_TapName;
UNICODE_STRING m_UnicodeLinkName;
BOOLEAN m_CreatedUnicodeLinkName;
// Used for device status ioctl only
const char *m_LastErrorFilename;
int m_LastErrorLineNumber;
LONG m_NumTapOpens;
// Flags
BOOLEAN m_TapIsRunning;
BOOLEAN m_CalledTapDeviceFreeResources;
// DPC queue for deferred packet injection
BOOLEAN m_InjectDpcInitialized;
KDPC m_InjectDpc;
NDIS_SPIN_LOCK m_InjectLock;
Queue *m_InjectQueue;
}
TapExtension, *TapExtensionPointer;
typedef struct _TapPacket
{
# define TAP_PACKET_SIZE(data_size) (sizeof (TapPacket) + (data_size))
# define TP_TUN 0x80000000
# define TP_SIZE_MASK (~TP_TUN)
ULONG m_SizeFlags;
UCHAR m_Data []; // m_Data must be the last struct member
}
TapPacket, *TapPacketPointer;
typedef struct _InjectPacket
{
# define INJECT_PACKET_SIZE(data_size) (sizeof (InjectPacket) + (data_size))
# define INJECT_PACKET_FREE(ib) NdisFreeMemory ((ib), INJECT_PACKET_SIZE ((ib)->m_Size), 0)
ULONG m_Size;
UCHAR m_Data []; // m_Data must be the last struct member
}
InjectPacket, *InjectPacketPointer;
typedef struct _TapAdapter
{
# define NAME(a) ((a)->m_NameAnsi.Buffer)
ANSI_STRING m_NameAnsi;
MACADDR m_MAC;
BOOLEAN m_InterfaceIsRunning;
NDIS_HANDLE m_MiniportAdapterHandle;
LONG m_Rx, m_Tx, m_RxErr, m_TxErr;
#if PACKET_TRUNCATION_CHECK
LONG m_RxTrunc, m_TxTrunc;
#endif
NDIS_MEDIUM m_Medium;
ULONG m_Lookahead;
ULONG m_MTU;
// TRUE if adapter should always be
// "connected" even when device node
// is not open by a userspace process.
BOOLEAN m_MediaStateAlwaysConnected;
// TRUE if device is "connected"
BOOLEAN m_MediaState;
// Adapter power state
char m_DeviceState;
// Info for point-to-point mode
BOOLEAN m_tun;
IPADDR m_localIP;
IPADDR m_remoteNetwork;
IPADDR m_remoteNetmask;
ETH_HEADER m_TapToUser;
ETH_HEADER m_UserToTap;
ETH_HEADER m_UserToTap_IPv6; // same as UserToTap but proto=ipv6
MACADDR m_MAC_Broadcast;
// Used for DHCP server masquerade
BOOLEAN m_dhcp_enabled;
IPADDR m_dhcp_addr;
ULONG m_dhcp_netmask;
IPADDR m_dhcp_server_ip;
BOOLEAN m_dhcp_server_arp;
MACADDR m_dhcp_server_mac;
ULONG m_dhcp_lease_time;
UCHAR m_dhcp_user_supplied_options_buffer[DHCP_USER_SUPPLIED_OPTIONS_BUFFER_SIZE];
ULONG m_dhcp_user_supplied_options_buffer_len;
BOOLEAN m_dhcp_received_discover;
ULONG m_dhcp_bad_requests;
// Help to tear down the adapter by keeping
// some state information on allocated
// resources.
BOOLEAN m_CalledAdapterFreeResources;
BOOLEAN m_RegisteredAdapterShutdownHandler;
// Multicast list info
NDIS_SPIN_LOCK m_MCLock;
BOOLEAN m_MCLockAllocated;
ULONG m_MCListSize;
MC_LIST m_MCList;
// Information on the TAP device
TapExtension m_Extension;
} TapAdapter, *TapAdapterPointer;
#endif

11
windows-tap/version.m4 Normal file
View File

@ -0,0 +1,11 @@
dnl define the TAP version
define([PRODUCT_NAME], [TAP-Windows])
define([PRODUCT_VERSION], [9.9.2])
define([PRODUCT_VERSION_RESOURCE], [9,0,0,9])
define([PRODUCT_TAP_WIN_COMPONENT_ID], [tap0901])
define([PRODUCT_TAP_WIN_MAJOR], [9])
define([PRODUCT_TAP_WIN_MINOR], [9])
define([PRODUCT_TAP_WIN_PROVIDER], [TAP-Windows Provider V9])
define([PRODUCT_TAP_WIN_CHARACTERISTICS], [0x81])
define([PRODUCT_TAP_WIN_DEVICE_DESCRIPTION], [TAP-Windows Adapter V9])
define([PRODUCT_TAP_WIN_RELDATE], [07/02/2012])