ImageVerifierCode 换一换
格式:DOC , 页数:18 ,大小:46KB ,
资源ID:8124149      下载积分:10 金币
快捷注册下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

开通VIP
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.zixin.com.cn/docdown/8124149.html】到电脑端继续下载(重复下载【60天内】不扣币)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

开通VIP折扣优惠下载文档

            查看会员权益                  [ 下载后找不到文档?]

填表反馈(24小时):  下载求助     关注领币    退款申请

开具发票请登录PC端进行申请

   平台协调中心        【在线客服】        免费申请共赢上传

权利声明

1、咨信平台为文档C2C交易模式,即用户上传的文档直接被用户下载,收益归上传人(含作者)所有;本站仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。所展示的作品文档包括内容和图片全部来源于网络用户和作者上传投稿,我们不确定上传用户享有完全著作权,根据《信息网络传播权保护条例》,如果侵犯了您的版权、权益或隐私,请联系我们,核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
2、文档的总页数、文档格式和文档大小以系统显示为准(内容中显示的页数不一定正确),网站客服只以系统显示的页数、文件格式、文档大小作为仲裁依据,个别因单元格分列造成显示页码不一将协商解决,平台无法对文档的真实性、完整性、权威性、准确性、专业性及其观点立场做任何保证或承诺,下载前须认真查看,确认无误后再购买,务必慎重购买;若有违法违纪将进行移交司法处理,若涉侵权平台将进行基本处罚并下架。
3、本站所有内容均由用户上传,付费前请自行鉴别,如您付费,意味着您已接受本站规则且自行承担风险,本站不进行额外附加服务,虚拟产品一经售出概不退款(未进行购买下载可退充值款),文档一经付费(服务费)、不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
4、如你看到网页展示的文档有www.zixin.com.cn水印,是因预览和防盗链等技术需要对页面进行转换压缩成图而已,我们并不对上传的文档进行任何编辑或修改,文档下载后都不会有水印标识(原文档上传前个别存留的除外),下载后原文更清晰;试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓;PPT和DOC文档可被视为“模板”,允许上传人保留章节、目录结构的情况下删减部份的内容;PDF文档不管是原文档转换或图片扫描而得,本站不作要求视为允许,下载前可先查看【教您几个在下载文档中可以更好的避免被坑】。
5、本文档所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用;网站提供的党政主题相关内容(国旗、国徽、党徽--等)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
6、文档遇到问题,请及时联系平台进行协调解决,联系【微信客服】、【QQ客服】,若有其他问题请点击或扫码反馈【服务填表】;文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“【版权申诉】”,意见反馈和侵权处理邮箱:1219186828@qq.com;也可以拔打客服电话:0574-28810668;投诉电话:18658249818。

注意事项

本文(使用DLPI来编写协议分析工具.doc)为本站上传会员【pc****0】主动上传,咨信网仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知咨信网(发送邮件至1219186828@qq.com、拔打电话4009-655-100或【 微信客服】、【 QQ客服】),核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载【60天内】不扣币。 服务填表

使用DLPI来编写协议分析工具.doc

1、[保留] 使用DLPI来编写协议分析工具 作者:stevens_wu  发表于:2007-12-13 17:10:35 【发表评论】【查看原文】【C/C++讨论区】【关闭】 系统环境:solaris 10 for x86,gcc 3.4.3,100M快速以太网 (偶是个初学者,本文难免存在错误,希望大家多多指教) 前一阵子要写一个简单的arp协议的分析程序,在翻阅了一些资料以后,决定使用libpcap库来实现,但是后来涉及到写链路层数据的缘故(另外一个程序,这个程序就是发送一个假冒的arp request,在本文没有实现,今后有空再整理吧),所以放弃了libpcap。

2、由于本人使用的是solaris环境,所以无法使用bpf,但是sun公司仍然为开发者提供了一个与设备底层无关的接口DLPI,DLPI的全称是Data Link Provider Interface,通过DLPI开发者可以访问数据链路层的数据包,在早期的sunos系统中基本上采用的是NIT设备,但是现在solaris系统都使用了DLPI.关于DLPI的具体介绍大家可以访问网站www.opengroup.org/pubs/catalog/c811.htm,我这里就不多说了。 在搜索了许多资料之后发现目前关于DLPI的编程资料不多,没有具体的过程,后来翻阅了Neal Nuckolls写的一篇文章H

