网络协议分析习题解答参考思路.doc_第1页
网络协议分析习题解答参考思路.doc_第2页
网络协议分析习题解答参考思路.doc_第3页
网络协议分析习题解答参考思路.doc_第4页
网络协议分析习题解答参考思路.doc_第5页
已阅读5页,还剩38页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

.网络协议分析与实现习题解答参考思路第1章习题解答参考思路习题1:该题考查对异构网络互联概念、异构网络涉及的问题以及解决方法的理解程度。其中涉及的问题包括地址问题、包格式转换问题、路由问题等,其中1.1.3节还列举了很多其他的问题。习题2:该题可参考教材中所讲述的用户A和用户B的数据转换和传输过程进行解答。习题3:该题主要考查网上查找资料的能力。在/网站上可以查到所有的RFC信息。习题4:TCP/IP模型和OSI参考模型之间的层次对应关系及各层协议参见教材中的图1-5。习题5:该题主要考查动手能力,可以使用Wireshark(曾称为Ethereal)、Sniffer Portable等软件进行抓包,然后针对一些具体报文进行分析。注意分析通信中的多路复用和多路分解过程,说出通信双方的物理地址、IP地址和端口地址。习题6:该题主要考查阅读代码的能力,这部分代码是对数据结构课程中队列操作的一个实现。该队列是一个基于优先级排序的队列,主要的数据结构是qinfo:structqinfo Boolq_valid;intq_type;/* mutex type*/intq_max;intq_count;intq_seen;intq_mutex;int*q_key;char*q_elt;具体操作如下:int enq(int q, void *elt, int key);/*入队列操作,根据key的大小插到队列中的合适位置*/void * deq(int q);/*出队列操作*/void * headq(int q);/*获取队列头部元素*/void * seeq(int q);/*按顺序取队列元素*/int newq(unsigned size, unsigned mtype);/*分配一个新的队列,并返回队列的索引位置*/int freeq(int q);/*释放队列*/int lenq(int q);/*获取队列长度*/static int initq();/*初始化队列*/.第2章习题解答参考思路习题1:该题主要考查对HDLC概念的理解程度,答案参见2.1节。习题2:该题主要考查对SLIP、PPP之间的关系,PPP对SLIP的改进以及PPPoE的概念的理解程度。SLIP和PPP可以在教材中找到参考资料,PPPoE可以到网上或RFC中查找参考资料。PPPoE全称为Point to Point Protocol over Ethernet(以太网上的点对点协议),简单地说,就是以太网和PPP结合后的协议,目前广泛应用在ADSL接入方式中。通过PPPoE技术和宽带调制解调器(比如ADSL Modem)可以实现高速宽带网的个人身份验证访问,为每个用户创建虚拟拨号连接,这样就可以高速连接入因特网。(1)PPP在SLIP的基础上的改进之处 提供了校验机制,可以对每一帧进行检查; 提供了IP地址的动态协商机制,使通信双方能够得知对方的IP地址; 在一条串行链路上提供了对多协议的支持; 提供了对TCP和IP数据报首部的压缩机制。(2)PPPoE和PPP的关系PPP提供了一种标准的方式在点对点的链路上传输多种网络层协议的数据报。它要求通信双方之间是点到点的关系,由于不适用于广播类型的以太网和另外一些多点访问类型的网络,因此就产生了PPPoE。在实际应用中,PPPoE利用以太网的工作机理,将ADSL Modem的10BASE-T接口与内部以太网互联,在ADSL Modem中采用RFC1483的桥接封装方式对终端发出的PPP报文进行LLC/SNAP封装后,通过连结两端的PVC在ADSL Modem与网络侧的宽带接入服务器之间建立连接,实现PPP的动态接入。PPPoE接入利用在网络侧和ADSL Modem之间的一条PVC(永久虚拟电路)就可以完成以太网上多用户的共同接入,实际组网方式简单,实用方便,大大降低了网络的复杂程度。PPPoE的实质就是以太网和拨号网络之间的一个中继协议,它继承了以太网的快速和PPP拨号的简单、用户验证、IP分配等优点。 (3)PPPoE的工作流程PPPoE提供了在广播式网络(如以太网)中多台主机连接到远端的访问集中器上的一种标准。在这种网络模型中,不难看出所有用户的主机都需要能独立地初始化自己的PPP协议栈,而且通过PPP本身所具有的一些特点能在广播式网络上对用户进行计费和管理。为了能在广播式网络上建立、维持各主机与访问集中器之间点对点的关系,需要每个主机与访问集中器之间建立唯一的点到点的会话。PPPoE共包括两个阶段,即PPPoE的发现阶段(PPPoE Discovery Stage)和PPPoE的会话阶段(PPPoE Session Stage)。 发现阶段:此阶段用来建立连接,如下图所示,当一个用户主机想开始一个PPPoE会话时,首先必须经过发现阶段以识别PPPoE Server的以太网MAC地址,并建立一个PPPoE会话标识(Session ID)。如上图所示,该阶段的基本工作流程由4个步骤组成。PADI:如果要建立一条PPPoE连接,首先PPPoE客户端要以广播的方式发送一个PADI(PPPoE Active Discovery Initiation)报文,PADI报文包括客户端请求的服务。PADO:在PPPoE服务器(BRAS)收到一个PADI报文之后,它会判断自己是否能够提供服务,如果能够提供服务,就会向客户端发送PADO(PPPoE Active Discovery Offer)报文来进行回应。PADO报文包括PPPoE服务器名称和与PADI报文中相同的服务名;如果PPPoE服务器不能为PADI提供服务,则不允许用PADO报文应答。PADR:由于PADI是以广播的形式发送出去的,PPPoE客户端可能会收到不止一个PADO报文,它将审查所有接收到的PADO报文并根据其中的服务器名或所提供的服务选择一个PPPoE服务器,同时向选中的服务器发送PADR(PPPoE Active Discovery Request)报文。PADR报文包括客户端所请求的服务。PADS:当PPPoE服务器收到客户端发送的PADR报文时,它准备开始一个PPPoE会话。它为PPPoE会话创建一个唯一的PPPoE会话标识,并向客户端发送PADS(PPPoE Active Discovery Session- confirmation)报文作为应答。当发现阶段正常结束后,通信的两端都会获得会话标识和对方的MAC地址,它们一起唯一定义一个PPPoE会话。 会话阶段:PPPoE进入PPP会话阶段后,客户端和服务器将进行标准的PPP协商,PPP协商通过后,数据通过PPP封装发送。PPP报文作为PPPoE帧的净荷被封装在以太网帧内,发送到PPPoE链路的对端。会话标识必须是发现阶段确定的标识,并且在会话过程中保持不变,MAC地址必须是对端的MAC地址。在会话阶段的任意时刻,PPPoE服务器和客户端都可向对方发送PADT(PPPoE Active Discovery Terminate)报文通知对方结束本会话。收到PADT以后,就不再允许使用该会话发送PPP流量了。在发送或接收到PADT报文后,即使是常规的PPP结束报文也不允许发送。一般情况下,PPP通信双方使用PPP报文自身来结束PPPoE会话,但在无法使用PPP时可以使用PADT来结束会话。(4)帧结构及其应用版本4位类型4位代码8位会话标识16位长度16位净载荷发现阶段承载一些标记会话阶段承载PPP报文PPPoE作为宽带网接入的一种有效方法,不但可以防止IP被盗用,还有利于开展多服务、速率限制和按时按流量计费等多方面的应用。习题3:该题主要考查对CSMA/CD和CSMA/CA协议,以及无线网络中“隐藏站”问题的理解程度。习题4: XINU操作系统源代码etherlance目录下存放的是AMD 7990 Lance以太网控制器驱动实现程序源代码,其中ethdemux函数实现了该控制器接收到以太帧后所要进行的多路分解操作。该函数首先进行一些检查,然后进行数据帧的复制,并最终转入ni_in()函数,进行网络接口层的多路分解。/* ethdemux.c - ethdemux */#include #include #include /*- * ethmudex -选择一个端口发送一个传入的数据报(ETHER端或者其他) *-*/ /*首先检查来自网络的数据帧的正确性,然后申请缓冲区以存储数据帧,最后将数据帧交由ni_in()函数处理*/int ethdemux(etptr, bn)struct etblk *etptr; /*以太网控制块描述*/int bn;structbre*pbre;structle_md*pmd; /*消息描述符*/structotblk*otptr;structep*pep; /*以太网的帧结构*/intnoth, readlen, errs, ifnum;char*dest;ifnum = etptr-etintf; /*端口号*/pbre = &etptr-etbrrbn;pmd = pbre-pmd;errs = pmd-lmd_flags & (RMD_FRAM|RMD_OFLO|RMD_CRC|RMD_BUFF);if ( errs != 0) if (errs & RMD_FRAM)kprintf(ethread: framing errorn);if (errs & RMD_OFLO)kprintf(ethread: buffer overflown);if (errs & RMD_CRC)kprintf(ethread: CRC errorn);if (errs & RMD_BUFF)kprintf(ethread: dont own next buffern);goto drop;readlen = pmd-lmd_mcnt; /*消息的长度(实际长度) */if (readlen (EP_DLEN+18) /*长度是否合法*/goto drop;pep = (struct ep *)nbgetbuf(Npool); /*申请帧缓冲区*/if (pep = 0) /*申请失败*/if (ifnum = 0 & ifnum ep_eh, pbre-buf, readlen-EP_CRC); /*将网卡缓冲区中的信息复制到帧缓冲区*/pmd-lmd_flags = LMD_OWN; /*将使用权还给以太网卡*/pbre-flags = 0; /*标志位清零*/#ifNoth 0/*其他设备端口*/dest = (char *)pep-ep_dst;for (noth=0; nothetothnoth;if (otptr = 0 | !otptr-ot_valid)continue; if (blkequ(dest, otptr-ot_paddr, EP_ALEN) |blkequ(dest, otptr-ot_baddr, EP_ALEN)break;if (noth != Noth)ifnum = otptr-ot_intf;#endifif (ifnum ep_type = net2hs(pep-ep_type); /*将帧类型字节序转换为本机字节序*/*ni_in函数可以根据帧类型来判断多路分解*/ni_in(&nififnum, pep, readlen); /*调用ni_in函数来处理数据帧*/return OK;drop:if (ifnum = 0 & ifnum lmd_flags = LMD_OWN; /*交还使用权*/pbre-flags = 0;return SYSERR; 流程图如下:习题5:dot2ip()函数和ip2dot()函数实现了字符串形式的点分十进制格式的IP地址与32位IP地址格式之间的相互转换。/* dot2ip.c - dot2ip */#include #include #include /*- * dot2ip -将字符串形式的点分十进制格式IP地址转换为一个没有小数点的IP地址 *- */ dot2ip(const char *pdot)/*参数pdot是一个指向字符数组的指针,字符数组每个单元存储IP地址的一个字节: */IPaddrip; /*IPaddr是个无符号长整型*/unsigned char*p;/*定义一个指向字符数组的指针,但此指针并没有指向真正的内存空间*/inti;ip = 0;p = (unsigned char *)&ip; /*使字符数组指针p指向起始地址是&ip的内存单元*/for (i=0; pdot & *pdot & iIP_ALEN; +i) /*如果pdot指针不为空,并且它所指向的内容也不为空,而且iip的长度*/*p+ = atoi(pdot); /*将IP地址的一个字节保存到指针p所指向的内存单元中*/if (pdot = index(pdot, .)/*判断pdot是否指向字符数组的最后一个单元,并且跳过.单元*/+pdot;elsebreak;return ip; /*返回存储IP地址首单元的地址*/* ip2dot.c - ip2dot */#include #include #include /*- * ip2dot - 将一个没有小数点的IP地址转换为字符串形式的点分十进制格式IP地址 *- */ char * ip2dot(char *pdot, IPaddr ip) /*pdot指向一个字符数组,用于存储转换后的IP地址;IP是没有小数点的IP地址的首地址*/char*pch = pdot;inti;sprintf(pch, %u, (char *)&ip)0 & 0xff); /*将IP地址第一个字节的值存入pch所指向的字符数组的第一个单元中*/pch += strlen(pch); /*pch跳过长度为strlen(pch)的内存单元,即指向下一个单元*/for (i=1; iIP_ALEN; +i) sprintf(pch, .%u, (char *)&ip)i & 0xff);/*将.及IP地址的下一个字节保存到pch指向的单元*/pch += strlen(pch);/*pch跳过长度为strlen(pch)的内存单元,即指向下一个单元*/*pch = NULL; /*指针置空*/return pdot; /*返回指向字符串形式的点分十进制格式IP地址的首地址*/习题6:Netmatch()函数用于判断一个IP地址是否属于某个网络,netnum()函数用于判断一个IP地址的类别。这两个函数都是采用C语言的位操作来完成的。/* netmatch.c - netmatch */#include #include #include /*- * netmatch 检查目的IP地址是否在此网络中 *- */ Bool netmatch(IPaddr dst, IPaddr net, IPaddr mask, Bool islocal)if (dst & mask) != (net & mask)/*IP地址跟子网掩码进行与运算的结果就是网络号,以此来判断dst在不在该网络上*/return FALSE;/* * local srcs should only match unicast (单一传播) addresses (host routes) */if (islocal) /*判断是否来自于本地网络*/if (isbrc(dst) | IP_CLASSD(dst)/如果dst是广播地址或是组播地址*/return mask != ip_maskall; /*如果是来自于本地网络并且是广播地址或是组播地址,那么发送该广播帧的主机就不需要接收此广播帧,于是将自己置成不匹配此网络,就不会再收到此广播帧了*/return TRUE;/* netnum.c - netnum */#include #include #include /*- * netnum - 用来得到某个IP地址的网络号 *- */ netnum(IPaddr ipa)IPaddrmask = 0; /*初始化为0*/if (IP_CLASSA(ipa) mask = hl2net(0xff000000); /*得到A类地址的子网掩码*/if (IP_CLASSB(ipa) mask = hl2net(0xffff0000); /*得到B类地址的子网掩码*/if (IP_CLASSC(ipa) mask = hl2net(0xffffff00); /*得到C类地址的子网掩码*/return ipa & mask; /*得到网络号,即网络地址*/第3章习题解答参考思路习题1:本题主要考查对ARP软件整体结构的理解程度,并帮助学生梳理ARP软件中函数之间的关系,从而更好地掌握ARP软件中函数的功能和处理机制。详细描述请参照3.3节。习题2:本题主要考查对ARP报文处理算法的理解程度,并帮助学生进一步理解ARP报文处理算法。报文处理算法可以概括为三个部分:当报文交付给arp_in()函数时,该算法首先确认该报文是否为合法报文及特征是否与接口相符;然后查询ARP缓冲区表项,若不存在对应表项且确认该报文是发往本机,则直接创建新表项,再根据该报文对表项进行修改操作;最后根据该ARP报文是否为ARP请求来决定下一步操作,构造一个ARP应答报文或清理该ARP报文。ARP报文处理算法的利弊分析如下:在正常操作下,这是一种很有效率的处理算法,简单明了快捷。但是由算法分析可知,arp_in()函数“不计后果”地使用当前处理的ARP报文中的创建新缓冲区或者修改已存在的缓冲表项,没有使用任何保护手段或者措施。ARP攻击者很容易利用这一缺陷,发送ARP欺骗报文。习题3:主机发送IP数据报是通过调用netwrite()函数来实现的,因此分析netwrite()函数即可了解IP数据报的发送过程。详细描述请参考3.5节。习题4:Arpalloc.c代码如下:/*-* 在ARP缓冲区表中分配一个表项 * -*/struct arpentry *arpalloc()/*缓冲区表中所指的当前表项,这里采用的是循环队列的数据结构,故需要记录当前表项所处的位置*/static int aenext = 0;struct arpentry *pae; /*返回值*/inti;for (i=0; iae_state = AS_PENDING & pae-ae_queue = 0)arpdq(pae);pae-ae_state = AS_PENDING;return pae;习题5:ARP攻击原理:由习题2可知,ARP报文处理算法只检查ARP报文格式的合法性,随即直接根据该报文内容修改ARP表项,这一处理方式为网络攻击者提供了“可乘之机”。ARP攻击分为两类:(1)ARP欺骗攻击即通过伪造并发送ARP报文,修改被攻击者ARP缓冲区表项以实现ARP欺骗,监听被攻击者与其他网络的通信;(2)ARP溢出攻击即通过发送大量的ARP报文致使被攻击主机的ARP表项存满无效的表项,从而导致该主机与外界通信中断。避免或阻止ARP攻击可以通过改进ARP自身(优化报文处理算法)或借助动态防御系统(如专用ARP防火墙等)来实现。第4章习题解答参考思路习题1:该题主要考查对IP软件整体结构的理解程度,旨在使学生能够脱离教材根据自己的理解勾勒出软件的构架。注重用自己的语言描述各函数的主要功能,以及相互之间的调用关系。具体内容参见4.3节。习题2:该题结合IP数据报结构,主要考查对C语言结构体的掌握程度。struct ipcharip_verpri;charip_flowlab3;shortip_ploadlen;charip_proto;charip_ttl;charsrc16;chardst16;charip_data1;另外,可以参考LINUX或者FreeBSD相应的实现程序。习题3:该题的解答请从4.6.3节的内容中进行综合提炼。习题4:该题主要考查对IP数据报首部个字段的理解程度。IP数据报转发过程中,TTL会发生变化,这样会导致检验和变化;如果IP数据报产生分片,则IP数据报长度字段、标识字段、标志字段、分片偏移字段也会发生变化;如果IP数据报首部存在分片,则首部长度字段有可能发生变化。习题5:该题需要注意,对于不同体系结构的主机需要设计不同的转换宏,这里仅提供16位转换宏。#ifBYTE_ORDER = LITTLE_ENDIAN#definehs2net(x) (unsigned) (x)8) &0xff) | (x) & 0xff)8)#definenet2hs(x) hs2net(x)#endif#ifBYTE_ORDER = BIG_ENDIAN#define hs2net(x) (x)#define net2hs(x) (x)#endif习题6:XINU操作系统中环回接口的实现方案如下:我们从IP数据的流向图理解环回接口的实现,IP输入队列中的数据来源有两种:一种是网络中输入的报文,一种是上层协议希望通过ipsend()函数发送的报文。这两种报文经过ipproc()函数处理后调用ipputp()函数发送,报文有两个去向:一个是交付物理网络接口发送,一个是通过环回接口交付上层协议。所以在IP层数据的流向有4种:第一种是13,内部数据发送给内部数据;第二种是23,将外部接收到的数据向上层协议发送;第三种是14,将来自上层协议的数据向外发送;第四种是24,只是将收到的数据转发出去。当ipputp()函数调用netwrite()函数发送一个报文时,若路由中提供的报文出接口为本地环回接口,则netwrite()函数会调用local_out()函数将IP数据报交付上层协议,即习题6图示中的3。local_out()函数先是将IP数据报的字节序转换为主机字节序,然后将收到的数据帧重组,再处理IP数据报的选项部分,最后根据协议字段将数据发送给UDP、ICMP、TCP等上层协议。如果协议字段有错误,就发送ICMP不可达报文。因此,local_out()函数处理的是本机接收的数据,这个数据有可能是自己产生的,也可能是网络中收到的数据。习题7:选路和转发的主要差异及三层转发的实现方式如下:选路的原理:当路由器收到一个需要它转发的IP数据报时,它会根据数据报中的目的IP地址搜索路由表,找到相关的路由表项,并根据路由中的三元组将数据报从相关的出接口转发。而路由表的维护是由专门的路由选择协议来进行的,IP层只需要在转发数据时搜索路由表即可。转发的原理:交换机接收到源主机发送的数据帧后,在MAC地址表中查找数据帧中的目的MAC地址。如果找到,就将该数据帧发送到相应的端口;如果找不到,就向所有的端口发送。同时利用接收数据帧中的源MAC地址来建立MAC地址表。选路和转发的区别主要是,选路在IP层,根据目的IP地址找到出接口;转发在数据链路层,根据MAC地址对数据进行转发。另外,转发表和路由表不同,转发表中的一行包括从网络号到发出接口的映射和一些MAC信息,而路由表是由路由选择算法建立的一个表,它通常包含从网络号到下一跳IP地址的映射,转发表可以由特殊的硬件来实现,而路由表很少这样。为了实现三层交换技术,交换机将维护一张至少包括“目的IP地址,下一跳MAC地址”在内的硬件转发表。当交换机接收到数据时,根据报文中的“目的IP地址”查询硬件转发表,根据匹配结果进行相应的数据转发,并且采用硬件芯片或高速缓冲区支持,可以达到线速。在交换机刚启动完毕时,交换机就把设备的软件路由表下载到ASIC芯片上。在需要进行三层交换的报文到达交换机后,交换机首先会查询最长匹配硬件转发表,但由于MAC地址是未知的,无法同时下载,此时的硬件转发表是无效的,所以无法进行硬件数据转发。因此,交换机将利用CPU对数据进行软件路由转发,交换机在数据转发过程中获取下一跳IP地址和数据转发出口的MAC地址,然后会被自动下载到三层硬件转发表,此时包含了下一跳IP地址和数据转发出口MAC地址的硬件转发表项才真正生效。在这之后,发往相同目的IP网段的报文到达交换机都可以直接通过最长匹配硬件转发表进行硬件转发,而其他网段的数据转发则需要重复上述过程。习题8:汇编语言函数可参考net/cksum.s文件,C语言函数可参考ucpcksum.c或者tcpcksum.c实现程序。习题9:由于通常情况下,IP报文首部发生变化的字段主要是TTL。而检验和字段是伴随TTL字段变化而变化的,因此根据RFC1624可以设计一种不需要重新计算检验和的修正方法。具体方法参见RFC1642.习题10:使用散列结构并通过分离链接的方法处理散列冲突,在元素个数保持一定规模的情况下可以保证insert和search的时间复杂度为O(1)。但是随着元素规模的扩大,insert和search的时间复杂度会逐渐脱离常数。同时,选择散列函数时需要非常谨慎。对于元素关键字随机化程度较高的情况,可采用二分搜索树的实现方式。这种方式可以保证search的时间复杂度为O(log n),但是对元素关键字随机化程度的要求比较高。为了防止不平衡的二分搜索树出现,可采用AVL树或者红黑树作为路由结构。只是两者在元素的insert操作时需要一些额外的时间。目前广泛流行的路由表结构是采用radix树的构造。它可以保证最坏情况下search的时间复杂度达到O(log n)。第5章习题解答参考思路习题1: 本题主要考查对ICMP软件整体结构的理解程度,帮助学生梳理ICMP软件中函数之间的关系,从而更好地掌握ICMP软件中函数的功能和处理机制。详细描述请参照5.3节。习题2:(1)终点不可达报文:当路由器不能为报文找到路由或者主机不能交付报文时,丢弃该报文并发送该类型报文给源主机;(2)源点抑制报文:当路由器或主机因拥塞而丢弃报文时,向源主机发送该类型报文;(3)超时报文:当路由器收到TTL为零的报文或目的主机在规定的时间内没有收到所有的分片报文时,向源主机发送该类型报文;(4)参数错误报文:当路由器或主机收到存在二义性或字段缺失的报文时,丢弃该报文并发送该类型报文;(5)改变路由报文:当路由器收到本应发往其他路由器的报文时,把该报文发送给正确的路由器,并发送该类型报文通知源主机更正路由,以帮助更新路由。ICMP的5种差错报告报文结构如下: (1)终点不可达报文 类型:3代码:015检验和未使用(全0)收到的IP数据报的一部分,包括IP数据报首部以及数据报数据的前8个字节(2)源点抑制报文 类型:4代码:0检验和未使用(全0)收到的IP数据报的一部分,包括IP数据报首部以及数据报数据的前8个字节(3)超时报文 类型:11代码:0或1检验和未使用(全0)收到的IP数据报的一部分,包括IP数据报首部以及数据报数据的前8个字节(4)参数错误报文类型:12代码:0或1检验和指针未使用(全0)收到的IP数据报的一部分,包括IP数据报首部以及数据报数据的前8个字节(5)改变路由报文类型:5代码:03检验和目标路由器IP地址收到的IP数据报的一部分,包括IP数据报首部以及数据报数据的前8个字节习题3:本题主要考查对PING程序实现及与ICMP报文联系的掌握程度,帮助学生更深入地了解ICMP报文的实现。详细描述请参照5.6节。 习题4:icsetbuf.c文件的源代码如下。/*-* icsetbuf - 为ICMP报文申请一个缓冲区* icsetbuf()函数为ICMP报文分配缓冲区,设置了两个变量,其中一个变量指出该报文是否是一个差错报告报文(或是一个信息请求);而另一个指出这个报文的类型是否是对上一个请求做出的应答。* 该函数很直观,具体分四种情况:对绝大多数的应答,icsetbuf()函数重新利用抵达的请求报文占用的缓冲区(即返回由入口参数pa1提供的地址);对于没有具体实现的报文类型,icsetbuf()函数释放引起差错的报文,返回SYSERR;对含有大量数据的ICMP报文,icsetbuf()函数为其分配一个大缓冲区;对其他不能利用原缓冲区的报文,icsetbuf()函数为它们分配一个标准缓冲区。*-*/struct ep *icsetbuf(type, pa1, pisresp, piserr)inttype;char*pa1;/*旧的报文(如果有的话)*/Bool*pisresp,/*查询报文*/*piserr;/*差错报告报文*/Struct ep *pep; /*正在处理的以太网帧*/*pisresp = *piserr = FALSE;switch (type) case ICT_REDIRECT:/*重定向报文*/pep = (struct ep *)getbufi(Npool);/* char *getbufi(poolid)申请小缓冲区*/if (pep = NULL)return(NULL);blkcopy(pep, pa1, MAXNETBUF);/* 函数原型为blkcopy(to, from, nbytes)*/pa1 = (char *)pep;*piserr = TRUE;break;case ICT_DESTUR:/*终点不可达报文*/case ICT_SRCQ: /*源点抑制报文*/case ICT_TIMEX: /*超时报文*/case ICT_PARAMP: /*参数错误报文*/pep = (struct ep *)pa1;*piserr = TRUE;break;case ICT_ECHORP:/*ECHO应答报文*/case ICT_INFORP:/*消息应答报文*/case ICT_MASKRP:/ *ICMP掩码应答报文*/pep = (struct ep *)pa1;*pisresp = TRUE;break;case ICT_ECHORQ:/*ECHO请求报文*/case ICT_TIMERQ: /*时间戳请求报文*/case ICT_INFORQ: /*消息请求报文*/case ICT_MASKRQ: /*ICMP掩码请求报文*/pep = (struct ep *)getbufi(Net.lrgpool); /*申请大缓冲区*/if (pep = NULL)return(NULL);break;case ICT_TIMERP:/* 时间戳应答报文 */* IcmpOutTimestampsReps+; */IcmpOutErrors-;/* Kludge:超时报文数加1 */freebuf(pa1);return(NULL);switch (type) /* 更新MIB 统计信息量*/case ICT_ECHORP:IcmpOutEchos+;break;case ICT_ECHORQ:IcmpOutEchoReps+;break;case ICT_DESTUR:IcmpOutDestUnreachs+;break;case ICT_SRCQ:IcmpOutSrcQuenchs+;break;case ICT_REDIRECT:IcmpOutRedirects+;break;case ICT_TIMEX:IcmpOutTimeExcds+;break;case ICT_PARAMP:IcmpOutParmProbs+;break;case ICT_TIMERQ:IcmpOutTimestamps+;break;case ICT_TIMERP:IcmpOutTimestampReps+;break;case ICT_MASKRQ:IcmpOutAddrMasks+;break;case ICT_MASKRP:IcmpOutAddrMaskReps+;break;return pep;char *getbufi(poolid)/*从预先设定的缓冲池申请缓冲区,如果没有可用的缓冲区则立即返回*/struct ep /* 以太帧结构*/IPaddrep_nexthop; /* niput函数使用 */shortep_len; /*以太帧长度 */structeh ep_eh; /*以太帧首部 */charep_dataEP_DLEN;/*以太帧的数据部分*/;icsetdata.c文件的源代码如下。/* ECHOMAX必须是偶数*/#define ECHOMAX(pip) (MAXLRGBUF-IC_HLEN-IP_HLEN(pip)-EP_HLEN)/*MAXLRGBUF 最大缓冲区*/*IC_HLEN 8*/*IP_HLEN(pip) (pip-ip_verlen & 0xf)ip_data;inti, len;switch (type) case ICT_ECHORP: /*ECHO应答报文*/len = pip-ip_len-IP_HLEN(pip)-IC_HLEN;/* 长度 = IP报文长度-IP首部长度-ICMP首部长度*/if (isodd(len)/* isodd()函数:判断其参数是不是奇数,如果是奇数就返回TRUE,否则返回FASLE和错误值*/pic-ic_datalen = 0;/*ICMP数据区CRC校验 */return len;case ICT_DESTUR:/*终点不可达报文*/case ICT_SRCQ: /*源点抑制报文*/case ICT_TIMEX: /*超时报文*/pic-ic_mbz = (long) 0; /*必须为0 */break;case ICT_REDIRECT:/*重定向报文*/blkcopy(pic-ic_gw, pa2, IP_ALEN); /* blkcopy(to, from, nbytes) 重定向到网关*/break;case ICT_PARAMP:/*参数错误报文*/len = (int)pa2;pic-ic_p

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论