原文来自:http://www.study-area.org/network/networkfr2.htm
除了subnetting,关于IP协议的另一个关键改建就是IP路由(routing)。那么什么是路由呢?简单来水,就是当一个封包从发送端被传送到接收端所经过的路径。
IP路由原理:
若您重新复习IP封包的格式,就会发现第4行和第5行分别用来记录源IP地址和目的IP地址。必须注意,除非封包由特定程序修改过,在正常的传递中,这两个段是永远不会变动的(在数据发送的过程中,一旦源和目的IP地址确定,一般不会发生改变)。IP路由的依据主要是看目的地址:如果目的的地址属于处理封包的设备目前所在的网络范围(也就是同一网段,这就是subnetting的重要性所在了),那么就直接从ARP表格中寻找目的地址的IP所对应的物理地址,如果没有的话就用ARP协议来查询。但是,如果目的地址在其他网络的话,那么就在ARP表格中寻找路由器的物理地址,如果没有则用ARP协议来查询。
您或者会问:这个路由器怎么跑出来的,机器怎么会有路由器的IP呢?答案很简单:在设定网络环境时指定,这个可以手工设定,也可以由其他协议如DHCP来指定。总之,如果您的网络将会和其他网络相连接,那么您就一定要为每一台主机指定路由器IP;除非,您想让主机,除了本地网络之外,任何地方都连不上。
要判断一个封包是否要经过路由器,上一段中讲过:要看目的地址是否在同一个网段上,如果不是,就一定要经过路由器来传递封包。那么作为路由器本身也不例外(当然,实际的设计是有例外的,比方说PPP或Static/Proxy ARP等情形)、也就是说必须与发送端在同一个网络里面。通常路由器都有最少两个界面(?界面到底是什么)以链接两个网络(多个界面链接多个网络),假如路由器本身的界面地址和封包目的地址不在同一网络,那么路由器必须要将封包交给下一个它认为最合适的路由器,继续传送这个封包。情形就像接力游戏一样:一站传一站,直到最后一个路由发现目的地址和它其中一个界面在同一个网络,然后才透过ARP获得对方的物理地址,最后交给下层协议完成最后一段传送任务。假如所经过路由均在Enthernet上,那么,路由器与路由器之间的传送,每两站之间也是同样要经过ARP来获取物理地址才能将封包传给对方。
封包的路由选择:
我们已经知道一个程序要和远端主机的程序通信,它说送下来的资料,往往会被拆分成多个封包在网络中传递。事实上,每一个封包所经过的路径都可能不同。在前面所描述的路由接力过程,从封包后一个IP网络传递到另一个IP网络,每一个传送都是独立的,与其他封包之间并非存在着必然关系。也就是说,从一个来源来源到一个目的地,可以选择的路径往往不止一条,而且,请求封包的回应封包所经过的路径也不尽相同。这情形在Internet的环境中尤为突出。
影响每一个封包当前路径的因素很多,都由当时所经过的路由器(包括连线两端的主机在内)所使用的路由表格来决定。而路由表格的维护大致上分为两种情形:
在这样的架构下,所有网络都经由一个核心路由系统而达成链接,每个网络都会有一条关于核心系统的预设路由设定。我们可以从下图看到核心路由系统的架构模式:
然而随着网络的迅速成长,这样的单一管理核心架构已经难以为继了。首先,中央管理骨干的路由将变得越来越复杂,路由器的一致性也变得异常重要及难以管理。其次,并非每一个网点都能连接到核心路由器,这就需要新增路由结构和协议。最后,基于核心资料一致性要求,所有核心路由器必须相互交换资料,那么核心结构将不能过于庞大。
由于上述原因,网络的路由结构已经从核心模式转为对等骨干模式,如下图:
对大部分对等式骨干形态而言,路径的取向依据相连主机间的几何传输路径选取最短路径。这样描述看起来很简单,但事实上要实现起来非常困难。首先,虽然标准的IP路由算法是使用IP地址中的网络部分来选取路径,然而在对等骨干架构中的最近路径则需要对单个主机进行单独的路径选择。其次,两个骨干的管理者必须在所有路由器之间达成路径的一致性,以避免路径回路出现。
以现在的网络架构来说,路由器的界定并非如早期那么明显,而网络之间的路由也变得非常复杂多样,路径的选择往往是多重的。我们可以从下图看看简化了的网络路由环境:
应用大型骨干之间的路由协议非常复杂,而且种类繁多,例如有:Gateway-Gateway Protocol(GGP)、BCP(Border Bateway Protocol)等等。这些都属于外部网关协议(Exterior Gateway Protocol)。
本地网络的路由选择
从上面我们已经了解到网络的核心路由结构,我们需要知道它是为了帮我我们认识网络与网络之间的路由关系。然后,对一般的网络管理人员来说,恐怕也难有机会接触和管理那样的路由器,反而最常接触的,应该是企业内部较小型的网络之间的路由。相对而言,内部网关协议规模小较小,所消耗的路由资源也比较少。常见的内部路由协议有: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协议就可以解决地址的对应问题。再提醒您一遍:在整个过程中,封包的目的地址是不会改变的,除非,路由器本身启动了修改封包地址的功能(如:NAT--Network Address Translation)。
要维护这样一个网络数目不多的环境,各路由器上面的路由资料不会很复杂,这样的情况下,我们可以使用静态路由,以手动方式为每台机器设定事先计算好的路由。静态路由的主要好处是它的可预测性,而且路由器或网络造成的负担不多,所以占用的频宽比较少。
静态路由的选择:
为了更好的理解静态路由,我们不妨从单一的主机路由开始研究一下路由表。事实上,在每一台机器上面,都必须存在一份各自独立的路由表格(Routing Table),记录着本机的路由咨询。我们可以在linux主机上面用route这个命令来查看当前的路由状况:
第一列是”目的地址“,可以是一个网络,也可以是一台主机;然后“网关”(加入输入-n参数,则以IP地址显示,“×”表示无需使用网关,例如本地网络地址或本机地址);接下来是目的地使用的NetMask(这个非常重要,我们已经在前面介绍子网路的时候说明过了);然后是“旗标”,这里的U是指Up的意思,也就是目前已启用、H表示目的为一个“Host”、G表示使用“网关(Gateway)”的意思;接下来是的Metric和Ref是供路由参考的;最后是使用的网络界面(网络类型,以太网或者。。。)。
最后由一个路径要特别提醒一下,目的地址位为0.0.0.0,代表那是一个预设路由,在路由表上找不到关于目的地的路由咨询,则尝试把封包传给预设路由所指的路由处理。
使用这个route命令,我们还可以修改、增加、和删除系统的路由表格设定,它可以用来告诉机器通往某一个网路或主机使用哪一个网关、matrix、以及使用哪一个界面等等。下面我们将会示范一下如何使用这个命令。
在此例子中,首先将原已出现在路由表格的设定移除掉(否则待会会出现复设定):
这时候再输入一次/sbin/route就可以确定有关203.168.168.0这个网络的路由设定已经移除掉了。好了,我现在可以用route将刚才移除的路由设定加进系统的路由表格去:
相信您现在不难看出:增加和移除路由设定,分别是使用add和del来做命令的选项。这时候再用route命令就可以看到路由设定又回到路由表格中去了。然而,这里要特别提醒的是:如果要两个网络能够成功的达成路由,对方网络也必须有相应的路由设定指向本地网络才行。
刚才我们用route这个命令来设定某些网络(net ID),但是有时候如果我们使用ifconfig手工的增加了一个网络,严格来说,我们还应该为这个网络增加一个H记录的:
事实上,使用-host选项,我们也可以指定通往某一主机的静态路由,尤其在多重可选路径出现的时候。
上面只是一个非常简单的路由表格而已,机器所连的网络越多、安装的界面越多,路由表格也越复杂。如果您的机器有连接MODEM,当您成功连上ISP之后,您再跑一次route,就会发现多了通往ISP网络的路由设定了,而且Default上internet,否则您就无法和外边的世界沟通。然而,若是您要使用ADSL连接(PPPoE)的话,只要您的路由表格已出现Default Gateway的话,pppoe程序似乎并不会修改这个设定。如果您发现连接上Modem后预设的路由设定并没有改变为ISP那段的话,那就利用前面所教的命令手工修改路由表格了。
动态路由选择(RIP):
所谓动态路由选择,就是指路由协议来。这里,我们不会讨论在Internet上面负责大型网络之间的Exterior协议,相对的,在比较少的网络之间,使用的会是Interior协议,其中最古老最简单的就是RIP协议来。下面我们就以RIP为例子,尝试了解动态路由的运作原理:
在Linux系统里面有一个程序叫做routed,它就是RIP的实现程序。routed是由美国博莱克大学设计出来的,不过并不是设计给大型网络使用的。基础的RIP协议是一种局域网络的向量距离路由的直接实现。它把参与者分为两个类型:主动与被动。主动路由器对其他机器广告自己的路由咨询,它的广播周期预设为30秒,被动的路由器则收听别的广播以改变路由咨询,但本身不参与广播。
RIP协议的信息包含有多对资讯,每对咨询包含一个IP网络地址和通往另一个网络的整数距离。RIP采用的计数制是以路由值为依据,陈伟Metric,用来测量目的地的距离,因此被归类为距离向量(Distance-Vector)路由协议。最简单的Metric值是以从起始端到目的之间的跳站数目为依据的(Hop Count),代表了路由过程中所要穿越的路由器多少,其中Metric越低的路径就被视为最佳路径。然而,跳站数目低并不一定就是最佳路径,因为,跳站信息中并没有网络负载、频宽、延迟、等影响路由质量的信息。很明显,通过两个慢速的网络跳站,并不见得会比通过三个告诉网络的跳站要快。所以,大多数RIP程序都允许程序员以手工的方式来调整Metric参数(例如,把慢速网络的Metric提高)。RIP在交换路由咨询的时候,会把从别的路由器“学”来跳站值从原有数值上加1;当这个数值达到“无穷”值的时候(一般规定为16),就表示这条路径为“unreachable”,同时也会将之从路由表中删除。
下面让我们以一个小型路由网络的例子来更好的看看RIP是怎么样进行路由表格更新的,(强烈建议将下图话出来,以备后面讨论时参考所需):
当路由器刚设定好并连接上网络的时候,各自都有一个“初始路由表”,这里只包含与其直接相连的网络的路由信息:
上表中,NetID所知道如何到达的网络,而“M”值我们暂时将之看成metric数值,“G”指的是通往该网络的下一个要经过的router名字(记住:所谓的路由事实上就是决定下一站是哪个router)。这时,各router看到这样的资讯:M都为1,而G都指向自己。
然后,router与router之间经过第一轮资料交换,并将与相邻router“学”来的路由加入到自己的路由表格中,其metric值也相应的增加“1”.这时,我们看到各router的路由表将会变成这样:
或许,您在刚开始比较这两个表的时候,会无所适从,但其实不是很难的:我们先找到相邻的router之路由表,然后比较本身的路由表,看看有没有新的NetID,有则加到自己的路由表中,并且“M”增加“1”,而“G”则修改为所“学”的router的名字。如果有相同的NetID,则相加metric值,如果的出来的值比自己还低,则抄过来,M也加1;如果比自己值高,则保留自己的。
我们以router1为例子:与之相邻的router分别是:router2和router4。它们的路由表分别是:
而router1自己的路由表则是:
和route2比较:可以发现NetID2和4是新的,那么router1将之抄过来,M加1成为2,然后G指向router2成了2.其中NetID1相同,将router2的metric值加1,等于2,比自己的高,保留自己的。
和route4比较:可以发现NetID7新的,那么router1将之抄过来,M加1成为2,然后G指向router4成为4.其中NetID3相同,将router4的metric值加1,比自己的高,保留自己的好了。
那么经过整理之后,就得出:
好了,到了自己动手练习的时候了,看看能不能为每一个router算以算,是否最终得出下面的路由表?
如果您第一次未能算出正确的答案也不要紧,慢慢算总会得出正确答案的。如果您够细心的话,获取能够看出如下规律:G下面的名字,永远只有相邻的router,而M下面的数值,则取决于所学的次数。如果超过一条路径到达同一个目的地,而且metric值也一样,在实际应用中,router只会听取最先获得的路由信息。
RIP的最大缺点是无法适应大型网络,因此,除RIP路由协议之外,还有许多其他路由协议使用在相同的环境中。不过,在非RIP协议中,他们也有各自的规矩,每种协议都有其优缺点,这里不再详细讨论了。有兴趣的朋友大可自己多找些资料回来研究。
RIP封包讯息格式
若要更好的了解RIP协议,我们不妨参考一下RIP封包的格式:
RIP的信息可以被广泛分为两个类型:路由资讯讯息、咨讯请求讯息。两者都是使用固定的标头,然后一个可选的网络及距离配对资讯列。RIP信息中的命令一共有5个,命令内容如下:
指定一个IP地址:
if 我有这个目的地的路由
从路由表中取得下一站的地址
将封包传给下一站
else
决定目的地网络号
if 我有这个网络的界面
决定我的界面上这个网络的子网掩码
else
从这个网络的层级决定它的子网掩码
endif
利用子网掩码在目的地之上,取得子网络
if 我有这个子网络的界面
将封包直接送往目的地
else if 我的路由表格包含这个子网络的记录
从路由表格取得下一站的地址
将封包传给下一站
else if 我的路由表格中有一笔预设路由
从路由表格中取得下一站的地址
将封包传给下一站
else
宣布这个地址无效
endif
endif
在路由表格中寻找与此地址相符的最长掩码预订值
从路由表格中取得下一站的地址
将封包传给下一站
if 对比不成功
宣布这个目的地无法到达
endif
網中人 wrote in message news:[email protected]... > > 雪龍~ wrote in message > news:[email protected]... > > ※ 引述《[email protected] (網中人)》之銘言: > > > 小州 wrote in message > > > news:[email protected]... > > > > 有這種規定嗎?分別是 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}' 來看看) >