uint8_t buf[1000];
const uint8_t *buf_pastend = buf + sizeof(buf);
uint8_t *pim_msg;
- uint8_t *pim_msg_curr;
int pim_msg_size;
struct ip *ip_hdr;
size_t ip_hlen; /* ip header length in bytes */
const char *ifname;
struct interface *ifp;
int result;
- int remain;
- uint16_t num_joined;
- uint16_t num_pruned;
/* Find interface */
ifname = argv[0]->arg;
*/
pim_msg = buf + ip_hlen;
- /* skip room for pim header */
- pim_msg_curr = pim_msg + PIM_MSG_HEADER_LEN;
-
- remain = buf_pastend - pim_msg_curr;
- pim_msg_curr = pim_msg_addr_encode_ipv4_ucast(pim_msg_curr,
- remain,
- neigh_dst_addr);
- if (!pim_msg_curr) {
- vty_out(vty, "Failure encoding destination address %s: space left=%d%s",
- neigh_dst_str, remain, VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- remain = buf_pastend - pim_msg_curr;
- if (remain < 4) {
- vty_out(vty, "Group will not fit: space left=%d%s",
- remain, VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- *pim_msg_curr = 0; /* reserved */
- ++pim_msg_curr;
- *pim_msg_curr = 1; /* number of groups */
- ++pim_msg_curr;
- *((uint16_t *) pim_msg_curr) = htons(neigh_holdtime);
- ++pim_msg_curr;
- ++pim_msg_curr;
-
- remain = buf_pastend - pim_msg_curr;
- pim_msg_curr = pim_msg_addr_encode_ipv4_group(pim_msg_curr,
- remain,
- group_addr);
- if (!pim_msg_curr) {
- vty_out(vty, "Failure encoding group address %s: space left=%d%s",
- group_str, remain, VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- remain = buf_pastend - pim_msg_curr;
- if (remain < 4) {
- vty_out(vty, "Sources will not fit: space left=%d%s",
- remain, VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- if (src_is_join) {
- num_joined = 1;
- num_pruned = 0;
- }
- else {
- num_joined = 0;
- num_pruned = 1;
- }
-
- /* number of joined sources */
- *((uint16_t *) pim_msg_curr) = htons(num_joined);
- ++pim_msg_curr;
- ++pim_msg_curr;
-
- /* number of pruned sources */
- *((uint16_t *) pim_msg_curr) = htons(num_pruned);
- ++pim_msg_curr;
- ++pim_msg_curr;
-
- remain = buf_pastend - pim_msg_curr;
- pim_msg_curr = pim_msg_addr_encode_ipv4_source(pim_msg_curr,
- remain,
- source_addr,
- PIM_ENCODE_SPARSE_BIT);
- if (!pim_msg_curr) {
- vty_out(vty, "Failure encoding source address %s: space left=%d%s",
- source_str, remain, VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- /* Add PIM header */
-
- pim_msg_size = pim_msg_curr - pim_msg;
-
- pim_msg_build_header(pim_msg, pim_msg_size,
- PIM_MSG_TYPE_JOIN_PRUNE);
+ pim_msg_size = pim_msg_join_prune_encode (pim_msg, buf_pastend - pim_msg, src_is_join,
+ source_addr, group_addr, neigh_dst_addr,
+ neigh_holdtime);
/*
"Receive" message
source_flags & PIM_WILDCARD_BIT_MASK,
up_str, holdtime, neigh_str, ifp->name);
}
-
+
+ /*
+ * If the RPT and WC are set it's a (*,G)
+ * and the source is the RP
+ */
+ if ((source_flags & PIM_RPT_BIT_MASK) &&
+ (source_flags & PIM_WILDCARD_BIT_MASK))
+ {
+ struct pim_rpf *rp = RP (sg.u.sg.grp);
+
+ /*
+ * If the RP sent in the message is not
+ * our RP for the group, drop the message
+ */
+ if (sg.u.sg.src.s_addr != rp->rpf_addr.s_addr)
+ return;
+
+ sg.u.sg.src.s_addr = INADDR_ANY;
+ }
+
/* Restart join expiry timer */
pim_ifchannel_join_add(ifp, neigh->source_addr, upstream,
&sg, source_flags, holdtime);
{
struct pim_interface *pim_ifp;
uint8_t pim_msg[1000];
- const uint8_t *pastend = pim_msg + sizeof(pim_msg);
- uint8_t *pim_msg_curr = pim_msg + PIM_MSG_HEADER_LEN; /* room for pim header */
int pim_msg_size;
- int remain;
on_trace (__PRETTY_FUNCTION__, ifp, upstream_addr);
/*
Build PIM message
*/
+ pim_msg_size = pim_msg_join_prune_encode (pim_msg, 1000, send_join,
+ sg->u.sg.src, sg->u.sg.grp,
+ upstream_addr, PIM_JP_HOLDTIME);
- remain = pastend - pim_msg_curr;
- pim_msg_curr = pim_msg_addr_encode_ipv4_ucast(pim_msg_curr,
- remain,
- upstream_addr);
- if (!pim_msg_curr) {
- char dst_str[100];
- pim_inet4_dump("<dst?>", upstream_addr, dst_str, sizeof(dst_str));
- zlog_warn("%s: failure encoding destination address %s: space left=%d",
- __PRETTY_FUNCTION__, dst_str, remain);
- return -3;
- }
-
- remain = pastend - pim_msg_curr;
- if (remain < 4) {
- zlog_warn("%s: group will not fit: space left=%d",
- __PRETTY_FUNCTION__, remain);
- return -4;
- }
-
- *pim_msg_curr = 0; /* reserved */
- ++pim_msg_curr;
- *pim_msg_curr = 1; /* number of groups */
- ++pim_msg_curr;
- *((uint16_t *) pim_msg_curr) = htons(PIM_JP_HOLDTIME);
- ++pim_msg_curr;
- ++pim_msg_curr;
-
- remain = pastend - pim_msg_curr;
- pim_msg_curr = pim_msg_addr_encode_ipv4_group(pim_msg_curr,
- remain,
- sg->u.sg.grp);
- if (!pim_msg_curr) {
- char group_str[100];
- pim_inet4_dump("<grp?>", sg->u.sg.grp, group_str, sizeof(group_str));
- zlog_warn("%s: failure encoding group address %s: space left=%d",
- __PRETTY_FUNCTION__, group_str, remain);
- return -5;
- }
-
- remain = pastend - pim_msg_curr;
- if (remain < 4) {
- zlog_warn("%s: sources will not fit: space left=%d",
- __PRETTY_FUNCTION__, remain);
- return -6;
- }
-
- /* number of joined sources */
- *((uint16_t *) pim_msg_curr) = htons(send_join ? 1 : 0);
- ++pim_msg_curr;
- ++pim_msg_curr;
-
- /* number of pruned sources */
- *((uint16_t *) pim_msg_curr) = htons(send_join ? 0 : 1);
- ++pim_msg_curr;
- ++pim_msg_curr;
-
- remain = pastend - pim_msg_curr;
- pim_msg_curr = pim_msg_addr_encode_ipv4_source(pim_msg_curr,
- remain,
- sg->u.sg.src,
- PIM_ENCODE_SPARSE_BIT);
- if (!pim_msg_curr) {
- char source_str[100];
- pim_inet4_dump("<src?>", sg->u.sg.src, source_str, sizeof(source_str));
- zlog_warn("%s: failure encoding source address %s: space left=%d",
- __PRETTY_FUNCTION__, source_str, remain);
- return -7;
- }
-
- /* Add PIM header */
-
- pim_msg_size = pim_msg_curr - pim_msg;
-
- pim_msg_build_header(pim_msg, pim_msg_size,
- PIM_MSG_TYPE_JOIN_PRUNE);
+ if (pim_msg_size < 0)
+ return pim_msg_size;
if (pim_msg_send(pim_ifp->pim_sock_fd,
qpim_all_pim_routers_addr,
#include <zebra.h>
#include "if.h"
+#include "log.h"
#include "pimd.h"
#include "pim_pim.h"
#include "pim_msg.h"
#include "pim_util.h"
+#include "pim_str.h"
void pim_msg_build_header(uint8_t *pim_msg, int pim_msg_size,
uint8_t pim_msg_type)
return buf + ENCODED_IPV4_SOURCE_SIZE;
}
+
+int
+pim_msg_join_prune_encode (uint8_t *buf, int buf_size, int is_join,
+ struct in_addr source, struct in_addr group,
+ struct in_addr upstream, int holdtime)
+{
+ uint8_t *pim_msg = buf;
+ uint8_t *pim_msg_curr = buf + PIM_MSG_HEADER_LEN;
+ uint8_t *end = buf + buf_size;
+ struct in_addr stosend;
+ uint8_t bits;
+ int remain;
+
+ remain = end - pim_msg_curr;
+ pim_msg_curr = pim_msg_addr_encode_ipv4_ucast (pim_msg_curr, buf_size - PIM_MSG_HEADER_LEN, upstream);
+ if (!pim_msg_curr) {
+ char dst_str[100];
+ pim_inet4_dump("<dst?>", upstream, dst_str, sizeof(dst_str));
+ zlog_warn("%s: failure encoding destination address %s: space left=%d",
+ __PRETTY_FUNCTION__, dst_str, remain);
+ return -3;
+ }
+
+ remain = end - pim_msg_curr;
+ if (remain < 4) {
+ zlog_warn("%s: group will not fit: space left=%d",
+ __PRETTY_FUNCTION__, remain);
+ return -4;
+ }
+
+ *pim_msg_curr = 0; /* reserved */
+ ++pim_msg_curr;
+ *pim_msg_curr = 1; /* number of groups */
+ ++pim_msg_curr;
+
+ *((uint16_t *) pim_msg_curr) = htons(holdtime);
+ ++pim_msg_curr;
+ ++pim_msg_curr;
+
+ remain = end - pim_msg_curr;
+ pim_msg_curr = pim_msg_addr_encode_ipv4_group (pim_msg_curr, remain,
+ group);
+ if (!pim_msg_curr) {
+ char group_str[100];
+ pim_inet4_dump("<grp?>", group, group_str, sizeof(group_str));
+ zlog_warn("%s: failure encoding group address %s: space left=%d",
+ __PRETTY_FUNCTION__, group_str, remain);
+ return -5;
+ }
+
+ remain = end - pim_msg_curr;
+ if (remain < 4) {
+ zlog_warn("%s: sources will not fit: space left=%d",
+ __PRETTY_FUNCTION__, remain);
+ return -6;
+ }
+
+ /* number of joined sources */
+ *((uint16_t *) pim_msg_curr) = htons(is_join ? 1 : 0);
+ ++pim_msg_curr;
+ ++pim_msg_curr;
+
+ /* number of pruned sources */
+ *((uint16_t *) pim_msg_curr) = htons(is_join ? 0 : 1);
+ ++pim_msg_curr;
+ ++pim_msg_curr;
+
+ remain = end - pim_msg_curr;
+ if (source.s_addr == INADDR_ANY)
+ {
+ bits = PIM_ENCODE_SPARSE_BIT | PIM_ENCODE_WC_BIT | PIM_ENCODE_RPT_BIT;
+ stosend = qpim_rp.rpf_addr;
+ }
+ else
+ {
+ bits = PIM_ENCODE_SPARSE_BIT;
+ stosend = source;
+ }
+ pim_msg_curr = pim_msg_addr_encode_ipv4_source (pim_msg_curr, remain, stosend, bits);
+ if (!pim_msg_curr) {
+ char source_str[100];
+ pim_inet4_dump("<src?>", source, source_str, sizeof(source_str));
+ zlog_warn("%s: failure encoding source address %s: space left=%d",
+ __PRETTY_FUNCTION__, source_str, remain);
+ return -7;
+ }
+
+ remain = pim_msg_curr - pim_msg;
+ pim_msg_build_header (pim_msg, remain, PIM_MSG_TYPE_JOIN_PRUNE);
+
+ return remain;
+}
struct in_addr addr,
uint8_t bits);
+
+int pim_msg_join_prune_encode (uint8_t *buf, int buf_size, int is_join,
+ struct in_addr source, struct in_addr group,
+ struct in_addr upstream, int holdtime);
#endif /* PIM_MSG_H */