patch-1.3.15 linux/net/ipv4/icmp.c
Next file: linux/net/ipv4/ip.c
Previous file: linux/net/ipv4/arp.c
Back to the patch index
Back to the overall index
- Lines: 205
- Date:
Mon Jul 31 18:51:58 1995
- Orig file:
v1.3.14/linux/net/ipv4/icmp.c
- Orig date:
Thu Jul 13 16:20:21 1995
diff -u --recursive --new-file v1.3.14/linux/net/ipv4/icmp.c linux/net/ipv4/icmp.c
@@ -34,6 +34,7 @@
* Alan Cox : Tightened even more.
* Arnt Gulbrandsen: Misplaced #endif with net redirect and break
* A.N.Kuznetsov : ICMP timestamp still used skb+1
+ * Mike Shaver : RFC1122 checks.
*
*
* This program is free software; you can redistribute it and/or
@@ -41,6 +42,69 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
+
+/* RFC1122 Status: (boy, are there a lot of rules for ICMP)
+ 3.2.2 (Generic ICMP stuff)
+ MUST discard messages of unknown type. (OK)
+ MUST copy at least the first 8 bytes from the offending packet
+ when sending ICMP errors. (OK)
+ MUST pass received ICMP errors up to protocol level. (OK)
+ SHOULD send ICMP errors with TOS == 0. (OK)
+ MUST NOT send ICMP errors in reply to:
+ ICMP errors (OK)
+ Broadcast/multicast datagrams (OK)
+ MAC broadcasts (OK)
+ Non-initial fragments (OK)
+ Datagram with a source address that isn't a single host. (OK)
+ 3.2.2.1 (Destination Unreachable)
+ All the rules govern the IP layer, and are dealt with in ip.c, not here.
+ 3.2.2.2 (Redirect)
+ Host SHOULD NOT send ICMP_REDIRECTs. (OK)
+ MUST update routing table in response to host or network redirects.
+ (host OK, network NOT YET) [Intentionally -- AC]
+ SHOULD drop redirects if they're not from directly connected gateway
+ (OK -- we drop it if it's not from our old gateway, which is close
+ enough)
+ 3.2.2.3 (Source Quench)
+ MUST pass incoming SOURCE_QUENCHs to transport layer (OK)
+ Other requirements are dealt with at the transport layer.
+ 3.2.2.4 (Time Exceeded)
+ MUST pass TIME_EXCEEDED to transport layer (OK)
+ Other requirements dealt with at IP (generating TIME_EXCEEDED).
+ 3.2.2.5 (Parameter Problem)
+ SHOULD generate these, but it doesn't say for what. So we're OK. =)
+ MUST pass received PARAMPROBLEM to transport layer (NOT YET)
+ [Solaris 2.X seems to assert EPROTO when this occurs] -- AC
+ 3.2.2.6 (Echo Request/Reply)
+ MUST reply to ECHO_REQUEST, and give app to do ECHO stuff (OK, OK)
+ MAY discard broadcast ECHO_REQUESTs. (We don't, but that's OK.)
+ MUST reply using same source address as the request was sent to.
+ We're OK for unicast ECHOs, and it doesn't say anything about
+ how to handle broadcast ones, since it's optional.
+ MUST copy data from REQUEST to REPLY (OK)
+ unless it would require illegal fragmentation (MUST) (NOT YET)
+ MUST pass REPLYs to transport/user layer (OK)
+ MUST use any provided source route (reversed) for REPLY. (NOT YET)
+ 3.2.2.7 (Information Request/Reply)
+ MUST NOT implement this. (I guess that means silently discard...?) (OK)
+ 3.2.2.8 (Timestamp Request/Reply)
+ MAY implement (OK)
+ SHOULD be in-kernel for "minimum variability" (OK)
+ MAY discard broadcast REQUESTs. (OK, but see source for inconsistency)
+ MUST reply using same source address as the request was sent to. (OK)
+ MUST reverse source route, as per ECHO (NOT YET)
+ MUST pass REPLYs to transport/user layer (requires RAW, just like ECHO) (OK)
+ MUST update clock for timestamp at least 15 times/sec (OK)
+ MUST be "correct within a few minutes" (OK)
+ 3.2.2.9 (Address Mask Request/Reply)
+ MAY implement (OK)
+ MUST send a broadcast REQUEST if using this system to set netmask
+ (OK... we don't use it)
+ MUST discard received REPLYs if not using this system (OK)
+ MUST NOT send replies unless specifically made agent for this sort
+ of thing. (NOT YET)
+*/
+
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/kernel.h>
@@ -180,6 +244,9 @@
icmp_statistics.IcmpOutSrcQuenchs++;
break;
case ICMP_REDIRECT:
+ /* RFC1122: (3.2.2.2) Sorta bad. SHOULDN'T send */
+ /* ICMP_REDIRECTs unless we're a gateway. -- MS */
+ /* We don't .. this path isnt invoked -- AC */
icmp_statistics.IcmpOutRedirects++;
break;
case ICMP_ECHO:
@@ -227,6 +294,11 @@
*/
our_addr = dev->pa_addr;
+
+ /* RFC1122: (3.2.2). MUST NOT send ICMP in reply to */
+ /* packet with a source IP address that doesn't define a single */
+ /* host. -- MS. Checked higher up -- AC */
+
if (iph->daddr != our_addr && ip_chk_addr(iph->daddr) == IS_MYADDR)
our_addr = iph->daddr;
offset = ip_build_header(skb, our_addr, iph->saddr,
@@ -250,6 +322,9 @@
* Fill in the frame
*/
+ /* RFC1122: SHOULD send with TOS == 0, and I guess this does. */
+ /* Perhaps it should be explicit? -- MS */
+
icmph = (struct icmphdr *) (skb->data + offset);
icmph->type = type;
icmph->code = code;
@@ -257,6 +332,9 @@
icmph->un.gateway = info; /* This might not be meant for
this form of the union but it will
be right anyway */
+
+ /* RFC1122: OK. Copies the minimum 8 bytes unchanged from the offending */
+ /* packet (MUST) as per 3.2.2. -- MS */
memcpy(icmph + 1, iph, sizeof(struct iphdr) + 8);
icmph->checksum = ip_compute_csum((unsigned char *)icmph,
@@ -332,6 +410,10 @@
/*
* Pass it off to everyone who wants it.
*/
+
+ /* RFC1122: OK. Passes appropriate ICMP errors to the */
+ /* appropriate protocol layer (MUST), as per 3.2.2. */
+
if (iph->protocol == ipprot->protocol && ipprot->err_handler)
{
ipprot->err_handler(err, (unsigned char *)(icmph + 1),
@@ -469,6 +551,12 @@
*/
icmphr = (struct icmphdr *) (skb2->data + offset);
memcpy((char *) icmphr, (char *) icmph, len);
+
+ /* Are we copying the data from the ECHO datagram? */
+ /* We're supposed to, and it looks like we are. -- MS */
+ /* We're also supposed to truncate it if it would force */
+ /* illegal fragmentation. *sigh* */
+
icmphr->type = ICMP_ECHOREPLY;
icmphr->code = 0;
icmphr->checksum = 0;
@@ -587,11 +675,20 @@
/*
* Handle ICMP_ADDRESS_MASK requests.
*/
+
+/* RFC1122 (3.2.2.9). A host MUST only send replies to */
+/* ADDRESS_MASK requests if it's been configured as an address mask */
+/* agent. Receiving a request doesn't constitute implicit permission to */
+/* act as one. Of course, implementing this correctly requires (SHOULD) */
+/* a way to turn the functionality on and off. Another one for sysctl(), */
+/* I guess. -- MS */
+/* Botched with a CONFIG option for now - Linus add scts sysctl please.. */
static void icmp_address(struct icmphdr *icmph, struct sk_buff *skb, struct device *dev,
unsigned long saddr, unsigned long daddr, int len,
struct options *opt)
{
+#ifdef CONFIG_IP_ADDR_AGENT
struct icmphdr *icmphr;
struct sk_buff *skb2;
int size, offset;
@@ -647,7 +744,7 @@
/* Ship it out - free it when done */
ip_queue_xmit((struct sock *)NULL, ndev, skb2, 1);
-
+#endif
skb->sk = NULL;
kfree_skb(skb, FREE_READ);
}
@@ -699,6 +796,11 @@
if (ip_chk_addr(daddr) != IS_MYADDR)
{
if (icmph->type != ICMP_ECHO)
+ /* RFC1122: We're allowed to reply to ICMP_TIMESTAMP */
+ /* requests in the same manner as ICMP_ECHO (optionally */
+ /* drop those to a bcast/mcast), so perhaps we should be */
+ /* consistent? -- MS */
+
{
icmp_statistics.IcmpInErrors++;
kfree_skb(skb1, FREE_READ);
@@ -738,6 +840,9 @@
icmp_timestamp(icmph, skb1, dev, saddr, daddr, len, opt);
return 0;
case ICMP_TIMESTAMPREPLY:
+ /* RFC1122: MUST pass TIMESTAMPREPLY messages up to app layer, */
+ /* just as with ECHOREPLY. You have to use raw to get that */
+ /* functionality, just as with ECHOREPLY. Close enough. -- MS */
icmp_statistics.IcmpInTimestampReps++;
kfree_skb(skb1,FREE_READ);
return 0;
@@ -762,6 +867,8 @@
kfree_skb(skb1, FREE_READ);
return(0);
default:
+ /* RFC1122: OK. Silently discarding weird ICMP (MUST), */
+ /* as per 3.2.2. -- MS */
icmp_statistics.IcmpInErrors++;
kfree_skb(skb1, FREE_READ);
return(0);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this