梦见锡安
msgbartop
小舟从此逝,江海寄余生。
msgbarbottom

5 UDP、广播/多播 | 2006年10月05日

  • UDP用户数据报协议是工作在运输层的协议,其正式规范为RFC 768。

UDP没有应答机制,不保证可靠传输,不重发数据,由于速度快,常用于本地通信(局域网或主机上的环回接口)。

  • UDP的报文格式(封装在IP包内):
src port(16 bits)–dst port(16 bits)–UDP length(16 bits)–check sum(16 bits)–data (its length depends on socket API or TCP/IP’s kernel features)

端口为UDP协议的端口,协议已经由IP数据首部标出;

16位UDP长度包括数据部分;

校验和校验整个UDP首部和数据部分,也采用16 bits二进制反码和。如果UDP有奇数字节,常在最后填充0字节以满足16bits的整数倍;

校验和包括32位源IP和32位目的IP地址为伪首部;

UDP校验和是可选项,如果全为0则未打开校验和,RFC规定默认下打开。

  • IP分片

由于路径MTU的制约,UDP、TCP等协议的数据在IP封装后通常要进行分片。其分片的标识、标志和片偏移(其值以字节为单位)在IP首部指定。IP分片可能在主机上也可能在中间路由器上进行,它对UDP、TCP等上层协议是透明的。

如果需要分片但是IP的标志设置了不分片位,将引起MTU小于该包的路由上的TCMP IP未分片报文,报文提供了下一站的MTU。

通常可利用这种错误报文进行路径MTU的发现。例如可以修改traceroute程序,使分组长度等于出口路由的MTU,收到ICMP未分片报文后,按报文的下一站MTU值修改分组长度,如果该报文未含MTU值,则按自己的机制递增长度,直到得到最小MTU。

UDP本身也可以进行路径MTU发现,但是其原理书中说的不是很明白。

  • ICMP源站抑制差错

若主机或路由接收数据报的速度比其处理速度要快导致缓存溢出,可能会引发这种差错。

UDP很容易会引发这种差错,但是目前多数的实现只接收TCP的源站抑制差错报文而忽略UDP的差错报文。

  • UDP服务器的端口(port)和接口(interface)

通常每个指定的接口和端口只提供一个服务进程,其客户端请求通过FIFO队列进行处理。

如果有多个IP(接口),各自接口的相同端口都可以运行一个服务器进程。

远程服务器的同一个应用或许会提供多个接口和端口。但是本地进程在指定对远程的连接接口后将自动选择本地的接口地址。

  • 单播、广播和多播:

单播把数据报发送给单一主机;

广播把数据报发送给指定网络上的所有主机;

多播发送给指定的多个主机。

单播、广播和多播的概念仅用于UDP实现。

  • 广播地址的类型

受限广播地址:255.255.255.255,本主机所在本地网络的广播地址,例如我所在子网219.221.206.32的广播地址 219.221.206.63。

网络广播地址:A类、B类、C类的广播地址,网络号不变,主机号所有位置1。

子网广播地址:子网号不变,主机号所有位置1。可以通过子网地址跟子网掩码的逻辑或得到。

所有子网的广播地址:子网号和主机好所有位置1。可以使用所用C类地址跟子网地址及子网掩码的反码依次相或得到。

  • 广播的应用范围

需要应用程序支持广播,例如tftp就不支持广播。ping广播地址需要加上-b选项即可得到所ping网络上所有主机的响应。

如果广播地址不是本地网络,需要路由器配置的支持。

  • 多播

多播概念的引入是为了避免广播时网络中对此广播没有兴趣的主机的负载。

多播使用多播组,多播组使用的是D类地址。从224.0.0.0~239.255.255.255。

多播组也跟TCP/UDP端口一样使用知名地址(wellkown)的概念。由RFC给出。

多播可应用于视频会议、在线聊天室等。

  • 多播在单一物理网络上的实现相对比较简单,多播进程把所要发送的数据报发给多播IP地址,设备驱动程序把多播地址转换为相应的以太网地址往外发。接收进程通过以太网卡过滤接收多播帧。

多播地址到以太网地址的转换使用其低23位直接映射到相应以太网地址中。映射地址并不唯一,需要设备驱动程序或IP层提供多播数据报过滤功能。

  • 多播使用IGMP——Internet组管理协议作为其基本模块,用于为主机和路由实现同一物理网络上的多播提供支持。

4 IP选路及相关选路协议 | 2006年10月04日

  • 几个显示本机路由表的相关命令,主机路由表的复杂性取决于所连接网络的拓扑结构。

route,输出为

root@mjxian-ubuntu ~
# route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
localnet        *               255.255.255.224 U     0      0        0 eth0
default         219.221.206.62  0.0.0.0         UG    0      0        0 eth0

netstat -r,输出为

root@mjxian-ubuntu ~
# netstat -r
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
localnet        *               255.255.255.224 U         0 0          0 eth0
default         219.221.206.62  0.0.0.0         UG        0 0          0 eth0

netstat -rn,输出为

root@mjxian-ubuntu ~
# netstat -rn
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
219.221.206.32  0.0.0.0         255.255.255.224 U         0 0          0 eth0
0.0.0.0         219.221.206.62  0.0.0.0         UG        0 0          0 eth0
  • IP选路策略:

先搜索匹配主机,再搜索匹配网络,最后搜索默认路由 (default)

  • 路由表中Flags的含义:
