/*
  PIM for Quagga
  Copyright (C) 2008  Everton da Silva Marques

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful, but
  WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  General Public License for more details.
  
  You should have received a copy of the GNU General Public License
  along with this program; see the file COPYING; if not, write to the
  Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
  MA 02110-1301 USA
  
  $QuaggaId: $Format:%an, %ai, %h$ $
*/

#include <zebra.h>

#include "log.h"
#include "prefix.h"

#include "pimd.h"
#include "pim_str.h"
#include "pim_tlv.h"
#include "pim_msg.h"
#include "pim_pim.h"
#include "pim_join.h"
#include "pim_iface.h"
#include "pim_hello.h"
#include "pim_ifchannel.h"

static void on_trace(const char *label,
		     struct interface *ifp, struct in_addr src)
{
  if (PIM_DEBUG_PIM_TRACE) {
    char src_str[100];
    pim_inet4_dump("<src?>", src, src_str, sizeof(src_str));
    zlog_debug("%s: from %s on %s",
	       label, src_str, ifp->name);
  }
}

static void recv_join(struct interface *ifp,
		      struct pim_neighbor *neigh,
		      uint16_t holdtime,
		      struct in_addr upstream,
		      struct in_addr group,
		      struct in_addr source,
		      uint8_t source_flags)
{
  if (PIM_DEBUG_PIM_TRACE) {
    char up_str[100];
    char src_str[100];
    char grp_str[100];
    char neigh_str[100];
    pim_inet4_dump("<upstream?>", upstream, up_str, sizeof(up_str));
    pim_inet4_dump("<src?>", source, src_str, sizeof(src_str));
    pim_inet4_dump("<grp?>", group, grp_str, sizeof(grp_str));
    pim_inet4_dump("<neigh?>", neigh->source_addr, neigh_str, sizeof(neigh_str));
    zlog_warn("%s: join (S,G)=(%s,%s) rpt=%d wc=%d upstream=%s holdtime=%d from %s on %s",
	      __PRETTY_FUNCTION__,
	      src_str, grp_str,
	      source_flags & PIM_RPT_BIT_MASK,
	      source_flags & PIM_WILDCARD_BIT_MASK,
	      up_str, holdtime, neigh_str, ifp->name);
  }
  
  /* Restart join expiry timer */
  pim_ifchannel_join_add(ifp, neigh->source_addr, upstream,
			 source, group, source_flags, holdtime);
}

static void recv_prune(struct interface *ifp,
		       struct pim_neighbor *neigh,
		       uint16_t holdtime,
		       struct in_addr upstream,
		       struct in_addr group,
		       struct in_addr source,
		       uint8_t source_flags)
{
  if (PIM_DEBUG_PIM_TRACE) {
    char up_str[100];
    char src_str[100];
    char grp_str[100];
    char neigh_str[100];
    pim_inet4_dump("<upstream?>", upstream, up_str, sizeof(up_str));
    pim_inet4_dump("<src?>", source, src_str, sizeof(src_str));
    pim_inet4_dump("<grp?>", group, grp_str, sizeof(grp_str));
    pim_inet4_dump("<neigh?>", neigh->source_addr, neigh_str, sizeof(neigh_str));
    zlog_warn("%s: prune (S,G)=(%s,%s) rpt=%d wc=%d upstream=%s holdtime=%d from %s on %s",
	      __PRETTY_FUNCTION__,
	      src_str, grp_str,
	      source_flags & PIM_RPT_BIT_MASK,
	      source_flags & PIM_WILDCARD_BIT_MASK,
	      up_str, holdtime, neigh_str, ifp->name);
  }
  
  pim_ifchannel_prune(ifp, upstream, source, group, source_flags, holdtime);
}

