Chinaunix首页 | 论坛 | 博客
  • 博客访问: 23365
  • 博文数量: 7
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 45
  • 用 户 组: 普通用户
  • 注册时间: 2018-10-14 13:22
文章分类

全部博文(7)

文章存档

2019年(7)

我的朋友
最近访客

分类: 网络与安全

2019-01-21 13:35:58

严格来说,TCP/IP 协定家族并没有定义"TCP/IP 专属的" 网路硬体规格。硬体的范围实在太过广泛了﹐标准非常多﹐当今大部份的低层网路硬体标准都是由IEEE 制定的,但也有许多标准是厂商专属的。要让TCP/IP 协定能够顺利与不同类型的硬体进行沟通﹐那么就需要建立起一些标准协定来让大家共同参考。以我们最常用的乙太网(Ethernet)为例﹐我们无需理会厂商如何设计网路界面的驱动程式﹐一旦它能够被系统接纳﹐网路储存层(Datalink)就能使用网路界面在实体网路上传送和接收资料了。

IP 位址和实体位址对应之困扰

在「网路基础」课程中﹐我们知道乙太网上面使用的传送方式叫CSMA/CD (Carrier-Sensing Multiple Access with Collision Detection)﹕虽然讯框会在整个网段(segment)中用广播的方式传递﹐而且所有节点都会收到讯框﹐然而﹐只有目的位址符合自己实体位址的讯框才会被接收下来。因此,不管上层协定是哪一种(可以是TCP/IP也可以是其它),在底层的传送若是使用Ethernet的话,就得使用MAC (Media Access Control)实体位址。若要查询到当前系统目前所有界面的实体位址,我们可在Linux系统里面输入ifconfig命令﹕

eth0 Link encap:Ethernet HWaddr 00:A0:0C:11:EA:11 inet addr:203.30.35.134 Bcast:203.30.35.159 Mask:255.255.255.224 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:100 Interrupt:3 Base address:0x300  eth1 Link encap:Ethernet HWaddr 00:80:C7:47:8C:9A inet addr:192.168.0.17 Bcast:192.168.0.255 Mask:255.255.255.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:12303 errors:0 dropped:0 overruns:0 frame:0 TX packets:12694 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:100 Interrupt:10 Base address:0x2e0 


从上面的命令结果中可发现:关于每一个界面的第一行资讯﹐最后的部份就是该界面的实体位址。讯框在实体网路上面传送的过程中﹐IP 位址(或曰罗辑位址)一点都派不上用场。但问题是:当我们使用TCP/IP 的时侯,上层的协定都是以IP 位址为传送依据的。那么﹐这时候我们就必须有一套方法来对应IP 位址和实体位址了。

在此一过程中﹐关键点是如果将IP 位址对与实体位址做对应。有些使用简单实体位址的网路(如proNET-10 )﹐其实体位址只占一个byte 的长度﹐而且允许使用者在配置网路卡的是选择自己的实体位址。在这样的网路上进行IP 位址和实体位址的对应﹐是比较简单的﹐我们可以把实体位址设为和IP 位址设为一样。例如﹐假设某一个节点的IP 位址为192.168.1.17﹐那么我们可以将该实体位址设为17。这样﹐在proNET 就可以轻易的根据IP 位址来得到实体位址。这样的对应非常简单﹐而且要维护起来也很容易﹐在新机器加入网路的时候﹐并不需要修改或重编已存的资料。

然而﹐我们知道在乙太网上﹐每一个实体界面都有一个48bit(6byte) 的MAC 位址﹐而IP (v4)使用的位址则为32bit(4byte)﹔每各位址格式都只提供相应的层级协定使用﹐彼此是不能互换使用的。这时候我们就无法用简单的数学关系来做IP 位址和实体位址的对应了。


IP 位址和实体位址的对应方法

建立表格


