Hi,

> It appears that the CISCO refuses to forward UDP packets if the
> checksum is not correct. Part of the IPConfig documentation
> states that 'UDP checksum not calculated -- explicitly allowed
> in BOOTP RFC'.

   Please try the following patch. In addition to some cosmetic changes,
it adds checksumming of BOOTP packets being sent.

                                Have a nice fortnight
-- 
Martin `MJ' Mares   <[EMAIL PROTECTED]>   http://atrey.karlin.mff.cuni.cz/~mj/
Faculty of Math and Physics, Charles University, Prague, Czech Rep., Earth
"Never make any mistaeks."


--- net/ipv4/ipconfig.c.mj      Sun Jan 10 14:30:07 1999
+++ net/ipv4/ipconfig.c Sun Jan 10 22:05:37 1999
@@ -73,7 +73,14 @@
 
 #define CONFIG_IP_PNP_DYNAMIC
 
-static int ic_proto_enabled __initdata = IC_BOOTP | IC_RARP;   /* Protocols enabled */
+static int ic_proto_enabled __initdata = 0                     /* Protocols enabled */
+#ifdef CONFIG_IP_PNP_BOOTP
+                       | IC_BOOTP
+#endif
+#ifdef CONFIG_IP_PNP_RARP
+                       | IC_RARP
+#endif
+                       ;
 static int ic_got_reply __initdata = 0;                                /* Protocol(s) 
we got reply from */
 
 #else
@@ -491,6 +498,7 @@
        struct bootp_pkt *b;
        int hh_len = (dev->hard_header_len + 15) & ~15;
        struct iphdr *h;
+       int ulen = sizeof(struct bootp_pkt) - sizeof(struct iphdr);
 
        /* Allocate packet */
        skb = alloc_skb(sizeof(struct bootp_pkt) + hh_len + 15, GFP_KERNEL);
@@ -509,14 +517,12 @@
        h->ttl = 1;
        h->protocol = IPPROTO_UDP;
        h->daddr = INADDR_BROADCAST;
-       h->check = 0;
        h->check = ip_fast_csum((unsigned char *) h, h->ihl);
 
        /* Construct UDP header */
        b->udph.source = htons(68);
        b->udph.dest = htons(67);
-       b->udph.len = htons(sizeof(struct bootp_pkt) - sizeof(struct iphdr));
-       /* UDP checksum not calculated -- explicitly allowed in BOOTP RFC */
+       b->udph.len = htons(ulen);
 
        /* Construct BOOTP header */
        b->op = BOOTP_REQUEST;
@@ -526,6 +532,12 @@
        b->secs = htons(jiffies / HZ);
        b->xid = ic_bootp_xid;
        ic_bootp_init_ext(b->vendor_area);
+
+       /* RFC explicitly allows us to omit UDP checksum. Reality doesn't. */
+       b->udph.check = csum_tcpudp_magic(h->saddr, h->daddr, ulen, IPPROTO_UDP,
+                                         csum_partial((char *) &b->udph, ulen, 0));
+       if (!b->udph.check)
+               b->udph.check = -1;
 
        /* Chain packet down the line... */
        skb->dev = dev;
-
To unsubscribe from this list: send the line "unsubscribe linux-net" in
the body of a message to [EMAIL PROTECTED]

Reply via email to