int pim_joinprune_recv(struct interface *ifp,
		       struct pim_neighbor *neigh,
		       struct in_addr src_addr,
		       char *tlv_buf, int tlv_buf_size)
{
  struct prefix   msg_upstream_addr;
  uint8_t         msg_num_groups;
  uint16_t        msg_holdtime;
  int             addr_offset;
  char           *buf;
  char           *pastend;
  int             remain;
  int             group;

  on_trace(__PRETTY_FUNCTION__, ifp, src_addr);

  buf     = tlv_buf;
  pastend = tlv_buf + tlv_buf_size;

  /*
    Parse ucast addr
  */
  addr_offset = pim_parse_addr_ucast(ifp->name, src_addr,
				     &msg_upstream_addr,
				     buf, pastend - buf);
  if (addr_offset < 1) {
    char src_str[100];
    pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
    zlog_warn("%s: pim_parse_addr_ucast() failure: from %s on %s",
	      __PRETTY_FUNCTION__,
	      src_str, ifp->name);
    return -1;
  }
  buf += addr_offset;

  /*
    Check upstream address family
   */
  if (msg_upstream_addr.family != AF_INET) {
    if (PIM_DEBUG_PIM_TRACE) {
      char src_str[100];
      pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
      zlog_warn("%s: ignoring join/prune directed to unexpected addr family=%d from %s on %s",
		__PRETTY_FUNCTION__,
		msg_upstream_addr.family, src_str, ifp->name);
    }
    return -2;
  }

  remain = pastend - buf;
  if (remain < 4) {
    char src_str[100];
    pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
    zlog_warn("%s: short join/prune message buffer for group list: size=%d minimum=%d from %s on %s",
	      __PRETTY_FUNCTION__,
	      remain, 4, src_str, ifp->name);
    return -4;
  }

  ++buf; /* skip reserved byte */
  msg_num_groups = *(const uint8_t *) buf;
  ++buf;
  msg_holdtime = ntohs(*(const uint16_t *) buf);
  ++buf;
  ++buf;

  if (PIM_DEBUG_PIM_TRACE) {
    char src_str[100];
    char upstream_str[100];
    pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
    pim_inet4_dump("<addr?>", msg_upstream_addr.u.prefix4,
		   upstream_str, sizeof(upstream_str));
    zlog_warn("%s: join/prune upstream=%s groups=%d holdtime=%d from %s on %s",
	      __PRETTY_FUNCTION__,
	      upstream_str, msg_num_groups, msg_holdtime,
	      src_str, ifp->name);
  }

  /* Scan groups */
  for (group = 0; group < msg_num_groups; ++group) {
    struct prefix msg_group_addr;
    struct prefix msg_source_addr;
    uint8_t       msg_source_flags;
    uint16_t      msg_num_joined_sources;
    uint16_t      msg_num_pruned_sources;
    int           source;

    addr_offset = pim_parse_addr_group(ifp->name, src_addr,
				       &msg_group_addr,
				       buf, pastend - buf);
    if (addr_offset < 1) {
      return -5;
    }
    buf += addr_offset;

    remain = pastend - buf;
    if (remain < 4) {
      char src_str[100];
      pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
      zlog_warn("%s: short join/prune buffer for source list: size=%d minimum=%d from %s on %s",
		__PRETTY_FUNCTION__,
		remain, 4, src_str, ifp->name);
      return -6;
    }

    msg_num_joined_sources = ntohs(*(const uint16_t *) buf);
    buf += 2;
    msg_num_pruned_sources = ntohs(*(const uint16_t *) buf);
    buf += 2;

    if (PIM_DEBUG_PIM_TRACE) {
      char src_str[100];
      char upstream_str[100];
      char group_str[100];
      pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
      pim_inet4_dump("<addr?>", msg_upstream_addr.u.prefix4,
		     upstream_str, sizeof(upstream_str));
      pim_inet4_dump("<grp?>", msg_group_addr.u.prefix4,
		     group_str, sizeof(group_str));
      zlog_warn("%s: join/prune upstream=%s group=%s/%d join_src=%d prune_src=%d from %s on %s",
		__PRETTY_FUNCTION__,
		upstream_str, group_str, msg_group_addr.prefixlen,
		msg_num_joined_sources, msg_num_pruned_sources,
		src_str, ifp->name);
    }

    /* Scan joined sources */
    for (source = 0; source < msg_num_joined_sources; ++source) {
      addr_offset = pim_parse_addr_source(ifp->name, src_addr,
					  &msg_source_addr,
					  &msg_source_flags,
					  buf, pastend - buf);
      if (addr_offset < 1) {
	return -7;
      }
      buf += addr_offset;

      recv_join(ifp, neigh, msg_holdtime,
		msg_upstream_addr.u.prefix4,
		msg_group_addr.u.prefix4,
		msg_source_addr.u.prefix4,
		msg_source_flags);
    }

    /* Scan pruned sources */
    for (source = 0; source < msg_num_pruned_sources; ++source) {
      addr_offset = pim_parse_addr_source(ifp->name, src_addr,
					  &msg_source_addr,
					  &msg_source_flags,
					  buf, pastend - buf);
      if (addr_offset < 1) {
	return -8;
      }
      buf += addr_offset;

      recv_prune(ifp, neigh, msg_holdtime,
		 msg_upstream_addr.u.prefix4,
		 msg_group_addr.u.prefix4,
		 msg_source_addr.u.prefix4,
		 msg_source_flags);
    }

  } /* scan groups */

  return 0;
}

