这几天在公司做项目要用到WinPcap,但在实现的过程中,需要分析捕获的数据包,恰好用到了大学时学习的计算机网络课程。现初步总结了几个网络协议及其格式:
在局域网中,硬件地址又称为物理地址或MAC地址(因为这种地址用在MAC帧中)。
大家知道,在所有计算机系统的设计中,标识系统(identification system)都是一个核心问题。在标识系统中,地址就是为识别某个系统的一个非常重要的标识符。在讨论地址问题时,很多人常常引用著名文献[SHOC78]给出的如下定义:
“名字指出我们所要寻找的那个资源,地址指出那个资源在何处,路由告诉我们如何到达该处。”
这个非形式的定义固然很简单,但有时不够准确。严格地讲,名字应当与系统的所在地无关。这就像我们每一个人的名字一样,不随我们所处的地点而改变。但是802标准为局域网规定了一种48bit的全球地址(一般都简称为“地址”),是指局域网上的每一台计算机所插入的网卡上的地址。因此:
(1) 假定连接在局域网的一台计算机的网卡坏了而我们更换了一个新的网卡,那么这台计算机的局域网的“地址”也就改变了,即使这台计算机的地形位置一点也没有变化。所接入的局城网也没有任何改变。
(2) 假定我们将位于南京的某局城网上的一台计算机转移到北京。并连接在北京的某局域网上。虽然这台计算机的地理位置改变了,但只要这台计算机中的网卡不变,那么这台计算机在北京的局域网中的“地址”仍然和它在南京的局域网中的“地址”一样。
因此可见,802标准所说的“地址”严格地讲应当是每一个站的“名字”或标识符。但鉴于在家都早已习惯了将这种48bit的“名字”称为“地址”,所以本书也采用这种习惯用法。
尽管这种说法并不太严格,请读者一定要弄清这个概念。
MAC地址也叫物理地址、硬件地址或链路地址,由网络设备制造商生产时写在硬件内部。IP地址与MAC地址在计算机里都是以二进制表示的,IP地址是32位的,而MAC地址则是48位的。MAC地址的长度为48位(6个字节),通常表示为12个16进制数,每2个16进制数之间用冒号隔开,如:08:00:20:0A:8C:6D就是一个MAC地址,其中前6位16进制数08:00:20代表网络硬件制造商的编号,它由IEEE(电气与电子工程师协会)分配,而后3位16进制数0A:8C:6D代表该制造商所制造的某个网络产品(如网卡)的系列号。只要你不去更改自己的MAC地址,那么你的MAC地址在世界是惟一的。
以太网的MAC帧格式有两种标准,一种是DIX Ethernet V2标准,另一种是IEEE的802.3标准,图1 画出了这两种不同的MAC帧格式。
图1 两种不同的MAC帧格式
IP协议(Internet Protocol)是网络层协议,用在因特网上,TCP,UDP,ICMP,IGMP数据都是按照IP数据格式发送得。IP协议提供的是不可靠无连接得服务。IP数据包由一个头部和一个正文部分构成。正文主要是传输的数据,IP头部由20字节的固定长度和一个可选任意长度部分构成,以大段点机次序传送,从左到右,IP协议数据包格式如图2。
图2 IP协议数据包格式
字段 | 长度(位) | 描述 |
---|---|---|
备份 | 1 | 当此选项需要被备份到所有分片中时,设为1。 |
类 | 2 | 常规的选项类别,0为“控制”,2为“查错和措施”,1和3保留。 |
数字 | 5 | 指明一个选项。 |
长度 | 8 | 指明整个选项的长度,对于简单的选项此字段可能不存在。 |
数据 | 可变 | 选项相关数据,对于简单的选项此字段可能不存在。 |
数据字段不是首部的一部分,因此并不被包含在检验和中。数据的格式在协议首部字段中被指明,并可以是任意的传输层协议。
一些常见协议的协议字段值被列在下面:
协议字段值 | 协议名 | 缩写 |
---|---|---|
1 | 互联网控制消息协议 | ICMP |
2 | 互联网组管理协议 | IGMP |
6 | 传输控制协议 | TCP |
17 | 用户数据报协议 | UDP |
41 | IPv6封装 | - |
89 | 开放式最短路径优先 | OSPF |
132 | 流控制传输协议 | SCTP |
TCP协议(TRANSMISSION CONTROL PROTOCOL)是传输层协议,为应用层提供服务,和UDP不同的是,TCP协议提供的可靠的面向连接的服务,跟IP头部差不多,基本的长度也是20字节。TCP数据包是包含在一个IP数据报文中的,TCP数据包如图3所示。
图3 TCP数据包格式
在TCP/IP模型中,UDP为网络层以上和应用层以下提供了一个简单的接口。UDP只提供数据的不可靠传递,它一旦把应用程序发给网络层的数据发送出去,就不保留数据备份(所以UDP有时候也被认为是不可靠的数据报协议)。UDP在IP数据报的头部仅仅加入了复用和数据校验(字段)。
UDP首部字段由4个部分组成,如图4所示,其中两个是可选的。各16bit的来源端口和目的端口用来标记发送和接受的应用进程。因为UDP不需要应答,所以来源端口是可选的,如果来源端口不用,那么置为零。在目的端口后面是长度固定的以字节为单位的长度域,用来指定UDP数据报包括数据部分的长度,长度最小值为8byte。首部剩下地16bit是用来对首部和数据部分一起做校验和(Checksum)的,这部分是可选的,但在实际应用中一般都使用这一功能。
图4 UDP协议格式
由于缺乏可靠性且属于非连接导向协定,UDP应用一般必须允许一定量的丢包、出错和复制。有些应用,比如TFTP,如果需要则必须在应用层增加根本的可靠机制。但是绝大多数UDP应用都不需要可靠机制,甚至可能因为引入可靠机制而降低性能。流媒体、实时多媒体游戏和IP电话 (VoIP)就是典型的UDP应用。如果某个应用需要很高的可靠性,那么可以用传输控制协议(TCP协议)来代替UDP。
端口号表示发送进程和接收进程。UDP长度字段指的是UDP首部和UDP数据的字节长度。该字段的最小值为8字节(发送一份0字节的UDP数据报是OK)。这个UDP长度是有冗余的。IP数据报长度指的是数据报全长,因此UDP数据报长度是全长减去IP首部的长度。
UDP检验和覆盖UDP首部和UDP数据。回想IP首部的检验和,它只覆盖IP的首部,并不覆盖IP数据报中的任何数据。UDP的检验和是可选的,它是一个端到端的检验和。它由发送端计算,然后由接收端验证。其目的是为了发现UDP首部和数据在发送端到接收端之间发生的任何改动。
尽管U D P检验和的基本计算方法与I P首部检验和计算方法相类似(16 bit字的二进制反码和) ,但是它们之间存在不同的地方。首先, U D P数据报的长度可以为奇数字节,但是检验和算法是把若干个 16 bit字相加。解决方法是必要时在最后增加填充字节0,这只是为了检验和的计算(也就是说,可能增加的填充字节不被传送) 。其次,U D P数据报和T C P段都包含一个1 2字节长的伪首部,它是为了计算检验和而设置的。伪首部包含 I P首部一些字段。其目的是让 U D P两次检查数据是否已经正确到达目的地(例如,I P没有接受地址不是本主机的数据报,以及 I P没有把应传给另一高层的数据报传给U D P)。
图5 带伪首部的UDP格式
UDP和TCP首部都包含一个12字节的伪首部(如图6),包含了IP首部和自身的一些字段,主要是为了计算检验和而设置的。伪首部是不占实际空间的。伪首部包含IP首部的一些字段,目的是让UDP两次检查数据是否已经到达目的地,以及IP层是否正确地传输了数据。
如果发送端没有计算检验和而接收端检测到检验和有差错,那么 U D P数据报就要被悄悄地丢弃。不产生任何差错报文(当I P层检测到I P首部检验和有差错时也这样做) 。
伪首部的源IP地址字段和目的IP地址字段记录了发送UDP报文时使用的源IP地址和目的IP地址。 协议字段指明了所使用的协议类型代码(UDP是17),而UDP长度字段是UDP数据报的长度(伪首部的长度不计算在内)。
UDP计算校验和的方法和计算IP数据报首部校验和的方法相似。 但不同的是:IP数据报的校验和只检验IP数据报的首部,但UDP的校验和是将首部和数据部分一起都检验。 在发送端,首先是将全零放入检验和字段。再将伪首部以及UDP用户数据报看成是由许多16bit的字串接起来。 若UDP用户数据报的数据部分不是偶数个字节,则要填入一个全零字节(但此字段不发送)。 然后按二进制反码计算出这些16bit字的和(两个数进行二进制反码求和的运算的规则是:从低位到高位逐列进行计算。 0和0相加是0,0和1相加是1,1和1相加是0但要产生一个进位1,加到下一列。若最高位相加后产生进位,则最后得到的结果要加1)。 将此和的二进制反码写入校验和字段后,发送此UDP用户数据报。 在接收端,将收到的UDP用户数据报连同伪首部(以及可能的填充全零字节)一起,按二进制反码求这些16bit字的和。 当无差错时其结果应全为1。否则就表明有差错出现, 接收端就应将此UDP用户数据报丢弃(也可以上交给应用层,但附上出现了差错的警告)。
以后再补充吧,呵呵,各位笑纳。