主页‎ > ‎

TAPDriver

    TAPDriver是一种基于OpenVPN虚拟网卡的驱动程序。通过虚拟网卡,TAPDriver可以截获各种通讯协议,并对感兴趣的协议进行调整或者 篡改。在这里主要是针对Windows 2000无法调整VPN的通讯端口所特制的通讯程序。使用TAPDriver,可以让Windows 2000对本地TAPDriver进行VPN通讯,再由TAPDriver与外部实际VPN服务器进行通讯。

       TAPDriver主要是通过虚拟网卡设备,给基于L2TPVPN通道提供便利。

一、    主要文件

TAPDriver的主要文件有:Global.hTAPDriver.hTAPDriver.lib

1.1   Global.h

全局定义文件,主要是对一些常量进行了重新规范化定义。

例如:

//INT8

typedef char                                                                                       _INT8;

//Unsigned INT8

typedef unsigned char                                                                        _UINT8;

//INT16

typedef short                                                                                      _INT16;

//Unsigned INT16

typedef unsigned short                                                                       _UINT16;

//INT32

typedef int                                                                                         _INT32;

//Unsigned INT32

typedef unsigned int                                                                           _UINT32;

1.2 TAPDriver.h

       TAPDriver驱动的主要函数定义文件。

1.2.1 InitializeTAPDriver

       初始化TAPDriver的运行环境。包括启动日志、启动Socket功能、查找注册表等等。在使用TAP设备前,必须运行该函数。

参数名

类型

备注

(无)

 

 

 

 

 

返回值类型

备注

_BOOL

如果初始化成功,则返回_TRUE;否则返回_FALSE

注意:无论该函数是否返回成功或者失败,都必须调用UninitializeTAPDriver

1.2.2 UninitializeTAPDriver

       释放TAPDriver的运行环境。包括释放注册表内容、释放Socket功能、关闭文件日志等等。在程序退出之前必须调用此函数,否则可能导致内存泄漏。

参数名

类型

备注

(无)

 

 

 

 

 

返回值类型

备注

void

 

1.2.3 SetVirtualAddress

       设置TAPDriver的虚拟IP地址。

参数名

类型

备注

lpstrLocalIPAddress

_STRING

本地IP地址。

例如:10.7.0.6

lpstrLocalNetmask

_STRING

本地IP地址的掩码。

例如:255.0.0.0

lpstrRemoteIPAddress

_STRING

远程IP地址。

例如:10.7.0.5

返回值类型

备注

void

 

       在初始化TAPDriver运行环境后,且在开启TAPDriver之前,可以调用此函数来设置虚拟本地和远程地址。此地址必须配对使用,具体的要求可以参考openvpn。常用配置见上表。

1.2.4 SetL2TPServer

       设置L2TP服务器的远程地址和端口。

参数名

类型

备注

lpstrIPAddress

_STRING

远程IP地址。

例如:60.28.160.110

nPort

_UINT16

远程端口。

例如:1701

返回值类型

备注

void

 

       在初始化TAPDriver运行环境后,且在开启TAPDriver之前,可以调用此函数来设置L2TP服务器的IP地址和端口。

1.2.5 TAPDriverExists

       检查TAPDriver是否注册。

参数名

类型

备注

lpstrAdapterName

_STRING

设备名。

例如:“tap0801”。

 

 

 

返回值类型

备注

_BOOL

如果在注册表中可以找到相关设备,则返回_TRUE;否则返回_FALSE

       在初始化TAPDriver运行环境后,且在开启TAPDriver之前,可以用此函数检测TAPDriver是否注册。如果已经注册,可以选择开启TAPDriver;如果没有注册,可以选择提示安装或者放弃开启TAPDriver

1.2.6 OpenTAPDriver

       开启TAPDriver。开启TAPDriver将包括建立Socket通道、打开设备、建立读写机制等等。

参数名

类型

备注

lpstrAdapterName

_STRING

设备名。

例如:“tap0801”。

 

 

 

返回值类型

备注

_BOOL

如果开启设备成功,则返回_TRUE;否则返回开启设备失败。

       注意:无论开启设备是否成功或者失败,都需要调用CloseTAPDriver。否则可能会导致内存泄漏,某些设备或者通讯未关闭的情况。

1.2.7 CloseTAPDriver

       关闭TAPDriver

参数名

类型

备注

(无)

 

 

 

 

 

返回值类型

备注

void

 

1.2.8 IsTAPDriverRunning

       检查TAPDriver是否正常运行。

参数名

类型

备注

(无)

 

 

 

 

 

返回值类型

备注

_BOOL

如果正常运行则返回_TRUE;否则返回_FALSE

       在开启TAPDriver以后,通过此函数可以检测读写线程的工作情况。如果任何一个线程出现异常,将会导致此函数返回_FALSE。此时可以选择关闭设备,再重新打开。

1.2.9 GetTAPDriverInputSize

       输入数据计数器。

参数名

类型

备注

(无)

 

 

 

 

 

返回值类型

备注

_UINT32

返回自TAPDriver开启以后,TAPDriver接收到的来自机器的L2TP请求的字节数。

       在开启TAPDriver以后,可以通过此函数检测从本机发往远程主机的数据情况。

1.2.10 GetTAPDriverOutputSize

       输出数据计数器。

参数名