3、ow to Use the STREAMS Data Link Provider Interface (DLPI),根据例子做了修改(主要是提供了协议分析的部分),现在把编写一个DLPI过程共享一下,希望能对大家有所帮助。建议大家可以先看看Neal Nuckolls的文章,其中有部分涉及到流编程的,可以参考 programming guide(不过这不是必须的)。 使用DLPI来访问数据链路层有几个步骤: 1、打开网络设备 2、将一个流 attach到一个特定的设备上,这里就是我们刚才打开的设备 3、将设备设置为混杂模式(可选) 4、把数据链路层sap绑定到流 5、调用

4、ioctl,设置raw模式 6、配置其他模块(可选) 7、刷新缓存 8、接收数据进入分析阶段 第一步,我们首先打开一个网络设备,在本例中我们打开的是/dev/bge设备,这是本机的网络接口,注意不是/dev/bge0,通过open调用打开,并且返回一个描述符 fd=open(device, 2) 第二步,attach一个流到设备上,这是通过发送DL_ATTACH_REQ原语来完成的 dlattachreq(fd, ppa) int fd; u_long ppa; { dl_attach_req_t attach_req; struct strbu

5、f ctl; int flags; 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, (struct strbuf*) NULL, flags) < 0) syserr("dlattachreq:  putmsg"); } dl_att

6、ach_req_t是一个定义在dlpi.h中的结构体,我们通过填写结构体来发布原语,putmsg将消息发送到一个流,以上这个函数是DLPI中发布原语的主要格式 发布了DL_ATTACH_REQ原语之后,还要确认是否成功, dlokack(fd, bufp) int fd; char *bufp; { union DL_primitives *dlp; struct strbuf ctl; int flags; ctl.maxlen = MAXDLBUF; ctl.len = 0; ctl.buf = bufp; strgetmsg(fd,

7、 &ctl, (struct strbuf*)NULL, &flags, "dlokack"); dlp = (union DL_primitives *) ctl.buf; expecting(DL_OK_ACK, dlp); if (ctl.len < sizeof (dl_ok_ack_t)) err("dlokack:  response ctl.len too short:  %d", ctl.len); if (flags != RS_HIPRI) err("dlokack:  DL_OK_ACK was not M_PCPROTO");

8、 if (ctl.len < sizeof (dl_ok_ack_t)) err("dlokack:  short response ctl.len:  %d", ctl.len); } 第三步,将设备设置为混杂模式下工作(可选) dlpromisconreq(fd, DL_PROMISC_PHYS); 这一个步骤也是通过发布DLPI原语来实现的,具体代码后面给出 第四步,绑定流 dlbindreq(fd, sap, 0, DL_CLDLS, 0, 0); dlbindack(fd, buf); 第五步,设置raw模式 strioctl(fd, DL

9、IOCRAW, -1, 0, NULL)  第六步,配置其他模块(在详细代码中给出) 第七步,刷新数据,这是通过ioctl调用实现的 ioctl(fd, I_FLUSH, FLUSHR)  第八步,这是我们最关心的步骤,实际上,前面的这些步骤我们都可以忽略,大致明白有这么个过程就可以了,到时候写代码的时候照搬这个框架就可以。使用DLPI编程并不难,关键在于大家要了解它的框架,没必要非得自己去写一个框架来,本文就是利用了Michael R. Widner的代码,今后如果要增加功能只需要往这个框架里填就可以了。 协议分析的过程是在函数filter完成的,函数申明如下 voi

10、d filter(register char *cp,register u_int  pktlen); 该函数接收两个参数,cp是直接从设备缓存里拷贝过来的待分析数据,是链路层的封装数据,pktlen是数据的长度。在本文中由于操作环境是以太网,因此接收的数据链路层数据是以太网封装格式,如不清楚以太网封装的可以参考《TCP/IP详解 卷一:协议》,以太网封装三种标准的协议类型:IP协议、ARP协议和RARP协议。14字节的以太网首部包括了6字节的目的地址,6字节的源地址和2字节的类型字段,IP的类型值为0x0800,ARP的类型值为0x0806,RARP的类型值为0x8035。通过检查类型字

11、段来区别接收到的数据是属于哪一种协议,函数实现代码如下 void filter(cp, pktlen) register char *cp; register u_int pktlen; {  register struct ip     *ip;  register struct tcphdr *tcph;  register struct ether_header *eth;  char *head=cp;  static long line_count=0;//计数器,用来记录接收的数据次数    u_short EtherType=ntohs

12、struct ether_header *)cp)->;ether_type);    //如果EtherType小于0x600说明这是一个符合802.3标准的数据格式,应当对数据作出调整    if(EtherType < 0x600) {      EtherType = *(u_short *)(cp + SZETH + 6);      cp+=8; pktlen-=8;    }    eth=(struct ether_header*)cp;    fprintf(LOG,"%-5d",++line_count);    if(EtherTyp