U       可用路由
G       该路由作为网关
H       该路由为主机地址(而不是网络地址)
D       该路由通过ICMP重定向得到
  • Metric字段,表示路由每一跳的度量。
  • 若IP无法到达目的地,出错的路由器将向源主机发送ICMP主机不可达或者网络不可达差错报文。
  • ICMP重定向:

在主机有多个路由出口时,收到IP数据报的默认路由器识别到从主机开始,另有最佳路由,将向源主机发送ICMP重定向报文,修改更新源主机上的路由表。

  • ICMP路由发现请求/应答报文:

主机对TCP/IP网络进行初始化时向路由器发送ICMP请求,路由器进行应答,发送ICMP路由器通告报文。同时路由器也不定期向网络上的广播或多播地址发送路由通告,主机进行监听。这些工作通过Unix的守护进程实现。

  • 动态选路:

路由器的动态选路策略通过守护进程实现。quagga是一个提供RIP/OSPF/BGP选路管理的实用程序。守护进程在前往同一信宿有多个路由时可以以某种策略选择最佳路由并更新路由表,同时也可以在链路断开时删除该路由或者新增一条。

用于动态选路的选路协议包括IGP和EGP,内部网关或者外部网关协议。


  • RIP动态选路信息协议:

RIP的正式规范见RFC 1058。

RIP是一种IGP,是基于距离向量的选路协议。距离向量意味着RIP的报文包含了IP的跳数(距离向量)。

RIP使用了UDP,封装在UDP数据报内传送。接收端(server)的UDP端口为 520

RIP的首部格式(4 bytes):

cmd(8 bits,value:1~6)–version(8 bits)–left 0 (16 bits)

每个路由信息的数据格式(20 bytes):

address family(16 bits)–left 0(16 bits)–IP address(32 bits)–left 0(32 bits)–left 0(32 bits)–metric(32 bits, value<16)

一共可以使用25个路由。使总数 4 + 25 x 20 = 504 < 512   (bytes)

  • 使用RIP的守护进程的主要任务:

初始化,请求发送完整路由表求。RIP作为发送完整路由表请求时,cmd值为1,地址族置0,metric置16,总长度为24字节。

响应时按照格式填入报文,发送给请求端。metric为跳数,以请求主机为起点,如果没有目的主机,metric设置为16。收到响应可能会更新路由表使响应生效。

正常工作时,路由器通过广播或者点对点链路定时向其它路由器发送完整的路由表。

如果有一条路由的metric发生变化,发送该路由的RIP报文给其它主机进行更新。收到报文的路由按照metric最小的策略选择更新自己的路由表。 metric的最大值为15,为16时表明该IP无法到达。

  • RIP的缺点:
  1. 不支持子网;
  2. 路由器或链路发生故障后,网络在稳定前可能会发生路由环路错误。
  3. metric<16限制了使用RIP的网络规模。
  • RIP-2

RIP的扩充版本,定义了原RIP包中一些置零的字段。如下:

首部格式(4 bytes):

cmd(8 bits,value:1~6)–version(8 bits)–routing domain (16 bits)

每个路由信息的数据格式(20 bytes):

address family(16 bits)–routing tags(16 bits)–IP address(32 bits)–netmask(32 bits)–next IP address(32 bits)–metric(32 bits, value<16)

routing domain:一般定义为选路守护进程的 pid;

routing tag:   对EGP支持的扩充;

RIP-2扩充了对多播的支持,以减少不监听RIP-2报文的主机的负载。


  • OSPF协议

也是一种IGP协议,其正式规范见RFC 1247,它是基于链路状态的选路协议。

使用OSPF的路由器主动测试与邻站的连接状态,并把状态信息发到其它邻站,通过这样的一种交互更新各自的路由表。

  • OSPF的特点:

使用IP而不是 TCP/UDP;

每个IP服务类型都可以有一套自己的路由集,即使目的地址一样;

管理各IP服务类型的费用和流量平衡;

支持子网;

采用多播而不是广播,以减少不参与OSPF的系统负载。


  • BGP边际网关协议

一种EGP协议,基于距离向量。略。


3 ICMP协议及应用 | 2006年10月02日

  • ICMP:Internet控制报文协议

用于为IP或者更高层协议传递查询/请求/差错相关报文,封装在IP数据报内部。其规范见RFC 792。

  • 发送网络广播不会引起ICMP差错报文。
  • ICMP报文的主要格式:
类型(8位)–代码(8位)–校验和(16位)–报文内容

类型共15种,其值为0~18,但不包括1、2、6、 7;

代码字段从0~15共16种。类型字段和代码字段共同组成定义了ICMP的报文类型。

检验和算法与IP首部相同,即全部取反,然后每16位累加。覆盖整个ICMP报文。

  • ICMP掩码地址请求与应答报文(共12字节):

用于无盘系统在引导过程中获取自己的子网掩码。

格式:

类型(Req=17/Ack=18)–代码(0)–校验和–标识符(2 bytes)–序号(2 bytes)–Netmask(32 bits)

由IP往广播地址发送,应答主机把响应传回给请求主机。

  • ICMP时间戳请求与应答报文(20字节):

用于一台主机向另一台主机查询当前时间。时间戳的建议值为UTC从0时开始计算的时间,单位为毫秒。

格式:

类型(Req=17/Ack=18)–代码(0)–校验和–标识符(2 bytes)–序列号(2 bytes)–
发起时间戳(32 bits)–接收时间戳(32 bits)–传送时间戳(32 bits)

请求时只填写发起时间戳。大多数实现在响应时把接收和传送时间戳填写为相同的值。

与请求主机的时钟的差别的算法(单位: 毫秒):

(接收时间戳-发起时间戳)-(发请求的时间-收到响应的时间)/2

