看你是否够老 – ipman的vxd程序介绍的翻译

不知到现在hack小将们还有多少知道ipman这个东西,当时2000年左右在学校的内网大家玩的不亦乐乎。

年龄大了就开始怀旧,在我尝试了n种搜索方法之后,终于找到了当年我翻译的ipman的网卡驱动的说明。可惜的是nankai bbs几经变迁,在上面已经找不到我发的原文。只有一个转载了n层的版本:

http://nkbbs.org/cgi-bin/bbs/bbstcon?board=SysSafe&file=M.947127744.A

在这个叫做“烟雨漓江BBS站”的BBS以及四川大学“蓝色星空“站,居然今天也仍旧能找到别人转载的我写的关于vpacket.vxd的翻译(或者直接google "vpacket.vxd jxj"):

http://bbs.gxnu.cn/bbstcon.php?board=Programming&gid=1286

http://anphia.blog.lsxk.org/wForum/boardcon.php?bid=16&id=202&ftype=6

那时的人还是有节操,转载时不忘注明出处。

也贴在这里博大家一笑:

———————-我是原文分割线—————————————————-

这个,vxd有个说明文档,试着翻译了一下,不当之处请指出…. Windows 95下的直接网卡读写 澳大利亚堪培拉大学 信息科学和工程系 1997.8.6 概论

这个文档是VPACKET的说明.VPACKET是Windows 95下的一个虚拟设备驱动程序,它可以通过WIN32程序对安装在PC机上的任何网卡进行直接读写操作。直接网卡读写对编写网络管理程序和那些想实现自己的意图的编程者是十分有用的。这个驱动程序是P32编程环境[1]的一部分。P32是一个堪培拉大学用于操作系统和协议设计课程的WIN32程序包。

1.介绍

WIN32程序平台不支持低层次的直接的网卡操作.需要这种操作的程序(由于种种原因)必须用一个自定制的虚拟设备驱动程序(VXD).VXD提供一个在底层网络控制接口(NICS)和高层的WIN32程序间的一个服务接口.它的基本结构见图一. _________________ | 应用程序 | |_________________| /|\ | ———|——————————————– | _____\|/___________ | VPACKET | | VXD | |____________ ___| /|\ /|\ | _____\|/___________________________________________ | | | NDIS 3.10 | |_________________________________________________ | /|\ /|\ /|\ | | | ___\|/___ ___\|/___ ___\|/___ | NIC 0 | | NIC 0 | ……… | NIC N | |______ | |_______| |_______| 图一: 结构

一个程序必须首先用一个WIN32_API函数:CreateFile将此VXD装入内存,然后才能调用WIN32设备I/O控制函数来实现此VXD提供的功能。

2.关于接口抽象层

正像在图一中所看到的那样,这个虚拟设备驱动程序并没有直接面对已安装好的底层网络控制接口.在网络硬件和VXD之间有一个叫做NDIS 3.10的接口抽象层,使用这种接口抽象层的意图在于保护需要NIC接口的软件不受底层网络适配器特殊硬件细节的影响。因此这个VAPCKET VXD可以方便的同安装在不同机器上的任何NIC接口进行通讯,但这台机器上的网卡必须是支持NDIS的.注意,不同版本的NDIS对网卡的支持有些不同.尤其是微软的Dialup网卡(PPPMAC)不支持NDIS.因为一个普通的NDIS Send函数在这种网卡上传送不了任何数据。此外,这种网卡也不支持NDSI所支持的网卡所具有的数字统计硬件。

3.怎样装入一个VXD

一个WIN32程序使用一个特定的形式调用WIN32_API函数:CreateFile来装入VXD.下面的代码演示了如何装入VAPCKET VXD.

#include <windows.h>
HANDLE hVxD;        
hVxD = CreateFile("\\\\.\\VPACKET.VXD", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED | FILE_FLAG_DELETE_ON_CLOSE, NULL); NULL); 
if (hVxD == INVALID_HANDLE_VALUE)
  return SYSERR;

第一个参数说明将要装入的VPACKET.VXD所在的目录.第六个参数应特别注意:它指明此驱动程序支持异步操作(FILE_FLAG_OVERLAPPED),同时也指出当VXD关闭时应当从内存中被释放(FILE_FLAG_DELETE_ON_CLOSE).

此函数要求异步操作立即返回到它的调用者那里,而不必非要等到操作被完成.应用程序必须用另外的方法(下面将要提到)来断定操作是否已经完成.

