以太帧封装与解析----感谢 网友 分享 载自 互联网.doc_第1页
以太帧封装与解析----感谢 网友 分享 载自 互联网.doc_第2页
以太帧封装与解析----感谢 网友 分享 载自 互联网.doc_第3页
以太帧封装与解析----感谢 网友 分享 载自 互联网.doc_第4页
以太帧封装与解析----感谢 网友 分享 载自 互联网.doc_第5页
已阅读5页,还剩4页未读 继续免费阅读

下载本文档

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

文档简介

计算机网络的第一次作业,得了90分。其实实际上就是字符串的处理,没有什么难的。一、帧的封装1、背景知识介绍当数据在以太网通信中传输时,被封装在帧中(见下图)。帧的组成部分都是预定义的。 第1部分为前同步信号, 5 6位长。前同步信号同步帧的传输,由交替的0和1构成。下一个域是 8位的帧首定界符(Start Frame De l i m i t e r,S F D )。帧首定界符的形式为1 0 1 0 1 0 11。在帧首定界 符之后,跟随着两个包含目标地址和源地址的地址域。根据I E E E 8 0 2 . 3标准,地址域或者是1 6 位,或者是4 8位。接下来就是指定帧长度的1 6位域。帧的数据部分在长度域之后。封装的数据的长度必须是8位的倍数,如果不是,就必须包含一个填充域。帧的最末部分是帧校验序列(Frame Check Se q u e n c e,FC S )域,3 2位长,允许使用循环冗余校验法(Cyclic Redundancy Ch e c k,C R C )进行错误检测。这个值是在封装时从帧的其他域中计算出来的,当目标结点接收到帧时会重新计算一次。如果重新计算的值与原来计算出来的值不同,就会产生错误,接收结点就要求帧重新传输。当重计算的值与原来的值完全匹配时, C R C比较算法产生结果0,不发出重新计算的要求。现在C R C算法已经被指定为I E E E标准。Ethernet II是一种以太网数据格式化方法,用于I n t e r n e t和其他现代网络中,与I E E E 8 0 2 . 3标准的差别很小,从而使得网络传输更有效。在EthernetII中,前同步信号为6 4位长,包含有起始分界符和帧开始定界符( S O F )。Ethernet II中的目标和源地址都是严格的4 8位(图2 - 1 2 )。Ethernet II使用1 6位类型域而不是长度域,该域用于高水平的网络通信。数据域无须p a d域来封装,长度界于5 7 6位和12 208位之间。域尺寸的最小值和最大值有利于提高改善包的冲突检测,并确保一个大型的包不会太长时间地占据网络。Ethernet II帧中的最后一个域是3 2位长的帧校验序列( F C S )域,按照8 0 2 . 3标准中的方法执行C R C.为避免网络通信问题,切勿于同一网络上在相同的通信结点中同时使用Ethernet II和8 0 2 . 3标准的帧。8 0 2 . 3标准和Ethernet II在长度(或类型域)与I E E E 8 0 2 . 2的数据链路层的L L C子层通信标准中指定的数据域之间有3个可选的域:目标地址服务访问点( D S A P )、源服务访问点( S S A P )和控制。这些域使得数据链路层可以管理帧并与O S I模型中的高层进行通信。D S A P和S S A P均为8位长。服务访问点( S A P )可使网络层确定目标结点的哪一个网络进程可以接收帧。而且它们也代表着诸如O S I、N o v e l l、N e t B I O S、T C P / I P、B PD U和I B M网络管理、X N S等通信进程。下面来举例说明。E 0是Novell SAP的1 6进制值,0 6是T C P / I P的S A P的1 6进制码。D S A P指定了接收帧的接收结点的服务访问点, S S A P则标识发送帧的发送结点的服务访问点。控制域的长度为8位或1 6位,用来识别帧的功能,比如它是否带有数据或报错信息。图1几种常见的局域网数据链路帧类型2、封装的实现2.1编程风格的约定变量的命名的约定:变量名的第一个字母都用该变量的类型的第一个字母,比如char 类型的变量定义为cName,int类型的变量命名为iName。对于指针类型的变量,则在上述的基础上加上“pointer”的第一个字母“p”,比如char * pcName。对于数组变量则变量名以“a”开头,比如int aiName,这样就可以不看定义知道是整型的数组变量。方便代码的阅读和理解。变量名都是与变量意义相关的单词组成,不写无意义的变量名和容易产生歧义的变量名。代码的缩进以4个空格为基本单位,这样可以使多层的嵌套容易理解,而且嵌套不超过3层,以减少代码的出错和整体的理解。2.2主要常量的定义#define DATA_MAX 1500 /*数据的最长长度*/#define DATA_MIN 46 /*数据的最短长度*/#define PREAMBLE_LEN 8 /*前导码长度*/#define DEST_LEN 6 /*目的地址长度*/#define SOURCE_LEN 6 /*源地址长度*/#define DATA_AREA_LEN 2 /*数据的实际长度*/#define FCS_LEN 4 /*帧校验字段的长度*/char cPreamble8=(char)0xAA,(char)0xAA,(char)0xAA,(char)0xAA,(char)0xAA,(char)0xAA,(char)0xAA,(char)0xAB;/* 前导码的定义 */ char cDest6=(char)0xFF,(char)0xFF,(char)0xFF,(char)0xFF,(char)0xFF,(char)0xFF;/*目的地址的定义*/char cSource6=(char)0x00,(char)0x16,(char)0x76,(char)0xB4,(char)0xE4,(char)0x77; /*源地址的定义*/2.3函数的功能说明void framer()实现了具体的封装,主函数在封装帧时调用该接口。 void deFramer();实现了具体的帧的解析,主函数在解析帧时调用该接口。int GenerateCRC(char* DataBuf,unsigned long len); 根据所给的字符串,生成该字符串的校验码。void frameInDetail(char *pcFrame,char *pcData,long lDataLeft,int *pnDataAreaLen,int *pnFCS);实现了对一个帧的具体的封装,对于三种不同的帧,即数据长度小于46,大于1500和介于两者之间的数据长度进行不同的封装。2.4主函数的框架在程序执行时,需要用户输入两个参数,第一个参数用来标识是封装或者解析帧,第二个参数用来标识输入或者输出的文件名。所以需要对用户输入的参数进行判断,以用来处理异常情况。 if(argcDATA_MAX) lDataLeft=lDataLeft-DATA_MAX; else /*数据已经封装完毕,退出循环体*/ break; foutpcFrameendl;/*将数据帧的信息输出到文件中*/ cout帧封装完毕! DATA_MAX) nMASK= DATA_MAX; else nMASK = lDataLeft; /*计算当前数据帧的总长度*/nFrameLen=PREAMBLE_LEN+DEST_LEN+SOURCE_LEN+DATA_AREA_LEN+nMASK+FCS_LEN; pcFrame=(char *) malloc(nFrameLen); /*为帧分配空间*/memcpy(pcFrame,cPreamble,PREAMBLE_LEN); /*加入前导码*/ memcpy(pcFrame+PREAMBLE_LEN,cDest,DEST_LEN); /*加入目的地址*/*加入源地址*/memcpy(pcFrame+PREAMBLE_LEN+DEST_LEN,cSource,SOURCE_LEN); *pnDataAreaLen=nMASK&0xFFFF; /* 求得数据长度*/ memcpy(pcFrame+PREAMBLE_LEN+DEST_LEN+SOURCE_LEN,pnDataAreaLen,DATA_AREA_LEN); /*加入数据长度*/ memcpy(pcFrame+PREAMBLE_LEN+DEST_LEN+SOURCE_LEN+DATA_AREA_LEN,pcData,nMASK);/* 加入数据 */ if (lDataLeft=0) (void)checkCRC(chCurrByte,(int)pcDatanCont-1);return chCurrByte;二、帧的解析1、背景知识介绍Ethernet帧的解析,简单说就是列出帧的各字段的值。历史上以太网帧格式有五种: 1.Ethernet V1:这是最原始的一种格式,是由Xerox PARC提出的3Mbps CSMA/CD以太网标准的封装格式,后来在1980年由DEC,Intel和Xerox标准化形成Ethernet V1标准. 2.Ethernet V2(ARPA):由DEC,Intel和Xerox在1982年公布其标准,主要更改了Ethernet V1的电气特性和物理接口,在帧格式上并无变化;Ethernet V2出现后迅速取代Ethernet V1成为以太网事实标准;Ethernet V2帧头结构为6bytes的源地址+6bytes的目标地址+2Bytes的协议类型字段+数据。 3.RAW 802.3:这是1983年Novell发布其划时代的Netware/86网络套件时采用的私有以太网帧格式,该格式以当时尚未正式发布的802.3标准为基础;但是当两年以后IEEE正式发布802.3标准时情况发生了变化IEEE在802.3帧头中又加入了802.2 LLC(Logical Link Control)头,这使得Novell的RAW 802.3格式跟正式的IEEE 802.3标准互不兼容. 4.802.3/802.2 LLC:这是IEEE 正式的802.3标准,它由Ethernet V2发展而来。它将Ethernet V2帧头的协议类型字段替换为帧长度字段(取值为0000-05dc;十进制的1500);并加入802.2 LLC头用以标志上层协议,LLC头中包含DSAP,SSAP以及Crontrol字段. 5.802.3/802.2 SNAP:这是IEEE为保证在802.2 LLC上支持更多的上层协议同时更好的支持IP协议而发布的标准,与802.3/802.2 LLC一样802.3/802.2 SNAP也带有LLC头,但是扩展了LLC属性,新添加了一个2Bytes的协议类型域(同时将SAP的值置为AA),从而使其可以标识更多的上层协议类型;另外添加了一个3Bytes的OUI字段用于代表不同的组织,RFC 1042定义了IP报文在802.2网络中的封装方法和ARP协议在802.2 SANP中的实现.802.3以太网帧格式备注:前导码(7字节)、帧起始定界符(1字节)、目的MAC地址(6字节)、源MAC地址(6字节)、类型/长度(2字节)、数据(461500字节)、帧校验序列(4字节)MAC地址可以用26字节来表示,原则上是这样,实际都是6字节2、帧解析的实现2.1编程风格的约定编程风格与变量命名与帧的封装相同2.2主要常量的定义2.3函数的功能说明2.4解析函数void deFramer()实现的主要部分unsigned char aucPremode7; /前导码 unsigned char ucDelimiter; /定界符 unsigned char aucDest6; /目的地址 unsigned char aucSource6; /源地址 unsigned char ucLen2; /长度字符 unsigned char ucData1500; /数据字段 unsigned char ucFCS; /校验字段 ifstream fin; fin.open(acFileName, ios:in); /文件打开失败时退出 if (!(fin.is_open() cout Cant open file! endl; cout *请输入命令行,格式如下* endl *FrameParser inputfile * endl; return ; int sum = 1; /初始化序号为1 fin.seekg(0, ios:end); cout11endl; int fLen = fin.tellg(); /取得文件长度 int curLen = 0; /标记当前读取的文件长度 coutfLenendl; fin.seekg(0, ios:beg); /把文件指针定位在文件开头 int j; while (curLen fLen) fin.read(char *) aucPremode, 7); /读取前导码 fin.read(char *)(&ucDelimiter), 1); /读取定界符 fin.read(char *)aucDest, 6); /读取目的地址 fin.read(char *)aucSource, 6); /读取源地址 fin.read(char *)(&ucLen), 2); /读取长度 int highAddr = ucLen0&0xff; int lowAddr = ucLen1&0xff; int dataLength = highAddr*256 + lowAddr; /计算长度 /判断长度是否在461500范围内 if (dataLength 1500) cout ERROR endl; /长度大于1500退出 return; /end of if unsigned char* dataTemp = new unsigned chardataLength+14; /存放用于计算校验码的数据字段 cout 序号: sum endl; cout 前导码:; / 输出前导码 for ( j=0; j7; j+) cout hex (short) aucPremodej; /end of for cout endl 帧前定界符:; cout hex (short)ucDelimiter endl; /输出界定符 cout 目的地址:; /输出目的地址 for (j=0; j6; j+) dataTempj = aucDestj; /把目的地址存入 cout hex (short)aucDestj; /end of for cout endl 源地址:; /输出源地址 for (int j=0; j6; j+) dataTempj+6 = a

温馨提示

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

最新文档

评论

0/150

提交评论