类型

备注

(无)

 

 

 

 

 

返回值类型

备注

_UINT32

返回自TAPDriver开启以后,TAPDriver写入到本机的L2TP请求的字节数。

在开启TAPDriver以后,可以通过此函数检测从远程主机发往本机的数据情况。

1.2.11 SetTAPDriverLog

       日志开关

参数名

类型

备注

bLog

_BOOL

如果需要打开日志,则设置bLog_TRUE;如果需要关闭,则设置bLog_FALSE

 

 

 

返回值类型

备注

void

 

1.3基本例程

////////////////////////////////////////////////////////////////////////////////

//

// General including files.

//

// Including the files for the system.

//

// These including files are generally used in different operation system.

//

////////////////////////////////////////////////////////////////////////////////

 

//包括类型定义文件

#include "Global.h"

//包括驱动基本函数文件

#include "TAPDriver.h"

 

//For windows.

#ifdef _MICROSOFT_WINDOWS

#include <windows.h>

#endif

 

//Import Library

//引入库文件。

#pragma comment(lib,"TAPDriver.lib")

 

//TAP Driver Name

//缺省的TAPDriver的名字。

#define TAP_DRIVER_NAME                                                                    "tap0801"

 

////////////////////////////////////////////////////////////////////////////////

//

// Main function.

//

////////////////////////////////////////////////////////////////////////////////

 

_INT32 main(_INT32 argc,_STRING argv[])

{

       //Initialize TAP driver.

       //初始化TAPDriver的运行环境。

//在启动TAPDriver之前必须调用此函数。

       if(InitializeTAPDriver())

       {

              //Check existance.

              //检查TAPDriver是否注册。

              //如果没有发现注册,则放弃启动。

              if(TAPDriverExists(TAP_DRIVER_NAME))

              {

                     //Set address.

                     //设置虚拟地址,包括本地虚拟地址、网络掩码和远程虚拟地址。

                     SetVirtualAddress("10.7.0.6","255.0.0.0","10.7.0.5");

                     //Set L2TP server.

                     //设置L2TP服务器的参数,包括远程地址和端口。

                     SetL2TPServer("60.28.160.110",1701);

                     //Open TAP driver.

                     //打开TAPDriver设备。

                     if(OpenTAPDriver(TAP_DRIVER_NAME))

                     {

                            //Do process.

                            do

                            {

                                   //Check keyboard.

                                   if(kbhit())

                                   {

                                          //Get a char.

                                          _CHAR c = getchar();

                                          //Get a char.

                                          if(c == 'Q')

                                          {

                                                 break;

                                          }

                                          else if(c == 'A')

                                          {

                                                 //打开TAPDriver日志

                                                 SetTAPDriverLog(_TRUE);

                                          }

                                          else if(c == 'X')

                                          {

                                                 //关闭TAPDriver日志

                                                 SetTAPDriverLog(_FALSE);

                                          }

                                          else

                                          {

                                                 //Print information.

                                                 printf("Main::main : press \"Q\" for exit !");

                                          }

                                   }

                                   //Print.

                                   printf("Output = %dByte(s),Input = %dByte(s)\r",

                                          GetTAPDriverOutputSize(),GetTAPDriverInputSize());

                                   //Sleep

                                   //通过休眠来释放CPU的占有率。

                                   Sleep(1);

                            //检查设备是否在运行

                            }while(IsTAPDriverRunning());

                     }

                     else

                     {

#ifdef _DEBUG

                            printf("Main::main : fail to open TAP driver !");

#endif

                     }

                     //Close TAP driver.

                     //关闭TAPDriver设备。

                     //无论开启是否成功,该函数都必须被调用。

                     CloseTAPDriver();

              }

              else

              {

#ifdef _DEBUG

                     printf("Main::main : TAP driver not exists !");

#endif

              }

       }

       else

       {

#ifdef _DEBUG

              printf("Main::main : fail to initialize TAP driver !");

#endif

       }

       //Uninitialize TAP driver.

       //释放TAPDriver运行环境。

//无论初始化是否成功,该函数都必须被调用。

       UninitializeTAPDriver();

 

#ifdef _DEBUG

       printf("Main::main : successfully done !");

#endif

       //Return success.

       return _SUCCESS;

}

1.4常见问题

1.4.1 TAPDriver的安装

       TAPDriver安装以后,必须重新启动机器,才可以启动该驱动程序。否则会导致打开设备失败。具体返回错误为31。原因是:系统没有找到新安装设备的ARP设备表入口。

1.4.2 TAPDriver的名字

       TAPDriver安装后的常见注册名为“tap0801”。一般使用这个名字开启设备。如果原始驱动有变化,则该名字也会产生变化。

1.4.3 L2TP拨号

       有时候TAPDriver开启以后,L2TP第一拨号可能会失败。可以再超时以后,重新再拨号一次即可正常使用。

1.4.4 默认网关的问题

       TAPDriver开启以及L2TP拨号成功以后,如果使用“远程默认网关地址”将可能导致大量发包,使得CPU占用至100%。取消此项目以后,则恢复到正常状态。

1.4.5 TAPDriver的日志

       系统会自动在当前工作目录下建立一个log目录,所有相关日志会记录在此文件夹当中。如果日志开放,则可能会影响通讯速度。请根据实际情况选择使用。