即先比较响应主机接收到请求报文时的时间与发起的差,再减去网络往返的时间。

  • ICMP端口不可达差错报文:

一种常见的ICMP差错。

格式:

类型(3)–代码(0~15)–校验和–未用(32 bits,必须为 0)–IP首部–原始IP数据报中数据的前8个字节

类型3为各种ICMP不可达报文,共16 种。

IP首部用于为出错主机提供协议字段,从而分析往后的8个字节,而后8个字节包含了TCP或者UDP等协议的源端口和目的端口,从而使出错主机可以从端口号把差错报文与相关的进程关联起来。

注:ICMP规范允许IP数据报中的数据多于8个字节,但大多BSD的派生系统只返回8个字节。


  • ping程序
  • ping是ICMP最常见的应用,使用的是ICMP回显请求/应答报文,而不必经过TCP/UDP的传输层。
  • ICMP回显请求/应答报文的格式:

        类型(Req=8/Ack=0)–代码(0)–校验和(16 bits)–标识符(16 bits)–序号(16 bits)–选项数据

  • ping局域网的另一台主机的输出:
root@mjxian-ubuntu ~
# ping 219.221.206.53
PING 219.221.206.53 (219.221.206.53) 56(84) bytes of data.
64 bytes from 219.221.206.53: icmp_seq=1 ttl=64 time=5.12 ms
64 bytes from 219.221.206.53: icmp_seq=2 ttl=64 time=0.727 ms
64 bytes from 219.221.206.53: icmp_seq=3 ttl=64 time=0.730 ms
64 bytes from 219.221.206.53: icmp_seq=4 ttl=64 time=0.756 ms
64 bytes from 219.221.206.53: icmp_seq=5 ttl=64 time=0.743 ms

— 219.221.206.53 ping statistics —
5 packets transmitted, 5 received, 0% packet loss, time 4016ms
rtt min/avg/max/mdev = 0.727/1.615/5.120/1.752 ms

第一个往返时间比后面的要大,一般是由于包含了局域网上arp请求与应答的时间。如果arp -a看到目标主机已经在本机的arp高速缓存上,就不用再进行arp请求。

以下是tcpdump在局域网上抓包的结果,显然是每秒发送和接收一次ICMP回显:

11:27:12.587877 arp who-has 219.221.206.53 tell ubuntu
11:27:12.588589 arp reply 219.221.206.53 is-at 00:14:78:d4:f1:43 (oui Unknown)
11:27:12.588612 IP ubuntu > 219.221.206.53: ICMP echo request, id 17432, seq 1,length 64
11:27:12.589342 IP 219.221.206.53 > ubuntu: ICMP echo reply, id 17432, seq 1,length 64
11:27:13.587972 IP ubuntu > 219.221.206.53: ICMP echo request, id 17432, seq 2,length 64
11:27:13.588667 IP 219.221.206.53 > ubuntu: ICMP echo reply, id 17432, seq 2,length 64
11:27:14.592023 IP ubuntu > 219.221.206.53: ICMP echo request, id 17432, seq 3,length 64
11:27:14.592724 IP 219.221.206.53 > ubuntu: ICMP echo reply, id 17432, seq 3,length 64
11:27:15.596088 IP ubuntu > 219.221.206.53: ICMP echo request, id 17432, seq 4,length 64
11:27:15.596814 IP 219.221.206.53 > ubuntu: ICMP echo reply, id 17432, seq 4,length 64
11:27:16.600304 IP ubuntu > 219.221.206.53: ICMP echo request, id 17432, seq 5,length 64
11:27:16.601015 IP 219.221.206.53 > ubuntu: ICMP echo reply, id 17432, seq 5,length 64
  • ping非本局域网上的一台主机的输出

例如校园网里面的www.wjl.cn,其结果如下。很显然这次第一次返回并没有很大的时间差,这是因为由于wjl.scu.edu.cn这台主机并不在局域网内,封装ICMP的IP数据报直接投递给路由,后面的事情由路由解决,看起来应该是这台机器的硬件地址已经在某台路由上的arp高速缓存里面了,省去了arp请求的一步。

root@mjxian-ubuntu ~
# ping www.wjl.cn
PING www.wjl.cn (202.115.32.129) 56(84) bytes of data.
64 bytes from wjl.scu.edu.cn (202.115.32.129): icmp_seq=1 ttl=62 time=0.368 ms
64 bytes from wjl.scu.edu.cn (202.115.32.129): icmp_seq=2 ttl=62 time=0.395 ms
64 bytes from wjl.scu.edu.cn (202.115.32.129): icmp_seq=3 ttl=62 time=0.261 ms
64 bytes from wjl.scu.edu.cn (202.115.32.129): icmp_seq=4 ttl=62 time=0.345 ms
64 bytes from wjl.scu.edu.cn (202.115.32.129): icmp_seq=5 ttl=62 time=0.324 ms
64 bytes from wjl.scu.edu.cn (202.115.32.129): icmp_seq=6 ttl=62 time=0.382 ms
64 bytes from wjl.scu.edu.cn (202.115.32.129): icmp_seq=7 ttl=62 time=0.423 ms
64 bytes from wjl.scu.edu.cn (202.115.32.129): icmp_seq=8 ttl=62 time=0.250 ms
64 bytes from wjl.scu.edu.cn (202.115.32.129): icmp_seq=9 ttl=62 time=0.428 ms

— www.wjl.cn ping statistics —
9 packets transmitted, 9 received, 0% packet loss, time 8034ms
rtt min/avg/max/mdev = 0.250/0.352/0.428/0.065 ms