首先﹐我们想到的最简单方法是在每一台机器上建立一个IP 位址和实体位址的对应表格( table )。不过这个方法还是没办法解决如下的情形﹕


  • 网路上的节点数量多如恒河沙数﹐要想将全部节点的对应关系列入表格之中几近不可能任务。
  • 如果某一个节点产生异动情形(例如更换网卡)﹐那么如果让所有表格正确做出相应修改﹐也是个头痛的问题。
  • 对某无磁碟工作站来说﹐因为没有本机的储存设备﹐将无法建立表格。


写入高阶程式


除了建立表格﹐我们还可以将实际的网路位址写死在高阶网路程式里面。不过﹐和前一个方法一样﹐如果遇到硬体位址变更等异动动情形﹐那么﹐程式也需要重新编译过才行。

显然﹐上述两个方法都不怎么高明。


ARP 协定


这里我们要介绍的是Address Resolution Protocol (ARP)。ARP 是TCP/IP 设计者利用乙太网的广播性质﹐设计出来的位址解释协定。它的主要特性和优点是它的位址对应关系是动态的﹐它以查询的方式来获得IP 位址和实体位址的对应。它的工作原理非常简单﹕


  1. 首先﹐每一台主机都会在ARP 快取缓冲区(ARP Cache)中建立一个ARP 表格﹐用来记录IP 位址和实体位址的对应关系。这个Table 的每一笔资料会根据自身的存活时间递减而最终消失﹐以确保资料的真实性。
  2. 当发送主机有一个封包要传送给目的主机的时候﹐并且获得目的主机的IP 位址﹔那发送主机会先检查自己的ARP 表格中有没有该IP 位址的实体位址对应。如果有﹐就直接使用此位址来传送框包﹔如果没有﹐则向网路发出一个ARP Request 广播封包﹐查询目的主机的实体位址。这个封包会包含发送端的IP 位址和实体位址资料。
  3. 这时﹐网路上所有的主机都会收到这个广播封包﹐会检查封包的IP 栏位是否和自己的IP 位址一致。如果不是则忽略﹔如果是则会先将发送端的实体位址和IP 资料更新到自己的ARP 表格去﹐如果已经有该IP 的对应﹐则用新资料覆盖原来的﹔然后再回应一个ARP Reply 封包给对方﹐告知发送主机关于自己的实体位址﹔
  4. 当发送端接到ARP Reply 之后﹐也会更新自己的ARP 表格﹔然后就可以用此纪录进行传送了。
  5. 如果发送端没有得到ARP Reply ﹐则宣告查询失败。


ARP 的查询过程可参考下图﹕


ARP 的查询过程


前面说的ARP 表格﹐只有在TCP/IP 协定被载入核心之后才会建立﹐如果TCP/IP 协定被卸载或关闭机器﹐那么表格就会被清空﹔到下次协定载入或开机的时候再重新建立﹐而同时会向网路发出一个ARP 广播﹐告诉其它机器它的目前位址是什么﹐以便所有机器都能保持最正确的资料。

然而﹐ARP cache 的大小是有所限制的﹐如果超过了界限﹐那么越长时间没被使用过渡资料就必须清理掉﹐以腾出空间来储存更新的资料。所以﹐当机器收到ARP equest 封包时﹐如果查询对象不是自己﹐则不会根据发送端位址资料来更新自己的ARP 表格﹐而是完全忽略该封包。同时﹐每笔存在cache 中的资料﹐都不是永久保存的﹕每笔资料再更新的时候﹐都会被赋予一个存活倒数计时值﹐如果在倒数时间到达的时候﹐该资料就会被清掉。然而﹐如果该资料在倒数时间到达之前被使用过﹐则计时值会被重新赋予。

当然了﹐ARP 尚有一套机制来处理当ARP 表格资料不符合实际位址资料的状况(例如﹐在当前连线尚未结束前﹐收到目的端的位址资料更新讯息)﹔或是目的主机太忙碌而未能回答ARP 请求等状况。

RARP 协定

刚才介绍的ARP 协定是透过向网路查询而找出实体位址﹐那我们接下来探讨的RARP 协定则相反﹕它是籍由查询网路上其它主机而得到自己的IP 位址。