13、e == ETHERTYPE_IP) //检查协议类型是否IP协议    {    ip=(struct ip *)(cp+SZETH);//调整指针的位置,SZETH是以太网首部长度    Mac_info(ð->;ether_shost);//Mac_info函数打印出物理地址    fprintf(LOG,"(");    Ip_info(&ip->;ip_src);//Ip_info函数打印出IP地址    fprintf(LOG,")");    fprintf(LOG,"--->;");    Mac_info(ð->;ether_dho

14、st);    fprintf(LOG,"(");    Ip_info(&ip->;ip_dst);    fprintf(LOG,")");    fprintf(LOG,"\n");    }    else if(EtherType == ARP_PROTO)//如果协议类型是ARP    {       cp+=SZETH;       struct ether_arp *arp=(struct ether_arp *)cp;       switch(ntohs(arp->;ea_hdr.ar_op))//检查arp的操作       {

15、         case ARPOP_REQUEST:   //如果是arp请求             fprintf(LOG,"arp request:who has ");             arp_ip_info(arp->;arp_tpa);  //打印arp报文信息中的地址             fprintf(LOG," tells ");             arp_ip_info(arp->;arp_spa);             fprintf(LOG,"\n");             break;         ca

16、se ARPOP_REPLY:     //arp应答             fprintf(LOG,"arp reply: ");             arp_ip_info(arp->;arp_spa);             fprintf(LOG," is at  ");             Mac_info((struct ether_addr*)&arp->;arp_sha);             fprintf(LOG,"\n");             break;        }                //可以在这里

17、添加代码打印出arp数据报的具体内容     } } 程序的具体实现代码如下: /*  程序sniffer.c的代码清单 */ #include ; #include ; #include ; #include ; #include ; #include ;   #include ; #include ; #include 

18、 #include ; #include ; #include ; #include ;   #include ; #include ;   #include ; #include ; #include ; #include ; #include 

19、tinet/udp.h>; #include ; #include ; #include ; #include ; #include ; #include ; #include ;   #define MAXDLBUF 32768  #define MAXWAIT 15 #define MAXDLADDR 1024

20、define         BITSPERBYTE        8 #define bcopy(s1, s2, len) memcpy(s2, s1, len) #define index(s, c) strchr(s, c) #define rindex(s, c) strrchr(s, c) #define bcmp(s1, s2, len) (memcmp(s1, s2, len)!=0) #define ERR stderr   char    *device,         *ProgName,         *LogName

21、 FILE    *LOG; int     debug=0; long databuf[MAXDLBUF]; int sap=0; #define NIT_DEV     "/dev/bge" #define CHUNKSIZE   4096       int     if_fd = -1; int     Packet[CHUNKSIZE+32]; int promisc = 1; int bufmod = 0; int filter_flags=0; int maxbuflen=128;   void Pexit(e

22、rr,msg) int err; char *msg; { perror(msg);   exit(err); }   void Zexit(err,msg) int err; char *msg; { fprintf(ERR,msg);   exit(err); } #define ARP_PROTO   (0x0806) #define IP          ((struct ip *)Packet) #define IP_OFFSET   (0x1FFF) #define SZETH       (sizeof(struct ether_

23、header)) #define ARPLEN      (sizeof(struct ether_arp)) #define MACLEN      (6) #define IPALEN      (4) #define IPLEN       (ntohs(ip->;ip_len)) #define IPHLEN      (ip->;ip_hl) #define INET_ADDRSTRLEN 16 #define MAXBUFLEN  (8192) time_t  LastTIME = 0;   char *Ptm(t)

24、register time_t *t; { register char *p = ctime(t);   p[strlen(p)-6]=0;    return(p); }   char *NOWtm() { time_t tm;   time(&tm);   return( Ptm(&tm) ); }   void print_data(uchar_t *buf,int size) { int i=0; char *p=buf; for(;i

25、n"); if(i%2 == 0) fprintf(LOG," ");  fprintf(LOG,"%02x",*p++&0x00ff); } fprintf(LOG,"\n"); } //打印物理地址 void Mac_info(struct ether_addr*mac) {    fprintf(LOG,"%02x:%02x:%02x:%02x:%02x:%02x",            mac->;ether_addr_octet[0],            mac->;ether_addr_octet[1],            

26、mac->;ether_addr_octet[2],              mac->;ether_addr_octet[3],              mac->;ether_addr_octet[4],             mac->;ether_addr_octet[5]); } //打印ip地址char buf[MAXDLBUF];    void Ip_info(struct in_addr *ip) {    char str[INET_ADDRSTRLEN];    inet_ntop(AF_INET,ip,str,sizeof(

