peral
驱动牛犊
驱动牛犊
  • 注册日期2002-04-29
  • 最后登录2004-01-14
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1406回复:3

为了解决问题,我可以贡献200分!

楼主#
更多 发布于:2003-01-02 10:02
以前从没接触过driver的编程,刚看了几天NDIS,一头雾水:(,

现在需要在wince下做一个packet filter,有点类似于NAT,
但需要增加一些传输层(TCP/UDP)的分析和改动。
简单的功能需求:
1 截获每一个发到本机MAC地址的IP包
2 分析IP包头和传输层包头,如果符合某种规则(
比如源/目标IP地址在某个范围内,源/目标端口在某个特定范围内),那么向上发给应用层来处理,不是转发!

从NDIS的模型上看,好象并不难,我目前主要的疑问:
是如何让IP地址不是本机的包上传给应用层,我想
是否可以修改应用层包数据,把原始的IP地址/端口信息写进去,
然后由上层某个固定端口的socket来接收。

大侠们,救救我吧。
 :P
HuYuguang
论坛版主
论坛版主
  • 注册日期2001-04-25
  • 最后登录2013-04-29
  • 粉丝3
  • 关注1
  • 积分92分
  • 威望11点
  • 贡献值0点
  • 好评度9点
  • 原创分1分
  • 专家分0分
沙发#
发布于:2003-01-02 11:01
以前从没接触过driver的编程,刚看了几天NDIS,一头雾水:(,

现在需要在wince下做一个packet filter,有点类似于NAT,
但需要增加一些传输层(TCP/UDP)的分析和改动。
简单的功能需求:
1 截获每一个发到本机MAC地址的IP包
2 分析IP包头和传输层包头,如果符合某种规则(
比如源/目标IP地址在某个范围内,源/目标端口在某个特定范围内),那么向上发给应用层来处理,不是转发!

从NDIS的模型上看,好象并不难,我目前主要的疑问:
是如何让IP地址不是本机的包上传给应用层,我想
是否可以修改应用层包数据,把原始的IP地址/端口信息写进去,
然后由上层某个固定端口的socket来接收。

大侠们,救救我吧。
 :P


这个方法原理上完全可行。
大致操作过程如下:
1、核心的到一个数据包。
2、判断需要交给app层。既然你的设备属于nat类型的设备,
那么想必其它主机的网关都设置为你的ip,所以也不需要
设置混杂模式。
3、构造一个udp数据包,封装原ip包,交给上层socket端口。

但是细节部分需要做如下考虑:
1、封装之后数据可能拉长。此情况下会得到一个超长的udp
包,上层协议,例如ip,可能没有分配足够大的空间容纳你
的数据包。这种情况下的对策是封装了udp头之后,碎成两个
ip包indicate。
2、你的机器上也许安装了firewall,而firewall的实现也许
在你的driver的上层。这样你indicate一个udp数据包到上层,
也许会被firewall丢弃。因此你必须打开firewall的这个udp
端口。
3、你构造udp包的时候,udp头前面还必须有一个ip头。这个
ip头不能直接复制原来的ip头。你最好是自己定义一个ip头,
用固定源地址,而且不分片。这样也有利于你设置firewall
规则。直接复制原ip头并不会产生太大的问题,因为通常后面
发过来的ip头并不分片。但是ping -l 2000的情况下,会分片。
4、最好用异步socket,否则也许会丢失数据包。

这本身就是核心层和应用层通讯的一个通用方法,freeswan
的pfkey就用类似的思路实现。

不过这个方法在win平台下未必最好。较好的方法还是使用irp
封装数据包上交。但是也许这个driver已经没有deviceobject,
或者已经有了一个irp路线,而你又不打算实现全双工的异步
io,那么这种方法也是完全可以接受的。

用irp的情况下,当判断该数据包需要通过irp交给应用层时,
在receivehandler中总是返回status_success,在
receiveppackethandler中,总是返回0,告诉ndis不需要对
此数据包进行继续处理,也不需要调用complete函数。

Good Luck!

不再回忆从前,我已经生活在幸福当中。
peral
驱动牛犊
驱动牛犊
  • 注册日期2002-04-29
  • 最后登录2004-01-14
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2003-01-02 14:29
谢谢版主!

第一步看来是迈出去了,至少方案可行,呵呵。
关于长度和分片的问题暂时可以不考虑,根据我的应用的需求,
我想要做的就是把真实的UDP/TCP头和真实IP地址写到应用层中,然后加上一个UDP头,再加上一个IP头(目的地址为本机),就OK了,总共增加的字节数就是4+8=12,没错吧。

具体的实现上还有很多细节,对于有这方面经验的人想来也不难了,
对我这种driver新手而言可能要走一些弯路,所以需要指导。:)

我的新问题:
1 一般的NAT应该是在IP层就解决问题了吧,不需要让应用层处理吧。
2 Wince跟win2000,XP还是有一些区别的,它提供了一些网卡的
NDIS driver源码,但是没有我用的RTL8139的。另外还提供了
一个passthru的例子,我不太明白passthru是否独立于还是替代
网卡driver来运行? IMD跟NDIS hook相比各有些什么优劣?
mikeluo
驱动老牛
驱动老牛
  • 注册日期2001-09-04
  • 最后登录2007-05-07
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2003-01-02 15:24
胡版主好久不见,别来无恙乎?
学而不思则罔,思而不学则殆 学而思之,思而学之,岂非圣人乎?
游客

返回顶部