From: Chirag Shah Date: Thu, 12 Jan 2017 03:36:50 +0000 (-0800) Subject: pimd: non-null register checksum incorrect X-Git-Tag: frr-3.0-branchpoint~30^2~4 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=5637da0501faa600273ecd7a2ed39cdbbe4531b1;p=matthieu%2Ffrr.git pimd: non-null register checksum incorrect Ticket: CM-12041 Reviewed By: sharpd, CCR-5556 Testing Done: Tested on Local setup generating PIM Register (Data/Null) and processing both Tx/Rx with correct checksum. Provided quagga debian to submitter and checksum cases passed on submitter setup. 1. PIM Register msg checksum only accounts for 8 bytes (4 bytes for PIM header and next 4 byetes before data payload). In PIM header checksum calculation checked PIM packet type (in this case REGISTER type) then only pass 8 bytes as length rather than full packet length. 2. PIM Register Rx path also handled with 8 byte and full pim lenth checksum. Signed-off-by: Chirag Shah --- diff --git a/pimd/pim_msg.c b/pimd/pim_msg.c index 7ea7b1ad82..ab14b3ae5f 100644 --- a/pimd/pim_msg.c +++ b/pimd/pim_msg.c @@ -35,6 +35,7 @@ #include "pim_iface.h" #include "pim_rp.h" #include "pim_rpf.h" +#include "pim_register.h" void pim_msg_build_header(uint8_t *pim_msg, int pim_msg_size, uint8_t pim_msg_type) @@ -54,8 +55,16 @@ void pim_msg_build_header(uint8_t *pim_msg, int pim_msg_size, * Compute checksum */ - *(uint16_t *) PIM_MSG_HDR_OFFSET_CHECKSUM(pim_msg) = 0; - checksum = in_cksum(pim_msg, pim_msg_size); + *(uint16_t *) PIM_MSG_HDR_OFFSET_CHECKSUM (pim_msg) = 0; + /* + * The checksum for Registers is done only on the first 8 bytes of the packet, + * including the PIM header and the next 4 bytes, excluding the data packet portion + */ + if (pim_msg_type == PIM_MSG_TYPE_REGISTER) + checksum = in_cksum (pim_msg, PIM_MSG_REGISTER_LEN); + else + checksum = in_cksum (pim_msg, pim_msg_size); + *(uint16_t *) PIM_MSG_HDR_OFFSET_CHECKSUM(pim_msg) = checksum; } diff --git a/pimd/pim_pim.c b/pimd/pim_pim.c index f727d3e627..840004c375 100644 --- a/pimd/pim_pim.c +++ b/pimd/pim_pim.c @@ -197,13 +197,37 @@ int pim_pim_packet(struct interface *ifp, uint8_t *buf, size_t len) /* for computing checksum */ *(uint16_t *) PIM_MSG_HDR_OFFSET_CHECKSUM(pim_msg) = 0; - checksum = in_cksum(pim_msg, pim_msg_len); - if (checksum != pim_checksum) { - if (PIM_DEBUG_PIM_PACKETS) - zlog_debug("Ignoring PIM pkt from %s with invalid checksum: received=%x calculated=%x", - ifp->name, pim_checksum, checksum); - return -1; - } + if (pim_type == PIM_MSG_TYPE_REGISTER) + { + /* First 8 byte header checksum */ + checksum = in_cksum (pim_msg, PIM_MSG_REGISTER_LEN); + if (checksum != pim_checksum) + { + checksum = in_cksum (pim_msg, pim_msg_len); + if (checksum != pim_checksum) + { + if (PIM_DEBUG_PIM_PACKETS) + zlog_debug + ("Ignoring PIM pkt from %s with invalid checksum: received=%x calculated=%x", + ifp->name, pim_checksum, checksum); + + return -1; + } + } + } + else + { + checksum = in_cksum (pim_msg, pim_msg_len); + if (checksum != pim_checksum) + { + if (PIM_DEBUG_PIM_PACKETS) + zlog_debug + ("Ignoring PIM pkt from %s with invalid checksum: received=%x calculated=%x", + ifp->name, pim_checksum, checksum); + + return -1; + } + } if (PIM_DEBUG_PIM_PACKETS) { pim_inet4_dump("", ip_hdr->ip_src, src_str, sizeof(src_str));