通常﹐我们使用的乙太网卡﹐在出厂的时候就有生产厂家把网卡的实体位址烧在ROM 里面﹐这个位址是不能改变的(某些型号的网路卡﹐或是透过其它技术手段﹐是允许您修改实体位址的)。不管系统是否起来﹐这个位址都会存在﹐而且要让系统获得它也很容易。然而,在一些无磁碟(diskless)工作站上面﹐系统档案都存放在远端的伺服器﹐当它在启动的时候﹐因为本身没有IP 位址﹐也就无法和伺服器沟通﹐更不能将系统档案载入。那么﹐我们就必须要有一个办法﹐让这样的无磁碟工作站在和伺服器沟通之前获得自己的IP 位址。RAPR 协定就是为解决此问题而设计出来的。

和ARP 协定一样﹐RARP 也是用广播的形式来进行查询﹐只不过这时候问的IP 位址不是别人﹐而是自己的IP 位址而已。我们可以从下图看出RARP 的运作﹐其实和ARP 是极其相似的﹕


RARP 的查询过程


首先是查询主机向网路送出一个RARP Request 广播封包﹐向别的主机查询自己的IP。在时候﹐网路上的RARP 伺服器就会将发送端的IP 位址用RARP Reply 封包回应给查询者。这样查询主机就获得自己的IP 位址了。

然而不像ARP﹐查询主机将RARP Request 封包丢出去之后﹐可能得到的RARP Reply 会不止一个(在ARP 查询中﹐我们可以确定只会获得一个回应而已)。因为网路上可能存在不止一台RARP 伺服器(基于备份和分担考量﹐极有可能如此设计)﹐那么﹐所有收到RARP 请求的伺服器都会尝试向查询主机作出RARP Reply 回应。如果这样的话﹐网路上将充斥这种RARP 回应﹐做成额外的负荷。这时候﹐我们有两种方法来解决RARP 的回应问题。


第一种方法﹐为每一个做RARP 请求的主机分配一主伺服器﹐正常来说﹐只有主伺服器才回做出RARP 回应﹐其它主机只是记录下接收到RARP 请求的时间而已。假如主伺服器不能顺利作出回应﹐那么查询主机在等待逾时再次用广播方式发送RARP 请求﹐其它非主伺服器假如在接到第一个请求后很短时间内再收到相同请求的话﹐才会作出回应动作。

第二种方法也很类似﹕正常来说﹐主伺服器当收到RARP 请求之后﹐会直接作出回应﹔为避免所有非主伺服器同时传回RARP 回应﹐每台非主伺服器都会随机等待一段时间再作出回应。如果主伺服器未能作出回应的话﹐查询主机会延迟一段时间才会进行第二次请求﹐以确保这段时间内获得非主伺服器的回应。当然﹐设计者可以精心的设计延迟时间至一个合理的间隔。


PROXY ARP

代理(Proxy) ARP 通常用来在路由器上代为回答在它后面的某个网路主机的ARP 请求。这是一种欺骗手法﹐因为查询端会以为目标主机就是路由器本身﹐但事实上﹐机器是在另一个网路里面。

Proxy ARP 常使用于远端连接网路(如拨接)环境中。例如在本地网路中有一台拨接主机﹐提供其他主机拨接上来连接本地网。当本地主机要查询远端拨接主机的ARP 请求的时候﹐因为它的广播封包是无法到达远端的﹔此时拨接伺服器就可以代替远端主机回答这个ARP 请求﹐然后本地主机就将封包送给拨接伺服器﹐伺服器再将封包传给远端主机。

Proxy ARP 还有另一个功能﹕就是将路由器所连接的两端实体网路相互「隐藏」起来。这样﹐两边的网路就能够使用同一个网路识别码(我们会在后面的章节中说明这个概念)﹐只要中间的路由器被配置Proxy ARP﹐便能替任何一端网路回应另一端网路的ARP 请求。这样的配置﹐除了能够解决现代主机与古老的机器之间的沟通(前者使用全部0 代表主机﹐而后者则使用全部1 代表主机﹔这个我们在后面的章节中再说明这个概念)。