27、str));    if(*str)    fprintf(LOG,"%s",str);     } //打印ip地址的另外一个版本 void arp_ip_info(uchar_t pa[]) {     fprintf(LOG,"%d.%d.%d.%d",pa[0],pa[1],pa[2],pa[3]); } void death() { register struct CREC *CLe;            fprintf(LOG,"\nLog ended at =>; %s\n",NOWtm());     fflus

28、h(LOG);     if(LOG != stdout)         fclose(LOG);     exit(1); } err(fmt, a1, a2, a3, a4) char *fmt; char *a1, *a2, *a3, *a4; { (void) fprintf(stderr, fmt, a1, a2, a3, a4); (void) fprintf(stderr, "\n"); (void) exit(1); }  void sigalrm() { (void) err("sigalrm:

29、  TIMEOUT"); } strgetmsg(fd, ctlp, datap, flagsp, caller) int fd; struct strbuf *ctlp, *datap; int *flagsp; char *caller; { int rc; static char errmsg[80]; (void) signal(SIGALRM, sigalrm); if (alarm(MAXWAIT) < 0) { (void) sprintf(errmsg, "%s:  alarm", caller); syserr(

30、errmsg); } *flagsp = 0; if ((rc = getmsg(fd, ctlp, datap, flagsp)) < 0) { (void) sprintf(errmsg, "%s:  getmsg", caller); syserr(errmsg); } if (alarm(0) < 0) { (void) sprintf(errmsg, "%s:  alarm", caller); syserr(errmsg); } if ((rc & (MORECTL | MOREDATA)) == (MORECTL

31、 | MOREDATA)) err("%s:  MORECTL|MOREDATA", caller); if (rc & MORECTL) err("%s:  MORECTL", caller); if (rc & MOREDATA) err("%s:  MOREDATA", caller); if (ctlp->;len < sizeof (long)) err("getmsg:  control portion length < sizeof (long):  %d", ctlp->;len); } expecting(prim, dlp)

32、 int prim; union DL_primitives *dlp; { if (dlp->;dl_primitive != (u_long)prim) { err("unexpected dlprim error\n"); exit(1); } } strioctl(fd, cmd, timout, len, dp) int fd; int cmd; int timout; int len; char *dp; { struct strioctl sioc; int rc; sioc.ic_cmd = cmd;

33、 sioc.ic_timout = timout; sioc.ic_len = len; sioc.ic_dp = dp; rc = ioctl(fd, I_STR, &sioc); if (rc < 0) return (rc); else return (sioc.ic_len); } dlattachreq(fd, ppa) int fd; u_long ppa; { dl_attach_req_t attach_req; struct strbuf ctl; int flags; attach_req.dl_pri

34、mitive = 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, (struct strbuf*) NULL, flags) < 0) syserr("dlattachreq:  putmsg"); } dlokack(fd, bufp) int fd; char *bufp; {

35、 union DL_primitives *dlp; struct strbuf ctl; int flags; ctl.maxlen = MAXDLBUF; ctl.len = 0; ctl.buf = bufp; strgetmsg(fd, &ctl, (struct strbuf*)NULL, &flags, "dlokack"); dlp = (union DL_primitives *) ctl.buf; expecting(DL_OK_ACK, dlp); if (ctl.len < sizeof (dl_ok_ack_t

36、)) err("dlokack:  response ctl.len too short:  %d", ctl.len); if (flags != RS_HIPRI) err("dlokack:  DL_OK_ACK was not M_PCPROTO"); if (ctl.len < sizeof (dl_ok_ack_t)) err("dlokack:  short response ctl.len:  %d", ctl.len); } dlbindreq(fd, sap, max_conind, service_mode, conn_mgmt

37、 xidtest) int fd; u_long sap; u_long max_conind; u_long service_mode; u_long conn_mgmt; u_long xidtest; { dl_bind_req_t bind_req; struct strbuf ctl; int flags; bind_req.dl_primitive = DL_BIND_REQ; bind_req.dl_sap = sap; bind_req.dl_max_conind = max_conind; bind_req.dl_

38、service_mode = service_mode; bind_req.dl_conn_mgmt = conn_mgmt; bind_req.dl_xidtest_flg = xidtest; ctl.maxlen = 0; ctl.len = sizeof (bind_req); ctl.buf = (char *) &bind_req; flags = 0; if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0) syserr("dlbindreq:  putmsg"); }

