Ethernet帧结构解析..

  • 格式:doc
  • 大小:381.50 KB
  • 文档页数:11

下载文档原格式

  / 26
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验一Ethernet帧结构解析

一.需求分析

实验目的:(1)掌握Ethernet帧各个字段的含义与帧接收过程;

(2)掌握Ethernet帧解析软件设计与编程方法;

(3)掌握Ethernet帧CRC校验算法原理与软件实现方法。

实验任务:(1)捕捉任何主机发出的Ethernet 802.3格式的帧和DIX Ethernet V2(即Ethernet II)格式的帧并进行分析。

(2)捕捉并分析局域网上的所有ethernet broadcast帧进行分析。

(3)捕捉局域网上的所有ethernet multicast帧进行分析。

实验环境:安装好Windows 2000 Server操作系统+Ethereal的计算机

实验时间; 2节课

二.概要设计

1.原理概述:

以太网这个术语通常是指由DEC,Intel和Xerox公司在1982年联合公布的一个标准,它是当今TCP/IP采用的主要的局域网技术,它采用一种称作CSMA/CD的媒体接入方法。几年后,IEEE802委员会公布了一个稍有不同的标准集,其中802.3针对整个CSMA/CD网络,802.4针对令牌总线网络,802.5针对令牌环网络;此三种帧的通用部分由802.2标准来定义,也就是我们熟悉的802网络共有的逻辑链路控制(LLC)。以太网帧是OSI参考模型数据链路层的封装,网络层的数据包被加上帧头和帧尾,构成可由数据链路层识别的数据帧。虽然帧头和帧尾所用的字节数是固定不变的,但根据被封装数据包大小的不同,以太网帧的长度也随之变化,变化的范围是64-1518字节(不包括8字节的前导字)。

帧格式Ethernet II和IEEE802.3的帧格式分别如下。

EthernetrII帧格式:

----------------------------------------------------------------------------------------------

| 前序| 目的地址| 源地址| 类型| 数据

| FCS |

----------------------------------------------------------------------------------------------

| 8 byte | 6 byte | 6 byte | 2 byte | 46~1500 byte | 4 byte|

IEEE802.3一般帧格式

-----------------------------------------------------------------------------------------------------------

| 前序| 帧起始定界符| 目的地址| 源地址| 长度| 数据| FCS | -----------------------------------------------------------------------------------------------------------

| 7 byte | 1 byte | 2/6 byte | 2/6 byte| 2 byte| 46~1500 byte | 4 byte | Ethernet II和IEEE802.3的帧格式比较类似,主要的不同点在于前者定义的2字节的类型,而后者定义的是2字节的长度;所幸的是,后者定义的有效长度值与前者定义的有效类型值无一相同,这样就容易区分两种帧格式

2程序流程图:

三.详细设计:

1.CRC校验部分设计:

为了对以太网帧的对错进行检验,需要设计CRC校验部分。采用以为相与的方式对帧的首部相继作8位CRC校验

输入参数:

chCurrByte 低8位数据有效,记录了上一次CRC校验的余数

chNextByte 低8位数据有效,记录了本次要继续校验的一个字节

传出参数:

chCurrByte 低8位数据有效,记录了本次CRC校验的余数

void checkCRC(int &chCurrByte, int chNextByte)

{

// CRC循环:每次调用进行8次循环,处理一个字节的数据。

for (int nMask = 0x80; nMask > 0; nMask >>= 1)

{

if ((chCurrByte & 0x80) != 0) // 首位为1:移位,并进行异或运算

{

chCurrByte <<= 1; // 移一位

if ( (chNextByte & nMask) != 0) // 补一位

{

chCurrByte |= 1;

}

chCurrByte ^= 7; // 首位已经移出,仅对低8位进行异或运算,7的二进制为0000,0111

}

else // 首位为0,只移位,不进行异或运算

{

chCurrByte <<= 1; // 移一位

if ( (chNextByte & nMask) != 0) // 补一位

{

chCurrByte |= 1;

}

}

}

}

2.部分变量的声明:

int nSN = 1; // 帧序号

int nCheck = 0; // 校验码

int nCurrDataOffset = 22; // 帧头偏移量

int nCurrDataLength = 0; // 数据字段长度

bool bParseCont = true; // 是否继续对输入文件进行解析

int nFileEnd = 0; // 输入文件的长度

3.计算数据段的长度:

nCurrDataLength =

bParseCont ? // 是否到达文件末尾

(file.tellg() - 8 - 1 - nCurrDataOffset) : // 没到文件末尾:下一帧头位置- 前导码和定界符长度- CRC校验码长度- 数据字段起始位置

(file.tellg() - 1 - nCurrDataOffset); // 已到达文件末尾:文件末尾位置- CRC校验码长度- 数据字段起始位置

4.主函数的设计:

void main(int argc, char* argv[])

{

// 检测命令行参数的正确性

if (argc != 2)

{

cout << "请以帧封装包文件为参数重新执行程序" << endl;

exit(0);

}

// 检测输入文件是否存在,并可以按所需的权限和方式打开

ifstream file(argv[1], ios::in|ios::binary|ios::nocreate);

if (!file.is_open())

{

cout << "无法打开帧封装包文件,请检查文件是否存在并且未损坏" << endl;

exit(0);