Proxy ARP 另一个很有用的场合﹐是解决IP 不足下的子网路切割情况。例如现在台湾的商业性ADSL 网路只能分配到5 个可用IP﹐如果要在这么小的范围下做子网的切割﹐那么﹐除路由器所占用的两个IP 之外﹐剩下的就只有一个IP 可以使用。这是毫无意义的﹐但使用Proxy ARP 之后﹐我们可以使用的IP 将不会被浪费掉。

ARP 和RARP 之封包格式

让我们温习前面讨论OSI 层级时提到的乙太网路框包格式﹕

序言
(Preamble)
目的地
位址
(Destination)
来源位址
(Source)
信息类型
(Message Type)
数据
(Data)
封包监测资料
(Frame check sequence)
8 bytes 6 bytes 6 bytes 2 bytes 46-1500 bytes 4 bytes

乙太网的框包格式

我们可以发现标准的乙太网框包其中有一段46 到1500 byte 长度的数据空间﹐假如这是一个ARP 封包的话﹐那么该段数据空间就用来包装整个ARP 封。ARP 和RARP 的封包格式是一模一样的﹕

0

8

16

31

Hardware Type

Protocol Type

HLEN

PLEN

Operation

Sender HA (Byte 0~3)

Sender HA (Byte 4~5)

Sender IP (Byte 0~1)

Sender IP (Byte 2~3)

Target HA (Byte 0~1)

Target HA (Byte 2~5)

Target IP (Byte 0~3)

ARP / ARAP 封包格式

下面我们就封包中每一栏位做一个简单的说明﹕

HARDWARE TYPE


这是指网路界面卡的种类﹐如果该值为1﹐则表示为乙太网( Ethernet )。


PROTOCOL TYPE


这是指高阶网路协定位址种类﹐如果该值为0x0800﹐则表示为IP 位址格式。


HLEN


这是指硬体位址长度(单位为byte)﹐乙太网的位址长度为6 。


PLEN


这是指网路协定位址的长度(单位为byte)﹐IP 协定位址长度为4。


OPERATION


这是指封包类别﹐一共有四种﹕


  1. ARP Request

  2. ARP Reply

  3. RARP Request

  4. RARP Reply


SENDER HA


这是指发送端的实体位址﹐如果是乙太网的话﹐将会是一个6 byte 长度的乙太网位址。


SENDER IP


这是指发送端的IP 位址﹐会是一个4 byte 长度的IP 位址。


TARGET HA


这是指目的端的实体位址﹐如果是乙太网的话﹐将会是一个6 byte 长度的乙太网位址。


TARGET IP


这是指目的端的IP 位址﹐会是一个4 byte 长度的IP 位址。


ARP 指令

假如您要在Linux 系统上验证一下前面所学的理论﹐只要您的网路功能已经设好﹐您可以用arp 命令来检查当前的ARP 表格内容﹕


# arp -n Address HWtype HWaddress Flags Mask Iface 192.168.20.88 ether 00:10:5A:74:19:A7 C eth1 192.168.20.16 ether 00:D0:B7:74:77:74 C eth1 192.168.20.140 ether 00:D0:B7:74:77:85 C eth1 192.168.20.176 ether 00:02:B3:0B:5A:60 C eth1 192.168.16.254 ether 00:D0:B7:85:40:FE C eth1 192.168.22.1 ether 00:50:8B:92:C3:AB C eth1 


在Linux 系统中﹐输入arp 带一个-n 的参数﹐是将资料用数字(number)的形式显示﹐否则它将尝试用DNS 或其他主机对应方式来显示IP 所对应的主机名称。大家可以很轻易在每一行资料中找到IP 位址和实体位址的对应﹐同时还有硬体类型等信息。

假如此时您下一个ping 命令﹐连接一台没有在ARP 表格中出现的IP ﹕


