Song <Song.bbs@bbs.cynix.com.tw> wrote in message
news:3c4E1j$8OG@bbs.cynix.com.tw...
>     謝謝 Netman 兄的指正,ADSL router 的 routing 是非改不可了。 :)
>
>     關於不同子網封包的處理,小弟又花了一些時間研究了手邊的資料,及
>     Study_area network 的部分,有些想法要請 Netman 兄再指導。
>
>     因為 Router 的解析是只到 網路層,而 IP 正是在這層。所以,是否
>     IP 的加封是每一個 Router 都要的動作?就是說,TCP 封包標頭的啟始端
>     及目的端是真正的位置,而 IP 封包標頭的只是這一次路由的位置?
>
>     例如說:啟始端 IP:192.168.1.1/24 目的端 IP:192.168.2.1/24
>     由啟始端發出時,TCP 封包標頭如上所示,而加封 IP 時,經路由判斷後,
>     因為目的端不在同一子網中,所以 IP 封包標頭的目的端改為 Gateway IP
>     (假設為 192.168.1.254)當此 IP 封包到達 Gateway (Router)後加以解封,
>     再經由 Router 的路由判斷要送交到 Router 的另一介面(假設為
192.168.2.254),
>     Router 再重新加封 IP ,而啟始端變為 192.168.1.254,目的端變為
>     192.168.2.254 同時存活時間、路由器記錄也加以更新。到 Router 的
>     另一個介面後又重複 解封、路由判斷、加封 的動作後,到達最後的目的端。
>     (省略 Data link layer 用 ARP table 加封 SNDAP 的過程 ...)
>
>     實際的動作是這樣的嗎?謝謝 Netman 兄。

不好意思﹐這兩天忙於修改 NAT 的文章和 script﹐現在才看到閣下文章。怠慢處望諒


不過﹐弟對 TCP/IP 也是略懂皮毛而已。姑且就自己所知的一點淺見和閣下交流一下
吧。

我始終認為學習 linux 必須具有堅實的網路理論基礎﹐而談封包路由也一樣﹐最好先
從 ISO 層級開始。太上層的我們不用理會了﹐ip routing 通常是指在 network 層級
所負責的事情。所以﹐有必要先了解一下 network 以下的底層架構是怎樣的。

1) 實體層
定義了應用在網路傳輸中的各種設備規格﹐以及如何將硬體所攜載的信號轉換成電腦可
以理解的信號(0和1)﹐這通常都是設備上面之韌體(Firmware)的功能。這些規格一般是
由硬體的生產廠商制定的﹐比如﹕數據線的接腳、電壓、波長、相位、等等。 這就要
求我們使用相同規格的硬體來組網了﹐您不能一個網路卡用 BNC﹐另外一個用 token
ring 就直接連線吧﹖如果玩過 RJ45 跳線的朋友﹐一定知道為什麼 1/3、2/6 要互調
的。沒辦法﹐硬體層就是要求這樣。

2) 資料連接層
使用數據框包(frame)的概念來在電腦之間傳輸數據﹐它負責安排框包的界定﹐也同時
處理重複框包和框包的確認。這些規定就沒有像實體層那樣可視了。但還是一樣﹕大家
都要用相同的協定來溝通。其中最常見的是 IEEE2.x 標準了﹐但最常用的的則是
ethernet IEEE802.3 (CSMA/CD )。

該協定是如何工作的呢﹖

很簡單﹐就是每次只能有一個節點在網路上傳遞數據給其它節點﹐其形式是通過對整個
網路進行廣播(broadcast)。然後其它接點收聽到廣播之後﹐就看看數據是否傳個自己
的﹐如果是﹐則接收下來﹔如果不是﹐則略過。每一節點都有一個自己用的48bit的地
址(也可以稱為Node ID﹐也就是在前面說的網卡地址了)﹐而每一個在網路中傳輸的數
據都是以這個地址為傳送和接收依據的。

當任何一個節點進行廣播的時候﹐所有的其它節點都收聽得到。其情形就像我們上課一
樣﹐老師說﹕“第幾排第幾號同學出來拿作業﹗”雖然全班同學都聽得到﹐但卻只有一
位同學可以拿到。Bus形態也和這種形式很類似﹐當然具有更嚴謹的一套法則啦。在bus
上面的數據都是以封包(packet)形式傳遞的﹐封包送出來之後﹐會同時向bus兩端廣
播﹐當目的地接收到給它的封包﹐也不是據為己有的﹐而是複製一份給自己﹐而原來的
封包則還是會繼續被送給下一個節點﹐直到封包抵達終端電阻才會被銷毀。


任何類型的數據要在這一網路上面傳遞的話﹐都必須嚴格的遵循既定的封包格式﹕Data
Link Layer Frame 格式﹐是給網路用來安排數據的。Ethernet的Data Link Layer
Frame包括下面的部件﹕
序言(Preamble)
目的地地址(Destination MAC)
來源地址(Source MAC)
信息類型(Message Type)
數據(Data)
封包監測資料(Frame check sequence)