调用CreateFile函数所返回的句柄不是一个普通的文件句柄.实际上,程序就是通过它来完成设备驱动程序所提供的功能.

VPACKET VxD能被"打开"无数次,每次调用CreateFile函数将返回一个与其它各次不同的句柄.仅仅在第一次调用CreateFile函数时是真正的装入和执行此VxD,其它时刻调用CreateFile函数仅仅是返回一个新句柄而已.

VPACKET VxD的一个显著特征就是不需要安装或者设置,因此没有相应的inf文件.所有的设置工作在这个VxD被执行并被确定的绑定到一个或多个网络接口时被自动完成.

4.怎样从内存中卸载VxD

这个VxD能够被WIN32_API函数CloseHandle所卸载,释放从CreateFile函数所获得的句柄.假如此驱动程序被打开多次,则必须当所有的句柄都被释放时此VxD才被卸载.

5.怎样绑定到网络接口层

当VPACKET VxD被装入和执行时,它必须与一个特定的网络接口控制器发生联系,即绑定.绑定可以通过下面的Bind函数来完成.

int Bind(HANDLE hVxD, BYTE* inBuffer) {
  HANDLE hEvent;
  DWORD cbRet;
  OVERLAPPED ovlp = {0,0,0,0,0};
  int result;
  int cbIn = 5;
  hEvent = CreateEvent(0, TRUE, 0, NULL);
  if (!hEvent)
    return SYSERR;           
  ovlp.hEvent = hEvent;
  result = DeviceIoControl(hVxD, IOCTL_PROTOCOL_BIND, IOCTL_PROTOCOL_BIND, inBuffer, cbIn, inBuffer, cbIn, &cbRet, &ovlp);
  if (!result)
    GetOverlappedResult(hVxD, &ovlp, &cbRet, TRUE);
    CloseHandle(hEvent);
    return OK;        
}

第一个参数是先前调用的CreateFile函数所返回的句柄.第二个参数是命名句柄所将要绑定的适配器的字符串.这个字符串可以从Windows95的注册表的如下目录找到:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Class\Net

注意:对于每一个CreateFile函数所返回的句柄,应用程序再进行任何其他操作之前必须被绑定.

6.设备驱动API函数

一个WIN32程序可以用DeviceIoControl函数来调用设备驱动程序所提供的服务功能.上面所列出的Bind函数,第一个参数是

CreateFile函数所返回的句柄,第二个参数是下列函数代码之一:
IOCTL_PROTOCOL_QUERY_OID        得到详细的目标Object的ID
IOCTL_PROTOCOL_SET_OID          设置详细的目标ObjectID
IOCTL_PROTOCOL_STATISTICS       得到特定网卡(适配器)的状态
IOCTL_PROTOCOL_RESET            复位网卡(适配器)
IOCTL_PROTOCOL_READ             从网络上接受一个包
IOCTL_PROTOCOL_WRITE            在网上发送一个包
IOCTL_PROTOCOL_MACNAME          得到网卡驱动的名称
IOCTL_PROTOCOL_BIND             绑定VPACKET VXD到特定网卡(适配器)

使用以上操作的例子在附录中给出.

7.异步操作

Bind函数说明了异步操作是怎样在WIN32程序中实现的.WIN32_API函数CreateEvent被调用后的返回值存入OVERLAPPED结构的成员hEvent句柄.OVERLAPPED结构中剩下的成员被赋值为0.在调用DevIoControl函数时OVERLAPPED结构体的地址指针被作为最后一个参数传递给设备驱动程序.然后驱动程序便开始进行操作并返回一个值.当驱动程序完成所要求的操作时将发给一动程序便开始进行操作并返回一个值.当驱动程序完成所要求的操作时将发给一个特定的事件一个信号.与此同时WIN32程序可以完成一些其他事情.在绑定结束之前,Bind函数干不了更多的事情.因此在Bind的线程中仅仅调用了WIN32_API函数GetOverlappedResult.这个函数会阻止程序运行,直到特定事件收到操作完成的信号.(因为此函数最后一个参数恒为真实值TRUE).

参数3:    包含指定操作所需要的输入数据的缓冲区的地址
参数4:    上面提到的缓冲区大小
参数5:    保留指定操作的返回信息的缓冲区的地址
参数6:    上面提到的缓冲区大小
参数7:    一个双字(DWORD)变量的地址.这个变量表示驱动程序所返回的字节数.注意:这个变量也被用作GetOverlappedResult函数的参数.

