summaryrefslogtreecommitdiff
path: root/pimd/pim_pim.c
diff options
context:
space:
mode:
Diffstat (limited to 'pimd/pim_pim.c')
-rw-r--r--pimd/pim_pim.c73
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) {