这是tcpdump抓包的结果 (略):

11:36:43.053719 IP ubuntu > wjl.scu.edu.cn: ICMP echo request, id 26713, seq 1,length 64
11:36:43.054048 IP wjl.scu.edu.cn > ubuntu: ICMP echo reply, id 26713, seq 1,length 64
11:36:44.059846 IP ubuntu > wjl.scu.edu.cn: ICMP echo request, id 26713, seq 2,length 64
11:36:44.060206 IP wjl.scu.edu.cn > ubuntu: ICMP echo reply, id 26713, seq 2,length 64

ping输出的ttl是62,是由于经过了2次路由,减了2,一个简单的路由查询可以使用ping -R选项。它显示了一次请求和应答整个往返过程经过的所有路由。

  • ping -R 目标主机,显示往返所经路径。

-R选项要求返回的IP数据报的首部操作选项包含RR路由记录。这要求路由提供IP数据报的R操作R选项支持,下例中,经过的两个路由都没有显示出来,说明这些路由都不支持RR选项。

root@mjxian-ubuntu ~
# ping -R www.wjl.cn
PING www.wjl.cn (202.115.32.129) 56(124) bytes of data.
64 bytes from wjl.scu.edu.cn (202.115.32.129): icmp_seq=1 ttl=62 time=1.20 ms
RR:     ubuntu (219.221.206.48)
        wjl.scu.edu.cn (202.115.32.129)
        wjl.scu.edu.cn (202.115.32.129)
        ubuntu (219.221.206.48)

64 bytes from wjl.scu.edu.cn (202.115.32.129): icmp_seq=2 ttl=62 time=1.20 ms (same route)
64 bytes from wjl.scu.edu.cn (202.115.32.129): icmp_seq=3 ttl=62 time=1.14 ms (same route)
64 bytes from wjl.scu.edu.cn (202.115.32.129): icmp_seq=4 ttl=62 time=2.49 ms (same route)
64 bytes from wjl.scu.edu.cn (202.115.32.129): icmp_seq=5 ttl=62 time=1.09 ms (same route)
64 bytes from wjl.scu.edu.cn (202.115.32.129): icmp_seq=6 ttl=62 time=1.12 ms (same route)
64 bytes from wjl.scu.edu.cn (202.115.32.129): icmp_seq=7 ttl=62 time=1.10 ms (same route)
64 bytes from wjl.scu.edu.cn (202.115.32.129): icmp_seq=8 ttl=62 time=1.10 ms (same route)
64 bytes from wjl.scu.edu.cn (202.115.32.129): icmp_seq=9 ttl=62 time=1.07 ms (same route)

— www.wjl.cn ping statistics —
9 packets transmitted, 9 received, 0% packet loss, time 8068ms
rtt min/avg/max/mdev = 1.074/1.282/2.491/0.432 ms

使用ping -R,就是要求返回的IP数据报的首部操作选项包含RR路由记录,

  • RR操作的IP选项主要格式为