39、 dlbindack(fd, bufp) int fd; char *bufp; { union DL_primitives *dlp; struct strbuf ctl; int flags; ctl.maxlen = MAXDLBUF; ctl.len = 0; ctl.buf = bufp; strgetmsg(fd, &ctl, (struct strbuf*)NULL, &flags, "dlbindack"); dlp = (union DL_primitives *) ctl.buf; expecting(DL_B

40、IND_ACK, dlp); if (flags != RS_HIPRI) err("dlbindack:  DL_OK_ACK was not M_PCPROTO"); if (ctl.len < sizeof (dl_bind_ack_t)) err("dlbindack:  short response ctl.len:  %d", ctl.len); } dlpromisconreq(fd, level) int fd; u_long level; { dl_promiscon_req_t promiscon_req; struc

41、t strbuf ctl; int flags; promiscon_req.dl_primitive = DL_PROMISCON_REQ; promiscon_req.dl_level = level; ctl.maxlen = 0; ctl.len = sizeof (promiscon_req); ctl.buf = (char *) &promiscon_req; flags = 0; if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0) syserr("dlpromisco

42、n:  putmsg"); } syserr(s) char *s; { (void) perror(s); exit(1); } void filter(cp, pktlen) register char *cp; register u_int pktlen; {  register struct ip     *ip;  register struct tcphdr *tcph;  register struct ether_header *eth;  char *head=cp;  static lo

43、ng line_count=0;    u_short EtherType=ntohs(((struct ether_header *)cp)->;ether_type);        if(EtherType < 0x600) {      EtherType = *(u_short *)(cp + SZETH + 6);      cp+=8; pktlen-=8;    }    eth=(struct ether_header*)cp;    fprintf(LOG,"%-5d",++line_count);    if(EtherType =

44、 ETHERTYPE_IP)     {    ip=(struct ip *)(cp+SZETH);          Mac_info(ð->;ether_shost);    fprintf(LOG,"(");    Ip_info(&ip->;ip_src);       fprintf(LOG,")");    fprintf(LOG,"--->;");    Mac_info(ð->;ether_dhost);    fprintf(LOG,"(");    Ip_info(&ip->;ip_dst);   

45、    fprintf(LOG,")");    fprintf(LOG,"\n");               }    else if(EtherType == ARP_PROTO)    {       cp+=SZETH;       struct ether_arp *arp=(struct ether_arp *)cp;       switch(ntohs(arp->;ea_hdr.ar_op))       {         case ARPOP_REQUEST:             fprintf(LOG,"arp 

46、request:who has ");             arp_ip_info(arp->;arp_tpa);             fprintf(LOG," tells ");             arp_ip_info(arp->;arp_spa);             fprintf(LOG,"\n");             break;         case ARPOP_REPLY:             fprintf(LOG,"arp reply: ");             arp_ip_info(arp->;ar

47、p_spa);             fprintf(LOG," is at  ");             Mac_info((struct ether_addr*)&arp->;arp_sha);             fprintf(LOG,"\n");             break;                 }                //打印出arp数据报的内容             }       } do_it() { long buf[MAXDLBUF]; char *devic

48、e; int ppa; int fd; struct strbuf data; int flags; int i; int c; int offset; int len; struct timeval t; u_int chunksize = 16 * 1024; struct sb_hdr *bp; char *p, *limp; int mrwtmp;  device = "/dev/bge"; ppa = 0; sap= 0x0806; if ((fd = open(device, 2)) < 0)

49、 syserr(device); dlattachreq(fd, ppa); dlokack(fd, buf); if (promisc) { dlpromisconreq(fd, DL_PROMISC_PHYS);           dlokack(fd, buf); } dlbindreq(fd, sap, 0, DL_CLDLS, 0, 0); dlbindack(fd, buf);         if (strioctl(fd, DLIOCRAW, -1, 0, NULL) < 0) syserr("DLIOCRAW"); if (bufmod) { if (ioctl(fd, I_PUSH, "bufmod") < 0) syserr("push bufmod"); t.tv_sec = 0; t.tv_usec = 500000; if (strioctl(fd, SBIOCSTIME, -1, sizeof (struct timeval), &t) < 0) syserr("SBIOCSTIME"); if

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服