Tuesday, October 27, 2009

32.5 rip_input Function

Team-Fly
 

 

TCP/IP Illustrated, Volume 2: The Implementation
By
Gary R. Wright, W. Richard Stevens
Table of Contents
Chapter 32. 
Raw IP


32.5 rip_input Function


Since all entries in the ip_protox array for unknown protocols are set to point to the entry for IPPROTO_RAW (Section 7.8), and since the pr_input function for this protocol is rip_input (Figure 32.6), this function is called for all IP datagrams that have a protocol value that the kernel doesn't recognize. But from Figure 32.2 we see that both ICMP and IGMP also call rip_input. This happens under the following conditions:


  • icmp_input calls rip_input for all unknown ICMP message types and for all ICMP messages that are not reflected.

  • igmp_input calls rip_input for all IGMP packets.


One reason for calling rip_input in these two cases is to allow a process with a raw socket to handle new ICMP and IGMP messages that might not be supported by the kernel.


Figure 32.8 shows the rip_input function.



Figure 32.8. rip_input function.


Save source IP address


59-66

The source address from the IP datagram is put into the global variable ripsrc, which becomes an argument to sbappendaddr whenever a matching PCB is found. Unlike UDP, there is no concept of a port number with raw IP, so the sin_port field in the sockaddr_in structure is always 0.



Search all raw IP PCBs for one or more matching entries


67-88

Raw IP handles its list of PCBs differently from UDP and TCP. We saw that these two protocols maintain a pointer to the PCB for the most recently received datagram (a one-behind cache) and call the generic function in_pcblookup to search for a single "best" match when the received datagram does not equal the cache entry. Raw IP has completely different criteria for a matching PCB, so it searches the PCB list itself. in_pcblookup cannot be used because a raw IP datagram can be delivered to multiple sockets, so every PCB on the raw PCB list must be scanned. This is similar to UDP's handling of a received datagram destined for a broadcast or multicast address (Figure 23.26).



Compare protocols


68-69

If the protocol field in the PCB is nonzero, and if it doesn't match the protocol field in the IP header, the PCB is ignored. This implies that a raw socket with a protocol value of 0 (the third argument to socket) can match any received raw IP datagram.



Compare local and foreign IP addresses


70-75

If the local address in the PCB is nonzero, and if it doesn't match the destination IP address in the IP header, the PCB is ignored. If the foreign address in the PCB is nonzero, and if it doesn't match the source IP address in the IP header, the PCB is ignored.


These three tests imply that a process can create a raw socket with a protocol of 0, not bind a local address, and not connect to a foreign address, and the process receives all datagrams processed by rip_input.



Lines 71 and 74 both contain the same bug: the test for equality should be a test for inequality.




Pass copy of received datagram to processes


76-94

sbappendaddr passes a copy of the received datagram to the process. The use of the variable last is similar to what we saw in Figure 23.26: since sbappendaddr releases the mbuf after placing it onto the appropriate queue, if more than one process receives a copy of the datagram, rip_input must make a copy by calling m_copy. But if only one process receives the datagram, there's no need to make a copy.



Undeliverable datagram


95-99

If no matching sockets are found for the datagram, the mbuf is released, ips_noproto is incremented, and ips_delivered is decremented. This latter counter was incremented by IP just before calling the rip_input (Figure 8.15). It must be decremented so that the two SNMP counters, ipInDiscards and ipInDelivers (Figure 8.6) are correct, since the datagram was not really delivered to a transport layer.



At the beginning of this section we mentioned that icmp_input calls rip_input for unknown message types and for messages that are not reflected. This means that the receipt of an ICMP host unreachable causes ips_noproto to be incremented if there are no raw listeners whose PCB is matched by rip_input. That's one reason this counter has such a large value in Figure 8.5. The description of this counter as being "unknown or unsupported protocols" is not entirely accurate.


Net/3 does not generate an ICMP destination unreachable message with code 2 (protocol unreachable) when an IP datagram is received with a protocol field that is not handled by either the kernel or some process through a raw socket. RFC 1122 says an implementation should generate this ICMP error. (See Exercise 32.4.)






    Team-Fly
     

     
    Top
     


    No comments:

    Post a Comment