广播是怎样传送的?路由器及主机又如何处理广播?很遗憾,这是难以回答的问题,因为它依靠于广播的类型、应用的类型、TCP/IP实现方法以及有关路由器的配置。
首先,应用程序必须支持广播。假如执行
sun%ping255.255.255.255
/usr/etc/ping:unknownhost255.255.255.255打算在本地电缆上进行广播。但它无法进行,原因在于该应用程序(ping)中存在一个程序设计上的问题。大多数应用程序收到点分十进制的IP地址或主机名后,会调用函数inet_addr(3)来把它们转化为32bit的二进制IP地址。假定要转化的是一个主机名,假如转化失败,该库函数将返回-1来表明存在某种差错(例如是字符而不是数字或串中有小数点)。但本网广播地址(255.255.255.255)也被当作存在差错而返回-1。大多数程序均假定接收到的字符串是主机名,然后查找DNS(第14章),失败后输出差错信息如“未知主机”。
假如我们修复ping程序中这个欠缺,结果也并不总是令人满足的。在6个不同系统的测试中,仅有一个像预期的那样产生了一个本网广播数据报。大多数则在路由表中查找IP地址255.255.255.255,而该地址被用作默认路由器地址,因此向默认路由器单播一个数据报。最终该数据报被丢弃。
指向子网的广播是我们应该使用的。我们向测试网络中IP地址为140.252.13.63的以太网发送数据报,并接收以太网中所有主机的应答。与子网广播地址关联的每个接口是用于命令ifconfig的值。假如我们ping那个地址,预期的结果是:
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实现中是低级插口(rawsocket))通常答应向一个广播地址发送数据报。假如使用不支持广播的应用如TFTP,情况又如何呢?(TFTP将在第15章具体介绍。)
bsdi%tftp启动客户程序
tftp>connect140.252.13.63说明服务器的IP地址
tftp>gettemp.foo试图从服务器或获取一个文件
tftp:sendto:Permissiondenied
tftp>quit终止客户程序
在这个例子中,程序立即产生了一个差错,但不向网络发送任何信息。产生这一切的原因在于,插口提供的应用程序接口API只有在进程明确打算进行广播时才答应它向广播地址发送UDP数据报。这主要是为了防止用户错误地采用了广播地址(正如此例)而应用程序却不打算广播。
在广播UDP数据报之前,使用插口中API的应用程序必须设置SO_BROADCAST插口选项。并非所有系统均强制使用这个限制。某些系统中无需进程进行这个说明就能广播UDP数据报。而某些系统则有更多的限制,需要有超级用户权限的进程才能广播。
下一个问题是是否转发广播数据。有些系统内核和路由器有一选项来控制答应或禁止这一特性
假如让路由器bsdi能够转发广播数据,然后在主机slip上运行ping程序,就能够观察到由路由器bsdi转发的子网广播数据报。转发广播数据报意味着路由器接收广播数据,确定该目的地址是对哪个接口的广播,然后用链路层广播向对应的网络转发数据报。
我们观察到它的确正常工作了,同时也看到BSD系统中的ping程序检查重复的数据报序列号。假如出现重复序列号的数据报就显示DUP!,这意味着一个数据报已经在某处重复了,然而它正是我们所期望看到的,因为我们正向一个广播地址发送数据。
我们还可以从远离广播所指向的网络上的主机上来进行这个试验。在主机angogh.cx.berkeley.edu(和我们的网络距离14跳)上运行ping程序,假如路由器sun被设置为能够转发所指向的广播,它还能正常工作。在这种情况下,这个IP数据报(传送ICMP回显请求)被路径上的每个路由器像正常的数据报一样转发,它们均不知道传送的实际上是广播数据。接着最后一个路由器netb看到主机号为63,就将其转发给路由器sun。路由器sun觉察到该目的IP地址事实上是一个相连子网接口上的广播地址,就将该数据报以链路层广播传往相应网络。