它們的大小分別為﹕
8 bytes  6 bytes  6 bytes  2 bytes  46-1500 bytes  4 bytes

每一個packet都不可以超過1518bytes﹐這樣就可以確保任何一個工作站都不會佔用網
路太久。工作站對網路廣播之前﹐都會先傾聽一下有沒其它人在使用網路﹐如果聽起來
很安靜﹐則它會發送廣播。但要是網路上仍然嘈嘈的呢﹖這時候工作站就需等待了。

假如節點A和節點B相隔得太遠的話﹐當他們傾聽的時候可能都還沒聽得到對方有話要
說﹐就都同時把封包出去﹐這就是所謂的碰撞(collision)了。如果當一個碰撞發生
了﹐就會在網線產生一個頻率漣漪( frequecy ripple)。如果第一個節點監測到有這樣
的 ripple ﹐它就會發出一個高頻信號去清除所有其它信號。這個信號告訴所有節點碰
撞已經發生﹐這樣全部節點都不會再發送封包了。這時候﹐每一個節點都會隨機的等待
一段時間再重新進行廣播﹐總共可以進行16次嘗試大家才會最終放棄。不過其情形也不
會好到哪裡﹐因為在大家等待之後﹐彼此都有封包要發送﹐誰都想先發送自己的封包﹐
如果節點越多﹐距離越長﹐發生碰撞的機會也就越高。

情形就象上課時您要發言﹐得先看看有沒有其它同學在發言﹐如果已經有人在說話了﹐
那你就先等他/她講完再舉手。要是兩個人都同時舉手﹐老師就會宣佈重新再舉手﹐這
時候大家可以在一秒鐘之內再舉手﹔要是還是一樣﹐那麼可以再於兩秒之內任何時段舉
手﹔再來就4秒、8秒、16秒....的延續下去﹐要試過16次都還一樣﹐沒辦法了﹐大家都
不要說好了。

在網路上﹐我們稱這樣的方法為 CSMA/CD (Carrier-Sensing Multiple Access with
Collision Dectection)。要注意的是﹐所有這些處理過程都必須在Ethernet 網卡上面
進行﹐也就是說﹐如果您要選用Ethernet形態﹐那麼你就必須全部使用Ethernet網卡。

3)網路層
讓封包(packet)在不同的網路之間成功地進行傳遞。它規定了網路的定址方式﹐及處理
資料在不同網路之間的傳遞方式、處理子網路之間的傳遞、決定路由路徑、網路環境、
資料處理順序、等等工作。

發送端電腦在封包被傳送出去之前﹐都會先為其建立header﹐作為在網路或子網間進行
路由的依據。網路層在辨認和處理資料的時候﹐會忽略由高層協定制定的定義﹐只負責
為數據在一個或多個網路間建立、維護、和終止連接。

好了﹐到這裡我們就是看 ip 封包是如何路由的吧﹕系統會先檢查路由表﹐如果路由表
已經有目的地的路由(mask 全部為 32bit)﹐則直接傳給路由表所指定的下一站。否則
就要計算 net ID ﹐它是用 IP 和 MASK 做 AND 運算來獲得的。如果計算出目的 net
ID 和界面 IP 地址在同一個 subnet 之內(也就是相同的 net ID)﹐那麼﹐路由表一定
會有這個 net ID 的敘述的﹐否則您的路由表是殘缺的(可能漏了 route add -net 吧
﹖)。然後封包就直接通過路由表指定的界面丟給對方。如果發現 net ID 不一樣﹐則
尋找路由表上是否還有其它 net ID 的路由資訊﹐如果沒有﹐則找 default gw 的路由
資訊﹐如發現則丟給路由表指定的 IP。注意﹕gw 的 net ID 一定是和其中一個界面一
至的(或說一定在同一個 subnet 內)。如果所有資訊都找不到關於目的地 IP 的路由﹐
則宣告失敗。

當程式從上層協定建立好 socket﹐定好選項和埠口﹐切割好封包﹐再交到網路層的時
候﹐網路層再建一個封包﹐其標頭除了各項選項外﹐一定會包含發送端的 IP 地址和接
收端的 IP 地址﹐要注意﹐除非經過 MASQ 或其它轉址處理﹐這對地址在所有的路由過
程中都不會更改(frame relay 和 ATM 另議)。路由的決定不用管來源地址﹐但一定會
以目的地址為依據進行路由判斷(請參考剛才所述)。當發送端決定將封包交到 router
之後(可以肯定此封包不會在同一個 subnet 之內)﹐router 也會根據目的地址重複前
面講的路由判斷﹕是否有該目的地﹖是否同 subnet? 是否有該 subnet 的路由﹖是否
有default gw? .... 這樣一直傳遞到目的網路的 router ﹐最後的 router 其中一個
界面一定會和目的地址在同一個 subnet﹐然後就往那個界面送。如果傳送失敗﹐則會
將透過 ICMP (或其它協定﹐這裡不是很肯定)﹐告訴發送端路由不能到達。此時﹐原來
的來源地址﹐則變成目的地址了﹐既然可以來﹐當然也有路回去。不過﹐路徑可能未必
和原來的一樣﹐因為每一個 router 都會根據當時的網路情況來決定路由﹐尤其在多路
由通道的大型網路中。至於路由表的維護﹐恐怕超出現在這個話題了(有空再談吧)。但
無論如何﹐正常狀態下﹐來源和目的 IP 地址是不會變的。

