除了 subnetting ,关于 IP 协定的令一个关键概念就是:IP 路由(routing)。那什麽是路由呢﹖简单而言﹐就是当一个封包从发送端被传送到接收端所经过的路径。
IP 路由原理
若您重看上一章所介绍的 IP 封包格式﹐您会发现第 4 和第 5 行﹐分别用来记录来源 IP 位址和目的地 IP 位址。必须注意﹐除非封包由特定程式修改过﹐在正常的传递中﹐这两个栏位的位址是永远不变动。IP 路由的依据主要是看目的地位址﹕如果目的地位址属于处理封包之设备目前所在的网路范围之内(这就是 subnetting 的重要性所在了)﹐那麽就直接从 ARP 表格中寻找目的地位址的 IP 所对应的实体位址﹐如果没有的话就用 ARP 协定来查询。但是﹐如果目的位址在其他网路的话﹐那么就在 ARP 表格中寻找 路由器 的实体位址﹐如果没有则用 ARP 协定来查询。
您或许会问﹕这个路由器是怎么跑出来的﹐机器怎么会有路由器的 IP 呢﹖答案很简单﹕在设定网路环境时指定﹐这个可以手工的设定﹐也可以由其他协定如 DHCP 来指定。总之﹐如果您的网路将会和其他网路连接﹐那么您就一定要为每一台主机指定路由器 IP 位址﹔除非﹐您想让该主机﹐除了本地网路之外﹐任何地方都连不上。
要判断一个封包是否要经过路由器﹐前面一段已经讲过了﹕要看目的地位址是否在同一个网路上﹐如果不是﹐就一定要经过路由器来传递封包。那么﹐做为路由器本身也不例外(当然,实际的设定是有例外的,比方说 PPP 或 Static/Prox ARP 等情形)、也就是说必需与发送端在同一个网路里面。通常路由器都有最少两个界面以连接两个网路(多个界面连接多个网路)﹐假如路由器本身的界面位址和封包目的地位址不在同的网路﹐那么路由器必须要将封包交给下一个它认为最合适的路由器﹐继续传送这个封包。情形就像接力游戏一样﹕一站传一站﹐直到最后一个路由器发现目的地位址和它其中一个界面在同一个网路﹐然后才透过 ARP 获得对方的实体位址﹐最后交有下层协定完成最后一段的传送任务。假设所经路由均在 Ethernet 上﹐那么,路由器与路由器之间的传送﹐每两站之间也是同样要经过 ARP 来获得实体位址才能将封包传给对方。
封包的路由选择
我们已经知道一只程序要和远端主机的程式沟通﹐它所送下来到资料﹐往往会被拆成许多个封包在网路中传递。事实上﹐每一个封包所经过的路径都可能不同。在前面所描述的个路由接力过程中﹐封包从一个实体网路传到另一个实体网路﹐每一个传递都是独立的﹐与其他封包之间并非存在著必然关系。也就是说﹐从一个来源到一个目的地﹐可以选择的路径往往不止一条﹐而且﹐请求封包和回应封包所经过过的路径也不尽相同。这情形在 Internet 的环境中尤显突出。
影响每一个封包当前路径的因素很多﹐都由当时所经过的路由器(包括连线两端的主机在内)所使用的路由表格来决定。而路由表格的维护大致上分为两种形式:
- 静态(Static):也就是由管理员预先设定或手工修改。
- 动态(Dynamic):则是路由器之间透过 路由协定 自动更新。
事实上﹐路由协议是非常多样的﹐同时也不断的演变著。早期的网际网路路由器分为两类﹕
- 核心路由器(core router)﹐由 Internet Network Operation Center (INOC) 控制和管理。
- 非核心路由器﹐由个别的群组所控制管理。
在这样的架构下﹐所有网路都经由一个核心路由系统而达成连接﹐各自的网路会有一笔关于核心系统的预设路由设定。我们可以从下图看到核心路由系统的架构模式﹕
核心路由架构
然而﹐随著网际网路的迅速成长﹐这样的单一管理核心架构已经难以为继了。首先﹐中央管理骨干的路由将变得越来越复杂﹐核心路由器的一致性也变得异常重要及难以管理。其次﹐并非每一个网点都能连接到核心路由器﹐这就需要新增路由结构和协定。最后﹐基于核心资料一致性的要求﹐所有核心路由器都必须相互交换资料﹐那么核心结构将不能过于庞大。
有鉴于上述原因﹐网际网路的路由结构已经从核心模式转向为对等骨干模式﹐如下图﹕
对等骨干路由架构
对大部份对等式骨干组态而言﹐路径的取向依照相连主机之间的几何传输路径选取最短短路径。这样的叙述看起来很简单﹐但事实上要实现起来是非常困难的。首先﹐虽然标准的 IP 路由演算法是使用 IP 位址中的网路部份来选择路径﹐然而在对等骨干架构中的最近路径则需要对单个主机进行单独的路径选择。其次﹐两个骨干的管理者必须在所有路由器之间达成路径的一致性﹐以避免路径迴圈的出现。
以现今的网际网路架构来说﹐路由器的界定并非如早期的界定那么明显﹐而网路与网路之间的路由也变得非常复杂多样﹐路径的选择往往是多重的。我们可以从下图看看简化了的网际网路路由环境﹕
网际网路路由简略结构图
应用在大型骨干之间的路由协定非常复杂﹐而且种类繁多﹐例如有﹕Gateway-Gateway Protocol (GGP)﹑BGP(Border Bateway Protocol) 等等。这些都属于 外部闸道协定(Exterior Gateway Protocol) 路由协定﹐在本教材中不打算详论了﹐同学们可以自行参考 RFC-1102﹑和 RFC-1104 等文件。
本地网路的路由选择
从上面我们已经了解到网际网路的核心路由结构﹐我们需要知道它是为了帮助我们认识网路与网路之间的路由关系。然而﹐对一般的网路管理人员来说﹐恐怕也难有机会接触和管理那样的路由器﹐反而最通常接触的﹐应该是企业内部的较小型的网路之间的路由。相对而言,内部闸道协定的规模较小、所耗的路由资源也较少。常见的内部路由协定有:RIP(Routing Information Protocol)、OSPF(Open Shortest Path First)、及 EIGRP(Enhanced Interior Gateway Protocol)、等等。内部路由协定的最大缺点是无法应付大型网路的需求。
不管我们管理的网路体积如何﹐只要您的网路是与其它网路相连的﹐路由设定就不能避免。下面先让我们看看两个网路之间的路由设定是怎样的﹕
兩个本地网路之间的路由
由上图我们可以看到 192.168.0.0 这个网路的所有机器﹐其闸道(gateway) 都指向 192.168.0.254 这个 IP﹐也就是路由器与该网路所连接的界面。同样﹐192.168.1.0 这个网路﹐其闸道则是 192.168.1.254。
通常﹐一个路由器可以同时连接好几个网路﹐只要界面设定好就没问题。作为路由器﹐必须有最少两个界面以上﹐来连接不同的网路。同时﹐许多网路也有超过一个路由器和其它的网路连接﹐那么各主机的路由表格就要一一设定好通往各网路的闸道。
当我们再结合之前学过的 ARP 协定,我们对于封包的路由将有更具体的认知﹕
不同实体网路之间的路由
由上图我们可以看到﹕当有一个封包从网路 A 经过网路 B 送到网路 C 的时候﹐其 Software Address (即IP位址)永远不变﹐但 Hardware Address (即实体位址)却随著所经的应体网路而有所不同。这是因为﹕不管封包经过多少个网路﹐在传输中归根结底要靠实体网路达成﹐而实体网路的传送依据是实体位址﹐只要 ARP 能够找出路由器的实体位址﹐就能顺利将封包传给它﹔然而﹐ IP 协定的传送则依据 IP 位址来定﹐路由器会根据目的位址而决定下一站路由的 IP (在这一层级来说,所依据的是 IP 位址而非硬体位址) ﹐当封包交由下层协定处理的时侯,运用 ARP 协定就可解决位址的对应问题(请参考 ARP 协定之章节内容)。然而,再提醒您一遍:在整个过程中﹐封包的目的位址是不会改变的﹐除非﹐路由器本身启动了修改封包位址的功能(如﹕NAT — Network Address Translation)。
要维护这样一个网路数目不多的环境﹐各路由器上面的路由资料不会很複杂﹐这样的情况之下﹐我们可以使用静态路由﹐以手动方式为每台机器设定事先计算好的路由。静态路由的主要好处是它的可预测性﹐而且对路由器或网路做成的负担不多﹐所占频宽较少。
静态路由选择
为了更好的理解静态路由﹐我们不妨从单一的主机路由开始研究一下路由表格。事实上,在每一台机器上面﹐都必需存在一分各自独立的路由表格 (Routing Table)﹐记录著本机的路由资讯。我们可以在 Linux 主机上面用 route 这个命令来查看当前的路由状况﹕
Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 192.168.0.17 * 255.255.255.255 UH 0 0 0 eth1 203.30.35.134 * 255.255.255.255 UH 0 0 0 eth0 203.30.35.128 * 255.255.255.224 U 0 0 0 eth0 192.168.0.0 * 255.255.255.0 U 0 0 0 eth1 192.168.0.0 * 255.255.255.0 U 0 0 0 eth0 203.168.168.0 rhroute 255.255.255.0 UG 0 0 0 eth1 127.0.0.0 * 255.0.0.0 U 0 0 0 lo 0.0.0.0 rhgw 0.0.0.0 U 0 0 0 lo
第一列是目的“目的地位址”﹐可以是一个网路﹐也可以是一台主机﹔然后“闸道位址”(假如输入 -n 参数﹐则以 IP 位址显示,‘*’ 表示无需使用闸道﹐例如本地网路位址或本机位址)﹔接下来是目的地使用的 Netmask (这非常重要﹐我们已在前面介绍子网路时说明过了)﹔然后是“旗标”﹐这里的 U 是“Up”的意思﹐也就是目前已启用H 表示目的为一个“Host”﹑ G 表示使用“Gateway”的意思﹔接下来的 Metric 和 Ref 是供路由系统参考的﹔最后是使用的网路界面。
最后有一个路径要特别提醒一下﹐目的地位址为 0.0.0.0 代表那是一个预设路由。也就是说﹐在路由表上找不到关于目的地的路由资讯﹐则尝试把封包传给预设路由所指的路由器处理。
使用这个 route 命令﹐我们还可以修改﹑增加﹑和删除系统的路由表格设定﹐它可以用来告诉机器通往某一个网路或主机使用哪一个闸道﹑matrix﹑以及使用哪一个界面等等。下面我们将会示范一下如何使用这个命令。
在此例子中﹐首先要先将原已出现在路由表格的设定移除掉(否则待会会出现重复设定)﹕
/sbin/route del -net 203.168.168.0 netmask 255.255.255.0 dev eth1
这时再输入一次 /sbin/route 就可以确定有关 203.168.168.0 这网路的路由设定已经给移除掉了。 好了﹐我现在可以用 route 将刚才移除的路由设定加进系统的路由表格去﹕
/sbin/route add -net 203.168.168.0 gw 192.168.0.4 netmask 255.255.255.0 dev eth1
相信您现在不难看出﹕增加和移除路由设定﹐分别是使用‘add’和‘del’来做命令选项。 这时候再用 route 命令就可以看到路由设定又回到路由表格中去了。然而,这裡要特别提醒的是:如果要两个网路能够成功的达成路由﹐对方网路也必须有相应的路由设定指向本地网路才行。
刚才我们用 route 这个命令来设定某些网路 (net ID) ﹐但有时候如果我们使用 ifconfig 手工的增加了一个界面﹐严格来说﹐我们还应该为界面增加一个‘H’记录的﹕
/sbin/route add -host 192.168.0.25 dev eth0:0
事实上﹐使用 -host 选项﹐我们也可以指定通往某一主机的静态路由﹐尤其在多重可选路径出现的时候。
上面只是一个非常简单的路由表格而已﹐机器所连的网路越多﹑安装的界面越多﹐路由表格也越复杂。如果您的机器有拨接连线( MODEM )﹐当您成功连上 ISP 之后﹐您再跑一次 route ﹐你就会发现多了通往 ISP 网路的路由设定了﹐而且﹐Default Gateway也使用了 ISP 那边的 IP。原因是使用拨接连线﹐内定是会使用 Remote Default Gateway 的设定。除非您网路本身连得上 internet﹐否则您就无法和外面的世界沟通。然而,若是您要是使用 ADSL 播接( PPPoE )的话,只要您的路由表格已出现 Default Gateway 的话,pppoe 程式似乎并不会修改这个设定。如果您发现拨接后预设的路由设定并没有改变为 ISP 那端的话﹐那就利用前面所教的命令手工修改路由表格了。
动态路由选择 (RIP 协议)
所谓动态路由选择﹐就是指路由协议了。这里,我们不会讨论在 Internet 上面负责大型网路之间的 Exterior 协议﹐相对的﹐在比较少的网路之间﹐使用的会是 Interior 协议﹐其中最古老和最简单的应是 RIP 协定了。下面我们就以 RIP 为例子,尝试了解动态路由的运作原理﹕
在 Linux系统里面有一只程序叫 routed﹐它就是 RIP 的实现程序。routed 是由美国柏克莱大学设计出来的﹐不过它不并是设计给大型网路使用的。基础的 RIP 协定是一种区域网路的向量距离路由的直接实现。它把参与者分为两种类型﹕主动与被动。主动路由器对其它机器广告自己的路由资讯﹐它的广播周期预设为 30 秒﹔被动的路由器则收听别的机器的广播以改变路由资讯﹐但本身并不参与广播。
RIP 协议的信息包含有多对的资讯﹐每对资讯包含一个 IP 网路位址和通往另一网路的整数距离。RIP 采用的的计数制是以路由值为依据﹐称为 Metric ﹐用来测量目的地的距离,因此被归类为 距离向量(Distance-Vector) 路由协议。最简单的 Metric 值是以从起始端到目的地之间的跳站数目为以据(Hop Count),代表了路由过程中所要穿越的路由器多寡,其中 Metic 越低的路迳就被视为最佳路迳。然而﹐跳站数目低并不一定就是最佳的路径﹐因为﹐跳站资讯中并没有把路网路负载﹑频宽﹑延迟﹑等影响路由质数的资讯反应出来。很明显﹐通过两个慢速网路的跳站﹐并不见得会比通过三个高速网路的跳站要快。所以﹐大多数 RIP 程序都允许管理员以手工的方式来调整 Metric 参数(例如﹐把慢速网路的 Metric 提高)。RIP 在交换路由资讯的时候﹐会把从别的路由器“学”来跳站值从原有数值上加 1 ﹔当这个数值达到“无穷”值的时候(通常会被设定为 16 )﹐就表示这条路径为“unreachable”﹐同时也会将之从路由表中删除。
下面让我们以一个小型路由网路的例子来更好的看看 RIP 是怎样进行路由表格更新的﹐(我强烈建议您将这图画出来﹐以备后面讨论时参考所需)﹕
小型网络之间的RIP应用
当路由器刚设定好并连接上网路的时候﹐各自都有一个“初始路由表”﹐里面只包含与其直接相连的网路的路由信息﹕
Router 1 | Router 2 | Router 3 | Router 4 | Router 5 | Router 6 | |||||||||||
Net ID | M,G | Net ID | M,G | Net ID | M,G | Net ID | M,G | Net ID | M,G | Net ID | M,G | |||||
1 3 |
1,1 1,1 |
1 2 4 |
1,2 1,2 1,2 |
2 5 6 |
1,3 1,3 1,3 |
3 7 |
1,4 1,4 |
4 5 7 8 |
1,5 1,5 1,5 1,5 |
6 8 |
1,6 1,6 |
上表中﹐NetID 就是 router 所知道如何到达的网路﹐而“M”值我们暂时将之看成 metric 数值﹐“G”指的是通往该网路的下一个要经的 router 名字(记住:所谓的路由事实上就是决定下一站是哪各 router )。这时﹐各 router 看到如此资讯﹕M 都为 1﹐而 G 都指向自己。
然后﹐router 与 router 之间经过第一轮资料交换﹐并将从相邻 router“学”来的路由加入到自己的路由表格中﹐其 metric 值也相应的增加“1”。这时﹐我们看到各 router 的路由表将会变成这样﹕
Router 1 | Router 2 | Router 3 | Router 4 | Router 5 | Router 6 | |||||||||||
Net ID | M,G | Net ID | M,G | Net ID | M,G | Net ID | M,G | Net ID | M,G | Net ID | M,G | |||||
1 2 3 4 7 |
1,1 2,2 1,1 2,2 2,4 |
1 2 3 4 5 6 7 8 |
1,2 1,2 2,1 1,2 2,3 2,3 2,5 2,5 |
1 2 4 5 6 7 8 |
2,2 1,3 2,2 1,3 1,3 2,5 2,5 |
1 3 4 5 7 8 |
2,1 1,4 2,5 2,5 1,4 2,5 |
1 2 3 4 5 6 7 8 |
2,2 2,2 2,4 1,5 1,5 2,3 1,5 1,5 |
2 4 5 6 7 8 |
2,3 2,5 2,3 1,6 2,5 1,6 |
或许,您在刚开始比较这两个表的时候﹐会无所适从﹐但其实也不是很难的:我们先找到相邻的 router 之路由表﹐然后比较本身的路由表﹐看看有没有新的 NetID ﹐有则加到自己的路由表中﹐并且“M”增加“1”﹐而“G”则修改为所“学”的 router 之名字。如果有相同的 NetID ﹐则相加 metric 值﹐如果得出来的值比自己还低﹐则抄过来﹐M 也加 1﹔如果比自己的值高﹐则保留自己的。
我们以 router1 为例子﹕与之相邻的 router 分别是﹕router2 和 router4。它们的路由表分别是﹕
Router 2 | Router 4 | |||
Net ID | M,G | Net ID | M,G | |
1 2 4 |
1,2 1,2 1,2 |
3 7 |
1,4 1,4 |
而 router1自己的路由表则是这样的:
Router 1 | |
Net ID | M,G |
1 3 |
1,1 1,1 |
和 router2 比较﹕可以发现 NetID 2 和 4 是新的﹐那么 router1 将之抄过来﹐M 加 1 成为 2 ﹐然后 G 指向 router2 成了 2。其中 NetID1相同﹐将 router2 的 metric 值加 1 ﹐等于 2 ﹐比自己的高﹐保留自己的。
和 router4 比较﹕可以发现 NetID 7 新的﹐那么 router1 将之抄过来﹐M 加 1 成为 2﹐然后 G 指向 router4 成为 4。其中 NetID3 相同﹐将 router4 的 metric 值加 1 ﹐比自己的高﹐保留自己的好了。
那么经过整理之后﹐就得出﹕
Router 1 | |
Net ID | M,G |
1 2 3 4 7 |
1,1 2,2 1,1 2,2 2,4 |
好了﹐到了自己动手练习的时候了﹐看看您能不能为每一个 router 算一算﹐会否最终得出下面的路由表﹖
Router 1 | Router 2 | Router 3 | Router 4 | Router 5 | Router 6 | |||||||||||
Net ID | M,G | Net ID | M,G | Net ID | M,G | Net ID | M,G | Net ID | M,G | Net ID | M,G | |||||
1 2 3 4 5 6 7 8 |
1,1 2,2 1,1 2,2 3,2 3,2 2,4 3,2 |
1 2 3 4 5 6 7 8 |
1,2 1,2 2,1 1,2 2,3 2,3 2,5 2,5 |
1 2 3 4 5 6 7 8 |
2,2 1,3 3,2 2,2 1,3 1,3 2,5 2,5 |
1 2 3 4 5 6 7 8 |
2,1 3,1 1,4 2,5 2,5 3,5 1,4 2,5 |
1 2 3 4 5 6 7 8 |
2,2 2,2 2,4 1,5 1,5 2,3 1,5 1,5 |
1 2 3 4 5 6 7 8 |
3,3 2,3 3,5 2,5 2,3 1,6 2,5 1,6 |
如果您第一次未能算出正确的答案也不要紧﹐慢慢算总会得出正确答案的。如果您够细心的话﹐或许能够看出如下规律﹕G 下面的名字﹐永远只有相邻的 router ﹐而 M 下面的数值﹐则取决于所“学”的次数。如果有超过一条路径到达同一个目的地﹐而且 metric 值也一样﹐在实际应用中﹐router 只会听取最先获得的路由信息。
RIP 的最大缺点是无法适应大型网路﹐因此﹐除 RIP 路由协议之外﹐还有许多其它路由协议使用在相同的环境中。不过﹐在非 RIP 协定中﹐它们也有各自的规矩﹐每种协定都有其优缺点,这里不再详细讨论了。有兴趣的朋友大可自己多找些资料回来研究。
RIP 封包讯息格式
若要更好的了解 RIP 协议﹐我們不妨參考一下 RIP 封包的格式﹕
0
8
16
31
命令 (1-5)
版本
必须为 0
1 号网络家族
必须为 0
1 号网络的 IP 位址
必须为 0
必须为 0
到 1 号网络的距离
2 号网络家族
必须为 0
2 号网络的 IP 位址
必须为 0
必须为 0
到 2 号网络的距离
…
RIP 封包格式
RIP 的讯息可以被广泛分为两类型﹕路由资讯讯息﹑资讯请求讯息。两者都是使用固定的标头﹐后接一个可选的网路及距离配对资讯列。RIP 信息中的命令一共有 5 个﹐命令内容如下﹕
1 | 要求部份或全部路由资讯 |
2 | 包含来自传送端路由表达网路距离的要求 |
3 | 启动追踪模式 (已过时) |
4 | 关闭追踪模式 (已过时) |
5 | 保留给 Sun Microsystem 内部使用 |
路由器可以通过发送请求信息来询问其它路由器的路由资讯﹐受询方会使用回答命令来回应请求﹐进而达到路由资讯的交换。然而﹐在大部份的情形下﹐路由器都会周期性的广播非请求性的路由资讯。
路由器的运作规则
我们已经知道路由器是如何以静态的方式建立路由表格﹐或以动态方式来更新路由资讯﹐但是当路由器接到一个封包的时候﹐是如何判定路由选择的呢﹖让我们先看看router是怎么工作的﹕
- 分层级 IP 的路由﹕
- 指定一个IP位址﹕
-
- if 我有这个目的地的路由
- 从路由表中取得下一站的位址
将封包传给下一站 - else
-
- 决定目的地网路号码
if 我有这个网路的界面 - 决定我的界面上这个网路的子网路遮罩
- else
- 从这个网路的层级决定它的子网路遮罩
- endif
- 利用遮罩套在目的地位址上﹐取得子网路
if 我有这个子网路的界面
将封包直接送往目的地 - else if 我的路由表格包含这个子网路的记录
- 从路由表格中取得下一站的位址
将封包传给下一站 - else if 我的路由表格中有一笔预设路由
- 从路由表格中取得下一站的位址
将封包传给下一站 - else
- 宣布这个目的地无效
- endif
- 决定目的地网路号码
- endif
- 不分层级IP的路由﹕
指定一个IP位址﹕
在路由表格中寻找与此位址相符的最长 mask 预定值
从路由表格中取得下一站的位址
将封包传给下一站if 对比不成功
宣布这个目的的无法达到endif
咋看起来﹐不分层级的路由比分层级的路由简单得多( IP 的层级我们已在前一章详细介绍过了)。而事实上却是相反的﹐这需 router 具备更复杂的运算能力。不过﹐现在的路由器都支援不分层级的路由协定,且运算能力都很强,因此不需要担心。
理解路由器的运作规则是很重要的﹐尤其管理一台连接多网路的路由器﹐或是在一个有多个路由器的网路。在这里﹐我还必须指出一点﹐在 Linux 的路由表上面﹐路由的选择是以 first-match 为原则的﹐如果在路由表上面发现同时有超过一笔路由指向同一个目的地﹐则会以排在表格前面的设定为优先。要是了解这点﹐我们可以避免一个网路初学者常易犯的错误﹕就是在同一机器上把多个界面设定为同一个子网路之内。下面是我在 Linux 新闻组上的一篇讨论文章﹐这对于我们了解此问题的子网和路由﹐相信是有所帮助的﹕
网中人 <netmanforever@yahoo.com> wrote in message news:8ov0r0$jb7@netnews.hinet.net... > > 雪龙~ <oolon.bbs@bbs.cynix.com.tw> wrote in message > news:3cGeLg$5iV@bbs.cynix.com.tw... > > ※ 引述《netmanforever@yahoo.com (网中人)》之铭言: > > > 小州 <kenduest.bbs@bbs.cynix.com.tw> wrote in message > > > news:3cG1US$5W6@bbs.cynix.com.tw... > > > > 有这种规定吗?分别是 192.168.1.1 与 192.168.1.2 并没有相衝突的地方。 > > > 弟以为这是原理而非规定的问题。 > > > 因为当一个封包被接收进来之后(来自 loopback device 的也一样)﹐首先要做的是检 > > > 查 route table 进行和目的地位址的比对。不过 route table 的特性之一是 first > > > match 的﹐也就是当找到第一笔符合条件的纪录﹐就不再往下找了。换句话说﹐如果两 > > > 张卡都在同一个 subnet 之内﹐那就会有两笔关于同一个 subnet 的纪录存在﹐这时候 > > > 要看第一个句子指定的是哪一个界面了。如果不是手工去修改﹐通常会是第一张﹐所以 > > > 他会以为第二张不工作了。 > > > > 应该不能说是找到第一笔符合的纪录就不再往下找, 就我所知道的好像是 > > 最详细的那一笔记录喔. 比如说呢 192.168.1.10 的这个 ip 的位址可以 > > 说是属于 192.0.0.0 这个网路, 也可以是说属于 192.168.0.0 的这个网 > > 路, 当然也属于 192.168.1.0 的网路, 端看你是用那一个等级的网路去看 > > 待 192.168.1.10 的这个 ip , 就这个部分来说只要是对 TCP/IP 网路有 > > 基本概念的人应该知道. 只不过在 route table 会针对所设定或是学习到 > > 的路由资讯按照 Net IP 与 Mask 的状况先做好排列, 所以会如你所说的找 > > 到的第一笔, 就是为了增进网路效率. 不知道我这样的说明有没有错误的地 > > 方, 真有的话要告诉我喔..... ^_^ > > > > 多谢指教﹗ > > 不过我觉得在同一个 router 上面(我想的目前讨论都只讲同一个 linux router 吧 > ﹖)﹐很少有人同时用 8bit﹑16bit﹑24bit (以及其它变动遮罩)同时描述一段 > 192.168.1.x 的网路吧﹖ > > 就算有这样的情形﹐让我们敲 route -n 看看﹐所有 route add -host 的记录会被排 > 在前面(用 32bit mask 显示)﹐然后到 route add -net 的记录(也是依 mask 的 bit > 数大小排列)﹐最后是 route add default 的记录(也可以多个﹐不过却是越迟写的越 > 前面﹐请留意这个现象)。 > > 好了﹐如果您有一张网路界面使用 192.168.1.17 ﹐不指定 mask 的话﹐将会使用预设 > 的 24bit (自然遮罩值)﹐否则按指定的写入。这裡我们假设用预设好了。您或许会下 > 这样的命令来完成这张界面的设定(不同的系统或许不同)﹕ > ifconfig eth1 192.168.1.17 up > route add -host 192.168.1.17 dev eth1 > route add -net 192.168.1.0 netmask 255.255.255.0 dev eth1 > #注﹕route add -net 的 netmask 不能省﹐因为正如阁下所指出﹐不同等 mask 会指 > 定不同的 network﹐不过用 redhat 的 ifconfig 或许已经帮您设定好 route > add -net 了。 > > 然后输入 ifconfig 您会看到 eth1 会使用预设的 24bit mask。请留意﹕这非常重 > 要﹐因为这会求出界面所在的 net_ID (用 AND 的逻辑运算)。 > 再输入 route -n 您会发现 192.168.1.17 这笔记录是用 32bit 的 mask﹐会和其它 > 32bit mask 的记录排在前端。同时您还会发现 192.168.1.0 这个 24 bit mask 的网 > 路之 device 会使用 eth1 。 > > 好了﹐到这里我们就可以进一步尝试阁下所假设的环境﹐我们分别用 8bit 和 16bit > 来增加 network 的记录﹕ > route add -net 192.168.0.0 netmask 255.255.0.0 dev eth0 > route add -net 192.0.0.0 netmask 255.0.0.0 dev eth2 > #注﹕我先故意使用 eth0 和 eth2 来设定这两个 network﹐以确定路由不会经过 > 192.168.1.17 所在的 eth1 界面。 > > 这时候的路由依据是什麽呢﹖(嗯~~﹐详细的我不想重复了﹐有兴趣可以参考前不久和 > song 兄讨论的文章﹐是关于 NAT 的) > 假如我有一笔路由要传递给 192.168.1.18 ﹐会先检查有没有关于它的 32bit 的路由 > 记录﹐没有﹐那看看有没有 netmask 指定﹖ > 这裡又带出两个情形﹕ > 1﹐没有 mask﹐那好﹐套用自然遮罩会使用 24bit﹐然后求出 net_ID﹐发现是 > 192.168.1.0 这个 network ﹐刚好路由表有关于这个 network 的记录﹐界面为 > eth1﹐那麽将封包交由 eth1 传递。(之后的动作这裡不再讨论了﹐请参考 arp 协定) > 2﹐假如有 mask﹐那好﹐看 mask 的值﹐这裡假设用 16bit 吧﹐然后求出的 net_ID > 是 192.168.0.0 ﹐再于路由表中发现这个 network 记录﹐它的界面是 eth0﹐那麽将 > 封包交由 eth0 传送。(假如 netmask 是 8 bit 也则会交由 eth2) > > 看这样的过程﹐应该不会困扰吧﹖那就让我们搞乱一下吧﹐再下这样的命令﹕ > route add -net 192.168.0.0 netmask 255.255.0.0 dev eth1 > route add -net 192.0.0.0 netmask 255.0.0.0 dev eth1 > > 哈﹐我们会同时有两笔记录分别是关于 192.168.0.0 和 192.0.0.0 的。这或许已经符 > 合这个讨论的要求了吧﹖ > 这时﹐您就会发现越晚加入的设定会越排在前面。这也就是弟所指出的 first match > 原则了。 > > 而其后的测试(别忘了路由要双向同时设定才有用哦)﹐还是交由您自己玩了。例如﹐您 > 确定 192.168.1.18 是经由 eth2 传到 192.0.0.0 这个网路的﹐可以下这样的命令﹕ > route add -host 192.168.1.18 dev eth2 > #注﹕如果还要经过另外一台 gateway﹐则要指定 gw 参数。 > (这就是弟在前面文章中所说的静态记录了﹐应该是可行的﹐因为无需再往下比对了。) > > p.s. 阁下所给出的例子﹐其实并没运用到 first match 原则﹐因为在 route table > 并没有相同的记录。(可用 route -n |awk '{print $1}' 来看看) > |
IP 的设定规则
Okay,到这裡,不妨让我们总结从前面所学,以掌握当我们在作 IP 规划的时侯需注意一些规则:
- 当我们进行主机 IP 设定的时候﹐如果想各机器能够直接沟通﹐那得使用相同的 Net ID 和不同的 Host ID。如果您想使用不同的 Net ID (比如经过 sub-net 切分)﹐那麽在不同 Net ID 之间的 host 就要经过 router 才能成功沟通。
- 当电脑用 AND 运算得出 Net ID 之后﹐会检查路由表格以决定下一站在哪里。若界面和目的地 Net ID 一致的话﹐就可以直接将封包传给对方﹐否则就将封包传给 Router 或 Default Gateway (因为它门的其中一个界面也是在同一 Net ID 之下)。这个过程我们在前面的 ARP 和 RIP 已经讲述过了﹐请好好温习一下。
- 如果您进行了 sub-net 的切割﹐在分配 IP 位址的时候就要非常小心了﹐以免 IP 超出了子网范围而无法沟通。比如﹐在没有划分子网路的情况下(例如使用 255.255.0.0 的 mask )﹐139.175.31.254 和139.175.32.1 都是在同一个网路之内的﹐他们的 IP 封包不用 router 就可以直接传递﹔但经过借用 3 个bit 的子网划分之后( net mask 成了 255.255.224.0 )﹐它们就被分隔在两个 sub-net 之内﹐这时候它们一定要使用 router 才能传递封包。此外﹐原本一些有效的 IP 位址﹐在 sub-net 之后﹐因为 Host ID 变成了全部 0 或 1 ﹐也就不能再分配给主机使用了﹐例如﹕139.175.63.255﹑139.175.64.0 等等。 (如果您不明白为什麽﹖将之换成二进位﹐然后找出经过子网切割后属于 Host ID部份的数字就清楚了)。
由此可见﹐当我们在一开始设计网路的时候﹐就要具备应有的责任和远见﹐及早就将子网路划分好。否则﹐等所有机器都设定好﹐并且运作了一段时期之后﹐才决定划分子网路﹐其情形将会变得异常复杂。如果要重新分配 IP﹐其所做的规划﹐以及遇到的可见问题和隐藏问题﹐都要比从零开始难上百倍﹐越大的网路越是如此﹗
参考资料﹕
IP 路由和 RIP 协定的 RFC 文件可以参考﹕RFC-1716﹑RFC-1104﹑RFC-1102﹑RFC-1058﹑RFC-891﹑RFC-1583。
习题﹕
- 请简单描述网际网路的路由结构。
- 作为路由器﹐最基本的设定条件是什麽﹖
- 请问 IP 路由的依据是什麽﹖请以实例来讲述 Net_ID 对路由的重要性。
- 请以本地网路为例子﹐描述封包的实体位址和 IP 位址在路由过程中的变化。
- 请结合 ARP 协定谈谈您对 IP 路由的理解。
- 请在 Linux 系统上面观测本机的路由资讯。尝试增加和删除路由资讯﹐并观测路由表的变化。
- 请使用实例来描述 RIP 路由协定的路由资讯交换过程。
- 请描述 RIP 协定的封包格式。
- 请描述路由器的运作规则﹐最好能配合实际的路由表格资讯来模拟运作过程。
- 为什麽我们不能在同一主机上设定多张界面在同一子网内﹖请以实例来分析。