code(RR=7,1 bytes)–len(1 bytes)–ptr(1 bytes)–addr1(4 bytes per addr#)

其中ptr为addr的指针,从4开始;

addr一共最多可以记录9个,因为一个IP选项字段最多可以存放40字节。

用tcpdump -v查看的输出如下:包含了IP首部和操作选项:

12:08:05.985310 IP (tos 0×0, ttl  64, id 0, offset 0, flags [DF], proto: ICMP(1), length: 124, options ( NOP (1) len 1 )) ubuntu > mail.scu.edu.cn: ICMP echo request, id 42296, seq 1, length 64
12:08:05.986331 IP (tos 0×0, ttl  62, id 24203, offset 0, flags [none], proto: ICMP (1), length: 124, options ( RR (7) len 39ubuntu, mail.scu.edu.cn, mail.scu.edu.cn, 0.0.0.00.0.0.00.0.0.00.0.0.00.0.0.00.0.0.0EOL (0) len 1 ))mail.scu.edu.cn > ubuntu: ICMP echo reply, id 42296, seq 1, length 64

第一个为 ICMP echo request, IP首部不包含操作选项(NOP,无操作)

第二个为 ICMP echo reply,记录了路由上的主机地址,后面空的填充为0,EOL表示操作选项清单结束。

  • IP时间戳选项: 
ping -T tsonly/tsandaddr/tsprespec  host1 [host2 [host3[host4]]] 目标主机
        tsonly          选项只显示时间戳 (timestamp)
        tsandaddr       包括每个路由上的主机名和时间戳
        tsprespec       预指定要显示时间戳的路由,最多4 个。

时间戳记录为UTC时间午夜00时至今的时间,单位毫秒。


  • traceroute程序
  • traceroute是使用ICMP报文的另一个重要应用程序。它还利用了这样一个事实,就是IP数据报里面的TTL字段每经过一个路由都将自动减1,如果在路由内停留超过1秒则减去这个秒数。事实上TTL在今天已经用来作为路由计数器,每一跳减1,到为0时该IP数据报即被丢弃,然后路由返回一个 ICMP超时出错报文。

traceroute程序运行后每次往目标主机反复发送3次一个带UDP数据的IP数据报,其TTL初始值为1,收到ICMP超时报文后再发一个,然后再发3次一个TTL值为2的报文。直到抵达目的主机。而UDP数据里面的目的端口设置为不可能的UDP端口,Unix的实现一般用traceroute的 pid | 32768,这样traceroute通过查询返回的ICMP出错报文是超时还是端口不可达判断是下一跳路由或者是目的主机。

  • 下面是一个用traceroute命令查看到主机wjl.scu.edu.cn的例子。和上面ping -R wjl.scu.edu.cn 用ping来查看路由比较,会发现ping -R的输出并不包含219.221.206.62这台路由,可能是路由不支持IP操作选项的RR特性的缘故。而trceroute利用的是ICMP的出错报文,只要求路由支持ICMP和目的主机支持UDP就可以了。另外两个tracerouteping -R更好用的原因是ping -R显示的是往返路由,且其长度受IP首部所限最多只能记录9个路由。而traceroute显示的是单向路由,显示的路由数能达到TTL规范的最大值。
root@mjxian-ubuntu ~
# traceroute wjl.scu.edu.cn
traceroute to wjl.scu.edu.cn (202.115.32.129), 30 hops max, 40 byte packets
 1  219.221.206.62 (219.221.206.62)  0.992 ms  0.656 ms  0.539 ms
 2  10.10.34.2 (10.10.34.2)  0.609 ms  0.596 ms  0.482 ms
 3  wjl.scu.edu.cn (202.115.32.129)  0.548 ms  0.312 ms  0.314 ms

前面的序号,和所发送的TTL值一次,第一个值比较大,为0.992 ms,一般认为是arp交换或者向dns服务器查询域名等其它预处理的原因。可见到主机wjl.scu.edu.cn共经过了2个路由,这一点也可以从 ping的时候看到TTL为62看得出来。

  • 以下为traceroute执行时用tcpdump的抓包输出。可见主机ubuntu一直在向wjl.scu.edu.cn发送一个包括12字节数据的 UDP包,每个经过的路由都发了三次,而路由也返回三次长度为36字节的ICMP超时报文,最后是主机wjl.scu.edu.cn发送三次端口不可达报文。UDP端口是每发一次自动加1,初始值由traceroute进程的pid和32768相或得到。该进程pid可以在程序运行时通过ps -A显示出来。
16:53:25.799438 IP ubuntu.40890 > wjl.scu.edu.cn.33435: UDP, length 12
16:53:25.800050 IP 219.221.206.62 > ubuntu: ICMP time exceeded in-transit,length 36
16:53:27.391779 IP ubuntu.40890 > wjl.scu.edu.cn.33436: UDP, length 12
16:53:27.392342 IP 219.221.206.62 > ubuntu: ICMP time exceeded in-transit,length 36
16:53:27.392808 IP ubuntu.40890 > wjl.scu.edu.cn.33437: UDP, length 12
16:53:27.393262 IP 219.221.206.62 > ubuntu: ICMP time exceeded in-transit,length 36
16:53:27.394112 IP ubuntu.40890 > wjl.scu.edu.cn.33438: UDP, length 12
16:53:27.394619 IP 10.10.34.2 > ubuntu: ICMP time exceeded in-transit, length 36
16:53:28.963890 IP ubuntu.40890 > wjl.scu.edu.cn.33439: UDP, length 12
16:53:28.964418 IP 10.10.34.2 > ubuntu: ICMP time exceeded in-transit, length 36
16:53:28.964837 IP ubuntu.40890 > wjl.scu.edu.cn.33440: UDP, length 12
16:53:28.965257 IP 10.10.34.2 > ubuntu: ICMP time exceeded in-transit, length 36
16:53:28.966022 IP ubuntu.40890 > wjl.scu.edu.cn.33441: UDP, length 12
16:53:28.966489 IP wjl.scu.edu.cn > ubuntu: ICMP wjl.scu.edu.cn udp port 33441 unreachable, length 48
16:53:28.967881 IP ubuntu.40890 > wjl.scu.edu.cn.33442: UDP, length 12
16:53:28.968127 IP wjl.scu.edu.cn > ubuntu: ICMP wjl.scu.edu.cn udp port 33442 unreachable, length 48
16:53:28.968541 IP ubuntu.40890 > wjl.scu.edu.cn.33443: UDP, length 12
16:53:28.968792 IP wjl.scu.edu.cn > ubuntu: ICMP wjl.scu.edu.cn udp port 33443 unreachable, length 48
  • traceroute-g -G选项

-g-G选项为自定义源站选路的选项,traceroute命令必须经过该选项指定的路由,其中-G严格指定了要经过的全部路由顺序,-g只指定必须要经过的路由顺序。

我机器上的traceroute的版本为1.4a12,从源代码来看已经取消了-G选项。

-g选项一个有用的应用是可以查看到某主机往返的路由是否一致,只需把目的主机设为-g指定的主机,把发出主机设为tracert的最终主机。这时 traceroute就先查找从发出主机srchost到dsthost的路由,再查找dsthost到srchost的路由。完成一次从 localhost到dsthost的往返。

traceroute -g dsthost srchost


  • IP网际协议:

负责数据报从源地址传给目的地址,提供的是非可靠、无连接的传送服务,所有可靠性和包装需要通过上层协议如TCP来提供。

  • IP首部格式:

每32 bits一组,共5组(20个字节)

第一组:

Version(4 bits)–HeadLength(4 bits)–TOS(8 bits)–TotalLength(16 bits)
  IPv4/IPv6     一般为5(按32位计算)              IP包总长(<65535 bytes)

TOS字段包括:   

优先级(3位,现代已经忽略)–0(未用)–TOS 值

        TOS值1位置1,3位置0,分别表示:

0×10(最小时延) 0×08(最大吞吐量) 0×04(最高可靠性) 0×02(最小费用)

现在大多数应用程序都不支持TOS特性。

第二组:

标识(16 bits)–标志(3 bits)–片偏移(13 bits)

第三组:

TTL(8 bits)–Protocol(8 bits)–Head Sum (16 bits)
        32/64        TCP/UDP/ICMP

首部校验和的算法:首部校验和位置零,20个字节全部取反码,每16位一组求和。

计算校验和的技术见RFC 1071,接收方计算结果如果不是全1,则认为传输出错。

第四组:源IP地址;

第五组:目的IP地址。

  • IP路由选择:    通过路由表。

路由类型:     

目标主机 > 目标网络 > 默认下一个路由 (转发数据的优先级)

在IP数据报传输中,32位的IP地址始终不变,而链路层的数据封装格式和48位的以太网地址由链路层协议确定,每站路由都可能会发生改变,其中封装格式有以太网/SLIP/PPP等(见链路层相关笔记),以太网地址为下一个路由的以太网地址。

  • A类地址、B类地址、C类地址的概念。子网的划分。
子网地址 = IP地址 <and> 子网掩码
广播地址 = 子网地址 <or> !子网掩码
  • 查看接口IP地址、子网掩码、广播地址、MTU的命令:netstatifconfig 等。

  • ARP地址解析协议:

用于在32位的IP地址与对应的硬件地址(以太网地址)之间建立映射。内核(如以太网驱动程序)必须知道硬件地址才能发送数据。

  • 发送IP数据报前,先广播发送一个ARP请求的数据帧,以获得ARP应答,应答包含目的IP地址及其硬件地址。
  • 点对点链路只需要知道两端的IP地址,不涉及硬件地址,不需要 ARP;
  • ARP的帧格式(42字节,其中前14个字节为以太网数据帧的首部):
以太网目的地址(6字节)–以太网源地址(6字节)–帧类型(2字节)–硬件地址类型(2字节)–协议类型(2字节)–硬件地址长度(1字节)
–协议地址长度(1字节)–操作类型(2字节)–发送端以太网地址(6字节)–发送端IP地址(4字节)–目的以太网地址(6字节)–目的 IP地址(4字节)

硬件地址类型:为1表示为以太网地址;

协议类型:为0×8000表示为IP协议(和以太网数据帧的首部帧类型相同定义);

硬件地址长度:以太网地址的值为 6;

协议地址长度:IP地址为 4;

操作类型:1: ARP请求;2: ARP应答;3: RARP请求;4: RARP应答。

发送端、目的以太网地址与以太网帧的首部12个字节相同,而目的以太网地址在发出ARP请求时所有位置1,表示为广播地址。

  • ARP代理(proxy ARP):

通过路由应答不同网络上的ARP请求,把路由的以太网地址发送给源主机。源主机端认为该路由的以太网地址就是所求地址,从而开始向该路由器发送IP数据报。

  • 免费ARP(gratuitous ARP):

发送自己IP地址的ARP请求。用于确定是否和别的主机产生IP冲突,或者用于更新网络上其他主机的相应的ARP高速缓存。

  • ARP相关命令:
$ arp -a                        查看ARP高速缓存;
$ arp -d [host]                 在ARP高速缓存中删除指定项;
$ arp -s [host] [hwaddr]        在ARP高速缓存中增减指定项。
  • tcpdump命令所监听到的ARP查询和应答一例:
11:44:33.865795 arp who-has 219.221.206.62 tell ubuntu
11:44:33.866219 arp reply 219.221.206.62 is-at 00:09:97:07:d6:06 (oui Unknown)

第一行发出广播,查询IP地址219.206.62的以太网地址,并要求返回给主机 ubuntu

第二行收到应答。

附:     水木社区关于ARP的讨论的一个小结。

发信人: cheyo (cheyo), 信区: Networking
标  题: Re: 请教ARP:当目标主机与源主机不在同一网段时
发信站: 水木社区 (Tue Jan 10 00:25:13 2006), 转信

嗯。改了一下下:

    在底层网络中,两台主机之间的通信需要知道源主机与目标主机的Mac地址。ARP缓存
表记录了本网段中IP地址与Mac地址的映射关系。
    当源主机与目标主机处在同一网段时,源主机首先查询本机的ARP缓存表,如果在该
表中可以查询到目标主机的Mac地址,则直接发送数据,否则源主机向同一网段的所有节
点发送广播,同一网段的所有主机都会接收到该广播,但只有目标主机会响应并告知源主
机其Mac地址。于是源主机把目标主机的IP与Mac地址记录到ARP缓存表中,并通过该Mac地
址发送数据。
    如果源主机与目标主机不在同一网段,则源主机在本机路由表中查询源主机到达目标
网络需要通过哪一个网关,然后与"源主机与目标主机处在同一网段"类似的,源主机先取
得该网关的Mac地址,然后本地主机将数据帧提交给网关。之后,由网关判断下一跳的主机
地址或者网络地址。


  • RARP    用于无盘系统/工作站在引导时获取IP地址。分组格式和ARP一致。

  • 链路层的功能:
  1. 为IP模块发送和接收IP数据报;
  2. 为ARP模块发送ARP请求和接收ARP应答;
  3. 为RARP发送RARP请求和接收RARP应答
  • 以太网IP数据报的封装定义在RFC 894中。
  • IP地址(32位)通过ARP映射到以太网地址(48位);
  • 以太网帧格式:
dest(6 bytes)–src(6 bytes)–type(2 bytes)–data(46~1500 bytes)–CRC(4 bytes)
 48 bits        48 bits       0800 (IP)
                              0806 (ARP)  28 bytes (R/A)-18 bytes(PAD)
                              8035 (RARP) as above
  • SLIP (串行线路IP,电话拨号等串行数据传输时使用):

END-数据-END        如果数据里含END,需要转义。

  • PPP(点对点协议),包括
1)串行线路上封装IP数据报的方法;              
                                                 RFC 1548