int pim_joinprune_send(struct interface *ifp,
		       struct in_addr upstream_addr,
		       struct in_addr source_addr,
		       struct in_addr group_addr,
		       int send_join)
{
  struct pim_interface *pim_ifp;
  char pim_msg[1000];
  const char *pastend = pim_msg + sizeof(pim_msg);
  char *pim_msg_curr = pim_msg + PIM_MSG_HEADER_LEN; /* room for pim header */
  int pim_msg_size;
  int remain;

  zassert(ifp);

  pim_ifp = ifp->info;

  if (!pim_ifp) {
    zlog_warn("%s: multicast not enabled on interface %s",
	      __PRETTY_FUNCTION__,
	      ifp->name);
    return -1;
  }

  if (PIM_DEBUG_PIM_TRACE) {
    char source_str[100];
    char group_str[100];
    char dst_str[100];
    pim_inet4_dump("<src?>", source_addr, source_str, sizeof(source_str));
    pim_inet4_dump("<grp?>", group_addr, group_str, sizeof(group_str));
    pim_inet4_dump("<dst?>", upstream_addr, dst_str, sizeof(dst_str));
    zlog_debug("%s: sending %s(S,G)=(%s,%s) to upstream=%s on interface %s",
	       __PRETTY_FUNCTION__,
	       send_join ? "Join" : "Prune",
	       source_str, group_str, dst_str, ifp->name);
  }

  if (PIM_INADDR_IS_ANY(upstream_addr)) {
    if (PIM_DEBUG_PIM_TRACE) {
      char source_str[100];
      char group_str[100];
      char dst_str[100];
      pim_inet4_dump("<src?>", source_addr, source_str, sizeof(source_str));
      pim_inet4_dump("<grp?>", group_addr, group_str, sizeof(group_str));
      pim_inet4_dump("<dst?>", upstream_addr, dst_str, sizeof(dst_str));
      zlog_debug("%s: %s(S,G)=(%s,%s): upstream=%s is myself on interface %s",
		 __PRETTY_FUNCTION__,
		 send_join ? "Join" : "Prune",
		 source_str, group_str, dst_str, ifp->name);
    }
    return 0;
  }

  /*
    RFC 4601: 4.3.1.  Sending Hello Messages

    Thus, if a router needs to send a Join/Prune or Assert message on
    an interface on which it has not yet sent a Hello message with the
    currently configured IP address, then it MUST immediately send the
    relevant Hello message without waiting for the Hello Timer to
    expire, followed by the Join/Prune or Assert message.
  */
  pim_hello_require(ifp);

  /*
    Build PIM message
  */

  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,
						group_addr);
  if (!pim_msg_curr) {
    char group_str[100];
    pim_inet4_dump("<grp?>", group_addr, 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,
						 source_addr);
  if (!pim_msg_curr) {
    char source_str[100];
    pim_inet4_dump("<src?>", source_addr, 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_send(pim_ifp->pim_sock_fd,
		   qpim_all_pim_routers_addr,
		   pim_msg,
		   pim_msg_size,
		   ifp->name)) {
    zlog_warn("%s: could not send PIM message on interface %s",
	      __PRETTY_FUNCTION__, ifp->name);
    return -8;
  }

  return 0;
}