# ping 1211.20.240.113 PING 211.20.240.113 (211.20.240.113): 56 data bytes 64 bytes from 211.20.240.113: icmp_seq=0 ttl=128 time=0.6 ms 64 bytes from 211.20.240.113: icmp_seq=1 ttl=128 time=0.6 ms 64 bytes from 211.20.240.113: icmp_seq=2 ttl=128 time=0.6 ms 64 bytes from 211.20.240.113: icmp_seq=3 ttl=128 time=0.6 ms 


此时您再次输入arp 命令的话﹐您将发现新主机的ARP 资料﹕


# arp -n Address HWtype HWaddress Flags Mask Iface 192.168.20.88 ether 00:10:5A:74:19:A7 C eth1 192.168.20.16 ether 00:D0:B7:74:77:74 C eth1 192.168.20.140 ether 00:D0:B7:74:77:85 C eth1 192.168.20.176 ether 00:02:B3:0B:5A:60 C eth1 192.168.16.254 ether 00:D0:B7:85:40:FE C eth1 192.168.22.1 ether 00:50:8B:92:C3:AB C eth1 211.20.240.113 ether 00:60:6C:08:2A:24 C eth0 


如果您把这台主机从网路上断开﹐确定它不会再发送ARP 请求或作出ARP 回应﹐那么过大约20 分钟后再输入arp 命令﹐您很可能发现许多ARP 记录都已经消失了﹐这就是资料存活倒数计时的后果。

假如您的Linux 系统还装有封包撷取软体﹐如tcpdump ﹐您可以在此期间抓些封包看看﹐细心点就能看出ARP Request 和ARP Reply 的过程﹕


09:17:33.803030 0:0:e8:68:98:b3 ff:ff:ff:ff:ff:ff 0806 42: arp who-has 211.20.240. 113 tell 211.20.240.117 09:17:33.803777 0:60:6c:8:2a:24 0:0:e8:68:98:b3 0806 60: arp reply 211.20.240.11 3 is-at 0:60:6c:8:2a:24 


您如果还有兴趣的话﹐还可以找些更强劲的封包撷取工具(如﹕snifit)﹐把ARP 封包的所有细节都抓出来看看。不过这里暂时不做这样的动作了。至于如何检查封包的每一个细节﹐我们将在后面介绍IP 和TCP 封包的时候再介绍。

我们用arp 不仅能查看当前的ARP 记录﹐而且我们还可以用arp 命令来建立ARP 记录﹐例如﹐我们前面提到过的Proxy ARP 功能﹐我们可以用中间的路由器来「隐藏」两端的网路﹕


# arp -s 211.20.240.115 00:10:B5:3A:8E:00 pub # arp -n Address HWtype HWaddress Flags Mask Iface 192.168.20.88 ether 00:10:5A:74:19:A7 C eth1 192.168.16.254 ether 00:D0:B7:85:40:FE C eth1 192.168.22.1 ether 00:50:8B:92:C3:AB C eth1 211.20.240.115 * * MP eth 


上面arp 命令中的-s 参数就是用来设定(set) 一个ARP 记录的。接着在输入arp 命令﹐就会发现刚才设定的资料旗标为MP 。这样﹐当另一端网路要查询211.20.240.115 的时候﹐这个Linux 路由器就能够代为回应了。

ARP 之RFC 文件

ARP 的详细资料可以查询RFC-826﹑RFC-814﹑以及RFC-1166 等文件。而RARP 的资料则可以参考RFC-903﹑RFC-906﹑还有RFC-1293 等文件。

 

习题﹕



  1. 请在Linux 系统上面找出界面的实体位址。
  2. 分别解释ARP﹑RARP﹑Proxy ARP 的功能与实现过程。
  3. 请描述ARP / RARP 的封包格式的各栏位说明。
  4. 用Linux 系统实作检查一下ARP 表格内容﹐并尝试连接新主机以观测表格资料的变化。
  5. 有条件的话﹐用封包撷取软体来撷取ARP 封包来观测一下它们是如何工作的
阅读(2044) | 评论(0) | 转发(0) |
0

上一篇:TCP/IP工作模型

下一篇:没有了

给主人留下些什么吧!~~