2)建立、配置、测试数据链路的链路控制协议LCP;  /
3)针对不同网络层协议的网络控制协议 NCP;       —RFC 1332

PPP数据侦格式(十六进制,两位表示一个字节):

标志(7E)–地址(FF)–控制(03)–协议(2字节)–信息(<1500字节)–CRC(2字节)-标志(7E)
                              0021 (IP)
                              c021 (LC)
                              8021 (NC)

信息段如果含0x7e(标志字段的值),需要转义,转义字符为0x7d,同时原值第六位取补码。如

0x7e –> 0x7d + 0x5e
0x7d –> 0x7d + 0x5d

原则上<0×20的值(ASCII控制字符之类)都要进行转义。

  • 环回接口(127.0.0.1 localhost):用于同一台主机上C/S的TCP/IP通信,
  • MTU最大传输单元:链路层的数据侦长度上限,各种网络的典型MTU值见RFC 1191
  • 路径MTU:两台通信主机路径中的最小MTU,由于取决于所选路由,故不是常数。

RFC1191描述了路径MTU的发现机制,即在任何时候确定路径MTU的方法。

  • $ netstat -i    查看主机接口及其MTU

与我崇拜的人生活一天 | 2006年09月23日

高中时候写的作文……结果没过半年又接触了大量反英雄的音乐小说影视等。但是切一直依然是我心中比耶酥还要尊贵的圣人,从来没想过去亵渎恶搞他的形象。

