09.05. ICMP virzienmaiņas kļūdas

Last modified by Valdis Vītoliņš on 2018/01/15 21:44

09.05. ICMP virzienmaiņas kļūdas

ICMP virzienmaiņas kļūdu sūta maršrutētājs IP datagrammas nosūtītājam, ja datagrammu bija vajadzējis sūtīt uz citu maršrutētāju. Šī pieeja ir vienkārša, kā mēs parādīsim #picref("f_9_3.gif", "9.3.attēla") trīs soļos. Vienīgā reize, kad mēs redzēsim ICMP virzienmaiņu, ir tad, ja mītnei ir iespēja izvēlēties maršrutētāju, kuram nosūtīt paketi. (Atcerēsimies, ka agrāku piemēru redzējām #picref("f_7_6.gif", "7.6.attēlā").)

#pic("f_9_3.gif", "500") 9.3.attēls: ICMP virzienmaiņas piemērs

  1. Pieņemam, ka mītne sūta IP datagrammu uz R1. Šis maršrutēšanas lēmums bieži tiek izdarīts, jo R1 ir noklusētais maršrutētājs mītnei.
  2. R1 saņem datagrammu un veic meklējumu tās maršrutēšanas tabulā un nosaka, ka R2 ir pareizais nākamā lēciena maršrutētājs, kuram nosūtīt datagrammu. Nosūtot datagrammu uz R2, R1 konstatē, ka tas nosūta datagrammu pa to pašu interfeisu, pa kuru datagramma atnāca (t.i. uz LAN'u, kuram ir pievienota mītne un šie divi maršrutētāji.) Tā ir norāde maršrutētājam, ka paketi nosūtījušo mītni var informēt par virzienmaiņu.
  3. R1 nosūta ICMP virzienmaiņu mītnei, sakot tai sūtīt turpmākās datagrammas ar to pašu adresātu uz maršrutētāju R2, nevis R1.

    Izplatīts virzienmaiņas lietojums ir ļaut mītnei ar minimālām zināšanām par maršrutēšanu, pamazām veidot labāku maršrutēšanas tabulu. Mītne var sākt ar noklusēto maršrutu (vai nu R1 vai R2 mūsu piemērā #picref("f_9_3.gif","9.3.attēlā")), un ikreiz, kad noklusētā vērtība izrādās aplama, noklusētais maršrutētājs to informēs ar virzienmaiņas ziņojumu, ļaujot mītnei attiecīgi labot savu maršrutēšanas tabulu. ICMP virzienmaiņas ļauj TCP/IP mītnēm būt maršrutēšanā neinformētām, kamēr visa izpratne par to atrodas maršrutētājos. Acīmredzot, R1 un R2 mūsu piemērā ir jāzina vairāk par pievienoto tīklu topoloģiju, bet visas mītnes šajā LANā var sākt visu darīt ar noklusēto maršrutu un iemācīties jaunus maršrutus, saņemot virzienmaiņas.

Piemērs

We can see ICMP redirects in action on our network (inside front cover). Although we show only three hosts (aix, solaris, and gemini) and two routers (gateway and netb) on the top network, there are more than 150 hosts and 10 other routers on this network. Most of the hosts specify gateway as the default router, since it provides access to the Internet.

How is the author's subnet (the bottom four hosts in the figure) accessed from the hosts on the 140.252.1 subnet? First recall that if only a single host is at the end of the SLIP link, proxy ARP is used (Section 4.6). This means nothing special is required for hosts on the top network (140.252.1) to access the host sun (140.252.1.29). The proxy ARP software in netb handles this.

When a network is at the other end of the SLIP link, however, routing becomes involved. One solution is for every host and router to know that the router netb is the gateway for the network 140.252.13. This could be done by either a static route in each host's routing table, or by running a routing daemon in each host. A simpler way (and the method actually used) is to utilize ICMP redirects.

Let's run the ping program from the host solaris on the top network to the host bsdi (140.252.13.35) on the bottom network. Since the subnet IDs are different, proxy ARP can't be used. Assuming a static route has not been installed, the first packet sent will use the default route to the router gateway. Here is the routing table before we run ping:

solaris % netstat -rn
Routing Table:
Destination  Gateway  Flags  Ref  Use  
Interface
127.0.0.1
140.252.1.0
224.0.0.0
default  127.0.0.1
140.252.1.32
140.252.1.32
140.252.1.4  UH
U
U
UG  0
3
3
0  848
15042
0
5747  lo0
le0
le0

(The entry for 224.0.0.0 is for IP multicasting. We describe it in Chapter 12.) If we specify the -v option to ping, we'll see any ICMP messages received by the host. We need to specify this to see the redirect message that's sent.

solaris % ping -sv bsdi
PING bsdi: 56 data bytes
ICMP Host redirect from gateway gateway (140.252.1.4)
to netb (140.252.1.183) for bsdi (140.252.13.35)
64 bytes from bsdi (140.252.13.35): icmp_seq=0. time=383. Ms
64 bytes from bsdi (140.252.13.35): icmp_seq=l. time=364. Ms
64 bytes from bsdi (140.252.13.35): icmp_seq=2. time=353. Ms
^? type interrupt key to stop
bsdi PING Statistics
4 packets transmitted, 3 packets received, 25% packet loss
round-trip (ms) min/avg/max = 353/366/383

Before we receive the first ping response, the host receives an ICMP redirect from the default router gateway. If we then look at the routing table, we'll see that the new route to the host bsdi has been inserted. (This new entry is shown in a bolder font.)

Solaris % netstat -rn
Routing Table:
Destination  Gateway  Flags  Ref Use  Interface
127.0.0.1
140.252.13.35
140.252.1.0
224.0.0.0
default  127.0.0.1
140.252.1.183
140.252.1.32
140.252.1.32
140.252.1.4  UH
HGHD
U
U
UG  0
0
3
3
0  848
2
15045
0
5747  lo0

le0 le0

This is the first time we've seen the D flag, which means the route was installed by an ICMP redirect. The G flag means it's an indirect route to a gateway (netb), and the H flag means it's a host route (as we expect), not a network route.

Since this is a host route, added by a host redirect, it handles only the host bsdi. If we then access the host svr4, another redirect is generated, creating another host route. Similarly, accessing the host slip creates another host route. The point here is that each redirect is for a single host, causing a host route to be added. All three hosts on the author's subnet (bsdi, svr4, and slip) could also be handled by a single network route pointing to the router sun. But ICMP redirects create host routes, not network routes, because the router generating the redirect in this example (gateway) has no knowledge of the subnet structure on the 140.252.13 network.

Citas nianses

#picref("f_9_4.gif", "9.4.attēls") parāda ICMP virzienmaiņas ziņojuma formātu.

#pic("f_9_4.gif", "500") 9.4.attēls: ICMP virzienmaiņas ziņojums

Ir pavisam četri dažādi virzienmaiņas ziņojumu veidi ar dažādām koda vērtībām, kā parādīts #picref("f_9_5.gif", "9.5.attēlā").

#pic("f_9_5.gif", "350") 9.5.attēls: Dažādas koda vērtības ICMP virzienmaiņai

There are three IP addresses that the receiver of an ICMP redirect must look at: (1) the IP address that caused the redirect (which is in the IP header returned as the data portion of the ICMP redirect), (2) the IP address of the router that sent the redirect (which is the source IP address of the IP datagram containing the redirect), and (3) the IP address of the router that should be used (which is in bytes 4-7 of the ICMP message).

There are numerous rules about ICMP redirects. First, redirects are generated only by routers, not by hosts. Also, redirects are intended to be used by hosts, not routers. It is assumed that routers participate in a routing protocol with other routers, and the routing protocol should obviate the need for redirects. (This means that in Figure 9.1 the routing table should be updated by either a routing daemon or redirects, but not by both.)

4.4BSD, when acting as a router, performs the following checks, all of which must be true before an ICMP redirect is generated.

  1. The outgoing interface must equal the incoming interface.
  2. The route being used for the outgoing datagram must not have been created or modified by an ICMP redirect, and must not be the router's default route.
  3. The datagram must not be source routed.
  4. The kernel must be configured to send redirects.

    The kernel variable is named ip_sendredirects, or something similar. (See Appendix E.) Most current systems (4.4BSD, SunOS 4.1.x, Solaris 2.x, and AIX 3.2.2, for example) enable this variable by default. Other systems such as SVR4 disable it by default.

    Additionally, a 4.4BSD host that receives an ICMP redirect performs some checks before modifying its routing table. These are to prevent a misbehaving router or host, or a malicious user, from incorrectly modifying a system's routing table.

  1. The new router must be on a directly connected network.
  2. The redirect must be from the current router for that destination.
  3. The redirect cannot tell the host to use itself as the router.
  4. The route that's being modified must be an indirect route.

    Mūsu pēdējais novērojums par virzienmaiņām ir tāds, ka maršrutētājiem ir jāsūta vienīgi mītņu virzienmaiņas (kodi 1 vai 3 no #picref("f_9_5.gif", "9.5.attēla")), nevis tīklu virzienmaiņas. Apakštīklošanās dēļ ir grūti precīzi norādīt, kad var sūtīt tīkla virzienmaiņu, nevis mītnes virzienmaiņu. Dažas mītnes uztver tīkla virzienmaiņu kā mītnes virzienmaiņu, gadījumam, ja maršrutētājs ir atsūtījis aplamu tipu.