向各位前辈请教一个关于自己编写网络驱动方面的问题

小弟接触QNX的时间太短,很多东西还不是很明白,望各位前辈能不吝赐教。

最近接到一个任务,要编写一个类似sniffer的小程序,完成的任务是能够对上行和下行传输数据进行实时监控,要求对TCP/IP和Qnet的数据流进行区分,并对其各自流量分别作出统计。

这几天认真看了看白皮书中的DDK的network部分,感觉很多东西很晦涩难懂,好不容易在openqnx中找到一个类似的源程序,个人认为略微加工就能完成任务,但不知道具体怎么下手。

我觉得也许这样能够行得通,就是向io-net注册一个REG_FILTER_BELOW的模块,并且使io_net_registrant_t中的top_type置为"qnet",bot_type置为"en"就能实时统计基于qnet传输的数据流量但不统计基于TCP/IP协议的流量;同样,如果将top_type置为"ip"就能监控基于TCP/IP传输的流量。

不知道这样是不是可行?给点建议吧。

另外一个问题,我知道在成功挂载自己写的fillter之后会在/dev/io-net/下生成一个相应的文件(如en_en0) ,首先通过open()打开这个文件,并设打开文件描述符为fd,并且我也知道通过在应用程序中以fd作为第一个参数进行devctl()调用可以使得io-net调用我在fillter源程序中的填写的相应的devctl()(就是在结构io_net_registrant_funcs_t中那个),我的问题是,怎么才能让我的应用程序得到fillter源程序中的一些变量的值呢?比如说我想要让应用程序调用devctl()得到当前时刻的流量值.
简而言之,就是我怎么才能让应用程序中的devctl()调用和fillter程序中的那个io_net_registrant_funcs_t结构的devctl()有机的联系起来进行某种值传递?
希望最好能给我一个简单的例子,提前谢谢大家了!

注册 REG_FILTER_ABOVE,用"en"、"en"做top/bot_type。这样就能收到所有以太网包。然后查ether_type,0806是arp,0800是ip,8204是QNET(假设你是6.3)。

Xtang,感谢您的指点,我想问问您所说的查看ether_type是在哪个结构中存在的吗?可以有现有的函数进行查询得到吗?或是要自己进行以太网包的某个字段进行分析?如果分析的话是不是就是要对npkt_t结构进行。
今天我在ftp.qnx.com中的FAQ中得到了关于以太网包的结构,是这样子的:
±-----------+
| | Preamble -
| 62 bits | A series of alternating 1’s and 0’s used by the
| | ethernet receiver to acquire bit synchronization.
| | This is generated by the chip.
±-----------+
| | Start Of Frame Delimiter -
| 2 bits | Two consecutive 1 bits used to acquire byte
| | alignment. This is generated by the chip.
±-----------+
±-----------+
| | Destination Ethernet Address -
| 6 bytes | Address of the intended receiver.
| | The broadcast address is all 1’s.
±-----------+
| | Source Ethernet Address -
| 6 bytes | The unique ethernet address of the sending
| | station.
±-----------+
| | Length or Type field -
| 2 bytes | For IEEE 802.3 this is the number of bytes of
| | data. For Ethernet I&II this is the type of
| | packet. Types codes are > 1500 to allow both to
| | coexist. The type code for IP packets is 0x800.
±-----------+
| 46 bytes | Data -
| to | Short packets must be padded to 46 bytes.
| 1500 bytes |
±-----------+
±-----------+
| | Frame Check Sequence -
| 4 bytes | The FCS is a 32 bit CRC calculated using
| | the AUTODIN II polynomial.
| | This field is normally generated by the chip.
±-----------+
您所说的ether_type是不是就是标记为Length or Type field的那两个字节? 另外我想知道的是,白皮书上说到的以太网packet的头(head)是14个字节,但这个结构中却远远不只14个字节呀,为什么呢?那14个字节是上面的哪14个字节呢?望给个解释,谢谢!

所有以太网的包头格式都是一样的,随便在网上查以太网说明就可以了。跟QNX不QNX没有关系。

你看的说明里,包括了在物理介质上传的一些特殊数据位,这些都由硬件来产生和吸收,软件看不见的。

EtherType在以太网包开头的第十二,十三个字节。

嗯,我现在已经可以截获以太网包了,那么进一步,如果我想对以太网包进行过滤,比如说我想过滤掉基于QNET协议的包(可以根据ether_type字段判断出),或者过滤掉来自某个MAC地址(可以根据source ethernet address字段判断出)的包,即不让上层得到这些包,我应当在我的fillter的源程序中怎样添加代码呢?

io_net_self->tx_done(reg, npkt);

devctl()带数据出来有几个注意点:

自定义的DCMD_* 里要或入DEVDIR_TO位(/usr/include/devctl.h)

看看 io_devctl_t (/usr/include/sys/iomsg.h) 结构,特别是回答结构 _io_devctl_reply.

Xtang,因为我用的是6.21的版本,所以您上次说那个根据ether_type来区分Qnet与IP包的方法好像行不通。我今天用自己编的一个基于Qnet通信的小程序实现了两台机器的通信,并把截获到的以太网包全写进了一个文件,最后拿到windows下用ultra edit进行了分析,结果是ether_type那两个字节全都是0800,请问还有什么方法可以区分ip的包和qnet的包吗(在我的版本基础上)?

改用6.3吧。:slight_smile:

QNX6.21上QNX包也是IP承载,IP头紧接着ether头。你要看IP头里的protocol。IP是0,TCP是6,UDP是17,QNET是106。可以参考netinet/in.h

请问一下,运行filter模块之后,可能看到各个协议的数据包,过了1-2分钟。就出问题了/dev/io-net 目录都没有了,点击网络配置窗口,提示 cannot open socket. 运行netmanager,提示 cannot open socket:Address family not supported by protocol family。 不知道是为什么,谢谢。

这个,io-net 进程 crash 了吧。pidin还能看到io-net吗?

你要debug你的filter,看看它为什么crash

恩,是退出了,解决了,3x