11.7 Request Processing ICMP requests may be generated by process using raw ip socket. Properly formatted request is responded to at L3. E.g. ping request reply from L3 Echo query: icmp_echo and icmp_echoreply "ping" based on app name, but ICMP actually has icmp_echo/icmp_echoreply messages ping named after sonar/ping idea, not packet inet groper Figure 11.20 form of ping icmp_code is 0 note icmp_id, icmp_seq, data icmp_id on unix is process id of ping sending packet, as all pings received are sent upstairs to all pinging processes ... there is no pcb ... (not UDP ...) Figure 11.21 icmp_input: case ICMP_ECHO type set to reply goto reflect; reflect: call icmp_reflect function ... use same mbuf Timestamp query: ICMP_TSTAMP and ICMP_TSTAMREPLY sender sets icmp_otime - originate time icmp_rtime, icmp_ttime set by reply box All times are in milliseconds since midnight UTC. high-order bit set if time value is nonstandard ("good luck" bit) Figure 11.23 call iptime() to get time ... and bail on ttime/rtime bsd kernel gets kernel idea of time in struct timeval and manipulates it to set rtime/ttime. rtime ... message may have set on input queue modify all device drivers? ttime ... message may sit in send queue modify all device drivers? Address Mask Query: ICMP_MASKREQ and ICMP_MASKREPLY in theory, a host sends this to a router on the same subnet. send to broadcast ... sysctl -a: net.inet.icmp.maskrepl: 0 select subnet mask if request mask is 0.0.0.0 or 255.255.255.255 ip_src is saved in icmpdst use ifaof_ifpforaddr to locate the address structure line 262: retain ptr to ip_dst as ip_src may be useless ia ... figure out input address acc. to i/f set mask based on input interface ip addr line 271: if src was 0 (boot) ip_src set to broadcast addr else ip_src set to us .. INFO QUERY: learn network ... obsolete Router Discovery: passed to rip_input as managed by daemon. routed(8), or rdisc(8) does this in BSD. in IPv6 this mechanism not only exists but can be said to be extended to take over arp functionality. this may be the biggest feature in ipv6. /etc/defaults/rc.conf: rtadvd_enable="NO" # Set to YES to enable an IPv6 router # advertisement daemon. If set to YES, # this router becomes a possible candidate # IPv6 default router for local subnets. rtadvd_interfaces="" # Interfaces rtadvd sends RA packets. So rtadvd(8) And ndp(8) for arp(8) ------------------------------------------------------------------------ 11.8 Redirect Processing icmp_gwaddr - preferred gateway ip as input, this means we must make routing table change Figure 11.26 set icmpgw.sin_addr to input ip src, of gateway that sent message icmpdst to desired gateway icmpsrc to ip_dst included as data (desired dst for route) call rtredirect to set host route net/3 never sends net redirects (can be wrong in terms of netmasks, since it doesn't have that info) update routes pfctlinput tells any protocols that need to know about the routing table change can invalidate route caches 11.9 reply processing As requests are generated by processes, kernel does not process the replies, but passes them upstairs. ... rip_input as in Figure 11.28 11.10 Output processing Figure 11.29 icmp output processing icmp_error may be called by ip/transports icmp_reflect used to send ICMP replies icmp_send called for last step process may form own icmp messages and send via raw socket 11.11 icmp_error Figure 11.30 icmp_error/validation arguments: n - mbuf chain containing invalid datagram type/code dest - next-hop router for icmp redirect destifp - which interface to send from desire to avoid broadcast storms in errors don't send it if: fragment already an error (no errors about errors) datagram was broadcast or multicast (no icmp) fails to check for: datagram sent to ip broadcast or multicast if datagram's src is not unicast ... handled by icmp_reflect function it is ok to respond to a request that way though ping broadcast response uses unicast src Figure 11.31, icmp error packet structure Figure 11.32 icmp error message header construction note: alignment done here, but not data copy m_gethdr - get hdr mbuf Figure 11.33, including original datagram copy data to back adjust mbuf copy data to front call icmp_reflect 11.12 icmp_reflect sends replies/errors back to the src of the request or offender icmp_reflect REVERSES ip_src and ip_dst Figure 11.34: icmp discard/address summary icmp_input: ip_src 0.0.0.0 with recv.if src or broadcast icmp_error: discard if link-level broadcast or multicast icmp_reflect: discard if multicast dst or class E convert nonunicast ip_dst to recv. i/f unicast ip swap src/dst ip_output discard outgoing broadcasts for icmp if input sent to broadcast address Figure 11:35 if we can't forward it, and/or loopback burn it store ip_dst set ip_dst to ip_src figure out ip_dst match our ips to see if unicast ip match if broadcast match if ia is null (no match) search on icmpdst ... if ia is still null take the 1st one !!! set ip_src and ttl Figure 11.36: option construction we SKIP THIS! 11.13 icmp_send function Figure 11.39 note moving of mbuf apparatus to hide ip hdr checksum is not computed over IP header icmp does not have route cache (tcp does) IP_ALLOWBROADCAST is NOT passed ... in flags, therefore ip_output does not allow it this does not mean icmp cannot generate broadcasts it can if icmp request ... 11.14 icmp_systcl icmp_maskrepl at time net.inet.icmp.maskrepl: 0 net.inet.icmp.icmplim: 200 limit icmp echo replies to N per second, -1 to turnoff dos limiter in theory net.inet.icmp.drop_redirect: 0 net.inet.icmp.log_redirect: 0 net.inet.icmp.icmplim_output: 1 ok for bandwidth limiter to printf net.inet.icmp.bmcastecho: 0 don't respond to broadcast ping (off) net.inet6.icmp6.rediraccept: 1 net.inet6.icmp6.redirtimeout: 600 net.inet6.icmp6.nd6_prune: 1 net.inet6.icmp6.nd6_delay: 5 net.inet6.icmp6.nd6_umaxtries: 3 net.inet6.icmp6.nd6_mmaxtries: 3 net.inet6.icmp6.nd6_useloopback: 1 net.inet6.icmp6.nodeinfo: 3 net.inet6.icmp6.errppslimit: 100 net.inet6.icmp6.nd6_maxnudhint: 0 net.inet6.icmp6.nd6_debug: 0 Note how icmpv6 gives us a whole raft of esoteric things to learn (sigh?)