Subject: [pim] Implementation Question

From: Nikhil Ninan <[email-masked]>
Date: Tue, 24 Oct 2006 11:20:32 +0100

Hello there,
                 I am researching into PIM-SM protocol behaviour. This 
requires me to create PIM-SM messsages to be used in my test-bed. For 
the life of me, I cant get the PIM-SM checksum value calculated 
properly. In the specification it says, that checksum is the one's 
complement of the PIM message. Does that include the IP header and if 
so, what about the checksum field within the IP header. Any help would 
be much appreaciated.
Cheers
Nikhil Ninan

_______________________________________________
pim mailing list
[email-masked]
https://www1.ietf.org/mailman/listinfo/pim

---

From: Stig Venaas <[email-masked]>
Date: Tue, 24 Oct 2006 13:43:04 +0200

> so, what about the checksum field within the IP header. Any help would 

First of all, the IP header checksum should be taken care of by the
operating system. If this is IPv4 PIM, the PIM checksum is based on
just the PIM message itself (for IPv6 there is a pseudo header with
info from IP header as well), see 4.9 in RFC 4601.

I think the following code should work for the checksum. It's based
on some code from libnet and pim6sd. I cooked this together now and
have not tested it. You would call pim_cksum() with pointer to PIM
header where the PIM payload follows directly behind in the same
buffer.

Stig

/* thanks to libnet code */
uint32_t in_cksum(uint16_t *addr, size_t len) {
     uint32_t sum = 0;

     while (len > 1) {
         sum += *addr++;
         len -= 2;
     }
     if (len == 1)
         sum += *addr;

     return (sum);
}

void pim_cksum(struct pim *pim, size_t len) {
     uint32_t sum;

     pim->pim_cksum = 0;
     /* pad with 0 if odd len, assuming buffer large enough */
     if (len % 2)
         ((char *)pim)[len] = 0;
     sum = in_cksum((uint16_t *)pim, len);
     sum = (sum >> 16) + (sum & 0xffff);
     sum += sum >> 16;
     pim->pim_cksum = ~sum & 0xffff;
}

Stig