=====================================

丛林。

一阵密集的枪声把我从睡梦中惊醒。我揉揉眼睛,想明白一下发生了什么事。

几个身穿迷彩服的士兵拿着枪慌慌张张跑过来冲我大喊:"嘿,你!还不快去保护切·格瓦拉!美国鬼子就要攻过来了!"

"天,切·格瓦拉!"我全身蓦地涌起一股热血。我从树上跳下,紧紧抓住手中的枪,往林中那若隐若现的营房奔去。

弟兄们已经整整齐齐的集合在营房前,一个身穿迷彩服,头戴贝雷帽,留着一脸小胡子的彪悍中年人正在训话:"由于可耻的叛徒出卖,我们这支 游击队的行踪已经被美国人发现了。现在不得不进行战略转移,今天我们必须向南行军。你,"他用手一指我,"带领几个弟兄,随我从丛林东部撤出,而你, 安……"他一脸冷峻的进行着作战部署。

我忍不住又是一阵热血沸腾。我今天,要跟着我们的英雄–切·格瓦拉战斗一天,而我的任务,正是保护他走出敌人的包围圈,走出这次危机。

南美的丛林怪木林立,毒虫猛兽层出不绝。我们这两年来转战于这些穷山恶水之间,不仅要和严酷的自然环境作斗争,而且要和更为严酷的敌人斗 争。显然,这些险恶的环境并没有使格瓦拉刚毅的神情有丝毫动摇。他一边迈着大步,一边神采飞扬地跟我们侃着:"哎,小伙子们,我们的艰苦生活看来要到头 啦。美帝又发生了经济危机,那可是资本主义的不治之症。嘿嘿,过不了几年……"他得意洋洋的唱出了《国际歌》。

我们都被这位英雄感染了。切·格瓦拉,不仅仅是古巴的革命英雄,更是美洲人民的英雄,世界人民的英雄。早在古巴革命时期,他就和领袖卡斯 特罗一期出生入死共同推翻了反动政府并挫败了美帝国主义的阴谋;他在联合国大会上慷慨激昂大义凛然痛斥美帝的讲话至今令我们津津乐道;而今天,在"全世界 无产者,联合起来!"的号召下他又放弃已有的荣誉和地位,义无反顾地投身南美的革命事业。他是一个战斗到生命最后一刻的战士!我们也都情不自禁地跟着吟 唱:"……英特纳雄耐尔就一定要实现!"密林深处,到处是我们的豪情。

敌人好像从地下冒出一样,把我们密密麻麻包围了。我们非常震惊,要知道这是一条非常隐蔽的小路,甚至比后来的"胡志明小道"还要隐蔽,只 有党内少数高级将领才能通晓。一个美国鬼子军官走出来,狞笑着说:"哼哼,只要出足够的钱,人的灵魂是可以收买的。什么革命理想,别做梦了!哇哈哈 哈……!"他满脸的肥肉不停的抖动。一刹那间,我看到格瓦拉的眼睛充满怒火。

中午,我们被带到一个监狱。而我和格瓦拉同一个牢房。

我的身子因愤怒不住颤抖,格瓦拉走过来,按着我的肩膀,微笑着说:"第一次坐牢吗?小伙子。害怕吗?"我咬着牙说:"切,金钱,真的可以 收买一个人的理想,甚至灵魂?!"他叹一口气说:"小伙子,人心很难料。帝国主义忘我之心不死,可是,不要灰心,胜利的一天是会到来的!"他紧紧盯着我, 眼神依然充满坚定。

牢门被打开了,几个鬼子冲进来紧紧按住格瓦拉。我怒火中烧,大喝:"你们要干什么!"鬼子军官说:"林登·约翰逊总统得知捉到了格瓦拉, 非常高兴。亲笔签下命令,就地处决,以绝后患。"我疯了样的扑上去,被营养充足的美国鬼子一脚踹倒。我最后听见英雄的声音:"小伙子,别灰心。继续革命! "

