[保留]使用DLPI来编写协议分析工具http://www.chinaunix.net作者:stevens_wu发表于:2007-12-1317:10:35【发表评论】【查看原文】【C/C++讨论区】【关闭】系统环境:solaris10forx86,gcc3.4.3,100M快速以太网(偶是个初学者,本文难免存在错误,希望大家多多指教)前一阵子要写一个简单的arp协议的分析程序,在翻阅了一些资料以后,决定使用libpcap库来实现,但是后来涉及到写链路层数据的缘故(另外一个程序,这个程序就是发送一个假冒的arprequest,在本文没有实现,今后有空再整理吧),所以放弃了libpcap。由于本人使用的是solaris环境,所以无法使用bpf,但是sun公司仍然为开发者提供了一个与设备底层无关的接口DLPI,DLPI的全称是DataLinkProviderInterface,通过DLPI开发者可以访问数据链路层的数据包,在早期的sunos系统中基本上采用的是NIT设备,但是现在solaris系统都使用了DLPI.关于DLPI的具体介绍大家可以访问网站www.opengroup.org/pubs/catalog/c811.htm,我这里就不多说了。在搜索了许多资料之后发现目前关于DLPI的编程资料不多,没有具体的过程,后来翻阅了NealNuckolls写的一篇文章HowtoUsetheSTREAMSDataLinkProviderInterface(DLPI),根据例子做了修改(主要是提供了协议分析的部分),现在把编写一个DLPI过程共享一下,希望能对大家有所帮助。建议大家可以先看看NealNuckolls的文章,其中有部分涉及到流编程的,可以参考http://docs.sun.com/app/docs/doc/816-4855的streamsprogrammingguide(不过这不是必须的)。使用DLPI来访问数据链路层有几个步骤:1、打开网络设备2、将一个流attach到一个特定的设备上,这里就是我们刚才打开的设备3、将设备设置为混杂模式(可选)4、把数据链路层sap绑定到流5、调用ioctl,设置raw模式6、配置其他模块(可选)7、刷新缓存8、接收数据进入分析阶段第一步,我们首先打开一个网络设备,在本例中我们打开的是/dev/bge设备,这是本机的网络接口,注意不是/dev/bge0,通过open调用打开,并且返回一个描述符fd=open(device,2)第二步,attach一个流到设备上,这是通过发送DL_ATTACH_REQ原语来完成的dlattachreq(fd,ppa)intfd;u_longppa;{dl_attach_req_tattach_req;structstrbufctl;intflags;attach_req.dl_primitive=DL_ATTACH_REQ;attach_req.dl_ppa=ppa;ctl.maxlen=0;ctl.len=sizeof(attach_req);ctl.buf=(char*)&attach_req;flags=0;if(putmsg(fd,&ctl,(structstrbuf*)NULL,flags)<0)syserr("dlattachreq:putmsg");}dl_attach_req_t是一个定义在dlpi.h中的结构体,我们通过填写结构体来发布原语,putmsg将消息发送到一个流,以上这个函数是DLPI中发布原语的主要格式发布了DL_ATTACH_REQ原语之后,还要确认是否成功,dlokack(fd,bufp)intfd;char*bufp;{unionDL_primitives*dlp;structstrbufctl;intflags;ctl.maxlen=MAXDLBUF;ctl.len=0;ctl.buf=bufp;strgetmsg(fd,&ctl,(structstrbuf*)NULL,&flags,"dlokack");dlp=(unionDL_primitives*)ctl.buf;expecting(DL_OK_ACK,dlp);if(ctl.len