不過﹐我們回看 network 以下的兩個層級﹐它們使用的卻不是 IP 地址﹐而是 MAC
(Media Access Control) 地址。那麼我們怎麼知道一個 IP 封包要丟給那個 MAC 呢﹖
此問題會發生在接收地址和界面地址(不是來源地址哦~~~﹗)在同一個 subnet 的時
候。這時就要借助 ARP (Address Reesolution Protocol) 協定來幫忙了。

ARP在本地網路的運用﹕

以使用TCP/IP 的 Ethernet 網路為例﹕每台電腦都有一個ARP表格(ARP Table)存放於
ARP快取記憶區(ARP Cach)之中﹐它主要記錄著同一網路中各節點的 IP 和 MAC 地址的
對應。

當機器有一個TCP/IP封包送出去的時候﹕

1﹐會先看看目的地址是否屬於同一 subnet 裡面﹐(還記得的netmask和IP的作用嗎
﹖)﹔
2﹐如果是的話﹐則會檢查ARP 表格有沒有對方的IP和MAC對應﹔
3﹐如果有的話﹐就直接將封包傳到該MAC去﹔
4﹐如果ARP表格上面找不到對方的對應﹐則會向網路發出一個ARP Request廣播封包﹐
查詢對方的MAC地址﹐這個封包會包含發送端的MAC資料﹔
5﹐當網路上面的機器接聽到該廣播﹐看看IP欄位是否和自己的一致﹐如果不是則忽略

6﹐如果是則會先將發送端的MAC和IP資料更新到自己的ARP表格去﹔然後再回應一個ARP
Reply封包給對方﹔
7﹐當發送端接到ARP Reply之後﹐也會更新自己的ARP表格﹔ 然後就可以用此紀錄進行
傳送了。
8﹐否則宣告傳送失敗。

跨網路環境下的ARP﹕

我們已經知道﹕如果Net ID不同的IP傳送都要經過router才可以做到。那麼當機器發現
封包不是傳給本地網路的時候﹐那麼它就要把封包傳給router了。記住﹕router必須有
一個界面和發送端在同一網路﹐這個router我們可以用DHCP來指定﹐也可以在各台機器
上面手工指定。如果本地網路同時還和好幾個網路連接﹐也就是說﹐有好幾個router可
以選擇﹐我們也必須一一在各機器上的IP環境中指定好。(可以參考 RIP 的資料)。

ARP 的跨網過程粗略如下﹕

1﹐先檢查封包是否寄給本地網路的﹔
2﹐如果不是﹐將之送給router﹔
3﹐如果ARP表格還沒有router的記錄的話﹐利用ARP Request來進行更新﹔
4﹐然後router會判斷下一個router的MAC﹐再把封包傳出去﹔
5﹐當封包傳到目的地的router﹐router也一樣檢查ARP表格﹐或利用ARP Request找到
目的主機的MAC﹔
6﹐最後將封包傳給目的IP地址。

當找到 MAC 地址之後﹐請回憶一下前面說的 Data Link Layer Frame 和 CSMA/CD ﹐
就知道資料如何送到目的地了。

這個﹐就是一個封包的整個路由過程了。您看﹐封包的 IP 地址﹐並非是 router 改寫
的(除非您用 NAT)﹐準確來說是程式在建立 socket 時確定的。而每一個 socket 必須
包括 IP 地址和 port ﹐port 供傳送層(TCP)使用﹐而 IP 地址則供網路層(IP)使用﹐
合起來就是 TCP/IP 了。

再多說一點 :)

當您在 browser 上面打一個 URL ﹐其實就是為了獲得最基本的 socket 元素了﹕IP
和 port 。 URL 的地址可以通過 hosts 或 DNS 來查得﹐而 port﹐除非另外指定﹐那
個URL 最前面的 http: 或 ftp: 就是了。

好了﹐DNS 的設定又是另外一個大題目﹐已經和目前討論無關。但設定過 linux 的朋
友﹐都不會忘了在 /etc/resolv.conf 上面打 nameserver 的 IP 。 溫習過前面的說
明﹐您會明白到為什麼 DNS 可以隨便在 internet 找一個了吧﹕因為路由是通的﹗

以上的資料﹐大部份可以在 study-area 找得到。如有錯漏﹐懇請指正。謝謝﹗