……

三十年过去了,切·格瓦拉的遗骨终于被发现,古巴人民给他举行了国葬。

今天,我在一个绝对安全的地方怀念着那场革命。脑海里浮现起他那坚定的眼神和同样坚定的话语:"继续革命!"


vim命令 | 2006年09月22日

注:前缀’:'表示vim命令(命令模式),前缀’$'表示为shell命令,<C-W>表示Ctrl + W,<C-Sh-6>表示 Ctrl + Shift+ 6,无前缀者均为普通模式下的键盘按键。

基本的插入与修改:

a        光标下一个字符处插入;
i        在当前光标处插入;
A        行尾插入;
o        在光标下新建一行插入;
O        在光标上新建一行插入;
p        在光标之后粘贴;
P        在光标之前粘贴;
r        键入替换一个字符;
R        键入替换所有字符;
x        删除光标所在处的字符;
`.       光标定位到上一次修改处;
u        Undo
<C- R>   Redo
:e!      撤销所有修改。

文件查找与替换:

*, #             向前/后查找相同单词(如果打开set hlsearch,则自动高亮所有匹配单词)
/dest            按n查找下一个;N查找上一个;
?dest            反向查找;
:#,#s/old /new/g 把几行之间的old全部替换成new
:%s/old /new/g   整个文件全局替换,old -> new;
:s/old /new      只替换下一个匹配的字符串
:s/old /new/g    替换一行的 old -> new;

文件光标定位:

%                括号配对
ctrl + g         显示当前行号
linenum + G      跳至某行
w                跳到下一个单词处
G                跳至末行
H                跳至首行
^                跳至行首
$                跳至行尾
fx Fx            移动到下一个/上一个x开头的单词
[[               跳至上一个在第一列的{ (一般是函数的开头)
]]               跳至下一个在第一列的{
{                跳至上一个空行
}                跳至下一个空行
gd               光标定位在某个局部变量上时,跳到它的定义处;

使用cscope时,在源文件顶层运行

cscope-indexer

生成cscope的tags, 然后使用<C-]>查找各种数据类型的定义,再使用<C-o>回到光标原来的位置.

shell:

:!cmdname        临时使用shell命令cmdname
:sh              暂时回到shell(exit回到vim编辑界面)

多文件操作:

$ vi file1 file2         一次性读入多个文件(支持shell的所有通配符)
:sp file                 从一个新的水平分割窗口中打开文件file
:vd file                 从一个新的垂直分隔窗口中打开文件file
:n、:N                   当前窗口进行文件间切换
<C- Sh- 6>               当前窗口在两个文件之间切换
:Sex                     在新的分割窗口中打开目录流览器
:ls                      列出当前在编辑的文件
:b x                     当前窗口跳到第x个文件buffer(:ls列出序号)
:b file                  当前窗口跳到下一个文件名包含"file"的文件buffer
<C-W>+<C-W>              多窗口中快速切换(ctrl + w两次)

其它: 

<C-N><C-P>               插入模式中,用于语法的单词/结构自动补全
=                        可视模式下,可用于根据语法自动缩进文本格式

常用设置:

1
cp /usr/share/vim/vim70/vimrc_example.vim ~/.vimrc
:set hlsearch 高亮显示/与?命令查找结果;
:set num 显示每行行号

Fterm 登录时如果要使用vi的语法彩色,需要把termtype设置为xterm- color,或者

1
export TERM=xterm-color

应该也可以……


九月末 | 2006年09月21日

夏天已经过去,成都盛夏时的暑气早已无影无踪。对于未知的新生活,我依然没有任何准备。

我的书籍资料、我的音乐、我的电脑、我的衣服、我的工作、理想、爱情、朋友。我过去的那么多宝贵的积累和经验。需要的时候,它们都不在我的身边。

都是我自己选择的,一切都是前因后果。世事无常,何必执著。

从群山到大海,从大海又退回山里。结果不过是一次次重复的循环。每个人的一生,都是一次远行。就像这天边的夕阳如血,不停燃烧又熄灭。那么,下一站又将是哪里呢?


关了灯听泰坦尼克的OST | 2006年09月14日

这是我有生以来听的第一张电影原声,专辑里面的每个音符都很自然的塞满了自己少年时代青涩的记忆。

每次听起来心里面都会很安详,会有很多很远很远的东西慢慢的爬将上来,在我眼前看不到的空间随着烟雾不断回转。例如被初春夜里的小雨润湿的石子铺成的中学门前的那条街道。


Midnight Mountain | 2006年09月05日

the Cathedral (大教堂)的著名金曲。有意思的是这首歌除了歌词和主唱的唱腔以外几乎没有什么厄运味道。相反让我想起80年代那些流行于欧美世界的Hair Metal,潇洒的吉他Riff,迪斯科节奏的打击鼓点,中间还来了一小段在给Joe Satriani致敬一般的Solo。the Ethereal Mirror这张碟整张听起来有意思要多一些,各曲目从演奏风格上并不是很统一,而且长度从8分多到1分钟的都有。贯穿整张专辑的是一直低沉扭曲加失真的音色和恶狠狠充满诅咒的咆哮的主唱声线,让人仿佛看到一副矛盾重重阴沉沉的充斥各种魔鬼、侏儒、恶棍、领主、商人、农夫的末世主题油画。加上最后一曲木吉他小品Imprisoned in Flesh,放在那里的感觉就象魔鬼们完成了一次人间的混乱的制造,正在黑暗城堡里面对着外面阴霾的天空微笑。