当应用程序需要读出网卡所接受到的数据时,异步输入输出机制的强大优势将会更明显.应用程序(往往如此)不可能预先知道何时数据包将会从网上到达.因此程序可以完成一些其他的处理(如:处理Windows 95的消息)和通过调用GetOverlappedResult函数来检查是否有数据包到达.假如GetOverlappedResult函数返回值为FALSE,同时调用GetLastError函数返回ERROR_IO_PENDING,应用程序就可以知道没有数据包到达.假如GetOverlappedResult函数返回值为TRUE,则应用程序便知道有数据包到达,因此可以进行一些操作.

9.结论

这个VPACKET虚拟设备驱动程序提供给运行于Windows 95下的WIN32应用程序一种简单且有效的直接进行网络接口控制的机制.

在P32编程环境中,利用这个驱动程序,在Comer和Stevens[2]编写的代码基础之上实现了完全的TCP/IP协议.这个程序支持复合网络接口,完全的IP协议和入口功能.

作者的版本中还有一些附加特征:支持IP地址和端口列表.一个局域网中的主机可以使用另一个局域网中的一个可用的IP地址.所有局域网中的主机可以使用端对端(PPP)协议的IP地址连接到互联网(Internet)服务商.

10.参考及附注

[1] 有关信息可在以下网址获得: http://willow.canberra.edu.au/~chrisc/p32.html

[2] 有关信息在<<用TCP/IP进行网络互连>>第一卷,第二本,第二版查到,由 Prentice-Hall出版.1994.

[3] 关于VPACKET VXD的源代码,可以写信给作者. chrisc@fir.canberra.edu.au

[4] NAT32是Windows 95下的一个地址翻译包.可从下列网址查到有关信息: http://willow.canberra.edu.au/~chrisc/nat32.html http://willow.canberra.edu.au/~chrisc/nat32.html

原文发布于微信公众号 - FreeBuf(freebuf)

原文发表时间:2014-04-21

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java技术分享

高并发分布式系统中生成全局唯一Id汇总

数据在分片时,典型的是分库分表,就有一个全局ID生成的问题。 单纯的生成全局ID并不是什么难题,但是生成的ID通常要满足分片的一些要求:    1 不能有单点故...

3185
来自专栏信安之路

PHP使用了PDO还可能存在sql注入的情况

“用 PDO 来防止 SQL 注入。”大概学过 PHP 的都听说过这句话。代码中出现了 PDO 就行了吗?答案肯定是否定的。接下来给大家介绍几种使用了 PDO ...

3520
来自专栏Bingo的深度学习杂货店

PHP 笔试 + 面试题

本章主要介绍常见的 PHP 笔试 + 面试题,包括: ---- 基础及程序题 数据库技术题 综合技术题 项目及设计题 ---- 基础及程序题 [1] 写一...

1.3K5
来自专栏xingoo, 一个梦想做发明家的程序员

Elasticsearch——分页查询From&Size VS scroll

Elasticsearch中数据都存储在分片中,当执行搜索时每个分片独立搜索后,数据再经过整合返回。那么,如果要实现分页查询该怎么办呢? 更多内容参考Ela...

8396
来自专栏乐沙弥的世界

Oralce 10g 使用DBCA创建数据库

   Oracle提供了DBCA来创建数据库,对于初学者来说使用DBCA创建数据库简化了很多工作和设置,直接在交互界面即可实现所有的功能。然而对于实际的生产数据...

712
来自专栏一枝花算不算浪漫

[Java面试八]Hibernate总结以及在面试中的一些问题.

46912
来自专栏pangguoming

PowerDesigner使用教程|使用方法

PowerDesigner安装方法: http://dev.firnow.com/course/3_program/java/javajs/20090908/...

4746
来自专栏互联网技术栈

Elasticsearch之元数据(meta-fields)介绍

在Elasticsearch下,一个文档除了有数据之外,它还包含了元数据(Metadata)。每创建一条数据时,都会对元数据进行写入等操作,当然有些元数据是在创...

1656
来自专栏祝威廉

ElasticSearch QueryCache漫谈

这些天在做ES调优,因为之前更多的是考虑ES的架构和可运维性,并没有过多关注query调优这块。今天一查Query Cache相关的内容,发现是少之又少。于是自...

1722
来自专栏皮皮之路

【MySQL】通过Binary Log简单实现数据回滚(一)

2966

扫码关注云+社区

领取腾讯云代金券