├── .svncommitters ├── installer ├── icon.ico ├── install-whirl.bmp ├── build.bat └── tap-windows.nsi ├── .mailmap ├── .gitignore ├── src ├── MAKEFILE ├── config.h.in ├── endian.h ├── macinfo.h ├── resource.rc ├── hexdump.h ├── hexdump.c ├── constants.h ├── SOURCES.in ├── error.h ├── tap-windows.h ├── lock.h ├── macinfo.c ├── mem.c ├── dhcp.h ├── types.h ├── prototypes.h ├── instance.c ├── proto.h ├── OemWin2k.inf.in ├── error.c └── dhcp.c ├── version.m4 ├── config-env.bat.in ├── _build.bat ├── COPYING ├── configure.bat └── COPYRIGHT.GPL /.svncommitters: -------------------------------------------------------------------------------- 1 | james = James Yonan 2 | -------------------------------------------------------------------------------- /installer/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenVPN/tap-windows-old/HEAD/installer/icon.ico -------------------------------------------------------------------------------- /.mailmap: -------------------------------------------------------------------------------- 1 | James Yonan james 2 | -------------------------------------------------------------------------------- /installer/install-whirl.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenVPN/tap-windows-old/HEAD/installer/install-whirl.bmp -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.pdb 2 | *.sys 3 | *.map 4 | *.cat 5 | *.cod 6 | *.exe 7 | *.zip 8 | tmp 9 | config-local.m4 10 | config-env.bat 11 | src/obj* 12 | src/amd64 13 | src/i386 14 | src/SOURCES 15 | src/config.h 16 | -------------------------------------------------------------------------------- /src/MAKEFILE: -------------------------------------------------------------------------------- 1 | # 2 | # DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source 3 | # file to this component. This file merely indirects to the real make file 4 | # that is shared by all the components of NT OS/2 5 | # 6 | !INCLUDE $(NTMAKEENV)\makefile.def 7 | -------------------------------------------------------------------------------- /version.m4: -------------------------------------------------------------------------------- 1 | dnl define the TAP version 2 | define([PRODUCT_NAME], [TAP-Windows]) 3 | define([PRODUCT_VERSION], [9.9.0_master]) 4 | define([PRODUCT_VERSION_RESOURCE], [9,0,0,9]) 5 | define([PRODUCT_TAP_WIN_COMPONENT_ID], [tap0901]) 6 | define([PRODUCT_TAP_WIN_MAJOR], [9]) 7 | define([PRODUCT_TAP_WIN_MINOR], [9]) 8 | define([PRODUCT_TAP_WIN_PROVIDER], [TAP-Windows Provider V9]) 9 | define([PRODUCT_TAP_WIN_CHARACTERISTICS], [0x81]) 10 | define([PRODUCT_TAP_WIN_DEVICE_DESCRIPTION], [TAP-Windows Adapter V9]) 11 | define([PRODUCT_TAP_WIN_RELDATE], [04/19/2010]) 12 | -------------------------------------------------------------------------------- /config-env.bat.in: -------------------------------------------------------------------------------- 1 | set DDK=@DDK@ 2 | set DEVCON32=@DEVCON32@ 3 | set DEVCON64=@DEVCON64@ 4 | set DEVCON_BASENAME=@DEVCON_BASENAME@ 5 | set SIGNTOOL=@SIGNTOOL@ 6 | set MAKENSIS=@MAKENSIS@ 7 | set CODESIGN_PKCS12=@CODESIGN_PKCS12@ 8 | set CODESIGN_PASS=@CODESIGN_PASS@ 9 | set CODESIGN_CROSS=@CODESIGN_CROSS@ 10 | set CODESIGN_TIMESTAMP=@CODESIGN_TIMESTAMP@ 11 | set CODESIGN_ISTEST=@CODESIGN_ISTEST@ 12 | set PRODUCT_TAP_WIN_COMPONENT_ID=@PRODUCT_TAP_WIN_COMPONENT_ID@ 13 | set PRODUCT_NAME=@PRODUCT_NAME@ 14 | set PRODUCT_VERSION=@PRODUCT_VERSION@ 15 | set OUTDIR=@OUTDIR@ 16 | -------------------------------------------------------------------------------- /src/config.h.in: -------------------------------------------------------------------------------- 1 | #define PRODUCT_NAME "@PRODUCT_NAME@" 2 | #define PRODUCT_VERSION "@PRODUCT_VERSION@" 3 | #define PRODUCT_VERSION_RESOURCE @PRODUCT_VERSION_RESOURCE@ 4 | #define PRODUCT_TAP_WIN_COMPONENT_ID "@PRODUCT_TAP_WIN_COMPONENT_ID@" 5 | #define PRODUCT_TAP_WIN_MAJOR @PRODUCT_TAP_WIN_MAJOR@ 6 | #define PRODUCT_TAP_WIN_MINOR @PRODUCT_TAP_WIN_MINOR@ 7 | #define PRODUCT_TAP_WIN_PROVIDER "@PRODUCT_TAP_WIN_PROVIDER@" 8 | #define PRODUCT_TAP_WIN_DEVICE_DESCRIPTION "@PRODUCT_TAP_WIN_DEVICE_DESCRIPTION@" 9 | #define PRODUCT_TAP_WIN_RELDATE "@PRODUCT_TAP_WIN_RELDATE@" 10 | -------------------------------------------------------------------------------- /src/endian.h: -------------------------------------------------------------------------------- 1 | /* 2 | * TAP-Windows -- A kernel driver to provide virtual tap 3 | * device functionality on Windows. 4 | * 5 | * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. 6 | * 7 | * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., 8 | * and is released under the GPL version 2 (see below). 9 | * 10 | * This program is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License version 2 12 | * as published by the Free Software Foundation. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program (see the file COPYING included with this 21 | * distribution); if not, write to the Free Software Foundation, Inc., 22 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23 | */ 24 | 25 | #ifdef TAP_LITTLE_ENDIAN 26 | #define ntohs(x) RtlUshortByteSwap(x) 27 | #define htons(x) RtlUshortByteSwap(x) 28 | #define ntohl(x) RtlUlongByteSwap(x) 29 | #define htonl(x) RtlUlongByteSwap(x) 30 | #else 31 | #define ntohs(x) ((USHORT)(x)) 32 | #define htons(x) ((USHORT)(x)) 33 | #define ntohl(x) ((ULONG)(x)) 34 | #define htonl(x) ((ULONG)(x)) 35 | #endif 36 | -------------------------------------------------------------------------------- /_build.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | rem TAP-Windows -- A kernel driver to provide virtual tap 3 | rem device functionality on Windows. 4 | rem 5 | rem Copyright (C) 2012 Alon Bar-Lev 6 | rem 7 | rem This program is free software; you can redistribute it and/or modify 8 | rem it under the terms of the GNU General Public License as published by 9 | rem the Free Software Foundation; either version 2 of the License, or 10 | rem (at your option) any later version. 11 | rem 12 | rem This program is distributed in the hope that it will be useful, 13 | rem but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | rem MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | rem GNU General Public License for more details. 16 | rem 17 | rem You should have received a copy of the GNU General Public License 18 | rem along with this program (see the file COPYING included with this 19 | rem distribution); if not, write to the Free Software Foundation, Inc., 20 | rem 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 | 22 | setlocal enableextensions enabledelayedexpansion 23 | 24 | set root=%cd% 25 | set myos=%1 26 | set myprofile=%2 27 | set mymode=fre 28 | 29 | echo Building %myos%-%myprofile%-%mymode% 30 | 31 | call "%DDK%\bin\setenv" %DDK% %mymode% %myprofile% %myos% no_oacr 32 | if errorlevel 1 goto error 33 | 34 | cd /d %root% 35 | cd src 36 | nmake 37 | if errorlevel 1 goto error 38 | 39 | set rc=0 40 | goto end 41 | 42 | :error 43 | echo FAIL %myos%-%myprofile%-%mymode% 44 | set rc=1 45 | goto end 46 | 47 | :end 48 | 49 | endlocal 50 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | TAP-Win32/TAP-Win64 Driver license: 2 | ----------------------------------- 3 | 4 | This device driver was inspired by the CIPE-Win32 driver by 5 | Damion K. Wilson. 6 | 7 | The source and object code of the TAP-Win32/TAP-Win64 driver 8 | is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., and is released under 9 | the GPL version 2. 10 | 11 | NSIS License: 12 | ------------- 13 | 14 | Copyright (C) 2002-2003 Joost Verburg 15 | 16 | This software is provided 'as-is', without any express or implied 17 | warranty. In no event will the authors be held liable for any damages 18 | arising from the use of this software. 19 | 20 | Permission is granted to anyone to use this software for any purpose, 21 | including commercial applications, and to alter it and redistribute 22 | it freely, subject to the following restrictions: 23 | 24 | 1. The origin of this software must not be misrepresented; 25 | you must not claim that you wrote the original software. 26 | If you use this software in a product, an acknowledgment in the 27 | product documentation would be appreciated but is not required. 28 | 2. Altered versions must be plainly marked as such, 29 | and must not be misrepresented as being the original software. 30 | 3. This notice may not be removed or altered from any distribution. 31 | 32 | GNU Public License (GPL) 33 | ------------------------ 34 | 35 | TAP-Win32 distributions are licensed under the GPL version 2 (see 36 | COPYRIGHT.GPL). 37 | 38 | In the Windows binary distribution of OpenVPN, the 39 | GPL is reproduced below. 40 | 41 | -------------------------------------------------------------------------------- /src/macinfo.h: -------------------------------------------------------------------------------- 1 | /* 2 | * TAP-Windows -- A kernel driver to provide virtual tap 3 | * device functionality on Windows. 4 | * 5 | * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. 6 | * 7 | * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., 8 | * and is released under the GPL version 2 (see below). 9 | * 10 | * This program is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License version 2 12 | * as published by the Free Software Foundation. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program (see the file COPYING included with this 21 | * distribution); if not, write to the Free Software Foundation, Inc., 22 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23 | */ 24 | 25 | #ifndef MacInfoDefined 26 | #define MacInfoDefined 27 | 28 | //=================================================================================== 29 | // Macros 30 | //=================================================================================== 31 | #define IsMacDelimiter(a) (a == ':' || a == '-' || a == '.') 32 | #define IsHexDigit(c) ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f')) 33 | 34 | #define COPY_MAC(dest, src) NdisMoveMemory ((dest), (src), sizeof (MACADDR)) 35 | #define CLEAR_MAC(dest) NdisZeroMemory ((dest), sizeof (MACADDR)) 36 | #define MAC_EQUAL(a,b) (memcmp ((a), (b), sizeof (MACADDR)) == 0) 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /src/resource.rc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "config.h" 5 | 6 | #undef VER_PRODUCTVERSION 7 | #undef VER_PRODUCTVERSION_STR 8 | #undef VER_COMPANYNAME_STR 9 | #undef VER_PRODUCTNAME_STR 10 | 11 | /* VER_FILETYPE, VER_FILESUBTYPE, VER_FILEDESCRIPTION_STR 12 | * and VER_INTERNALNAME_STR must be defined before including COMMON.VER 13 | * The strings don't need a '\0', since common.ver has them. 14 | */ 15 | 16 | #define VER_FILETYPE VFT_DRV 17 | /* possible values: VFT_UNKNOWN 18 | VFT_APP 19 | VFT_DLL 20 | VFT_DRV 21 | VFT_FONT 22 | VFT_VXD 23 | VFT_STATIC_LIB 24 | */ 25 | #define VER_FILESUBTYPE VFT2_DRV_NETWORK 26 | /* possible values VFT2_UNKNOWN 27 | VFT2_DRV_PRINTER 28 | VFT2_DRV_KEYBOARD 29 | VFT2_DRV_LANGUAGE 30 | VFT2_DRV_DISPLAY 31 | VFT2_DRV_MOUSE 32 | VFT2_DRV_NETWORK 33 | VFT2_DRV_SYSTEM 34 | VFT2_DRV_INSTALLABLE 35 | VFT2_DRV_SOUND 36 | VFT2_DRV_COMM 37 | */ 38 | 39 | #define VER_COMPANYNAME_STR "The OpenVPN Project" 40 | #define VER_FILEDESCRIPTION_STR "TAP-Windows Virtual Network Driver" 41 | #define VER_ORIGINALFILENAME_STR PRODUCT_TAP_WIN_COMPONENT_ID ".sys" 42 | #define VER_LEGALCOPYRIGHT_YEARS "2003-2010" 43 | #define VER_LEGALCOPYRIGHT_STR "OpenVPN Technologies, Inc." 44 | 45 | 46 | #define VER_PRODUCTNAME_STR VER_FILEDESCRIPTION_STR 47 | #define VER_PRODUCTVERSION PRODUCT_TAP_WIN_MAJOR,00,00,PRODUCT_TAP_WIN_MINOR 48 | 49 | #define XSTR(s) STR(s) 50 | #define STR(s) #s 51 | 52 | #define VSTRING PRODUCT_VERSION " " XSTR(PRODUCT_TAP_WIN_MAJOR) "/" XSTR(PRODUCT_TAP_WIN_MINOR) 53 | 54 | #ifdef DBG 55 | #define VER_PRODUCTVERSION_STR VSTRING " (DEBUG)" 56 | #else 57 | #define VER_PRODUCTVERSION_STR VSTRING 58 | #endif 59 | 60 | #define VER_INTERNALNAME_STR VER_ORIGINALFILENAME_STR 61 | 62 | #include "common.ver" 63 | -------------------------------------------------------------------------------- /src/hexdump.h: -------------------------------------------------------------------------------- 1 | /* 2 | * TAP-Windows -- A kernel driver to provide virtual tap 3 | * device functionality on Windows. 4 | * 5 | * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. 6 | * 7 | * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., 8 | * and is released under the GPL version 2 (see below). 9 | * 10 | * This program is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License version 2 12 | * as published by the Free Software Foundation. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program (see the file COPYING included with this 21 | * distribution); if not, write to the Free Software Foundation, Inc., 22 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23 | */ 24 | 25 | #ifndef HEXDUMP_DEFINED 26 | #define HEXDUMP_DEFINED 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif 31 | 32 | //===================================================================================== 33 | // Debug Routines 34 | //===================================================================================== 35 | 36 | #ifndef NDIS_MINIPORT_DRIVER 37 | # include 38 | # include 39 | # include 40 | # include 41 | # include 42 | 43 | # ifndef DEBUGP 44 | # define DEBUGP(fmt) { DbgMessage fmt; } 45 | # endif 46 | 47 | extern VOID (*DbgMessage)(char *p_Format, ...); 48 | 49 | VOID DisplayDebugString (char *p_Format, ...); 50 | #endif 51 | 52 | //=================================================================================== 53 | // Reporting / Debugging 54 | //=================================================================================== 55 | #define IfPrint(c) (c >= 32 && c < 127 ? c : '.') 56 | 57 | VOID HexDump (unsigned char *p_Buffer, unsigned long p_Size); 58 | 59 | #ifdef __cplusplus 60 | } 61 | #endif 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /src/hexdump.c: -------------------------------------------------------------------------------- 1 | /* 2 | * TAP-Windows -- A kernel driver to provide virtual tap 3 | * device functionality on Windows. 4 | * 5 | * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. 6 | * 7 | * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., 8 | * and is released under the GPL version 2 (see below). 9 | * 10 | * This program is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License version 2 12 | * as published by the Free Software Foundation. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program (see the file COPYING included with this 21 | * distribution); if not, write to the Free Software Foundation, Inc., 22 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23 | */ 24 | 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | 29 | #include "hexdump.h" 30 | 31 | #ifndef NDIS_MINIPORT_DRIVER 32 | 33 | VOID (*DbgMessage)(char *p_Format, ...) = DisplayDebugString; 34 | 35 | VOID DisplayDebugString (char *p_Format, ...) 36 | { 37 | static char l_Buffer [4096]; 38 | 39 | va_list l_ArgumentList; 40 | va_start (l_ArgumentList, p_Format); 41 | vsprintf (l_Buffer, p_Format, l_ArgumentList); 42 | va_end (l_ArgumentList); 43 | 44 | OutputDebugStringA (l_Buffer); 45 | } 46 | 47 | #endif 48 | 49 | VOID HexDump (unsigned char *p_Buffer, unsigned long p_Size) 50 | { 51 | unsigned long l_Index, l_Idx; 52 | unsigned char l_Row [17]; 53 | 54 | for (l_Index = l_Row [16] = 0; l_Index < p_Size || l_Index % 16; ++l_Index) 55 | { 56 | if (l_Index % 16 == 0) 57 | DEBUGP (("%05x ", l_Index)); 58 | DEBUGP (("%02x ", l_Row [l_Index % 16] = (l_Index < p_Size ? p_Buffer [l_Index] : 0))); 59 | l_Row [l_Index % 16] = IfPrint (l_Row [l_Index % 16]); 60 | if ((l_Index + 1) % 16 == 0) 61 | DEBUGP ((" %s\n", l_Row)); 62 | } 63 | 64 | DEBUGP (("\n")); 65 | } 66 | 67 | #ifdef __cplusplus 68 | } 69 | #endif 70 | -------------------------------------------------------------------------------- /src/constants.h: -------------------------------------------------------------------------------- 1 | /* 2 | * TAP-Windows -- A kernel driver to provide virtual tap 3 | * device functionality on Windows. 4 | * 5 | * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. 6 | * 7 | * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., 8 | * and is released under the GPL version 2 (see below). 9 | * 10 | * This program is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License version 2 12 | * as published by the Free Software Foundation. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program (see the file COPYING included with this 21 | * distribution); if not, write to the Free Software Foundation, Inc., 22 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23 | */ 24 | 25 | //==================================================================== 26 | // Product and Version public settings 27 | //==================================================================== 28 | 29 | #define PRODUCT_STRING PRODUCT_TAP_DEVICE_DESCRIPTION 30 | 31 | #define TAP_NDIS_MAJOR_VERSION 5 32 | #define TAP_NDIS_MINOR_VERSION 0 33 | 34 | //=========================================================== 35 | // Driver constants 36 | //=========================================================== 37 | 38 | #define ETHERNET_HEADER_SIZE (sizeof (ETH_HEADER)) 39 | #define ETHERNET_MTU 1500 40 | #define ETHERNET_PACKET_SIZE (ETHERNET_MTU + ETHERNET_HEADER_SIZE) 41 | #define DEFAULT_PACKET_LOOKAHEAD (ETHERNET_PACKET_SIZE) 42 | 43 | #define NIC_MAX_MCAST_LIST 32 // Max length of multicast address list 44 | 45 | #define MINIMUM_MTU 576 // USE TCP Minimum MTU 46 | #define MAXIMUM_MTU 65536 // IP maximum MTU 47 | 48 | #define PACKET_QUEUE_SIZE 64 // tap -> userspace queue size 49 | #define IRP_QUEUE_SIZE 16 // max number of simultaneous i/o operations from userspace 50 | #define INJECT_QUEUE_SIZE 16 // DHCP/ARP -> tap injection queue 51 | 52 | #define TAP_LITTLE_ENDIAN // affects ntohs, htonl, etc. functions 53 | -------------------------------------------------------------------------------- /src/SOURCES.in: -------------------------------------------------------------------------------- 1 | # Build TAP-Windows driver. 2 | # Build Command: build -cef 3 | 4 | MAJORCOMP=ntos 5 | MINORCOMP=ndis 6 | 7 | TARGETNAME=@PRODUCT_TAP_WIN_COMPONENT_ID@ 8 | TARGETTYPE=DRIVER 9 | TARGETPATH=. 10 | TARGETLIBS=$(DDK_LIB_PATH)\ndis.lib $(DDK_LIB_PATH)\ntstrsafe.lib 11 | INCLUDES=$(DDK_INCLUDE_PATH) .. 12 | 13 | # The TAP version numbers here must be >= 14 | # PRODUCT_TAP_WIN32_MIN_x values defined in version.m4 15 | C_DEFINES= 16 | C_DEFINES=$(C_DEFINES) @EXTRA_C_DEFINES@ 17 | C_DEFINES=$(C_DEFINES) -DTAP_DRIVER_MAJOR_VERSION=@PRODUCT_TAP_WIN_MAJOR@ 18 | C_DEFINES=$(C_DEFINES) -DTAP_DRIVER_MINOR_VERSION=@PRODUCT_TAP_WIN_MINOR@ 19 | 20 | # Produce the same symbolic information for both free & checked builds. 21 | # This will allow us to perform full source-level debugging on both 22 | # builds without affecting the free build's performance. 23 | !IF "$(DDKBUILDENV)" != "chk" 24 | NTDEBUGTYPE=both 25 | USE_PDB=1 26 | !ELSE 27 | NTDEBUGTYPE=both 28 | USE_PDB=1 29 | !ENDIF 30 | 31 | # Set compiler optimizations: 32 | # /Ox - Full optimization enabled 33 | # /Os - favor speed over size when optimizing 34 | # /Od - Disable all optimizations 35 | # /Oi - Enable optimization for intrinsic functions 36 | # /Fc - Generate mixed assembler/source code files 37 | # 38 | # For both checked and free builds, make sure that any intrinsic 39 | # functions are compiled correctly. To do this, ensure that /Oi 40 | # is selected for both free and checked builds. There is a bug in 41 | # VC++ 6.0 (at least through SP4) where, if you specify any 42 | # intrinsic functions in your code with "#pragma intrinsic" but 43 | # you don't have the /Oi optimization enabled, neither a call 44 | # to the function, nor the intrinsic inline version of the function 45 | # will end up in your object code. This bug only applies to free 46 | # builds, but just to be safe we'll make sure that the flag is 47 | # enabled for all builds. 48 | 49 | !IF "$(DDKBUILDENV)" != "chk" 50 | MSC_OPTIMIZATION=/Ox /Oi /Fc 51 | !ELSE 52 | MSC_OPTIMIZATION=/Od /Oi /Fc 53 | !ENDIF 54 | 55 | # Generate a linker map file just in case we need one for debugging 56 | LINKER_FLAGS=$(LINKER_FLAGS) /INCREMENTAL:NO /MAP /MAPINFO:EXPORTS 57 | 58 | # Generate a browser information file for use in IDE development 59 | #BROWSER_INFO=1 60 | #BROWSERFILE=$(TARGETNAME).BSC -n 61 | 62 | # Abort compilation on warnings by adding /WX 63 | MSC_WARNING_LEVEL=/W3 64 | 65 | SOURCES=tapdrvr.c resource.rc 66 | -------------------------------------------------------------------------------- /src/error.h: -------------------------------------------------------------------------------- 1 | /* 2 | * TAP-Windows -- A kernel driver to provide virtual tap 3 | * device functionality on Windows. 4 | * 5 | * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. 6 | * 7 | * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., 8 | * and is released under the GPL version 2 (see below). 9 | * 10 | * This program is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License version 2 12 | * as published by the Free Software Foundation. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program (see the file COPYING included with this 21 | * distribution); if not, write to the Free Software Foundation, Inc., 22 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23 | */ 24 | 25 | //----------------- 26 | // DEBUGGING OUTPUT 27 | //----------------- 28 | 29 | #define NOTE_ERROR() \ 30 | { \ 31 | g_LastErrorFilename = __FILE__; \ 32 | g_LastErrorLineNumber = __LINE__; \ 33 | } 34 | 35 | #if DBG 36 | 37 | typedef struct { 38 | unsigned int in; 39 | unsigned int out; 40 | unsigned int capacity; 41 | char *text; 42 | BOOLEAN error; 43 | MUTEX lock; 44 | } DebugOutput; 45 | 46 | VOID MyDebugPrint (const unsigned char* format, ...); 47 | 48 | VOID MyAssert (const unsigned char *file, int line); 49 | 50 | VOID DumpPacket (const char *prefix, 51 | const unsigned char *data, 52 | unsigned int len); 53 | 54 | VOID DumpPacket2 (const char *prefix, 55 | const ETH_HEADER *eth, 56 | const unsigned char *data, 57 | unsigned int len); 58 | 59 | #define CAN_WE_PRINT (DEBUGP_AT_DISPATCH || KeGetCurrentIrql () < DISPATCH_LEVEL) 60 | 61 | #if ALSO_DBGPRINT 62 | #define DEBUGP(fmt) { MyDebugPrint fmt; if (CAN_WE_PRINT) DbgPrint fmt; } 63 | #else 64 | #define DEBUGP(fmt) { MyDebugPrint fmt; } 65 | #endif 66 | 67 | #define MYASSERT(exp) \ 68 | { \ 69 | if (!(exp)) \ 70 | { \ 71 | MyAssert(__FILE__, __LINE__); \ 72 | } \ 73 | } 74 | 75 | #define DUMP_PACKET(prefix, data, len) \ 76 | DumpPacket (prefix, data, len) 77 | 78 | #define DUMP_PACKET2(prefix, eth, data, len) \ 79 | DumpPacket2 (prefix, eth, data, len) 80 | 81 | #else 82 | 83 | #define DEBUGP(fmt) 84 | #define MYASSERT(exp) 85 | #define DUMP_PACKET(prefix, data, len) 86 | #define DUMP_PACKET2(prefix, eth, data, len) 87 | 88 | #endif 89 | -------------------------------------------------------------------------------- /src/tap-windows.h: -------------------------------------------------------------------------------- 1 | /* 2 | * TAP-Windows -- A kernel driver to provide virtual tap 3 | * device functionality on Windows. 4 | * 5 | * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. 6 | * 7 | * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., 8 | * and is released under the GPL version 2 (see below). 9 | * 10 | * This program is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License version 2 12 | * as published by the Free Software Foundation. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program (see the file COPYING included with this 21 | * distribution); if not, write to the Free Software Foundation, Inc., 22 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23 | */ 24 | #ifndef __TAP_WIN_H 25 | #define __TAP_WIN_H 26 | 27 | /* 28 | * ============= 29 | * TAP IOCTLs 30 | * ============= 31 | */ 32 | 33 | #define TAP_WIN_CONTROL_CODE(request,method) \ 34 | CTL_CODE (FILE_DEVICE_UNKNOWN, request, method, FILE_ANY_ACCESS) 35 | 36 | /* Present in 8.1 */ 37 | 38 | #define TAP_WIN_IOCTL_GET_MAC TAP_WIN_CONTROL_CODE (1, METHOD_BUFFERED) 39 | #define TAP_WIN_IOCTL_GET_VERSION TAP_WIN_CONTROL_CODE (2, METHOD_BUFFERED) 40 | #define TAP_WIN_IOCTL_GET_MTU TAP_WIN_CONTROL_CODE (3, METHOD_BUFFERED) 41 | #define TAP_WIN_IOCTL_GET_INFO TAP_WIN_CONTROL_CODE (4, METHOD_BUFFERED) 42 | #define TAP_WIN_IOCTL_CONFIG_POINT_TO_POINT TAP_WIN_CONTROL_CODE (5, METHOD_BUFFERED) 43 | #define TAP_WIN_IOCTL_SET_MEDIA_STATUS TAP_WIN_CONTROL_CODE (6, METHOD_BUFFERED) 44 | #define TAP_WIN_IOCTL_CONFIG_DHCP_MASQ TAP_WIN_CONTROL_CODE (7, METHOD_BUFFERED) 45 | #define TAP_WIN_IOCTL_GET_LOG_LINE TAP_WIN_CONTROL_CODE (8, METHOD_BUFFERED) 46 | #define TAP_WIN_IOCTL_CONFIG_DHCP_SET_OPT TAP_WIN_CONTROL_CODE (9, METHOD_BUFFERED) 47 | 48 | /* Added in 8.2 */ 49 | 50 | /* obsoletes TAP_WIN_IOCTL_CONFIG_POINT_TO_POINT */ 51 | #define TAP_WIN_IOCTL_CONFIG_TUN TAP_WIN_CONTROL_CODE (10, METHOD_BUFFERED) 52 | 53 | /* 54 | * ================= 55 | * Registry keys 56 | * ================= 57 | */ 58 | 59 | #define ADAPTER_KEY "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}" 60 | 61 | #define NETWORK_CONNECTIONS_KEY "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}" 62 | 63 | /* 64 | * ====================== 65 | * Filesystem prefixes 66 | * ====================== 67 | */ 68 | 69 | #define USERMODEDEVICEDIR "\\\\.\\Global\\" 70 | #define SYSDEVICEDIR "\\Device\\" 71 | #define USERDEVICEDIR "\\DosDevices\\Global\\" 72 | #define TAP_WIN_SUFFIX ".tap" 73 | 74 | #endif 75 | -------------------------------------------------------------------------------- /installer/build.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | rem TAP-Windows -- A kernel driver to provide virtual tap 3 | rem device functionality on Windows. 4 | rem 5 | rem Copyright (C) 2012 Alon Bar-Lev 6 | rem 7 | rem This program is free software; you can redistribute it and/or modify 8 | rem it under the terms of the GNU General Public License as published by 9 | rem the Free Software Foundation; either version 2 of the License, or 10 | rem (at your option) any later version. 11 | rem 12 | rem This program is distributed in the hope that it will be useful, 13 | rem but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | rem MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | rem GNU General Public License for more details. 16 | rem 17 | rem You should have received a copy of the GNU General Public License 18 | rem along with this program (see the file COPYING included with this 19 | rem distribution); if not, write to the Free Software Foundation, Inc., 20 | rem 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 | 22 | setlocal 23 | 24 | set wd=%cd% 25 | cd %0\.. 26 | 27 | if "%MAKENSIS%"=="" call ..\config-env.bat 28 | 29 | if "%OUTDIR%"=="" set OUTDIR=. 30 | set OUTPUT=%OUTDIR%\tap-windows-%PRODUCT_VERSION% 31 | set TAP_ROOT=tmp\image\tap-windows-%PRODUCT_VERSION% 32 | 33 | set SIGNTOOL_CMD="%SIGNTOOL%" sign /v /p "%CODESIGN_PASS%" /f "%CODESIGN_PKCS12%" 34 | set SIGNTOOL_CMD_DRIVERS=%SIGNTOOL_CMD% 35 | if "%CODESIGN_ISTEST%" NEQ "yes" ( 36 | set SIGNTOOL_CMD=%SIGNTOOL_CMD% /t "%CODESIGN_TIMESTAMP%" 37 | set SIGNTOOL_CMD_DRIVERS=%SIGNTOOL_CMD% /ac "%CODESIGN_CROSS%" 38 | ) 39 | 40 | del "%OUTPUT%.*" > nul 2>&1 41 | rmdir /q /s tmp > nul 2>&1 42 | 43 | mkdir %TAP_ROOT%\include 44 | copy ..\src\tap-windows.h %TAP_ROOT%\include 45 | if errorlevel 1 goto error 46 | mkdir %TAP_ROOT%\i386 47 | copy ..\src\i386\* %TAP_ROOT%\i386 48 | if errorlevel 1 goto error 49 | mkdir %TAP_ROOT%\amd64 50 | copy ..\src\amd64\* %TAP_ROOT%\amd64 51 | if errorlevel 1 goto error 52 | 53 | type ..\COPYING > %TAP_ROOT%\license.txt 54 | type ..\COPYRIGHT.GPL >> %TAP_ROOT%\license.txt 55 | cscript //nologo ..\build\unix2dos.js %TAP_ROOT%\license.txt 56 | if errorlevel 1 goto error 57 | 58 | "%DDK%\bin\selfsign\inf2cat" /driver:%TAP_ROOT%\i386 /os:XP_X86,Vista_X86,7_X86,Server2003_X86,Server2008_X86 59 | "%DDK%\bin\selfsign\inf2cat" /driver:%TAP_ROOT%\amd64 /os:XP_X64,Vista_X64,7_X64,Server2003_X64,Server2008_X64,Server2008R2_X64 60 | 61 | if not "%CODESIGN_PKCS12%"=="" ( 62 | for %%a in (i386 amd64) do ( 63 | %SIGNTOOL_CMD_DRIVERS% "%TAP_ROOT%\%%a\%PRODUCT_TAP_WIN_COMPONENT_ID%.sys" 64 | if errorlevel 1 goto error 65 | %SIGNTOOL_CMD_DRIVERS% "%TAP_ROOT%\%%a\%PRODUCT_TAP_WIN_COMPONENT_ID%.cat" 66 | if errorlevel 1 goto error 67 | ) 68 | ) 69 | 70 | cscript //nologo ..\build\zip.js tmp\image "%OUTPUT%.zip" 71 | if errorlevel 1 goto error 72 | 73 | "%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 74 | if errorlevel 1 goto error 75 | 76 | if not "%CODESIGN_PKCS12%"=="" ( 77 | %SIGNTOOL_CMD% "%OUTPUT%.exe" 78 | if errorlevel 1 goto error 79 | ) 80 | 81 | set rc=0 82 | goto end 83 | 84 | :error 85 | echo FATAL 86 | set rc=1 87 | goto end 88 | 89 | :end 90 | 91 | cd %wd% 92 | 93 | endlocal 94 | 95 | exit /b %rc% 96 | -------------------------------------------------------------------------------- /src/lock.h: -------------------------------------------------------------------------------- 1 | /* 2 | * TAP-Windows -- A kernel driver to provide virtual tap 3 | * device functionality on Windows. 4 | * 5 | * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. 6 | * 7 | * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., 8 | * and is released under the GPL version 2 (see below). 9 | * 10 | * This program is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License version 2 12 | * as published by the Free Software Foundation. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program (see the file COPYING included with this 21 | * distribution); if not, write to the Free Software Foundation, Inc., 22 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23 | */ 24 | 25 | typedef struct 26 | { 27 | volatile long count; 28 | } MUTEX; 29 | 30 | #define MUTEX_SLEEP_TIME 10000 // microseconds 31 | 32 | #define INIT_MUTEX(m) { (m)->count = 0; } 33 | 34 | #define ACQUIRE_MUTEX_BLOCKING(m) \ 35 | { \ 36 | while (NdisInterlockedIncrement (&((m)->count)) != 1) \ 37 | { \ 38 | NdisInterlockedDecrement(&((m)->count)); \ 39 | NdisMSleep(MUTEX_SLEEP_TIME); \ 40 | } \ 41 | } 42 | 43 | #define RELEASE_MUTEX(m) \ 44 | { \ 45 | NdisInterlockedDecrement(&((m)->count)); \ 46 | } 47 | 48 | #define ACQUIRE_MUTEX_NONBLOCKING(m, result) \ 49 | { \ 50 | if (NdisInterlockedIncrement (&((m)->count)) != 1) \ 51 | { \ 52 | NdisInterlockedDecrement(&((m)->count)); \ 53 | result = FALSE; \ 54 | } \ 55 | else \ 56 | { \ 57 | result = TRUE; \ 58 | } \ 59 | } 60 | 61 | #define ACQUIRE_MUTEX_ADAPTIVE(m, result) \ 62 | { \ 63 | result = TRUE; \ 64 | while (NdisInterlockedIncrement (&((m)->count)) != 1) \ 65 | { \ 66 | NdisInterlockedDecrement(&((m)->count)); \ 67 | if (KeGetCurrentIrql () < DISPATCH_LEVEL) \ 68 | NdisMSleep(MUTEX_SLEEP_TIME); \ 69 | else \ 70 | { \ 71 | result = FALSE; \ 72 | break; \ 73 | } \ 74 | } \ 75 | } 76 | -------------------------------------------------------------------------------- /configure.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | rem TAP-Windows -- A kernel driver to provide virtual tap 3 | rem device functionality on Windows. 4 | rem 5 | rem Copyright (C) 2012 Alon Bar-Lev 6 | rem 7 | rem This program is free software; you can redistribute it and/or modify 8 | rem it under the terms of the GNU General Public License as published by 9 | rem the Free Software Foundation; either version 2 of the License, or 10 | rem (at your option) any later version. 11 | rem 12 | rem This program is distributed in the hope that it will be useful, 13 | rem but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | rem MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | rem GNU General Public License for more details. 16 | rem 17 | rem You should have received a copy of the GNU General Public License 18 | rem along with this program (see the file COPYING included with this 19 | rem distribution); if not, write to the Free Software Foundation, Inc., 20 | rem 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 | 22 | cd /d %0\.. 23 | 24 | if "%1"=="--help" ( 25 | echo %0 26 | echo Environment: 27 | echo DDK DDK home 28 | echo SIGNTOOL signtool, default from DDK 29 | echo DEVCON32 devcon, default from DDK 30 | echo DEVCON64 devcon, default from DDK 31 | echo MAKENSIS nullsoft installer 32 | echo CODESIGN_PKCS12 Code sign PKCS#12 optional 33 | echo CODESIGN_PASS Code sign password 34 | echo CODESIGN_CROSS Cross certificate to be used 35 | echo CODESIGN_TIMESTAMP Timestamp URL 36 | echo CODESIGN_ISTEST If yes, use test certificate 37 | echo OUTDIR Output directory 38 | exit /b 1 39 | ) 40 | 41 | setlocal 42 | 43 | if "%DDK%"=="" for /d %%f in (c:\WINDDK\*) do set DDK=%%f 44 | 45 | if "%DDK%"=="" ( 46 | echo cannot find ddk 47 | goto error 48 | ) 49 | 50 | if "%SIGNTOOL%"=="" set SIGNTOOL=%DDK%\bin\x86\signtool.exe 51 | if "%DEVCON32%"=="" set DEVCON32=%DDK%\tools\devcon\i386\devcon.exe 52 | if "%DEVCON64%"=="" set DEVCON64=%DDK%\tools\devcon\amd64\devcon.exe 53 | for /f %%f in ("%DEVCON32%") do set DEVCON_BASENAME=%%~nf%%~xf 54 | 55 | if "%MAKENSIS%"=="" for /d %%f in ("%ProgramFiles%\NSIS" "%ProgramFiles(x86)%\NSIS") do if exist "%%f" set MAKENSIS=%%~f 56 | 57 | if "%MAKENSIS%"=="" ( 58 | echo cannot find nsis 59 | goto error 60 | ) 61 | 62 | if "%CODESIGN_CROSS%"=="" set CODESIGN_CROSS=%cd%\build\MSCV-VSClass3.cer 63 | if "%CODESIGN_TIMESTAMP%"=="" set CODESIGN_TIMESTAMP=http://timestamp.verisign.com/scripts/timestamp.dll 64 | 65 | if "%OUTDIR%"=="" set OUTDIR=%cd% 66 | 67 | set msvcg_args=cscript //nologo build/msvc-generate.js --config=version.m4 68 | if exist config-local.m4 set msvcg_args=%msvcg_args% --config=config-local.m4 69 | 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%" 70 | 71 | for %%f in (config-env.bat src\SOURCES src\config.h) do ( 72 | %msvcg_args% --input=%%f.in --output=%%f 73 | if errorlevel 1 goto error 74 | ) 75 | 76 | for %%a in (i386 amd64) do ( 77 | mkdir src\%%a > nul 2>&1 78 | %msvcg_args% --config=build\vars.%%a.m4 --input=src\OemWin2k.inf.in --output=src\%%a\OemWin2k.inf 79 | if errorlevel 1 goto error 80 | ) 81 | 82 | set rc=0 83 | goto end 84 | 85 | :error 86 | echo FAILED 87 | set rc=1 88 | goto end 89 | 90 | :end 91 | 92 | endlocal 93 | 94 | exit /b %rc% 95 | -------------------------------------------------------------------------------- /src/macinfo.c: -------------------------------------------------------------------------------- 1 | /* 2 | * TAP-Windows -- A kernel driver to provide virtual tap 3 | * device functionality on Windows. 4 | * 5 | * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. 6 | * 7 | * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., 8 | * and is released under the GPL version 2 (see below). 9 | * 10 | * This program is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License version 2 12 | * as published by the Free Software Foundation. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program (see the file COPYING included with this 21 | * distribution); if not, write to the Free Software Foundation, Inc., 22 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23 | */ 24 | 25 | #include "macinfo.h" 26 | 27 | int 28 | HexStringToDecimalInt (const int p_Character) 29 | { 30 | int l_Value = 0; 31 | 32 | if (p_Character >= 'A' && p_Character <= 'F') 33 | l_Value = (p_Character - 'A') + 10; 34 | else if (p_Character >= 'a' && p_Character <= 'f') 35 | l_Value = (p_Character - 'a') + 10; 36 | else if (p_Character >= '0' && p_Character <= '9') 37 | l_Value = p_Character - '0'; 38 | 39 | return l_Value; 40 | } 41 | 42 | BOOLEAN 43 | ParseMAC (MACADDR dest, const char *src) 44 | { 45 | int c; 46 | int mac_index = 0; 47 | BOOLEAN high_digit = FALSE; 48 | int delim_action = 1; 49 | 50 | MYASSERT (src); 51 | MYASSERT (dest); 52 | 53 | CLEAR_MAC (dest); 54 | 55 | while (c = *src++) 56 | { 57 | if (IsMacDelimiter (c)) 58 | { 59 | mac_index += delim_action; 60 | high_digit = FALSE; 61 | delim_action = 1; 62 | } 63 | else if (IsHexDigit (c)) 64 | { 65 | const int digit = HexStringToDecimalInt (c); 66 | if (mac_index < sizeof (MACADDR)) 67 | { 68 | if (!high_digit) 69 | { 70 | dest[mac_index] = (char)(digit); 71 | high_digit = TRUE; 72 | delim_action = 1; 73 | } 74 | else 75 | { 76 | dest[mac_index] = (char)(dest[mac_index] * 16 + digit); 77 | ++mac_index; 78 | high_digit = FALSE; 79 | delim_action = 0; 80 | } 81 | } 82 | else 83 | return FALSE; 84 | } 85 | else 86 | return FALSE; 87 | } 88 | 89 | return (mac_index + delim_action) >= sizeof (MACADDR); 90 | } 91 | 92 | /* 93 | * Generate a MAC using the GUID in the adapter name. 94 | * 95 | * The mac is constructed as 00:FF:xx:xx:xx:xx where 96 | * the Xs are taken from the first 32 bits of the GUID in the 97 | * adapter name. This is similar to the Linux 2.4 tap MAC 98 | * generator, except linux uses 32 random bits for the Xs. 99 | * 100 | * In general, this solution is reasonable for most 101 | * applications except for very large bridged TAP networks, 102 | * where the probability of address collisions becomes more 103 | * than infintesimal. 104 | * 105 | * Using the well-known "birthday paradox", on a 1000 node 106 | * network the probability of collision would be 107 | * 0.000116292153. On a 10,000 node network, the probability 108 | * of collision would be 0.01157288998621678766. 109 | */ 110 | 111 | VOID GenerateRandomMac (MACADDR mac, const unsigned char *adapter_name) 112 | { 113 | unsigned const char *cp = adapter_name; 114 | unsigned char c; 115 | unsigned int i = 2; 116 | unsigned int byte = 0; 117 | int brace = 0; 118 | int state = 0; 119 | 120 | CLEAR_MAC (mac); 121 | 122 | mac[0] = 0x00; 123 | mac[1] = 0xFF; 124 | 125 | while (c = *cp++) 126 | { 127 | if (i >= sizeof (MACADDR)) 128 | break; 129 | if (c == '{') 130 | brace = 1; 131 | if (IsHexDigit (c) && brace) 132 | { 133 | const unsigned int digit = HexStringToDecimalInt (c); 134 | if (state) 135 | { 136 | byte <<= 4; 137 | byte |= digit; 138 | mac[i++] = (unsigned char) byte; 139 | state = 0; 140 | } 141 | else 142 | { 143 | byte = digit; 144 | state = 1; 145 | } 146 | } 147 | } 148 | } 149 | 150 | VOID GenerateRelatedMAC (MACADDR dest, const MACADDR src, const int delta) 151 | { 152 | COPY_MAC (dest, src); 153 | dest[2] += (UCHAR) delta; 154 | } 155 | -------------------------------------------------------------------------------- /src/mem.c: -------------------------------------------------------------------------------- 1 | /* 2 | * TAP-Windows -- A kernel driver to provide virtual tap 3 | * device functionality on Windows. 4 | * 5 | * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. 6 | * 7 | * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., 8 | * and is released under the GPL version 2 (see below). 9 | * 10 | * This program is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License version 2 12 | * as published by the Free Software Foundation. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program (see the file COPYING included with this 21 | * distribution); if not, write to the Free Software Foundation, Inc., 22 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23 | */ 24 | 25 | //------------------ 26 | // Memory Management 27 | //------------------ 28 | 29 | PVOID 30 | MemAlloc (ULONG p_Size, BOOLEAN zero) 31 | { 32 | PVOID l_Return = NULL; 33 | 34 | if (p_Size) 35 | { 36 | __try 37 | { 38 | if (NdisAllocateMemoryWithTag (&l_Return, p_Size, 'APAT') 39 | == NDIS_STATUS_SUCCESS) 40 | { 41 | if (zero) 42 | NdisZeroMemory (l_Return, p_Size); 43 | } 44 | else 45 | l_Return = NULL; 46 | } 47 | __except (EXCEPTION_EXECUTE_HANDLER) 48 | { 49 | l_Return = NULL; 50 | } 51 | } 52 | 53 | return l_Return; 54 | } 55 | 56 | VOID 57 | MemFree (PVOID p_Addr, ULONG p_Size) 58 | { 59 | if (p_Addr && p_Size) 60 | { 61 | __try 62 | { 63 | #if DBG 64 | NdisZeroMemory (p_Addr, p_Size); 65 | #endif 66 | NdisFreeMemory (p_Addr, p_Size, 0); 67 | } 68 | __except (EXCEPTION_EXECUTE_HANDLER) 69 | { 70 | } 71 | } 72 | } 73 | 74 | /* 75 | * Circular queue management routines. 76 | */ 77 | 78 | #define QUEUE_BYTE_ALLOCATION(size) \ 79 | (sizeof (Queue) + (size * sizeof (PVOID))) 80 | 81 | #define QUEUE_ADD_INDEX(var, inc) \ 82 | { \ 83 | var += inc; \ 84 | if (var >= q->capacity) \ 85 | var -= q->capacity; \ 86 | MYASSERT (var < q->capacity); \ 87 | } 88 | 89 | #define QUEUE_SANITY_CHECK() \ 90 | MYASSERT (q != NULL && q->base < q->capacity && q->size <= q->capacity) 91 | 92 | #define QueueCount(q) (q->size) 93 | 94 | #define UPDATE_MAX_SIZE() \ 95 | { \ 96 | if (q->size > q->max_size) \ 97 | q->max_size = q->size; \ 98 | } 99 | 100 | Queue * 101 | QueueInit (ULONG capacity) 102 | { 103 | Queue *q; 104 | 105 | MYASSERT (capacity > 0); 106 | q = (Queue *) MemAlloc (QUEUE_BYTE_ALLOCATION (capacity), TRUE); 107 | if (!q) 108 | return NULL; 109 | 110 | q->base = q->size = 0; 111 | q->capacity = capacity; 112 | q->max_size = 0; 113 | return q; 114 | } 115 | 116 | VOID 117 | QueueFree (Queue *q) 118 | { 119 | if (q) 120 | { 121 | QUEUE_SANITY_CHECK (); 122 | MemFree (q, QUEUE_BYTE_ALLOCATION (q->capacity)); 123 | } 124 | } 125 | 126 | PVOID 127 | QueuePush (Queue *q, PVOID item) 128 | { 129 | ULONG dest; 130 | QUEUE_SANITY_CHECK (); 131 | if (q->size == q->capacity) 132 | return NULL; 133 | dest = q->base; 134 | QUEUE_ADD_INDEX (dest, q->size); 135 | q->data[dest] = item; 136 | ++q->size; 137 | UPDATE_MAX_SIZE(); 138 | return item; 139 | } 140 | 141 | PVOID 142 | QueuePop (Queue *q) 143 | { 144 | ULONG oldbase; 145 | QUEUE_SANITY_CHECK (); 146 | if (!q->size) 147 | return NULL; 148 | oldbase = q->base; 149 | QUEUE_ADD_INDEX (q->base, 1); 150 | --q->size; 151 | UPDATE_MAX_SIZE(); 152 | return q->data[oldbase]; 153 | } 154 | 155 | PVOID 156 | QueueExtract (Queue *q, PVOID item) 157 | { 158 | ULONG src, dest, count, n; 159 | QUEUE_SANITY_CHECK (); 160 | n = 0; 161 | src = dest = q->base; 162 | count = q->size; 163 | while (count--) 164 | { 165 | if (item == q->data[src]) 166 | { 167 | ++n; 168 | --q->size; 169 | } 170 | else 171 | { 172 | q->data[dest] = q->data[src]; 173 | QUEUE_ADD_INDEX (dest, 1); 174 | } 175 | QUEUE_ADD_INDEX (src, 1); 176 | } 177 | if (n) 178 | return item; 179 | else 180 | return NULL; 181 | } 182 | 183 | #undef QUEUE_BYTE_ALLOCATION 184 | #undef QUEUE_ADD_INDEX 185 | #undef QUEUE_SANITY_CHECK 186 | #undef UPDATE_MAX_SIZE 187 | -------------------------------------------------------------------------------- /src/dhcp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * TAP-Windows -- A kernel driver to provide virtual tap 3 | * device functionality on Windows. 4 | * 5 | * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. 6 | * 7 | * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., 8 | * and is released under the GPL version 2 (see below). 9 | * 10 | * This program is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License version 2 12 | * as published by the Free Software Foundation. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program (see the file COPYING included with this 21 | * distribution); if not, write to the Free Software Foundation, Inc., 22 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23 | */ 24 | 25 | #pragma pack(1) 26 | 27 | //=================================================== 28 | // How many bad DHCPREQUESTs do we receive before we 29 | // return a NAK? 30 | // 31 | // A bad DHCPREQUEST is defined to be one where the 32 | // requestor doesn't know its IP address. 33 | //=================================================== 34 | 35 | #define BAD_DHCPREQUEST_NAK_THRESHOLD 3 36 | 37 | //============================================== 38 | // Maximum number of DHCP options bytes supplied 39 | //============================================== 40 | 41 | #define DHCP_USER_SUPPLIED_OPTIONS_BUFFER_SIZE 256 42 | #define DHCP_OPTIONS_BUFFER_SIZE 256 43 | 44 | //=================================== 45 | // UDP port numbers of DHCP messages. 46 | //=================================== 47 | 48 | #define BOOTPS_PORT 67 49 | #define BOOTPC_PORT 68 50 | 51 | //=========================== 52 | // The DHCP message structure 53 | //=========================== 54 | 55 | typedef struct { 56 | # define BOOTREQUEST 1 57 | # define BOOTREPLY 2 58 | UCHAR op; /* message op */ 59 | 60 | UCHAR htype; /* hardware address type (e.g. '1' = 10Mb Ethernet) */ 61 | UCHAR hlen; /* hardware address length (e.g. '6' for 10Mb Ethernet) */ 62 | UCHAR hops; /* client sets to 0, may be used by relay agents */ 63 | ULONG xid; /* transaction ID, chosen by client */ 64 | USHORT secs; /* seconds since request process began, set by client */ 65 | USHORT flags; 66 | ULONG ciaddr; /* client IP address, client sets if known */ 67 | ULONG yiaddr; /* 'your' IP address -- server's response to client */ 68 | ULONG siaddr; /* server IP address */ 69 | ULONG giaddr; /* relay agent IP address */ 70 | UCHAR chaddr[16]; /* client hardware address */ 71 | UCHAR sname[64]; /* optional server host name */ 72 | UCHAR file[128]; /* boot file name */ 73 | ULONG magic; /* must be 0x63825363 (network order) */ 74 | } DHCP; 75 | 76 | typedef struct { 77 | ETH_HEADER eth; 78 | IPHDR ip; 79 | UDPHDR udp; 80 | DHCP dhcp; 81 | } DHCPPre; 82 | 83 | typedef struct { 84 | DHCPPre pre; 85 | UCHAR options[DHCP_OPTIONS_BUFFER_SIZE]; 86 | } DHCPFull; 87 | 88 | typedef struct { 89 | unsigned int optlen; 90 | BOOLEAN overflow; 91 | DHCPFull msg; 92 | } DHCPMsg; 93 | 94 | //=================== 95 | // Macros for DHCPMSG 96 | //=================== 97 | 98 | #define DHCPMSG_LEN_BASE(p) (sizeof (DHCPPre)) 99 | #define DHCPMSG_LEN_OPT(p) ((p)->optlen) 100 | #define DHCPMSG_LEN_FULL(p) (DHCPMSG_LEN_BASE(p) + DHCPMSG_LEN_OPT(p)) 101 | #define DHCPMSG_BUF(p) ((UCHAR*) &(p)->msg) 102 | #define DHCPMSG_OVERFLOW(p) ((p)->overflow) 103 | 104 | //======================================== 105 | // structs to hold individual DHCP options 106 | //======================================== 107 | 108 | typedef struct { 109 | UCHAR type; 110 | } DHCPOPT0; 111 | 112 | typedef struct { 113 | UCHAR type; 114 | UCHAR len; 115 | UCHAR data; 116 | } DHCPOPT8; 117 | 118 | typedef struct { 119 | UCHAR type; 120 | UCHAR len; 121 | ULONG data; 122 | } DHCPOPT32; 123 | 124 | #pragma pack() 125 | 126 | //================== 127 | // DHCP Option types 128 | //================== 129 | 130 | #define DHCP_MSG_TYPE 53 /* message type (u8) */ 131 | #define DHCP_PARM_REQ 55 /* parameter request list: c1 (u8), ... */ 132 | #define DHCP_CLIENT_ID 61 /* client ID: type (u8), i1 (u8), ... */ 133 | #define DHCP_IP 50 /* requested IP addr (u32) */ 134 | #define DHCP_NETMASK 1 /* subnet mask (u32) */ 135 | #define DHCP_LEASE_TIME 51 /* lease time sec (u32) */ 136 | #define DHCP_RENEW_TIME 58 /* renewal time sec (u32) */ 137 | #define DHCP_REBIND_TIME 59 /* rebind time sec (u32) */ 138 | #define DHCP_SERVER_ID 54 /* server ID: IP addr (u32) */ 139 | #define DHCP_PAD 0 140 | #define DHCP_END 255 141 | 142 | //==================== 143 | // DHCP Messages types 144 | //==================== 145 | 146 | #define DHCPDISCOVER 1 147 | #define DHCPOFFER 2 148 | #define DHCPREQUEST 3 149 | #define DHCPDECLINE 4 150 | #define DHCPACK 5 151 | #define DHCPNAK 6 152 | #define DHCPRELEASE 7 153 | #define DHCPINFORM 8 154 | 155 | #if DBG 156 | 157 | VOID 158 | DumpDHCP (const ETH_HEADER *eth, 159 | const IPHDR *ip, 160 | const UDPHDR *udp, 161 | const DHCP *dhcp, 162 | const int optlen); 163 | 164 | #endif 165 | -------------------------------------------------------------------------------- /src/types.h: -------------------------------------------------------------------------------- 1 | /* 2 | * TAP-Windows -- A kernel driver to provide virtual tap 3 | * device functionality on Windows. 4 | * 5 | * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. 6 | * 7 | * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., 8 | * and is released under the GPL version 2 (see below). 9 | * 10 | * This program is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License version 2 12 | * as published by the Free Software Foundation. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program (see the file COPYING included with this 21 | * distribution); if not, write to the Free Software Foundation, Inc., 22 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23 | */ 24 | 25 | #ifndef TAP_TYPES_DEFINED 26 | #define TAP_TYPES_DEFINED 27 | 28 | typedef struct _Queue 29 | { 30 | ULONG base; 31 | ULONG size; 32 | ULONG capacity; 33 | ULONG max_size; 34 | PVOID data[]; 35 | } Queue; 36 | 37 | typedef struct _TapAdapter; 38 | typedef struct _TapPacket; 39 | 40 | typedef union _TapAdapterQuery 41 | { 42 | NDIS_HARDWARE_STATUS m_HardwareStatus; 43 | NDIS_MEDIUM m_Medium; 44 | NDIS_PHYSICAL_MEDIUM m_PhysicalMedium; 45 | UCHAR m_MacAddress [6]; 46 | UCHAR m_Buffer [256]; 47 | ULONG m_Long; 48 | USHORT m_Short; 49 | UCHAR m_Byte; 50 | } 51 | TapAdapterQuery, *TapAdapterQueryPointer; 52 | 53 | typedef struct _TapExtension 54 | { 55 | // TAP device object and packet queues 56 | Queue *m_PacketQueue, *m_IrpQueue; 57 | PDEVICE_OBJECT m_TapDevice; 58 | NDIS_HANDLE m_TapDeviceHandle; 59 | ULONG m_TapOpens; 60 | 61 | // Used to lock packet queues 62 | NDIS_SPIN_LOCK m_QueueLock; 63 | BOOLEAN m_AllocatedSpinlocks; 64 | 65 | // Used to bracket open/close 66 | // state changes. 67 | MUTEX m_OpenCloseMutex; 68 | 69 | // True if device has been permanently halted 70 | BOOLEAN m_Halt; 71 | 72 | // TAP device name 73 | unsigned char *m_TapName; 74 | UNICODE_STRING m_UnicodeLinkName; 75 | BOOLEAN m_CreatedUnicodeLinkName; 76 | 77 | // Used for device status ioctl only 78 | const char *m_LastErrorFilename; 79 | int m_LastErrorLineNumber; 80 | LONG m_NumTapOpens; 81 | 82 | // Flags 83 | BOOLEAN m_TapIsRunning; 84 | BOOLEAN m_CalledTapDeviceFreeResources; 85 | 86 | // DPC queue for deferred packet injection 87 | BOOLEAN m_InjectDpcInitialized; 88 | KDPC m_InjectDpc; 89 | NDIS_SPIN_LOCK m_InjectLock; 90 | Queue *m_InjectQueue; 91 | } 92 | TapExtension, *TapExtensionPointer; 93 | 94 | typedef struct _TapPacket 95 | { 96 | # define TAP_PACKET_SIZE(data_size) (sizeof (TapPacket) + (data_size)) 97 | # define TP_TUN 0x80000000 98 | # define TP_SIZE_MASK (~TP_TUN) 99 | ULONG m_SizeFlags; 100 | UCHAR m_Data []; // m_Data must be the last struct member 101 | } 102 | TapPacket, *TapPacketPointer; 103 | 104 | typedef struct _InjectPacket 105 | { 106 | # define INJECT_PACKET_SIZE(data_size) (sizeof (InjectPacket) + (data_size)) 107 | # define INJECT_PACKET_FREE(ib) NdisFreeMemory ((ib), INJECT_PACKET_SIZE ((ib)->m_Size), 0) 108 | ULONG m_Size; 109 | UCHAR m_Data []; // m_Data must be the last struct member 110 | } 111 | InjectPacket, *InjectPacketPointer; 112 | 113 | typedef struct _TapAdapter 114 | { 115 | # define NAME(a) ((a)->m_NameAnsi.Buffer) 116 | ANSI_STRING m_NameAnsi; 117 | MACADDR m_MAC; 118 | BOOLEAN m_InterfaceIsRunning; 119 | NDIS_HANDLE m_MiniportAdapterHandle; 120 | LONG m_Rx, m_Tx, m_RxErr, m_TxErr; 121 | #if PACKET_TRUNCATION_CHECK 122 | LONG m_RxTrunc, m_TxTrunc; 123 | #endif 124 | NDIS_MEDIUM m_Medium; 125 | ULONG m_Lookahead; 126 | ULONG m_MTU; 127 | 128 | // TRUE if adapter should always be 129 | // "connected" even when device node 130 | // is not open by a userspace process. 131 | BOOLEAN m_MediaStateAlwaysConnected; 132 | 133 | // TRUE if device is "connected" 134 | BOOLEAN m_MediaState; 135 | 136 | // Adapter power state 137 | char m_DeviceState; 138 | 139 | // Info for point-to-point mode 140 | BOOLEAN m_tun; 141 | IPADDR m_localIP; 142 | IPADDR m_remoteNetwork; 143 | IPADDR m_remoteNetmask; 144 | ETH_HEADER m_TapToUser; 145 | ETH_HEADER m_UserToTap; 146 | ETH_HEADER m_UserToTap_IPv6; // same as UserToTap but proto=ipv6 147 | MACADDR m_MAC_Broadcast; 148 | 149 | // Used for DHCP server masquerade 150 | BOOLEAN m_dhcp_enabled; 151 | IPADDR m_dhcp_addr; 152 | ULONG m_dhcp_netmask; 153 | IPADDR m_dhcp_server_ip; 154 | BOOLEAN m_dhcp_server_arp; 155 | MACADDR m_dhcp_server_mac; 156 | ULONG m_dhcp_lease_time; 157 | UCHAR m_dhcp_user_supplied_options_buffer[DHCP_USER_SUPPLIED_OPTIONS_BUFFER_SIZE]; 158 | ULONG m_dhcp_user_supplied_options_buffer_len; 159 | BOOLEAN m_dhcp_received_discover; 160 | ULONG m_dhcp_bad_requests; 161 | 162 | // Help to tear down the adapter by keeping 163 | // some state information on allocated 164 | // resources. 165 | BOOLEAN m_CalledAdapterFreeResources; 166 | BOOLEAN m_RegisteredAdapterShutdownHandler; 167 | 168 | // Multicast list info 169 | NDIS_SPIN_LOCK m_MCLock; 170 | BOOLEAN m_MCLockAllocated; 171 | ULONG m_MCListSize; 172 | MC_LIST m_MCList; 173 | 174 | // Information on the TAP device 175 | TapExtension m_Extension; 176 | } TapAdapter, *TapAdapterPointer; 177 | 178 | #endif 179 | -------------------------------------------------------------------------------- /src/prototypes.h: -------------------------------------------------------------------------------- 1 | /* 2 | * TAP-Windows -- A kernel driver to provide virtual tap 3 | * device functionality on Windows. 4 | * 5 | * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. 6 | * 7 | * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., 8 | * and is released under the GPL version 2 (see below). 9 | * 10 | * This program is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License version 2 12 | * as published by the Free Software Foundation. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program (see the file COPYING included with this 21 | * distribution); if not, write to the Free Software Foundation, Inc., 22 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23 | */ 24 | 25 | #ifndef TAP_PROTOTYPES_DEFINED 26 | #define TAP_PROTOTYPES_DEFINED 27 | 28 | NTSTATUS DriverEntry 29 | ( 30 | IN PDRIVER_OBJECT p_DriverObject, 31 | IN PUNICODE_STRING p_RegistryPath 32 | ); 33 | 34 | VOID TapDriverUnload 35 | ( 36 | IN PDRIVER_OBJECT p_DriverObject 37 | ); 38 | 39 | NDIS_STATUS AdapterCreate 40 | ( 41 | OUT PNDIS_STATUS p_ErrorStatus, 42 | OUT PUINT p_MediaIndex, 43 | IN PNDIS_MEDIUM p_Media, 44 | IN UINT p_MediaCount, 45 | IN NDIS_HANDLE p_AdapterHandle, 46 | IN NDIS_HANDLE p_ConfigurationHandle 47 | ); 48 | 49 | VOID AdapterHalt 50 | ( 51 | IN NDIS_HANDLE p_AdapterContext 52 | ); 53 | 54 | VOID AdapterFreeResources 55 | ( 56 | TapAdapterPointer p_Adapter 57 | ); 58 | 59 | NDIS_STATUS AdapterReset 60 | ( 61 | OUT PBOOLEAN p_AddressingReset, 62 | IN NDIS_HANDLE p_AdapterContext 63 | ); 64 | 65 | NDIS_STATUS AdapterQuery 66 | ( 67 | IN NDIS_HANDLE p_AdapterContext, 68 | IN NDIS_OID p_OID, 69 | IN PVOID p_Buffer, 70 | IN ULONG p_BufferLength, 71 | OUT PULONG p_BytesWritten, 72 | OUT PULONG p_BytesNeeded 73 | ); 74 | 75 | NDIS_STATUS AdapterModify 76 | ( 77 | IN NDIS_HANDLE p_AdapterContext, 78 | IN NDIS_OID p_OID, 79 | IN PVOID p_Buffer, 80 | IN ULONG p_BufferLength, 81 | OUT PULONG p_BytesRead, 82 | OUT PULONG p_BytesNeeded 83 | ); 84 | 85 | NDIS_STATUS AdapterTransmit 86 | ( 87 | IN NDIS_HANDLE p_AdapterContext, 88 | IN PNDIS_PACKET p_Packet, 89 | IN UINT p_Flags 90 | ); 91 | 92 | NDIS_STATUS AdapterReceive 93 | ( 94 | OUT PNDIS_PACKET p_Packet, 95 | OUT PUINT p_Transferred, 96 | IN NDIS_HANDLE p_AdapterContext, 97 | IN NDIS_HANDLE p_ReceiveContext, 98 | IN UINT p_Offset, 99 | IN UINT p_ToTransfer 100 | ); 101 | 102 | NTSTATUS TapDeviceHook 103 | ( 104 | IN PDEVICE_OBJECT p_DeviceObject, 105 | IN PIRP p_IRP 106 | ); 107 | 108 | NDIS_STATUS CreateTapDevice 109 | ( 110 | TapExtensionPointer p_Extension, 111 | const char *p_Name 112 | ); 113 | 114 | VOID DestroyTapDevice 115 | ( 116 | TapExtensionPointer p_Extension 117 | ); 118 | 119 | VOID TapDeviceFreeResources 120 | ( 121 | TapExtensionPointer p_Extension 122 | ); 123 | 124 | NTSTATUS CompleteIRP 125 | ( 126 | IN PIRP p_IRP, 127 | IN TapPacketPointer p_PacketBuffer, 128 | IN CCHAR PriorityBoost 129 | ); 130 | 131 | VOID CancelIRPCallback 132 | ( 133 | IN PDEVICE_OBJECT p_DeviceObject, 134 | IN PIRP p_IRP 135 | ); 136 | 137 | VOID CancelIRP 138 | ( 139 | TapExtensionPointer p_Extension, 140 | IN PIRP p_IRP, 141 | BOOLEAN callback 142 | ); 143 | 144 | VOID FlushQueues 145 | ( 146 | TapExtensionPointer p_Extension 147 | ); 148 | 149 | VOID ResetTapAdapterState 150 | ( 151 | TapAdapterPointer p_Adapter 152 | ); 153 | 154 | BOOLEAN ProcessARP 155 | ( 156 | TapAdapterPointer p_Adapter, 157 | const PARP_PACKET src, 158 | const IPADDR adapter_ip, 159 | const IPADDR ip_network, 160 | const IPADDR ip_netmask, 161 | const MACADDR mac 162 | ); 163 | 164 | VOID SetMediaStatus 165 | ( 166 | TapAdapterPointer p_Adapter, 167 | BOOLEAN state 168 | ); 169 | 170 | VOID InjectPacketDeferred 171 | ( 172 | TapAdapterPointer p_Adapter, 173 | UCHAR *packet, 174 | const unsigned int len 175 | ); 176 | 177 | VOID InjectPacketNow 178 | ( 179 | TapAdapterPointer p_Adapter, 180 | UCHAR *packet, 181 | const unsigned int len 182 | ); 183 | 184 | // for KDEFERRED_ROUTINE and Static Driver Verifier 185 | //#include 186 | //KDEFERRED_ROUTINE InjectPacketDpc; 187 | 188 | VOID InjectPacketDpc 189 | ( 190 | KDPC *Dpc, 191 | PVOID DeferredContext, 192 | PVOID SystemArgument1, 193 | PVOID SystemArgument2 194 | ); 195 | 196 | VOID CheckIfDhcpAndTunMode 197 | ( 198 | TapAdapterPointer p_Adapter 199 | ); 200 | 201 | VOID HookDispatchFunctions(); 202 | 203 | #if ENABLE_NONADMIN 204 | 205 | #if defined(DDKVER_MAJOR) && DDKVER_MAJOR < 5600 206 | /* 207 | * Better solution for use on Vista DDK, but possibly not compatible with 208 | * earlier DDKs: 209 | * 210 | * Eliminate the definition of SECURITY_DESCRIPTOR (and even ZwSetSecurityObject), 211 | * and at the top of tapdrv.c change: 212 | * 213 | * #include 214 | * #include 215 | * #include 216 | * 217 | * To 218 | * 219 | * #include 220 | * #include 221 | * #include 222 | */ 223 | typedef struct _SECURITY_DESCRIPTOR { 224 | unsigned char opaque[64]; 225 | } SECURITY_DESCRIPTOR; 226 | 227 | NTSYSAPI 228 | NTSTATUS 229 | NTAPI 230 | ZwSetSecurityObject ( 231 | IN HANDLE Handle, 232 | IN SECURITY_INFORMATION SecurityInformation, 233 | IN PSECURITY_DESCRIPTOR SecurityDescriptor); 234 | 235 | #endif 236 | 237 | VOID AllowNonAdmin (TapExtensionPointer p_Extension); 238 | 239 | #endif 240 | 241 | struct WIN2K_NDIS_MINIPORT_BLOCK 242 | { 243 | unsigned char opaque[16]; 244 | UNICODE_STRING MiniportName; // how mini-port refers to us 245 | }; 246 | 247 | #if PACKET_TRUNCATION_CHECK 248 | 249 | VOID IPv4PacketSizeVerify 250 | ( 251 | const UCHAR *data, 252 | ULONG length, 253 | BOOLEAN tun, 254 | const char *prefix, 255 | LONG *counter 256 | ); 257 | 258 | #endif 259 | 260 | #endif 261 | -------------------------------------------------------------------------------- /src/instance.c: -------------------------------------------------------------------------------- 1 | /* 2 | * TAP-Windows -- A kernel driver to provide virtual tap 3 | * device functionality on Windows. 4 | * 5 | * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. 6 | * 7 | * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., 8 | * and is released under the GPL version 2 (see below). 9 | * 10 | * This program is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License version 2 12 | * as published by the Free Software Foundation. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program (see the file COPYING included with this 21 | * distribution); if not, write to the Free Software Foundation, Inc., 22 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23 | */ 24 | 25 | #define INSTANCE_KEY(a) ((PVOID)((a)->m_Extension.m_TapDevice)) 26 | 27 | #define N_INSTANCE_BUCKETS 256 28 | 29 | typedef struct _INSTANCE { 30 | struct _INSTANCE *next; 31 | TapAdapterPointer m_Adapter; 32 | } INSTANCE; 33 | 34 | typedef struct { 35 | INSTANCE *list; 36 | MUTEX lock; 37 | } INSTANCE_BUCKET; 38 | 39 | typedef struct { 40 | INSTANCE_BUCKET buckets[N_INSTANCE_BUCKETS]; 41 | } INSTANCE_HASH; 42 | 43 | INSTANCE_HASH *g_InstanceHash = NULL; 44 | 45 | // must return a hash >= 0 and < N_INSTANCE_BUCKETS 46 | int 47 | InstanceHashValue (PVOID addr) 48 | { 49 | UCHAR *p = (UCHAR *) &addr; 50 | 51 | if (sizeof (addr) == 4) 52 | return p[0] ^ p[1] ^ p[2] ^ p[3]; 53 | else if (sizeof (addr) == 8) 54 | return p[0] ^ p[1] ^ p[2] ^ p[3] ^ p[4] ^ p[5] ^ p[6] ^ p[7]; 55 | else 56 | { 57 | MYASSERT (0); 58 | } 59 | } 60 | 61 | BOOLEAN 62 | InitInstanceList (VOID) 63 | { 64 | MYASSERT (g_InstanceHash == NULL); 65 | g_InstanceHash = MemAlloc (sizeof (INSTANCE_HASH), TRUE); 66 | if (g_InstanceHash) 67 | { 68 | int i; 69 | for (i = 0; i < N_INSTANCE_BUCKETS; ++i) 70 | INIT_MUTEX (&g_InstanceHash->buckets[i].lock); 71 | return TRUE; 72 | } 73 | else 74 | return FALSE; 75 | } 76 | 77 | int 78 | NInstances (VOID) 79 | { 80 | int i, n = 0; 81 | 82 | if (g_InstanceHash) 83 | { 84 | for (i = 0; i < N_INSTANCE_BUCKETS; ++i) 85 | { 86 | BOOLEAN got_lock; 87 | INSTANCE_BUCKET *ib = &g_InstanceHash->buckets[i]; 88 | ACQUIRE_MUTEX_ADAPTIVE (&ib->lock, got_lock); 89 | 90 | if (got_lock) 91 | { 92 | INSTANCE *current; 93 | for (current = ib->list; current != NULL; current = current->next) 94 | ++n; 95 | RELEASE_MUTEX (&ib->lock); 96 | } 97 | else 98 | return -1; 99 | } 100 | } 101 | 102 | return n; 103 | } 104 | 105 | int 106 | InstanceMaxBucketSize (VOID) 107 | { 108 | int i, n = 0; 109 | 110 | if (g_InstanceHash) 111 | { 112 | for (i = 0; i < N_INSTANCE_BUCKETS; ++i) 113 | { 114 | BOOLEAN got_lock; 115 | int bucket_size = 0; 116 | INSTANCE_BUCKET *ib = &g_InstanceHash->buckets[i]; 117 | ACQUIRE_MUTEX_ADAPTIVE (&ib->lock, got_lock); 118 | 119 | if (got_lock) 120 | { 121 | INSTANCE *current; 122 | for (current = ib->list; current != NULL; current = current->next) 123 | ++bucket_size; 124 | if (bucket_size > n) 125 | n = bucket_size; 126 | RELEASE_MUTEX (&ib->lock); 127 | } 128 | else 129 | return -1; 130 | } 131 | } 132 | 133 | return n; 134 | } 135 | 136 | VOID 137 | FreeInstanceList (VOID) 138 | { 139 | if (g_InstanceHash) 140 | { 141 | MYASSERT (NInstances() == 0); 142 | MemFree (g_InstanceHash, sizeof (INSTANCE_HASH)); 143 | g_InstanceHash = NULL; 144 | } 145 | } 146 | 147 | BOOLEAN 148 | AddAdapterToInstanceList (TapAdapterPointer p_Adapter) 149 | { 150 | BOOLEAN got_lock; 151 | BOOLEAN ret = FALSE; 152 | const int hash = InstanceHashValue(INSTANCE_KEY(p_Adapter)); 153 | INSTANCE_BUCKET *ib = &g_InstanceHash->buckets[hash]; 154 | 155 | DEBUGP (("[TAP] AddAdapterToInstanceList hash=%d\n", hash)); 156 | 157 | ACQUIRE_MUTEX_ADAPTIVE (&ib->lock, got_lock); 158 | 159 | if (got_lock) 160 | { 161 | INSTANCE *i = MemAlloc (sizeof (INSTANCE), FALSE); 162 | if (i) 163 | { 164 | MYASSERT (p_Adapter); 165 | i->m_Adapter = p_Adapter; 166 | i->next = ib->list; 167 | ib->list = i; 168 | ret = TRUE; 169 | } 170 | RELEASE_MUTEX (&ib->lock); 171 | } 172 | 173 | return ret; 174 | } 175 | 176 | BOOLEAN 177 | RemoveAdapterFromInstanceList (TapAdapterPointer p_Adapter) 178 | { 179 | BOOLEAN got_lock; 180 | BOOLEAN ret = FALSE; 181 | INSTANCE_BUCKET *ib = &g_InstanceHash->buckets[InstanceHashValue(INSTANCE_KEY(p_Adapter))]; 182 | 183 | ACQUIRE_MUTEX_ADAPTIVE (&ib->lock, got_lock); 184 | 185 | if (got_lock) 186 | { 187 | INSTANCE *current, *prev=NULL; 188 | for (current = ib->list; current != NULL; current = current->next) 189 | { 190 | if (current->m_Adapter == p_Adapter) // found match 191 | { 192 | if (prev) 193 | prev->next = current->next; 194 | else 195 | ib->list = current->next; 196 | MemFree (current->m_Adapter, sizeof (TapAdapter)); 197 | MemFree (current, sizeof (INSTANCE)); 198 | ret = TRUE; 199 | break; 200 | } 201 | prev = current; 202 | } 203 | RELEASE_MUTEX (&ib->lock); 204 | } 205 | 206 | return ret; 207 | } 208 | 209 | TapAdapterPointer 210 | LookupAdapterInInstanceList (PDEVICE_OBJECT p_DeviceObject) 211 | { 212 | BOOLEAN got_lock; 213 | TapAdapterPointer ret = NULL; 214 | INSTANCE_BUCKET *ib = &g_InstanceHash->buckets[InstanceHashValue((PVOID)p_DeviceObject)]; 215 | 216 | ACQUIRE_MUTEX_ADAPTIVE (&ib->lock, got_lock); 217 | 218 | if (got_lock) 219 | { 220 | INSTANCE *current, *prev=NULL; 221 | for (current = ib->list; current != NULL; current = current->next) 222 | { 223 | if (p_DeviceObject == INSTANCE_KEY (current->m_Adapter)) // found match 224 | { 225 | // move it to head of list 226 | if (prev) 227 | { 228 | prev->next = current->next; 229 | current->next = ib->list; 230 | ib->list = current; 231 | } 232 | ret = ib->list->m_Adapter; 233 | break; 234 | } 235 | prev = current; 236 | } 237 | RELEASE_MUTEX (&ib->lock); 238 | } 239 | 240 | return ret; 241 | } 242 | -------------------------------------------------------------------------------- /src/proto.h: -------------------------------------------------------------------------------- 1 | /* 2 | * TAP-Windows -- A kernel driver to provide virtual tap 3 | * device functionality on Windows. 4 | * 5 | * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. 6 | * 7 | * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., 8 | * and is released under the GPL version 2 (see below). 9 | * 10 | * This program is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License version 2 12 | * as published by the Free Software Foundation. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program (see the file COPYING included with this 21 | * distribution); if not, write to the Free Software Foundation, Inc., 22 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23 | */ 24 | 25 | //============================================================ 26 | // MAC address, Ethernet header, and ARP 27 | //============================================================ 28 | 29 | #pragma pack(1) 30 | 31 | #define IP_HEADER_SIZE 20 32 | #define IPV6_HEADER_SIZE 40 33 | 34 | typedef unsigned char MACADDR [6]; 35 | typedef unsigned long IPADDR; 36 | typedef unsigned char IPV6ADDR [16]; 37 | 38 | //----------------- 39 | // Ethernet address 40 | //----------------- 41 | 42 | typedef struct { 43 | MACADDR addr; 44 | } ETH_ADDR; 45 | 46 | typedef struct { 47 | ETH_ADDR list[NIC_MAX_MCAST_LIST]; 48 | } MC_LIST; 49 | 50 | //---------------- 51 | // Ethernet header 52 | //---------------- 53 | 54 | typedef struct 55 | { 56 | MACADDR dest; /* destination eth addr */ 57 | MACADDR src; /* source ether addr */ 58 | 59 | # define ETH_P_IP 0x0800 /* IPv4 protocol */ 60 | # define ETH_P_IPV6 0x86DD /* IPv6 protocol */ 61 | # define ETH_P_ARP 0x0806 /* ARP protocol */ 62 | USHORT proto; /* packet type ID field */ 63 | } ETH_HEADER, *PETH_HEADER; 64 | 65 | //---------------- 66 | // ARP packet 67 | //---------------- 68 | 69 | typedef struct 70 | { 71 | MACADDR m_MAC_Destination; // Reverse these two 72 | MACADDR m_MAC_Source; // to answer ARP requests 73 | USHORT m_Proto; // 0x0806 74 | 75 | # define MAC_ADDR_TYPE 0x0001 76 | USHORT m_MAC_AddressType; // 0x0001 77 | 78 | USHORT m_PROTO_AddressType; // 0x0800 79 | UCHAR m_MAC_AddressSize; // 0x06 80 | UCHAR m_PROTO_AddressSize; // 0x04 81 | 82 | # define ARP_REQUEST 0x0001 83 | # define ARP_REPLY 0x0002 84 | USHORT m_ARP_Operation; // 0x0001 for ARP request, 0x0002 for ARP reply 85 | 86 | MACADDR m_ARP_MAC_Source; 87 | IPADDR m_ARP_IP_Source; 88 | MACADDR m_ARP_MAC_Destination; 89 | IPADDR m_ARP_IP_Destination; 90 | } 91 | ARP_PACKET, *PARP_PACKET; 92 | 93 | //---------- 94 | // IP Header 95 | //---------- 96 | 97 | typedef struct { 98 | # define IPH_GET_VER(v) (((v) >> 4) & 0x0F) 99 | # define IPH_GET_LEN(v) (((v) & 0x0F) << 2) 100 | UCHAR version_len; 101 | 102 | UCHAR tos; 103 | USHORT tot_len; 104 | USHORT id; 105 | 106 | # define IP_OFFMASK 0x1fff 107 | USHORT frag_off; 108 | 109 | UCHAR ttl; 110 | 111 | # define IPPROTO_UDP 17 /* UDP protocol */ 112 | # define IPPROTO_TCP 6 /* TCP protocol */ 113 | # define IPPROTO_ICMP 1 /* ICMP protocol */ 114 | # define IPPROTO_IGMP 2 /* IGMP protocol */ 115 | UCHAR protocol; 116 | 117 | USHORT check; 118 | ULONG saddr; 119 | ULONG daddr; 120 | /* The options start here. */ 121 | } IPHDR; 122 | 123 | //----------- 124 | // UDP header 125 | //----------- 126 | 127 | typedef struct { 128 | USHORT source; 129 | USHORT dest; 130 | USHORT len; 131 | USHORT check; 132 | } UDPHDR; 133 | 134 | //-------------------------- 135 | // TCP header, per RFC 793. 136 | //-------------------------- 137 | 138 | typedef struct { 139 | USHORT source; /* source port */ 140 | USHORT dest; /* destination port */ 141 | ULONG seq; /* sequence number */ 142 | ULONG ack_seq; /* acknowledgement number */ 143 | 144 | # define TCPH_GET_DOFF(d) (((d) & 0xF0) >> 2) 145 | UCHAR doff_res; 146 | 147 | # define TCPH_FIN_MASK (1<<0) 148 | # define TCPH_SYN_MASK (1<<1) 149 | # define TCPH_RST_MASK (1<<2) 150 | # define TCPH_PSH_MASK (1<<3) 151 | # define TCPH_ACK_MASK (1<<4) 152 | # define TCPH_URG_MASK (1<<5) 153 | # define TCPH_ECE_MASK (1<<6) 154 | # define TCPH_CWR_MASK (1<<7) 155 | UCHAR flags; 156 | 157 | USHORT window; 158 | USHORT check; 159 | USHORT urg_ptr; 160 | } TCPHDR; 161 | 162 | #define TCPOPT_EOL 0 163 | #define TCPOPT_NOP 1 164 | #define TCPOPT_MAXSEG 2 165 | #define TCPOLEN_MAXSEG 4 166 | 167 | //------------ 168 | // IPv6 Header 169 | //------------ 170 | 171 | typedef struct { 172 | UCHAR version_prio; 173 | UCHAR flow_lbl[3]; 174 | USHORT payload_len; 175 | # define IPPROTO_ICMPV6 0x3a /* ICMP protocol v6 */ 176 | UCHAR nexthdr; 177 | UCHAR hop_limit; 178 | IPV6ADDR saddr; 179 | IPV6ADDR daddr; 180 | } IPV6HDR; 181 | 182 | //-------------------------------------------- 183 | // IPCMPv6 NS/NA Packets (RFC4443 and RFC4861) 184 | //-------------------------------------------- 185 | 186 | // Neighbor Solictiation - RFC 4861, 4.3 187 | // (this is just the ICMPv6 part of the packet) 188 | typedef struct { 189 | UCHAR type; 190 | # define ICMPV6_TYPE_NS 135 // neighbour solicitation 191 | UCHAR code; 192 | # define ICMPV6_CODE_0 0 // no specific sub-code for NS/NA 193 | USHORT checksum; 194 | ULONG reserved; 195 | IPV6ADDR target_addr; 196 | } ICMPV6_NS; 197 | 198 | // Neighbor Advertisement - RFC 4861, 4.4 + 4.6/4.6.1 199 | // (this is just the ICMPv6 payload) 200 | typedef struct { 201 | UCHAR type; 202 | # define ICMPV6_TYPE_NA 136 // neighbour advertisement 203 | UCHAR code; 204 | # define ICMPV6_CODE_0 0 // no specific sub-code for NS/NA 205 | USHORT checksum; 206 | UCHAR rso_bits; // Router(0), Solicited(2), Ovrrd(4) 207 | UCHAR reserved[3]; 208 | IPV6ADDR target_addr; 209 | // always include "Target Link-layer Address" option (RFC 4861 4.6.1) 210 | UCHAR opt_type; 211 | #define ICMPV6_OPTION_TLLA 2 212 | UCHAR opt_length; 213 | #define ICMPV6_LENGTH_TLLA 1 // multiplied by 8 -> 1 = 8 bytes 214 | MACADDR target_macaddr; 215 | } ICMPV6_NA; 216 | 217 | // this is the complete packet with Ethernet and IPv6 headers 218 | typedef struct { 219 | ETH_HEADER eth; 220 | IPV6HDR ipv6; 221 | ICMPV6_NA icmpv6; 222 | } ICMPV6_NA_PKT; 223 | 224 | #pragma pack() 225 | -------------------------------------------------------------------------------- /src/OemWin2k.inf.in: -------------------------------------------------------------------------------- 1 | ; **************************************************************************** 2 | ; * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. * 3 | ; * This program is free software; you can redistribute it and/or modify * 4 | ; * it under the terms of the GNU General Public License version 2 * 5 | ; * as published by the Free Software Foundation. * 6 | ; **************************************************************************** 7 | 8 | ; SYNTAX CHECKER 9 | ; cd \WINDDK\3790\tools\chkinf 10 | ; chkinf c:\src\openvpn\tap-win32\i386\oemwin2k.inf 11 | ; OUTPUT -> file:///c:/WINDDK/3790/tools/chkinf/htm/c%23+src+openvpn+tap-win32+i386+__OemWin2k.htm 12 | 13 | ; INSTALL/REMOVE DRIVER 14 | ; tapinstall install OemWin2k.inf TAP0901 15 | ; tapinstall update OemWin2k.inf TAP0901 16 | ; tapinstall remove TAP0901 17 | 18 | ;********************************************************* 19 | ; Note to Developers: 20 | ; 21 | ; If you are bundling the TAP-Windows driver with your app, 22 | ; you should try to rename it in such a way that it will 23 | ; not collide with other instances of TAP-Windows defined 24 | ; by other apps. Multiple versions of the TAP-Windows 25 | ; driver, each installed by different apps, can coexist 26 | ; on the same machine if you follow these guidelines. 27 | ; NOTE: these instructions assume you are editing the 28 | ; generated OemWin2k.inf file, not the source 29 | ; OemWin2k.inf.in file which is preprocessed by winconfig 30 | ; and uses macro definitions from settings.in. 31 | ; 32 | ; (1) Rename all tapXXXX instances in this file to 33 | ; something different (use at least 5 characters 34 | ; for this name!) 35 | ; (2) Change the "!define TAP" definition in openvpn.nsi 36 | ; to match what you changed tapXXXX to. 37 | ; (3) Change TARGETNAME in SOURCES to match what you 38 | ; changed tapXXXX to. 39 | ; (4) Change TAP_COMPONENT_ID in common.h to match what 40 | ; you changed tapXXXX to. 41 | ; (5) Change SZDEPENDENCIES in service.h to match what 42 | ; you changed tapXXXX to. 43 | ; (6) Change DeviceDescription and Provider strings. 44 | ; (7) Change PRODUCT_TAP_WIN_DEVICE_DESCRIPTION in constants.h to what you 45 | ; set DeviceDescription to. 46 | ; 47 | ;********************************************************* 48 | 49 | [Version] 50 | Signature = "$Windows NT$" 51 | CatalogFile = @PRODUCT_TAP_WIN_COMPONENT_ID@.cat 52 | ClassGUID = {4d36e972-e325-11ce-bfc1-08002be10318} 53 | Provider = %Provider% 54 | Class = Net 55 | 56 | ; This version number should match the version 57 | ; number given in SOURCES. 58 | DriverVer=@PRODUCT_TAP_WIN_RELDATE@,@PRODUCT_TAP_WIN_MAJOR@.00.00.@PRODUCT_TAP_WIN_MINOR@ 59 | 60 | [Strings] 61 | DeviceDescription = "@PRODUCT_TAP_WIN_DEVICE_DESCRIPTION@" 62 | Provider = "@PRODUCT_TAP_WIN_PROVIDER@" 63 | 64 | ;---------------------------------------------------------------- 65 | ; Manufacturer + Product Section (Done) 66 | ;---------------------------------------------------------------- 67 | [Manufacturer] 68 | %Provider% = @PRODUCT_TAP_WIN_COMPONENT_ID@@INF_PROVIDER_SUFFIX@ 69 | 70 | [@PRODUCT_TAP_WIN_COMPONENT_ID@@INF_SECTION_SUFFIX@] 71 | %DeviceDescription% = @PRODUCT_TAP_WIN_COMPONENT_ID@.ndi, @PRODUCT_TAP_WIN_COMPONENT_ID@ 72 | 73 | ;--------------------------------------------------------------- 74 | ; Driver Section (Done) 75 | ;--------------------------------------------------------------- 76 | 77 | ;----------------- Characteristics ------------ 78 | ; NCF_PHYSICAL = 0x04 79 | ; NCF_VIRTUAL = 0x01 80 | ; NCF_SOFTWARE_ENUMERATED = 0x02 81 | ; NCF_HIDDEN = 0x08 82 | ; NCF_NO_SERVICE = 0x10 83 | ; NCF_HAS_UI = 0x80 84 | ;----------------- Characteristics ------------ 85 | 86 | [@PRODUCT_TAP_WIN_COMPONENT_ID@.ndi] 87 | CopyFiles = @PRODUCT_TAP_WIN_COMPONENT_ID@.driver, @PRODUCT_TAP_WIN_COMPONENT_ID@.files 88 | AddReg = @PRODUCT_TAP_WIN_COMPONENT_ID@.reg 89 | AddReg = @PRODUCT_TAP_WIN_COMPONENT_ID@.params.reg 90 | Characteristics = @PRODUCT_TAP_WIN_CHARACTERISTICS@ 91 | 92 | [@PRODUCT_TAP_WIN_COMPONENT_ID@.ndi.Services] 93 | AddService = @PRODUCT_TAP_WIN_COMPONENT_ID@, 2, @PRODUCT_TAP_WIN_COMPONENT_ID@.service 94 | 95 | [@PRODUCT_TAP_WIN_COMPONENT_ID@.reg] 96 | HKR, Ndi, Service, 0, "@PRODUCT_TAP_WIN_COMPONENT_ID@" 97 | HKR, Ndi\Interfaces, UpperRange, 0, "ndis5" 98 | HKR, Ndi\Interfaces, LowerRange, 0, "ethernet" 99 | HKR, , Manufacturer, 0, "%Provider%" 100 | HKR, , ProductName, 0, "%DeviceDescription%" 101 | 102 | [@PRODUCT_TAP_WIN_COMPONENT_ID@.params.reg] 103 | HKR, Ndi\params\MTU, ParamDesc, 0, "MTU" 104 | HKR, Ndi\params\MTU, Type, 0, "int" 105 | HKR, Ndi\params\MTU, Default, 0, "1500" 106 | HKR, Ndi\params\MTU, Optional, 0, "0" 107 | HKR, Ndi\params\MTU, Min, 0, "100" 108 | HKR, Ndi\params\MTU, Max, 0, "1500" 109 | HKR, Ndi\params\MTU, Step, 0, "1" 110 | HKR, Ndi\params\MediaStatus, ParamDesc, 0, "Media Status" 111 | HKR, Ndi\params\MediaStatus, Type, 0, "enum" 112 | HKR, Ndi\params\MediaStatus, Default, 0, "0" 113 | HKR, Ndi\params\MediaStatus, Optional, 0, "0" 114 | HKR, Ndi\params\MediaStatus\enum, "0", 0, "Application Controlled" 115 | HKR, Ndi\params\MediaStatus\enum, "1", 0, "Always Connected" 116 | HKR, Ndi\params\MAC, ParamDesc, 0, "MAC Address" 117 | HKR, Ndi\params\MAC, Type, 0, "edit" 118 | HKR, Ndi\params\MAC, Optional, 0, "1" 119 | HKR, Ndi\params\AllowNonAdmin, ParamDesc, 0, "Non-Admin Access" 120 | HKR, Ndi\params\AllowNonAdmin, Type, 0, "enum" 121 | HKR, Ndi\params\AllowNonAdmin, Default, 0, "1" 122 | HKR, Ndi\params\AllowNonAdmin, Optional, 0, "0" 123 | HKR, Ndi\params\AllowNonAdmin\enum, "0", 0, "Not Allowed" 124 | HKR, Ndi\params\AllowNonAdmin\enum, "1", 0, "Allowed" 125 | 126 | ;---------------------------------------------------------------- 127 | ; Service Section 128 | ;---------------------------------------------------------------- 129 | 130 | ;---------- Service Type ------------- 131 | ; SERVICE_KERNEL_DRIVER = 0x01 132 | ; SERVICE_WIN32_OWN_PROCESS = 0x10 133 | ;---------- Service Type ------------- 134 | 135 | ;---------- Start Mode --------------- 136 | ; SERVICE_BOOT_START = 0x0 137 | ; SERVICE_SYSTEM_START = 0x1 138 | ; SERVICE_AUTO_START = 0x2 139 | ; SERVICE_DEMAND_START = 0x3 140 | ; SERVICE_DISABLED = 0x4 141 | ;---------- Start Mode --------------- 142 | 143 | [@PRODUCT_TAP_WIN_COMPONENT_ID@.service] 144 | DisplayName = %DeviceDescription% 145 | ServiceType = 1 146 | StartType = 3 147 | ErrorControl = 1 148 | LoadOrderGroup = NDIS 149 | ServiceBinary = %12%\@PRODUCT_TAP_WIN_COMPONENT_ID@.sys 150 | 151 | ;----------------------------------------------------------------- 152 | ; File Installation 153 | ;----------------------------------------------------------------- 154 | 155 | ;----------------- Copy Flags ------------ 156 | ; COPYFLG_NOSKIP = 0x02 157 | ; COPYFLG_NOVERSIONCHECK = 0x04 158 | ;----------------- Copy Flags ------------ 159 | 160 | ; SourceDisksNames 161 | ; diskid = description[, [tagfile] [, , subdir]] 162 | ; 1 = "Intel Driver Disk 1",e100bex.sys,, 163 | 164 | [SourceDisksNames] 165 | 1 = %DeviceDescription%, @PRODUCT_TAP_WIN_COMPONENT_ID@.sys 166 | 167 | ; SourceDisksFiles 168 | ; filename_on_source = diskID[, [subdir][, size]] 169 | ; e100bex.sys = 1,, ; on distribution disk 1 170 | 171 | [SourceDisksFiles] 172 | @PRODUCT_TAP_WIN_COMPONENT_ID@.sys = 1 173 | 174 | [DestinationDirs] 175 | @PRODUCT_TAP_WIN_COMPONENT_ID@.files = 11 176 | @PRODUCT_TAP_WIN_COMPONENT_ID@.driver = 12 177 | 178 | [@PRODUCT_TAP_WIN_COMPONENT_ID@.files] 179 | ; TapPanel.cpl,,,6 ; COPYFLG_NOSKIP | COPYFLG_NOVERSIONCHECK 180 | ; cipsrvr.exe,,,6 ; COPYFLG_NOSKIP | COPYFLG_NOVERSIONCHECK 181 | 182 | [@PRODUCT_TAP_WIN_COMPONENT_ID@.driver] 183 | @PRODUCT_TAP_WIN_COMPONENT_ID@.sys,,,6 ; COPYFLG_NOSKIP | COPYFLG_NOVERSIONCHECK 184 | 185 | ;--------------------------------------------------------------- 186 | ; End 187 | ;--------------------------------------------------------------- 188 | -------------------------------------------------------------------------------- /installer/tap-windows.nsi: -------------------------------------------------------------------------------- 1 | ; **************************************************************************** 2 | ; * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. * 3 | ; * Copyright (C) 2012 Alon Bar-Lev * 4 | ; * This program is free software; you can redistribute it and/or modify * 5 | ; * it under the terms of the GNU General Public License version 2 * 6 | ; * as published by the Free Software Foundation. * 7 | ; **************************************************************************** 8 | 9 | ; TAP-Windows install script for Windows, using NSIS 10 | 11 | SetCompressor lzma 12 | 13 | !include "MUI.nsh" 14 | !include "StrFunc.nsh" 15 | !include "x64.nsh" 16 | !define MULTIUSER_EXECUTIONLEVEL Admin 17 | !include "MultiUser.nsh" 18 | 19 | ${StrLoc} 20 | 21 | ;-------------------------------- 22 | ;Configuration 23 | 24 | ;General 25 | 26 | OutFile "${OUTPUT}" 27 | 28 | ShowInstDetails show 29 | ShowUninstDetails show 30 | 31 | ;Remember install folder 32 | InstallDirRegKey HKLM "SOFTWARE\${PRODUCT_NAME}" "" 33 | 34 | ;-------------------------------- 35 | ;Modern UI Configuration 36 | 37 | Name "${PRODUCT_NAME} ${PRODUCT_VERSION}" 38 | 39 | !define MUI_WELCOMEPAGE_TEXT "This wizard will guide you through the installation of ${PRODUCT_NAME}, an Open Source VPN package by James Yonan.\r\n\r\nNote that the Windows version of ${PRODUCT_NAME} will only run on Win 2000, XP, or higher.\r\n\r\n\r\n" 40 | 41 | !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." 42 | 43 | !define MUI_COMPONENTSPAGE_SMALLDESC 44 | !define MUI_FINISHPAGE_NOAUTOCLOSE 45 | !define MUI_ABORTWARNING 46 | !define MUI_ICON "icon.ico" 47 | !define MUI_UNICON "icon.ico" 48 | !define MUI_HEADERIMAGE 49 | !define MUI_HEADERIMAGE_BITMAP "install-whirl.bmp" 50 | !define MUI_UNFINISHPAGE_NOAUTOCLOSE 51 | 52 | !insertmacro MUI_PAGE_WELCOME 53 | !insertmacro MUI_PAGE_LICENSE "${IMAGE}\license.txt" 54 | !insertmacro MUI_PAGE_COMPONENTS 55 | !insertmacro MUI_PAGE_DIRECTORY 56 | !insertmacro MUI_PAGE_INSTFILES 57 | !insertmacro MUI_PAGE_FINISH 58 | 59 | !insertmacro MUI_UNPAGE_CONFIRM 60 | !insertmacro MUI_UNPAGE_INSTFILES 61 | !insertmacro MUI_UNPAGE_FINISH 62 | 63 | ;-------------------------------- 64 | ;Languages 65 | 66 | !insertmacro MUI_LANGUAGE "English" 67 | 68 | ;-------------------------------- 69 | ;Language Strings 70 | 71 | LangString DESC_SecTAP ${LANG_ENGLISH} "Install/Upgrade the TAP virtual device driver. Will not interfere with CIPE." 72 | LangString DESC_SecTAPUtilities ${LANG_ENGLISH} "Install the TAP Utilities." 73 | LangString DESC_SecTAPSDK ${LANG_ENGLISH} "Install the TAP SDK." 74 | 75 | ;-------------------------------- 76 | ;Reserve Files 77 | 78 | ;Things that need to be extracted on first (keep these lines before any File command!) 79 | ;Only useful for BZIP2 compression 80 | 81 | ReserveFile "install-whirl.bmp" 82 | 83 | ;-------------------------------- 84 | ;Installer Sections 85 | 86 | Function .onInit 87 | ClearErrors 88 | !insertmacro MULTIUSER_INIT 89 | SetShellVarContext all 90 | 91 | ${If} ${RunningX64} 92 | SetRegView 64 93 | StrCpy $INSTDIR "$PROGRAMFILES64\${PRODUCT_NAME}" 94 | ${Else} 95 | StrCpy $INSTDIR "$PROGRAMFILES\${PRODUCT_NAME}" 96 | ${EndIf} 97 | FunctionEnd 98 | 99 | Section "TAP Virtual Ethernet Adapter" SecTAP 100 | 101 | SetOverwrite on 102 | 103 | ${If} ${RunningX64} 104 | DetailPrint "We are running on a 64-bit system." 105 | 106 | SetOutPath "$INSTDIR\bin" 107 | File "${DEVCON64}" 108 | 109 | SetOutPath "$INSTDIR\driver" 110 | File "${IMAGE}\amd64\OemWin2k.inf" 111 | File "${IMAGE}\amd64\${PRODUCT_TAP_WIN_COMPONENT_ID}.cat" 112 | File "${IMAGE}\amd64\${PRODUCT_TAP_WIN_COMPONENT_ID}.sys" 113 | ${Else} 114 | DetailPrint "We are running on a 32-bit system." 115 | 116 | SetOutPath "$INSTDIR\bin" 117 | File "${DEVCON32}" 118 | 119 | SetOutPath "$INSTDIR\driver" 120 | File "${IMAGE}\i386\OemWin2k.inf" 121 | File "${IMAGE}\i386\${PRODUCT_TAP_WIN_COMPONENT_ID}.cat" 122 | File "${IMAGE}\i386\${PRODUCT_TAP_WIN_COMPONENT_ID}.sys" 123 | ${EndIf} 124 | SectionEnd 125 | 126 | Section /o "TAP Utilities" SecTAPUtilities 127 | SetOverwrite on 128 | 129 | # Delete previous start menu 130 | RMDir /r "$SMPROGRAMS\${PRODUCT_NAME}" 131 | 132 | FileOpen $R0 "$INSTDIR\bin\addtap.bat" w 133 | FileWrite $R0 "rem Add a new TAP virtual ethernet adapter$\r$\n" 134 | FileWrite $R0 '"$INSTDIR\bin\${DEVCON_BASENAME}" install "$INSTDIR\driver\OemWin2k.inf" ${PRODUCT_TAP_WIN_COMPONENT_ID}$\r$\n' 135 | FileWrite $R0 "pause$\r$\n" 136 | FileClose $R0 137 | 138 | FileOpen $R0 "$INSTDIR\bin\deltapall.bat" w 139 | 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" 140 | FileWrite $R0 "pause$\r$\n" 141 | FileWrite $R0 '"$INSTDIR\bin\${DEVCON_BASENAME}" remove ${PRODUCT_TAP_WIN_COMPONENT_ID}$\r$\n' 142 | FileWrite $R0 "pause$\r$\n" 143 | FileClose $R0 144 | 145 | ; Create shortcuts 146 | CreateDirectory "$SMPROGRAMS\${PRODUCT_NAME}\Utilities" 147 | CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\Utilities\Add a new TAP virtual ethernet adapter.lnk" "$INSTDIR\bin\addtap.bat" "" 148 | CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\Utilities\Delete ALL TAP virtual ethernet adapters.lnk" "$INSTDIR\bin\deltapall.bat" "" 149 | SectionEnd 150 | 151 | Section /o "TAP SDK" SecTAPSDK 152 | SetOverwrite on 153 | SetOutPath "$INSTDIR\include" 154 | File "${IMAGE}\include\tap-windows.h" 155 | SectionEnd 156 | 157 | ;-------------------------------- 158 | ;Dependencies 159 | 160 | Function .onSelChange 161 | ${If} ${SectionIsSelected} ${SecTAPUtilities} 162 | !insertmacro SelectSection ${SecTAP} 163 | ${EndIf} 164 | FunctionEnd 165 | 166 | ;-------------------- 167 | ;Post-install section 168 | 169 | Section -post 170 | 171 | SetOverwrite on 172 | 173 | ; Store README, license, icon 174 | SetOverwrite on 175 | SetOutPath $INSTDIR 176 | File "${IMAGE}\license.txt" 177 | File "icon.ico" 178 | 179 | ${If} ${SectionIsSelected} ${SecTAP} 180 | ; 181 | ; install/upgrade TAP driver if selected, using devcon 182 | ; 183 | ; TAP install/update was selected. 184 | ; Should we install or update? 185 | ; If tapinstall error occurred, $R5 will 186 | ; be nonzero. 187 | IntOp $R5 0 & 0 188 | nsExec::ExecToStack '"$INSTDIR\bin\${DEVCON_BASENAME}" hwids ${PRODUCT_TAP_WIN_COMPONENT_ID}' 189 | Pop $R0 # return value/error/timeout 190 | IntOp $R5 $R5 | $R0 191 | DetailPrint "${DEVCON_BASENAME} hwids returned: $R0" 192 | 193 | ; If tapinstall output string contains "${PRODUCT_TAP_WIN_COMPONENT_ID}" we assume 194 | ; that TAP device has been previously installed, 195 | ; therefore we will update, not install. 196 | Push "${PRODUCT_TAP_WIN_COMPONENT_ID}" 197 | Push ">" 198 | Call StrLoc 199 | Pop $R0 200 | 201 | ${If} $R5 == 0 202 | ${If} $R0 == "" 203 | StrCpy $R1 "install" 204 | ${Else} 205 | StrCpy $R1 "update" 206 | ${EndIf} 207 | DetailPrint "TAP $R1 (${PRODUCT_TAP_WIN_COMPONENT_ID}) (May require confirmation)" 208 | nsExec::ExecToLog '"$INSTDIR\bin\${DEVCON_BASENAME}" $R1 "$INSTDIR\driver\OemWin2k.inf" ${PRODUCT_TAP_WIN_COMPONENT_ID}' 209 | Pop $R0 # return value/error/timeout 210 | ${If} $R0 == "" 211 | IntOp $R0 0 & 0 212 | SetRebootFlag true 213 | DetailPrint "REBOOT flag set" 214 | ${EndIf} 215 | IntOp $R5 $R5 | $R0 216 | DetailPrint "${DEVCON_BASENAME} returned: $R0" 217 | ${EndIf} 218 | 219 | DetailPrint "${DEVCON_BASENAME} cumulative status: $R5" 220 | ${If} $R5 != 0 221 | MessageBox MB_OK "An error occurred installing the TAP device driver." 222 | ${EndIf} 223 | 224 | ; Store install folder in registry 225 | WriteRegStr HKLM SOFTWARE\${PRODUCT_NAME} "" $INSTDIR 226 | ${EndIf} 227 | 228 | ; Create uninstaller 229 | WriteUninstaller "$INSTDIR\Uninstall.exe" 230 | 231 | ; Show up in Add/Remove programs 232 | WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "DisplayName" "${PRODUCT_NAME} ${PRODUCT_VERSION}" 233 | WriteRegExpandStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "UninstallString" "$INSTDIR\Uninstall.exe" 234 | WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "DisplayIcon" "$INSTDIR\icon.ico" 235 | WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "DisplayVersion" "${PRODUCT_VERSION}" 236 | 237 | ; Advise a reboot 238 | ;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)." 239 | 240 | SectionEnd 241 | 242 | ;-------------------------------- 243 | ;Descriptions 244 | 245 | !insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN 246 | !insertmacro MUI_DESCRIPTION_TEXT ${SecTAP} $(DESC_SecTAP) 247 | !insertmacro MUI_DESCRIPTION_TEXT ${SecTAPUtilities} $(DESC_SecTAPUtilities) 248 | !insertmacro MUI_DESCRIPTION_TEXT ${SecTAPSDK} $(DESC_SecTAPSDK) 249 | !insertmacro MUI_FUNCTION_DESCRIPTION_END 250 | 251 | ;-------------------------------- 252 | ;Uninstaller Section 253 | 254 | Function un.onInit 255 | ClearErrors 256 | !insertmacro MULTIUSER_UNINIT 257 | SetShellVarContext all 258 | ${If} ${RunningX64} 259 | SetRegView 64 260 | ${EndIf} 261 | FunctionEnd 262 | 263 | Section "Uninstall" 264 | DetailPrint "TAP REMOVE" 265 | nsExec::ExecToLog '"$INSTDIR\bin\${DEVCON_BASENAME}" remove ${PRODUCT_TAP_WIN_COMPONENT_ID}' 266 | Pop $R0 # return value/error/timeout 267 | DetailPrint "${DEVCON_BASENAME} remove returned: $R0" 268 | 269 | Delete "$INSTDIR\bin\${DEVCON_BASENAME}" 270 | Delete "$INSTDIR\bin\addtap.bat" 271 | Delete "$INSTDIR\bin\deltapall.bat" 272 | 273 | Delete "$INSTDIR\driver\OemWin2k.inf" 274 | Delete "$INSTDIR\driver\${PRODUCT_TAP_WIN_COMPONENT_ID}.cat" 275 | Delete "$INSTDIR\driver\${PRODUCT_TAP_WIN_COMPONENT_ID}.sys" 276 | 277 | Delete "$INSTDIR\include\tap-windows.h" 278 | 279 | Delete "$INSTDIR\icon.ico" 280 | Delete "$INSTDIR\license.txt" 281 | Delete "$INSTDIR\Uninstall.exe" 282 | 283 | RMDir "$INSTDIR\bin" 284 | RMDir "$INSTDIR\driver" 285 | RMDir "$INSTDIR\include" 286 | RMDir "$INSTDIR" 287 | RMDir /r "$SMPROGRAMS\${PRODUCT_NAME}" 288 | 289 | DeleteRegKey HKLM "SOFTWARE\${PRODUCT_NAME}" 290 | DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" 291 | 292 | SectionEnd 293 | -------------------------------------------------------------------------------- /src/error.c: -------------------------------------------------------------------------------- 1 | /* 2 | * TAP-Windows -- A kernel driver to provide virtual tap 3 | * device functionality on Windows. 4 | * 5 | * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. 6 | * 7 | * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., 8 | * and is released under the GPL version 2 (see below). 9 | * 10 | * This program is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License version 2 12 | * as published by the Free Software Foundation. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program (see the file COPYING included with this 21 | * distribution); if not, write to the Free Software Foundation, Inc., 22 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23 | */ 24 | 25 | //----------------- 26 | // DEBUGGING OUTPUT 27 | //----------------- 28 | 29 | const char *g_LastErrorFilename; 30 | int g_LastErrorLineNumber; 31 | 32 | #if DBG 33 | 34 | DebugOutput g_Debug; 35 | 36 | BOOLEAN 37 | NewlineExists (const char *str, int len) 38 | { 39 | while (len-- > 0) 40 | { 41 | const char c = *str++; 42 | if (c == '\n') 43 | return TRUE; 44 | else if (c == '\0') 45 | break; 46 | } 47 | return FALSE; 48 | } 49 | 50 | VOID 51 | MyDebugInit (unsigned int bufsiz) 52 | { 53 | NdisZeroMemory (&g_Debug, sizeof (g_Debug)); 54 | g_Debug.text = (char *) MemAlloc (bufsiz, FALSE); 55 | if (g_Debug.text) 56 | g_Debug.capacity = bufsiz; 57 | } 58 | 59 | VOID 60 | MyDebugFree () 61 | { 62 | if (g_Debug.text) 63 | MemFree (g_Debug.text, g_Debug.capacity); 64 | NdisZeroMemory (&g_Debug, sizeof (g_Debug)); 65 | } 66 | 67 | VOID 68 | MyDebugPrint (const unsigned char* format, ...) 69 | { 70 | if (g_Debug.text && g_Debug.capacity > 0 && CAN_WE_PRINT) 71 | { 72 | BOOLEAN owned; 73 | ACQUIRE_MUTEX_ADAPTIVE (&g_Debug.lock, owned); 74 | if (owned) 75 | { 76 | const int remaining = (int)g_Debug.capacity - (int)g_Debug.out; 77 | 78 | if (remaining > 0) 79 | { 80 | va_list args; 81 | NTSTATUS status; 82 | char *end; 83 | 84 | #ifdef DBG_PRINT 85 | va_start (args, format); 86 | vDbgPrintEx (DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, format, args); 87 | va_end (args); 88 | #endif 89 | va_start (args, format); 90 | status = RtlStringCchVPrintfExA (g_Debug.text + g_Debug.out, 91 | remaining, 92 | &end, 93 | NULL, 94 | STRSAFE_NO_TRUNCATION | STRSAFE_IGNORE_NULLS, 95 | format, 96 | args); 97 | va_end (args); 98 | va_start (args, format); 99 | vDbgPrintEx(DPFLTR_IHVDRIVER_ID , 1, format, args); 100 | va_end (args); 101 | if (status == STATUS_SUCCESS) 102 | g_Debug.out = (unsigned int) (end - g_Debug.text); 103 | else 104 | g_Debug.error = TRUE; 105 | } 106 | else 107 | g_Debug.error = TRUE; 108 | 109 | RELEASE_MUTEX (&g_Debug.lock); 110 | } 111 | else 112 | g_Debug.error = TRUE; 113 | } 114 | } 115 | 116 | BOOLEAN 117 | GetDebugLine (char *buf, const int len) 118 | { 119 | static const char *truncated = "[OUTPUT TRUNCATED]\n"; 120 | BOOLEAN ret = FALSE; 121 | 122 | NdisZeroMemory (buf, len); 123 | 124 | if (g_Debug.text && g_Debug.capacity > 0) 125 | { 126 | BOOLEAN owned; 127 | ACQUIRE_MUTEX_ADAPTIVE (&g_Debug.lock, owned); 128 | if (owned) 129 | { 130 | int i = 0; 131 | 132 | if (g_Debug.error || NewlineExists (g_Debug.text + g_Debug.in, (int)g_Debug.out - (int)g_Debug.in)) 133 | { 134 | while (i < (len - 1) && g_Debug.in < g_Debug.out) 135 | { 136 | const char c = g_Debug.text[g_Debug.in++]; 137 | if (c == '\n') 138 | break; 139 | buf[i++] = c; 140 | } 141 | if (i < len) 142 | buf[i] = '\0'; 143 | } 144 | 145 | if (!i) 146 | { 147 | if (g_Debug.in == g_Debug.out) 148 | { 149 | g_Debug.in = g_Debug.out = 0; 150 | if (g_Debug.error) 151 | { 152 | const unsigned int tlen = strlen (truncated); 153 | if (tlen < g_Debug.capacity) 154 | { 155 | NdisMoveMemory (g_Debug.text, truncated, tlen+1); 156 | g_Debug.out = tlen; 157 | } 158 | g_Debug.error = FALSE; 159 | } 160 | } 161 | } 162 | else 163 | ret = TRUE; 164 | 165 | RELEASE_MUTEX (&g_Debug.lock); 166 | } 167 | } 168 | return ret; 169 | } 170 | 171 | VOID 172 | MyAssert (const unsigned char *file, int line) 173 | { 174 | DEBUGP (("MYASSERT failed %s/%d\n", file, line)); 175 | KeBugCheckEx (0x0F00BABA, 176 | (ULONG_PTR) line, 177 | (ULONG_PTR) 0, 178 | (ULONG_PTR) 0, 179 | (ULONG_PTR) 0); 180 | } 181 | 182 | VOID 183 | PrMac (const MACADDR mac) 184 | { 185 | DEBUGP (("%x:%x:%x:%x:%x:%x", 186 | mac[0], mac[1], mac[2], 187 | mac[3], mac[4], mac[5])); 188 | } 189 | 190 | VOID 191 | PrIP (IPADDR ip_addr) 192 | { 193 | const unsigned char *ip = (const unsigned char *) &ip_addr; 194 | 195 | DEBUGP (("%d.%d.%d.%d", 196 | ip[0], ip[1], ip[2], ip[3])); 197 | } 198 | 199 | const char * 200 | PrIPProto (int proto) 201 | { 202 | switch (proto) 203 | { 204 | case IPPROTO_UDP: 205 | return "UDP"; 206 | case IPPROTO_TCP: 207 | return "TCP"; 208 | case IPPROTO_ICMP: 209 | return "ICMP"; 210 | case IPPROTO_IGMP: 211 | return "IGMP"; 212 | default: 213 | return "???"; 214 | } 215 | } 216 | 217 | VOID 218 | DumpARP (const char *prefix, const ARP_PACKET *arp) 219 | { 220 | DEBUGP (("%s ARP src=", prefix)); 221 | PrMac (arp->m_MAC_Source); 222 | DEBUGP ((" dest=")); 223 | PrMac (arp->m_MAC_Destination); 224 | DEBUGP ((" OP=0x%04x", 225 | (int)ntohs(arp->m_ARP_Operation))); 226 | DEBUGP ((" M=0x%04x(%d)", 227 | (int)ntohs(arp->m_MAC_AddressType), 228 | (int)arp->m_MAC_AddressSize)); 229 | DEBUGP ((" P=0x%04x(%d)", 230 | (int)ntohs(arp->m_PROTO_AddressType), 231 | (int)arp->m_PROTO_AddressSize)); 232 | 233 | DEBUGP ((" MacSrc=")); 234 | PrMac (arp->m_ARP_MAC_Source); 235 | DEBUGP ((" MacDest=")); 236 | PrMac (arp->m_ARP_MAC_Destination); 237 | 238 | DEBUGP ((" IPSrc=")); 239 | PrIP (arp->m_ARP_IP_Source); 240 | DEBUGP ((" IPDest=")); 241 | PrIP (arp->m_ARP_IP_Destination); 242 | 243 | DEBUGP (("\n")); 244 | } 245 | 246 | struct ethpayload { 247 | ETH_HEADER eth; 248 | UCHAR payload[DEFAULT_PACKET_LOOKAHEAD]; 249 | }; 250 | 251 | VOID 252 | DumpPacket2 (const char *prefix, 253 | const ETH_HEADER *eth, 254 | const unsigned char *data, 255 | unsigned int len) 256 | { 257 | struct ethpayload *ep = (struct ethpayload *) MemAlloc (sizeof (struct ethpayload), TRUE); 258 | if (ep) 259 | { 260 | if (len > DEFAULT_PACKET_LOOKAHEAD) 261 | len = DEFAULT_PACKET_LOOKAHEAD; 262 | ep->eth = *eth; 263 | NdisMoveMemory (ep->payload, data, len); 264 | DumpPacket (prefix, (unsigned char *) ep, sizeof (ETH_HEADER) + len); 265 | MemFree (ep, sizeof (struct ethpayload)); 266 | } 267 | } 268 | 269 | VOID 270 | DumpPacket (const char *prefix, 271 | const unsigned char *data, 272 | unsigned int len) 273 | { 274 | const ETH_HEADER *eth = (const ETH_HEADER *) data; 275 | const IPHDR *ip = (const IPHDR *) (data + sizeof (ETH_HEADER)); 276 | 277 | if (len < sizeof (ETH_HEADER)) 278 | { 279 | DEBUGP (("%s TRUNCATED PACKET LEN=%d\n", prefix, len)); 280 | return; 281 | } 282 | 283 | // ARP Packet? 284 | if (len >= sizeof (ARP_PACKET) && eth->proto == htons (ETH_P_ARP)) 285 | { 286 | DumpARP (prefix, (const ARP_PACKET *) data); 287 | return; 288 | } 289 | 290 | // IPv4 packet? 291 | if (len >= (sizeof (IPHDR) + sizeof (ETH_HEADER)) 292 | && eth->proto == htons (ETH_P_IP) 293 | && IPH_GET_VER (ip->version_len) == 4) 294 | { 295 | const int hlen = IPH_GET_LEN (ip->version_len); 296 | const int blen = len - sizeof (ETH_HEADER); 297 | BOOLEAN did = FALSE; 298 | 299 | DEBUGP (("%s IPv4 %s[%d]", prefix, PrIPProto (ip->protocol), len)); 300 | 301 | if (!(ntohs (ip->tot_len) == blen && hlen <= blen)) 302 | { 303 | DEBUGP ((" XXX")); 304 | return; 305 | } 306 | 307 | // TCP packet? 308 | if (ip->protocol == IPPROTO_TCP 309 | && blen - hlen >= (sizeof (TCPHDR))) 310 | { 311 | const TCPHDR *tcp = (TCPHDR *) (data + sizeof (ETH_HEADER) + hlen); 312 | DEBUGP ((" ")); 313 | PrIP (ip->saddr); 314 | DEBUGP ((":%d", ntohs (tcp->source))); 315 | DEBUGP ((" -> ")); 316 | PrIP (ip->daddr); 317 | DEBUGP ((":%d", ntohs (tcp->dest))); 318 | did = TRUE; 319 | } 320 | 321 | // UDP packet? 322 | else if ((ntohs (ip->frag_off) & IP_OFFMASK) == 0 323 | && ip->protocol == IPPROTO_UDP 324 | && blen - hlen >= (sizeof (UDPHDR))) 325 | { 326 | const UDPHDR *udp = (UDPHDR *) (data + sizeof (ETH_HEADER) + hlen); 327 | 328 | // DHCP packet? 329 | if ((udp->dest == htons (BOOTPC_PORT) || udp->dest == htons (BOOTPS_PORT)) 330 | && blen - hlen >= (sizeof (UDPHDR) + sizeof (DHCP))) 331 | { 332 | const DHCP *dhcp = (DHCP *) (data 333 | + hlen 334 | + sizeof (ETH_HEADER) 335 | + sizeof (UDPHDR)); 336 | 337 | int optlen = len 338 | - sizeof (ETH_HEADER) 339 | - hlen 340 | - sizeof (UDPHDR) 341 | - sizeof (DHCP); 342 | 343 | if (optlen < 0) 344 | optlen = 0; 345 | 346 | DumpDHCP (eth, ip, udp, dhcp, optlen); 347 | did = TRUE; 348 | } 349 | 350 | if (!did) 351 | { 352 | DEBUGP ((" ")); 353 | PrIP (ip->saddr); 354 | DEBUGP ((":%d", ntohs (udp->source))); 355 | DEBUGP ((" -> ")); 356 | PrIP (ip->daddr); 357 | DEBUGP ((":%d", ntohs (udp->dest))); 358 | did = TRUE; 359 | } 360 | } 361 | 362 | if (!did) 363 | { 364 | DEBUGP ((" ipproto=%d ", ip->protocol)); 365 | PrIP (ip->saddr); 366 | DEBUGP ((" -> ")); 367 | PrIP (ip->daddr); 368 | } 369 | 370 | DEBUGP (("\n")); 371 | return; 372 | } 373 | 374 | { 375 | DEBUGP (("%s ??? src=", prefix)); 376 | PrMac (eth->src); 377 | DEBUGP ((" dest=")); 378 | PrMac (eth->dest); 379 | DEBUGP ((" proto=0x%04x len=%d\n", 380 | (int) ntohs(eth->proto), 381 | len)); 382 | } 383 | } 384 | 385 | #endif 386 | -------------------------------------------------------------------------------- /src/dhcp.c: -------------------------------------------------------------------------------- 1 | /* 2 | * TAP-Windows -- A kernel driver to provide virtual tap 3 | * device functionality on Windows. 4 | * 5 | * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. 6 | * 7 | * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., 8 | * and is released under the GPL version 2 (see below). 9 | * 10 | * This program is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License version 2 12 | * as published by the Free Software Foundation. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program (see the file COPYING included with this 21 | * distribution); if not, write to the Free Software Foundation, Inc., 22 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23 | */ 24 | 25 | //========================= 26 | // Code to set DHCP options 27 | //========================= 28 | 29 | VOID 30 | SetDHCPOpt (DHCPMsg *m, void *data, unsigned int len) 31 | { 32 | if (!m->overflow) 33 | { 34 | if (m->optlen + len <= DHCP_OPTIONS_BUFFER_SIZE) 35 | { 36 | if (len) 37 | { 38 | NdisMoveMemory (m->msg.options + m->optlen, data, len); 39 | m->optlen += len; 40 | } 41 | } 42 | else 43 | { 44 | m->overflow = TRUE; 45 | } 46 | } 47 | } 48 | 49 | VOID 50 | SetDHCPOpt0 (DHCPMsg *msg, int type) 51 | { 52 | DHCPOPT0 opt; 53 | opt.type = (UCHAR) type; 54 | SetDHCPOpt (msg, &opt, sizeof (opt)); 55 | } 56 | 57 | VOID 58 | SetDHCPOpt8 (DHCPMsg *msg, int type, ULONG data) 59 | { 60 | DHCPOPT8 opt; 61 | opt.type = (UCHAR) type; 62 | opt.len = sizeof (opt.data); 63 | opt.data = (UCHAR) data; 64 | SetDHCPOpt (msg, &opt, sizeof (opt)); 65 | } 66 | 67 | VOID 68 | SetDHCPOpt32 (DHCPMsg *msg, int type, ULONG data) 69 | { 70 | DHCPOPT32 opt; 71 | opt.type = (UCHAR) type; 72 | opt.len = sizeof (opt.data); 73 | opt.data = data; 74 | SetDHCPOpt (msg, &opt, sizeof (opt)); 75 | } 76 | 77 | //============== 78 | // Checksum code 79 | //============== 80 | 81 | USHORT 82 | ip_checksum (const UCHAR *buf, const int len_ip_header) 83 | { 84 | USHORT word16; 85 | ULONG sum = 0; 86 | int i; 87 | 88 | // make 16 bit words out of every two adjacent 8 bit words in the packet 89 | // and add them up 90 | for (i = 0; i < len_ip_header - 1; i += 2) { 91 | word16 = ((buf[i] << 8) & 0xFF00) + (buf[i+1] & 0xFF); 92 | sum += (ULONG) word16; 93 | } 94 | 95 | // take only 16 bits out of the 32 bit sum and add up the carries 96 | while (sum >> 16) 97 | sum = (sum & 0xFFFF) + (sum >> 16); 98 | 99 | // one's complement the result 100 | return ((USHORT) ~sum); 101 | } 102 | 103 | USHORT 104 | udp_checksum (const UCHAR *buf, 105 | const int len_udp, 106 | const UCHAR *src_addr, 107 | const UCHAR *dest_addr) 108 | { 109 | USHORT word16; 110 | ULONG sum = 0; 111 | int i; 112 | 113 | // make 16 bit words out of every two adjacent 8 bit words and 114 | // calculate the sum of all 16 bit words 115 | for (i = 0; i < len_udp; i += 2){ 116 | word16 = ((buf[i] << 8) & 0xFF00) + ((i + 1 < len_udp) ? (buf[i+1] & 0xFF) : 0); 117 | sum += word16; 118 | } 119 | 120 | // add the UDP pseudo header which contains the IP source and destination addresses 121 | for (i = 0; i < 4; i += 2){ 122 | word16 =((src_addr[i] << 8) & 0xFF00) + (src_addr[i+1] & 0xFF); 123 | sum += word16; 124 | } 125 | for (i = 0; i < 4; i += 2){ 126 | word16 =((dest_addr[i] << 8) & 0xFF00) + (dest_addr[i+1] & 0xFF); 127 | sum += word16; 128 | } 129 | 130 | // the protocol number and the length of the UDP packet 131 | sum += (USHORT) IPPROTO_UDP + (USHORT) len_udp; 132 | 133 | // keep only the last 16 bits of the 32 bit calculated sum and add the carries 134 | while (sum >> 16) 135 | sum = (sum & 0xFFFF) + (sum >> 16); 136 | 137 | // Take the one's complement of sum 138 | return ((USHORT) ~sum); 139 | } 140 | 141 | //================================ 142 | // Set IP and UDP packet checksums 143 | //================================ 144 | 145 | VOID 146 | SetChecksumDHCPMsg (DHCPMsg *m) 147 | { 148 | // Set IP checksum 149 | m->msg.pre.ip.check = htons (ip_checksum ((UCHAR *) &m->msg.pre.ip, sizeof (IPHDR))); 150 | 151 | // Set UDP Checksum 152 | m->msg.pre.udp.check = htons (udp_checksum ((UCHAR *) &m->msg.pre.udp, 153 | sizeof (UDPHDR) + sizeof (DHCP) + m->optlen, 154 | (UCHAR *)&m->msg.pre.ip.saddr, 155 | (UCHAR *)&m->msg.pre.ip.daddr)); 156 | } 157 | 158 | //=================== 159 | // DHCP message tests 160 | //=================== 161 | 162 | int 163 | GetDHCPMessageType (const DHCP *dhcp, const int optlen) 164 | { 165 | const UCHAR *p = (UCHAR *) (dhcp + 1); 166 | int i; 167 | 168 | for (i = 0; i < optlen; ++i) 169 | { 170 | const UCHAR type = p[i]; 171 | const int room = optlen - i - 1; 172 | if (type == DHCP_END) // didn't find what we were looking for 173 | return -1; 174 | else if (type == DHCP_PAD) // no-operation 175 | ; 176 | else if (type == DHCP_MSG_TYPE) // what we are looking for 177 | { 178 | if (room >= 2) 179 | { 180 | if (p[i+1] == 1) // message length should be 1 181 | return p[i+2]; // return message type 182 | } 183 | return -1; 184 | } 185 | else // some other message 186 | { 187 | if (room >= 1) 188 | { 189 | const int len = p[i+1]; // get message length 190 | i += (len + 1); // advance to next message 191 | } 192 | } 193 | } 194 | return -1; 195 | } 196 | 197 | BOOLEAN 198 | DHCPMessageOurs (const TapAdapterPointer p_Adapter, 199 | const ETH_HEADER *eth, 200 | const IPHDR *ip, 201 | const UDPHDR *udp, 202 | const DHCP *dhcp) 203 | { 204 | // Must be UDPv4 protocol 205 | if (!(eth->proto == htons (ETH_P_IP) && ip->protocol == IPPROTO_UDP)) 206 | return FALSE; 207 | 208 | // Source MAC must be our adapter 209 | if (!MAC_EQUAL (eth->src, p_Adapter->m_MAC)) 210 | return FALSE; 211 | 212 | // Dest MAC must be either broadcast or our virtual DHCP server 213 | if (!(MAC_EQUAL (eth->dest, p_Adapter->m_MAC_Broadcast) 214 | || MAC_EQUAL (eth->dest, p_Adapter->m_dhcp_server_mac))) 215 | return FALSE; 216 | 217 | // Port numbers must be correct 218 | if (!(udp->dest == htons (BOOTPS_PORT) 219 | && udp->source == htons (BOOTPC_PORT))) 220 | return FALSE; 221 | 222 | // Hardware address must be MAC addr sized 223 | if (!(dhcp->hlen == sizeof (MACADDR))) 224 | return FALSE; 225 | 226 | // Hardware address must match our adapter 227 | if (!MAC_EQUAL (eth->src, dhcp->chaddr)) 228 | return FALSE; 229 | 230 | return TRUE; 231 | } 232 | 233 | 234 | //===================================================== 235 | // Build all of DHCP packet except for DHCP options. 236 | // Assume that *p has been zeroed before we are called. 237 | //===================================================== 238 | 239 | VOID 240 | BuildDHCPPre (const TapAdapterPointer a, 241 | DHCPPre *p, 242 | const ETH_HEADER *eth, 243 | const IPHDR *ip, 244 | const UDPHDR *udp, 245 | const DHCP *dhcp, 246 | const int optlen, 247 | const int type) 248 | { 249 | // Should we broadcast or direct to a specific MAC / IP address? 250 | const BOOLEAN broadcast = (type == DHCPNAK 251 | || MAC_EQUAL (eth->dest, a->m_MAC_Broadcast)); 252 | // Build ethernet header 253 | 254 | COPY_MAC (p->eth.src, a->m_dhcp_server_mac); 255 | 256 | if (broadcast) 257 | COPY_MAC (p->eth.dest, a->m_MAC_Broadcast); 258 | else 259 | COPY_MAC (p->eth.dest, eth->src); 260 | 261 | p->eth.proto = htons (ETH_P_IP); 262 | 263 | // Build IP header 264 | 265 | p->ip.version_len = (4 << 4) | (sizeof (IPHDR) >> 2); 266 | p->ip.tos = 0; 267 | p->ip.tot_len = htons (sizeof (IPHDR) + sizeof (UDPHDR) + sizeof (DHCP) + optlen); 268 | p->ip.id = 0; 269 | p->ip.frag_off = 0; 270 | p->ip.ttl = 16; 271 | p->ip.protocol = IPPROTO_UDP; 272 | p->ip.check = 0; 273 | p->ip.saddr = a->m_dhcp_server_ip; 274 | 275 | if (broadcast) 276 | p->ip.daddr = ~0; 277 | else 278 | p->ip.daddr = a->m_dhcp_addr; 279 | 280 | // Build UDP header 281 | 282 | p->udp.source = htons (BOOTPS_PORT); 283 | p->udp.dest = htons (BOOTPC_PORT); 284 | p->udp.len = htons (sizeof (UDPHDR) + sizeof (DHCP) + optlen); 285 | p->udp.check = 0; 286 | 287 | // Build DHCP response 288 | 289 | p->dhcp.op = BOOTREPLY; 290 | p->dhcp.htype = 1; 291 | p->dhcp.hlen = sizeof (MACADDR); 292 | p->dhcp.hops = 0; 293 | p->dhcp.xid = dhcp->xid; 294 | p->dhcp.secs = 0; 295 | p->dhcp.flags = 0; 296 | p->dhcp.ciaddr = 0; 297 | 298 | if (type == DHCPNAK) 299 | p->dhcp.yiaddr = 0; 300 | else 301 | p->dhcp.yiaddr = a->m_dhcp_addr; 302 | 303 | p->dhcp.siaddr = a->m_dhcp_server_ip; 304 | p->dhcp.giaddr = 0; 305 | COPY_MAC (p->dhcp.chaddr, eth->src); 306 | p->dhcp.magic = htonl (0x63825363); 307 | } 308 | //============================= 309 | // Build specific DHCP messages 310 | //============================= 311 | 312 | VOID 313 | SendDHCPMsg (const TapAdapterPointer a, 314 | const int type, 315 | const ETH_HEADER *eth, 316 | const IPHDR *ip, 317 | const UDPHDR *udp, 318 | const DHCP *dhcp) 319 | { 320 | DHCPMsg *pkt; 321 | 322 | if (!(type == DHCPOFFER || type == DHCPACK || type == DHCPNAK)) 323 | { 324 | DEBUGP (("[TAP] SendDHCPMsg: Bad DHCP type: %d\n", type)); 325 | return; 326 | } 327 | 328 | pkt = (DHCPMsg *) MemAlloc (sizeof (DHCPMsg), TRUE); 329 | 330 | if (pkt) 331 | { 332 | //----------------------- 333 | // Build DHCP options 334 | //----------------------- 335 | 336 | // Message Type 337 | SetDHCPOpt8 (pkt, DHCP_MSG_TYPE, type); 338 | 339 | // Server ID 340 | SetDHCPOpt32 (pkt, DHCP_SERVER_ID, a->m_dhcp_server_ip); 341 | 342 | if (type == DHCPOFFER || type == DHCPACK) 343 | { 344 | // Lease Time 345 | SetDHCPOpt32 (pkt, DHCP_LEASE_TIME, htonl (a->m_dhcp_lease_time)); 346 | 347 | // Netmask 348 | SetDHCPOpt32 (pkt, DHCP_NETMASK, a->m_dhcp_netmask); 349 | 350 | // Other user-defined options 351 | SetDHCPOpt (pkt, 352 | a->m_dhcp_user_supplied_options_buffer, 353 | a->m_dhcp_user_supplied_options_buffer_len); 354 | } 355 | 356 | // End 357 | SetDHCPOpt0 (pkt, DHCP_END); 358 | 359 | if (!DHCPMSG_OVERFLOW (pkt)) 360 | { 361 | // The initial part of the DHCP message (not including options) gets built here 362 | BuildDHCPPre (a, 363 | &pkt->msg.pre, 364 | eth, 365 | ip, 366 | udp, 367 | dhcp, 368 | DHCPMSG_LEN_OPT (pkt), 369 | type); 370 | 371 | SetChecksumDHCPMsg (pkt); 372 | 373 | DUMP_PACKET ("DHCPMsg", 374 | DHCPMSG_BUF (pkt), 375 | DHCPMSG_LEN_FULL (pkt)); 376 | 377 | // Return DHCP response to kernel 378 | InjectPacketDeferred (a, 379 | DHCPMSG_BUF (pkt), 380 | DHCPMSG_LEN_FULL (pkt)); 381 | } 382 | else 383 | { 384 | DEBUGP (("[TAP] SendDHCPMsg: DHCP buffer overflow\n")); 385 | } 386 | 387 | MemFree (pkt, sizeof (DHCPMsg)); 388 | } 389 | } 390 | 391 | //=================================================================== 392 | // Handle a BOOTPS packet produced by the local system to 393 | // resolve the address/netmask of this adapter. 394 | // If we are in TAP_WIN_IOCTL_CONFIG_DHCP_MASQ mode, reply 395 | // to the message. Return TRUE if we processed the passed 396 | // message, so that downstream stages can ignore it. 397 | //=================================================================== 398 | 399 | BOOLEAN 400 | ProcessDHCP (TapAdapterPointer p_Adapter, 401 | const ETH_HEADER *eth, 402 | const IPHDR *ip, 403 | const UDPHDR *udp, 404 | const DHCP *dhcp, 405 | int optlen) 406 | { 407 | int msg_type; 408 | 409 | // Sanity check IP header 410 | if (!(ntohs (ip->tot_len) == sizeof (IPHDR) + sizeof (UDPHDR) + sizeof (DHCP) + optlen 411 | && (ntohs (ip->frag_off) & IP_OFFMASK) == 0)) 412 | return TRUE; 413 | 414 | // Does this message belong to us? 415 | if (!DHCPMessageOurs (p_Adapter, eth, ip, udp, dhcp)) 416 | return FALSE; 417 | 418 | msg_type = GetDHCPMessageType (dhcp, optlen); 419 | 420 | // Drop non-BOOTREQUEST messages 421 | if (dhcp->op != BOOTREQUEST) 422 | return TRUE; 423 | 424 | // Drop any messages except DHCPDISCOVER or DHCPREQUEST 425 | if (!(msg_type == DHCPDISCOVER || msg_type == DHCPREQUEST)) 426 | return TRUE; 427 | 428 | // Should we reply with DHCPOFFER, DHCPACK, or DHCPNAK? 429 | if (msg_type == DHCPREQUEST 430 | && ((dhcp->ciaddr && dhcp->ciaddr != p_Adapter->m_dhcp_addr) 431 | || !p_Adapter->m_dhcp_received_discover 432 | || p_Adapter->m_dhcp_bad_requests >= BAD_DHCPREQUEST_NAK_THRESHOLD)) 433 | SendDHCPMsg (p_Adapter, 434 | DHCPNAK, 435 | eth, ip, udp, dhcp); 436 | else 437 | SendDHCPMsg (p_Adapter, 438 | (msg_type == DHCPDISCOVER ? DHCPOFFER : DHCPACK), 439 | eth, ip, udp, dhcp); 440 | 441 | // Remember if we received a DHCPDISCOVER 442 | if (msg_type == DHCPDISCOVER) 443 | p_Adapter->m_dhcp_received_discover = TRUE; 444 | 445 | // Is this a bad DHCPREQUEST? 446 | if (msg_type == DHCPREQUEST && dhcp->ciaddr != p_Adapter->m_dhcp_addr) 447 | ++p_Adapter->m_dhcp_bad_requests; 448 | 449 | return TRUE; 450 | } 451 | 452 | #if DBG 453 | 454 | const char * 455 | message_op_text (int op) 456 | { 457 | switch (op) 458 | { 459 | case BOOTREQUEST: 460 | return "BOOTREQUEST"; 461 | case BOOTREPLY: 462 | return "BOOTREPLY"; 463 | default: 464 | return "???"; 465 | } 466 | } 467 | 468 | const char * 469 | message_type_text (int type) 470 | { 471 | switch (type) 472 | { 473 | case DHCPDISCOVER: 474 | return "DHCPDISCOVER"; 475 | case DHCPOFFER: 476 | return "DHCPOFFER"; 477 | case DHCPREQUEST: 478 | return "DHCPREQUEST"; 479 | case DHCPDECLINE: 480 | return "DHCPDECLINE"; 481 | case DHCPACK: 482 | return "DHCPACK"; 483 | case DHCPNAK: 484 | return "DHCPNAK"; 485 | case DHCPRELEASE: 486 | return "DHCPRELEASE"; 487 | case DHCPINFORM: 488 | return "DHCPINFORM"; 489 | default: 490 | return "???"; 491 | } 492 | } 493 | 494 | const char * 495 | port_name (int port) 496 | { 497 | switch (port) 498 | { 499 | case BOOTPS_PORT: 500 | return "BOOTPS"; 501 | case BOOTPC_PORT: 502 | return "BOOTPC"; 503 | default: 504 | return "unknown"; 505 | } 506 | } 507 | 508 | VOID 509 | DumpDHCP (const ETH_HEADER *eth, 510 | const IPHDR *ip, 511 | const UDPHDR *udp, 512 | const DHCP *dhcp, 513 | const int optlen) 514 | { 515 | DEBUGP ((" %s", message_op_text (dhcp->op))); 516 | DEBUGP ((" %s ", message_type_text (GetDHCPMessageType (dhcp, optlen)))); 517 | PrIP (ip->saddr); 518 | DEBUGP ((":%s[", port_name (ntohs (udp->source)))); 519 | PrMac (eth->src); 520 | DEBUGP (("] -> ")); 521 | PrIP (ip->daddr); 522 | DEBUGP ((":%s[", port_name (ntohs (udp->dest)))); 523 | PrMac (eth->dest); 524 | DEBUGP (("]")); 525 | if (dhcp->ciaddr) 526 | { 527 | DEBUGP ((" ci=")); 528 | PrIP (dhcp->ciaddr); 529 | } 530 | if (dhcp->yiaddr) 531 | { 532 | DEBUGP ((" yi=")); 533 | PrIP (dhcp->yiaddr); 534 | } 535 | if (dhcp->siaddr) 536 | { 537 | DEBUGP ((" si=")); 538 | PrIP (dhcp->siaddr); 539 | } 540 | if (dhcp->hlen == sizeof (MACADDR)) 541 | { 542 | DEBUGP ((" ch=")); 543 | PrMac (dhcp->chaddr); 544 | } 545 | 546 | DEBUGP ((" xid=0x%08x", ntohl (dhcp->xid))); 547 | 548 | if (ntohl (dhcp->magic) != 0x63825363) 549 | DEBUGP ((" ma=0x%08x", ntohl (dhcp->magic))); 550 | if (dhcp->htype != 1) 551 | DEBUGP ((" htype=%d", dhcp->htype)); 552 | if (dhcp->hops) 553 | DEBUGP ((" hops=%d", dhcp->hops)); 554 | if (ntohs (dhcp->secs)) 555 | DEBUGP ((" secs=%d", ntohs (dhcp->secs))); 556 | if (ntohs (dhcp->flags)) 557 | DEBUGP ((" flags=0x%04x", ntohs (dhcp->flags))); 558 | 559 | // extra stuff 560 | 561 | if (ip->version_len != 0x45) 562 | DEBUGP ((" vl=0x%02x", ip->version_len)); 563 | if (ntohs (ip->tot_len) != sizeof (IPHDR) + sizeof (UDPHDR) + sizeof (DHCP) + optlen) 564 | DEBUGP ((" tl=%d", ntohs (ip->tot_len))); 565 | if (ntohs (udp->len) != sizeof (UDPHDR) + sizeof (DHCP) + optlen) 566 | DEBUGP ((" ul=%d", ntohs (udp->len))); 567 | 568 | if (ip->tos) 569 | DEBUGP ((" tos=0x%02x", ip->tos)); 570 | if (ntohs (ip->id)) 571 | DEBUGP ((" id=0x%04x", ntohs (ip->id))); 572 | if (ntohs (ip->frag_off)) 573 | DEBUGP ((" frag_off=0x%04x", ntohs (ip->frag_off))); 574 | 575 | DEBUGP ((" ttl=%d", ip->ttl)); 576 | DEBUGP ((" ic=0x%04x [0x%04x]", ntohs (ip->check), 577 | ip_checksum ((UCHAR*)ip, sizeof (IPHDR)))); 578 | DEBUGP ((" uc=0x%04x [0x%04x/%d]", ntohs (udp->check), 579 | udp_checksum ((UCHAR *) udp, 580 | sizeof (UDPHDR) + sizeof (DHCP) + optlen, 581 | (UCHAR *) &ip->saddr, 582 | (UCHAR *) &ip->daddr), 583 | optlen)); 584 | 585 | // Options 586 | { 587 | const UCHAR *opt = (UCHAR *) (dhcp + 1); 588 | int i; 589 | 590 | DEBUGP ((" OPT")); 591 | for (i = 0; i < optlen; ++i) 592 | { 593 | const UCHAR data = opt[i]; 594 | DEBUGP ((".%d", data)); 595 | } 596 | } 597 | } 598 | 599 | #endif /* DBG */ 600 | -------------------------------------------------------------------------------- /COPYRIGHT.GPL: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc. 5 | 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Library General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License version 2 298 | as published by the Free Software Foundation. 299 | 300 | This program is distributed in the hope that it will be useful, 301 | but WITHOUT ANY WARRANTY; without even the implied warranty of 302 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 303 | GNU General Public License for more details. 304 | 305 | You should have received a copy of the GNU General Public License 306 | along with this program; if not, write to the Free Software 307 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 308 | 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Library General 339 | Public License instead of this License. 340 | --------------------------------------------------------------------------------