12.1 引言
在第1章中我們提到有三種IP地址:單播地址、廣播地址和多播地址。本章將更詳細地
介紹廣播和多播。
廣播和多播僅應用于UDP,它們對需將報文同時傳往多個接收者的應用來說十分重要。
TCP是一個面向連接的協議,它意味著分別運行于兩主機(由IP地址確定)內的兩進程
(由端口號確定)間存在一條連接。
考慮包含多個主機的共享信道網絡如以太網。每個以太網幀包含源主機和目的主機的以
太網地址(48 bit)。通常每個以太網幀僅發往單個目的主機,目的地址指明單個接收
接口,因而稱為單播(unicast)。在這種方式下,任意兩個主機的通信不會干擾網內其
他主機(可能引起爭奪共享信道的情況除外)。
然而,有時一個主機要向網上的其他主機發送幀,這就是廣播。通過ARP和RARP可以看
到這一過程。多播(multicast) 處于單播和廣播之間:幀僅傳送給屬于多播組的多個主
機。
為了弄清廣播和多播,需要了解主機對由信道傳送過來幀的過濾過程。圖12.1說明了這
一過程。
首先,網卡查看由信道傳送過來的幀,確定是否接收該幀,若接收后就將它傳往設備驅
動程序。通常網卡僅接收那些目的地址為網卡物理地址或廣播地址的幀。另外,多數接
口均被設置為混合模式,這種模式能接收每個幀的一個復制。作為一個例子,tcpdump
使用這種模式。
圖12.1 協議棧各層對收到幀的過濾過程
目前,大多數的網卡經過配置都能接收目的地址為多播地址或某些子網多播地址的幀。
對于以太網,當地址中最高字節的最低位設置為1時表示該地址是一個多播地址,用十
六進制可表示為01:00:00:00:00:00。(以太網廣播地址ff:ff:ff:ff:ff:ff可看作是以
太網多播地址的特例。)
如果網卡收到一個幀,這個幀將被傳送給設備驅動程序。(如果幀檢驗和錯,網卡將丟
棄該幀。)設備驅動程序將進行另外的幀過濾。首先,幀類型中必須指定要使用的協議
(IP,ARP等等)。其次,進行多播過濾來檢測該主機是否屬于多播地址說明的多播組。
設備驅動程序隨后將數據幀傳送給下一層,比如,當幀類型指定為IP數據報時,就傳往
IP層。IP根據IP地址中的源地址和目的地址進行更多的過慮檢測,如果正常,將數據報
傳送給下一層(如TCP或UDP)。
每次UDP收到由IP傳送來的數據報,就根據目的端口號,有時還有源端口號進行數據報
過濾。如果當前沒有進程使用該目的端口號,就丟棄該數據報并產生一個ICMP不可達報
文。(TCP根據它的端口號作相似的過慮。)如果UDP數據報存在檢驗和錯,將被丟棄。
使用廣播的問題在于它增加了對廣播數據不感興趣主機的處理負荷。拿一個使用UDP廣
播應用作為例子,如果網內有50個主機,但僅有20個參與該應用,每次這20個主機中的
一個發送UDP廣播數據時,其余30個主機不得不處理這些廣播數據報,而直到UDP層,收
到的UDP廣播數據報才會被丟棄。這30個主機丟棄UDP廣播數據報是因為這些主機沒有使
用這個目的端口。
多播的出現減少了對應用不感興趣主機的處理負荷。使用多播,主機可加入一個或多個
多播組。這樣,網卡將獲悉該主機屬于哪個多播組,然后僅接收主機所在多播組的那些
多播幀。
12.2 廣播
在圖3.9中,我們知道了四種IP廣播地址,下面對它們進行更詳細的介紹。
受限的廣播
受限的廣播地址是255.255.255.255。該地址用于主機配置過程中IP數據報中目的地址,
此時,主機可能還不知道它所在網絡的網絡掩碼,甚至連它的IP地址也不知道。
在任何情況下,路由器都不轉發目的地址為受限的廣播地址的數據報,這樣的數據報僅
出現在本地網絡中。
一個未解的問題是:如果一個主機是多接口的,當一個進程向本網廣播地址發送數據報
時,為實現廣播,是否應該將數據報發送到每個相連的接口上?如果不是這樣,想對主
機所有接口廣播的應用必須確定主機中支持廣播的所有接口,然后向每個接口發送一個
數據報復制。
大多數BSD系統將255.255.255.255看作是配置后第一個接口的廣播地址,并且不提供向
所屬具備廣播能力接口傳送數據報的功能。不過,routed(見10.3)和rwhod(BSD
rwho客戶的服務器)是向每個接口發送UDP數據報的兩個應用程序。這兩個應用程序均
有相似的啟動過程來確定主機中的所有接口,并了解哪些接口具備廣播能力。同時,將
對應于那種接口的指向網絡的廣播地址作為向該接口發送的數據報的目的地址。
Host Requirements RFC沒有進一步涉及多接口主機是否應當向其所有的接口發送受限
的廣播。
指向網絡的廣播
指向網絡的廣播地址是主機號字段均為1的地址。A類網絡廣播地址為
netid.255.255.255,其中netid為A類網絡的網絡號。
一個路由器必須轉發指向網絡的廣播,但它也必須有一個不進行轉發的選擇。
指向子網的廣播
指向子網的廣播地址為主機號碼字段均為1且有特定子網號的地址。作為子網直接廣播
地址的IP地址需要了解子網的掩碼。例如,如果路由器收到發往128.1.2.255的數據報,
當B類網絡128.1的子網掩碼為255.255.255.0時,該地址就是指向子網的廣播地址;但
如果該子網的掩碼為255.255.254.0,該地址就不是指向子網的廣播地址。
指向所有子網的廣播
指向所有子網的廣播也需要了解目的網絡的子網掩碼,以便與指向網絡的廣播地址區分
開。指向所有子網的廣播地址的子網號字段及主機號字段均為1。例如,如果目的子網
掩碼為255.255.255.0,那么IP地址128.1.255.255是一個指向所有子網的廣播地址。然
而,如果網絡沒有劃分子網,這就是一個指向網絡的廣播。
當前的看法[Almquist 1993]是這種廣播是陳舊過時的,更好的方式是使用多播而不是
對所有子網的廣播。
----[Almquist 1993] 解釋了RFC 922需要一個向所有子網的廣播來傳送給所有子網,但
當前的路由器沒有這么做。這很幸運,因為一個已經錯誤配置的主機沒有它的主機掩碼
會把它的本地廣播傳送到所有子網。例如,如果IP地址為128.1.2.3的主機沒有設置子
網掩碼,它的廣播地址在正常情況下的默認值是128.1.255.255。但如果子網掩碼被設
置為255.255.255.0,那么由錯誤配置的主機發出的廣播將指向所有的子網。
--
--1983年問世的4.2BSD是第一個影響廣泛的TCP/IP的實現,它使用主機號全0作為廣播地
址。一個最早有關廣播IP地址參考是IEN 212 [Gurwitz and Hinden 1982],它提出用
主機號中的1比特來表示IP廣播地址。(IENs 是互聯網試驗注釋,基本上是RFC的前
身。)RFC 894 [Hornig 1984]認為4.2BSD使用不標準的廣播地址,但RFC 906
[Finlayson 1984] 注意到對廣播地址還沒有Internet標準。他還在RFC 906加了一個腳
注承認缺少標準的廣播地址,并強烈推薦將主機號全1作為廣播地址。盡管1986年的
4.3BSD采用主機號全1表示廣播地址,但直到90年代早期操作系統(突出的是SunOS 4.x)
還繼續使用非標準的廣播地址。
12.3 廣播的例子
廣播是怎樣傳送的?路由器及主機又如何處理廣播?很遺憾,這是難于回答的問題,因
為它依賴于廣播的類型、應用的類型、TCP/IP實現方法以及有關路由器的配置。
首先,應用程序必須支持廣播。如果執行
sun % ping 255.255.255.255
/usr/etc/ping: unknown host 255.255.255.255
打算進行在本地電纜上的廣播,但它無法進行,原因在于該應用程序(ping)中存在一
個程序設計上的問題。大多數應用程序收到點分十進制的IP地址或主機名后,會調用函
數inet_addr(3)來把它們轉化為32 bit的二進制IP地址。假定要轉化的是一個主機名,
如果轉化失敗,該庫函數將返回-1來表明存在某種差錯(例如是字符而不是數字或串中
有小數點),但本網廣播地址(255.255.255.255)也被當作存在差錯而返回-1。大多
數程序均假定接收到的字符串是主機名,然后查找域名系統DNS(第14章),失敗后輸
出差錯信息如“未知主機”。
如果我們修復ping程序中這個欠缺,結果也并不總是令人滿意的。在6個不同系統的測
試中,僅有一個像預期的那樣產生了一個本網廣播數據報。大多數則在路由表中查找IP
地址255.255.255.255,而該地址被用作默認路由器地址,因此向默認路由器單播一個
數據報。最終該數據報被丟棄。
指向子網的廣播是我們應該使用的。在6.3節中,我們向測試網絡(見封2)中IP地址為
140.252.13.63 的以太網發送數據報,并接收以太網中所有主機的回答。與子網廣播
地址關聯的每個接口是用于命令ifconfig(見3.8節)的值。如果我們ping那個地址,
預期的結果是:
(見原書p.173①)
IP通過目的地址(140.252.13.63)來確定這是指向子網的廣播地址,然后向鏈路層的
廣播地址發送該數據報。
我們在6.3提及的這種類型廣播的接收對象為包括發送主機在內的局域網中的所有主機,
因此可以看到除了收到網內其他主機的答復外,還收到了來自發送主機(sun)的答復。
在這個例子中,我們也顯示了執行ping廣播地址前后ARP緩存的內容。這可以顯示廣播
與ARP之間的相互作用。執行ping命令前ARP緩存是空的,而執行后是滿的。(也就是說,
對網內其他每個響應回顯請求的主機在ARP緩存中均有一個條目。)我們提到的該以太
數據幀被傳送到鏈路層的廣播地址(0xffffffff)是如何發生的呢?由sun主機發送的
數據幀不需要ARP。
如果使用tcpdump來觀察ping的執行過程,可以看到廣播數據幀的接收者在發送它的響
應之前,首先產生一個對sun主機的ARP請求,因為它的回答是以單播形式發回的。在
4.5節我們介紹了一個ARP請求的接收者(該例中是sun)通常在發送ARP應答外,還將請
求主機的IP地址和物理地址加入到ARP緩存中去。這基于這樣一個假定:如果請求者向
我們發送一個數據報,我們也很可能想向它發回什么。
我們使用的ping程序有些特殊,原因在于它使用的編程接口(在大多數Unix實現中是
“低級插口(raw socket)”)通常允許向一個廣播地址發送數據報。如果我們使用不支
持廣播的應用如TFTP情況如何呢?(TFTP將在第15章詳細介紹。)
bsdi % tftp-------- 啟動客戶程序
tftp> connect 140.252.13.63----說明服務器的IP地址
tftp> get temp.foo------ 試圖從服務器或獲取一個文件
tftp: sendto: Permission denied
tftp> quit-------- 終止客戶程序
在這個例子中,程序立即產生了一個差錯,但不向網絡發送任何信息。產生這一切的原
因在于插口提供的應用程序接口API只有進程明確打算進行廣播時才允許它向廣播地址
發送UDP數據報。這主要是為了防止用戶錯誤地采用了廣播地址(正如此例)而應用程
序卻不打算廣播。
在廣播UDP數據報之前,使用插口中API的應用程序必須設置SO_BROADCAST 插
口選項。
并非所有系統均強制使用這個限制。某些系統中無需進程進行這個說明就能廣
播UDP數據報。而某些系統則有更多的限制,需要有超級用戶權限的進程才能廣播。
下一個問題是是否轉發廣播數據。一些系統內核和路由器有一選項來控制允許或禁止這
一特性。(見附錄E)
如果我們讓路由器bsdi能夠轉發廣播數據,然后在主機slip上運行ping程序,我們能夠
觀察到由路由器bsdi轉發的子網廣播數據報。轉發廣播數據報意味著路由器接收廣播數
據,確定該目的地址是對哪個接口的廣播,然后用鏈路層廣播向對應的網絡轉發數據報。
(見原書p.174①)
我們觀察到它的確正常工作了,同時也看到了BSD系統中的ping程序檢查重復的數據報
序列號,如果出現重復的序列號的數據報就顯示DUP! ,它意味著一個數據報已經在某
處重復了,然而它正是我們所期望看到的,因為我們正向一個廣播地址發送數據。
我們還可以從更遠離廣播所指向的絡網上的主機上來進行這個試驗。如果在主機
angogh.cx.berkeley.edu(和我們的網絡距離14跳)上運行ping程序,如果路由器sun
被設置為能夠轉發所指向的廣播,它還能正常工作。在這種情況下,這個IP數據報(傳
送ICMP回顯請求)被路徑上的每個路由器像正常的數據報一樣轉發,它們均不知道它們
傳送的實際上是廣播數據。接著最后一個路由器netb看到主機號為63,就將其轉發給路
由器sun。路由器sun覺察到該目的IP地址事實上是一個相連子網接口上的廣播地址,就
以該數據報以鏈路層廣播傳往相應網絡。
廣播是一種應該謹慎使用功能。在許多情況下,IP多播被證明是一個更好的解決辦法。
12.4 多播
IP多播提供兩類服務。
1. 向多個目的地址傳送數據。有許多向多個接收者傳送信息的應用:例如交互式會議
系統和向多個接收者分發郵件或新聞。如果不采用多播,目前這些應用大多采用TCP來
完成(向每個目的地址傳送一個單獨的數據復制)。然而,既使使用多播,某些應用可
能繼續采用TCP來保證它的可靠性。
2. 客戶對服務器的請求。例如,無盤工作站需要確定啟動引導服務器。目前,這項服
務是通過廣播來提供的(正如第16章的BOOTP),但是使用多播可降低不提供這項服務
主機的負擔。
多播組地址
圖12.2 顯示了D類IP地址的格式。
圖12.2 D類IP地址格式
不像圖1.5 所示的其他三類IP地址(A、B和C),分配的28 bit均用作多播組號碼而不
再表示其他。
多播組地址包括最高4 bit為1110的類別比特和多播組號。它們通常可表示為由點分十
進制數,范圍從224.0.0.0到239.255.255.255。
能夠接收發往一個特定多播組地址數據的主機集合稱為主機組(host group)。一個主機
組可跨越多個網絡。主機組中成員可隨時加入或離開主機組。主機組中對主機的數量沒
有限制,同時不屬于某一主機組的主機可以向該組發送信息。
一些多播組地址被IANA確定為熟知地址。它們也被當作永久主機組,這和TCP及UDP中的
熟知端口相似。同樣的,這些熟知多播地址在RFC最新分配數字中列出。注意這些多播
地址所代表的組是永久組,而它們的組成員卻不是永久的。
例如,224.0.0.1代表“該子網內的所有系統組”,224.0.0.2代表“該子網內的所有路
由器組”。多播地址224.0.1.1用作網絡時間協議NTP,224.0.0.9用作RIP-2(見10.5節),
224.0.1.2用作SGI公司的dogfight應用。
多播組地址到以太網地址的轉換
IANA擁有一個以太網地址塊,即高位24 bit為00:00:5e(十六進制表示)的以太網地址,
這意味著該地址塊所擁有的地址范圍從00:00:5e:00:00:00到00:00:5e:ff:ff:ff。IANA
將其中的一半分配為多播地址。為了指明一個多播地址,任何一個以太網地址的首字節
必須是01,這意味著與IP多播相對應的以太網地址范圍從01:00:5e:00:00:00到
01:00:5e:7f:ff:ff。
----這里對CSMA/CD或令牌網使用的是Internet標準比特順序,和在內存中出現的比特順
序一樣。這也是大多數程序設計者和系統管理者采用的順序。IEEE文檔采用了這種比特
的傳輸順序。Assigned Numbers RFC給出了這些表示的差別。
這個地址分配將使以太網多播地址中的23 bit與IP多播組號對應起來,這通過將多播組
號中的低位23 bit映射到以太網地址中的低位23 bit實現,這個過程如圖12.3。
既然多播組號中的最高5 bit在映射過程中被忽略,因此每個以太網多播地址對應的多
播組是不唯一的。32個不同的多播組號被映射為一個以太網地址。例如,多播地址
224.128.64.32(十六進制e0.80.40.20)和224.0.64.32(十六進制e0.00.40.20)都映
射為同一以太網地址01:00:5e:00:40:20。
既然地址映射是不唯一的,這意味著設備驅動程序或IP層(見圖12.1)必須進行數據報
過濾,因為網卡可能接收到主機不想接收的多播數據幀。另外,如果網卡不提供足夠的
多播數據幀過濾功能,設備驅動程序就必須接收所有多播數據幀,然后對它們進行過濾。
圖12.3 D類IP地址到以太網多播地址的映射
局域網網卡趨向兩種處理類型,一種是網卡根據對多播地址的散列值實行多播過濾,這
意味仍會接收到不想接收的多播數據。另一種網卡是只接收一些固定數目的多播地址,
這意味著當主機想接收超過網卡預先支持多播地址以外的多播地址時,必須將網卡設置
為“多播混雜(multicast promiscuous)”模式。因此,這兩種類型的網卡仍需要設備
驅動程序檢查收到的幀是否真是主機所需要的。
既使網卡實現了完美的多播過濾(基于48 bit的硬件地址),由于從D類IP地址到48
bit的硬件地址的映射不是一對一的,過濾過程仍是必要的。
盡管存在地址映射不完美和需要硬件過濾的不足,多播仍然比廣播好。
單個物理網絡的多播是簡單的。多播進程將目的IP地址指明為多播地址,設備驅動程序
將它轉換為相應的以太網地址,然后把數據發送出去。這些接收進程必須通知它們的IP
層它們想接收的發往給定多播地址的數據報,并且設備驅動程序必須能夠接收這些多播
幀。這個過程就是“加入一個多播組”。(使用“接收進程”復數形式的原因在于對一
確定的多播信息,在同一主機或多個主機上存在多個接收者,這也是為什么要首先使用
多播的原因。)當一個主機收到多播數據報時,它必須向屬于那個多播組的每個進程均
傳送一個復制。這和單個進程收到單播UDP數據報的UDP不同,使用多播,一個主機上可
能存在多個屬于同一多播組的進程。
當把多播擴展到單個物理網絡以外需要通過路由器轉發多播數據時,復雜性就增加了。
需要有一個協議讓多播路由器了解確定網絡中屬于確定多播組的任何一個主機。這個協
議就是Internet組管理協議(IGMP),也是下一章介紹的內容。
FDDI和令牌環網絡中的多播
FDDI網絡使用相同的D類IP地址到48 bit FDDI地址的映射過程[Katz 1990]。令牌環網
絡通常使用不同的地址映射方法,這是因為大多數令牌控制中的限制。
12.5 小結
廣播是將數據報發送到網絡中的所有主機(通常是本地相連的網絡),而多播是將數據
報發送到網絡的一個主機組。這兩個概念的基本點在于當收到送往上一個協議棧的數據
幀時采用不同類型的過濾。每個協議層均可以因為不同的理由丟棄數據報。
目前有四種類型的廣播地址:受限的廣播、指向網絡的廣播、指向子網的廣播和指向所
有子網的廣播。最常用的是指向子網的廣播。受限的廣播通常只在系統初始啟動時才會
用到。
試圖通過路由器進行廣播而發生的問題,常常是因為路由器不了解目的網絡的子網掩碼。
結果與多種因素有關:廣播地址類型、配置參數等等。
D類IP地址被稱為多播組地址。通過將其低位23 bit映射到相應以太網地址中便可實現
多播組地址到以太網地址的轉換。由于地址映射是不唯一的,因此需要其他的協議實現
額外的數據報過濾。
習題
12.1 廣播是否增加了網絡通信量?
12.2 考慮一個擁有50臺主機的以太網:20臺運行TCP/IP而其他30臺運行其他的協議族。
主機如何處理來自運行另一個協議族主機的廣播?
12.3 你登錄到一個過去從來沒有用過的Unix系統,并且打算找出所有支持廣播的接口
的指向子網的廣播地址。你如何做到這點?
12.4 如果我們用ping程序向一個廣播地址發送一個長的分組,如
(見原書p.178①)
它正常工作,但將分組的長度再增加一個字節后出現如下差錯:
sun % ping 140.252.13.63 1473
PING 140.252.13.63: 1473 data bytes
sendto: Message too long
究竟出了什么問題?
12.5 重做習題10.6,假定8個RIP報文是通過多播而不是廣播(使用RIP 版本2)。有什
么變化?
12—1