diff options
Diffstat (limited to 'pimd/pim_pim.c')
| -rw-r--r-- | pimd/pim_pim.c | 73 |
1 files changed, 64 insertions, 9 deletions
diff --git a/pimd/pim_pim.c b/pimd/pim_pim.c index f727d3e627..e4c654557a 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("<src?>", ip_hdr->ip_src, src_str, sizeof(src_str)); @@ -533,6 +557,8 @@ pim_msg_send(int fd, struct in_addr src, socklen_t tolen; unsigned char buffer[10000]; unsigned char *msg_start; + uint8_t ttl = MAXTTL; + enum pim_msg_type pim_type = PIM_MSG_TYPE_HELLO; struct ip *ip; memset (buffer, 0, 10000); @@ -541,14 +567,43 @@ pim_msg_send(int fd, struct in_addr src, msg_start = buffer + sizeof (struct ip); memcpy (msg_start, pim_msg, pim_msg_size); - ip = (struct ip *)buffer; + /* + * Omnios apparently doesn't have a #define for IP default + * ttl that is the same as all other platforms. + */ +#ifndef IPDEFTTL +#define IPDEFTTL 64 +#endif + /* TTL for packets destine to ALL-PIM-ROUTERS is 1 */ + pim_type = PIM_MSG_HDR_GET_TYPE (pim_msg); + switch (pim_type) + { + case PIM_MSG_TYPE_HELLO: + case PIM_MSG_TYPE_JOIN_PRUNE: + case PIM_MSG_TYPE_BOOTSTRAP: + case PIM_MSG_TYPE_ASSERT: + ttl = 1; + break; + case PIM_MSG_TYPE_REGISTER: + case PIM_MSG_TYPE_REG_STOP: + case PIM_MSG_TYPE_GRAFT: + case PIM_MSG_TYPE_GRAFT_ACK: + case PIM_MSG_TYPE_CANDIDATE: + ttl = IPDEFTTL; + break; + default: + ttl = MAXTTL; + break; + } + + ip = (struct ip *) buffer; ip->ip_id = htons (++ip_id); ip->ip_hl = 5; ip->ip_v = 4; ip->ip_p = PIM_IP_PROTO_PIM; ip->ip_src = src; ip->ip_dst = dst; - ip->ip_ttl = MAXTTL; + ip->ip_ttl = ttl; ip->ip_len = htons (sendlen); if (PIM_DEBUG_PIM_PACKETS) { |
