/*
 * Copyright (C) 1999 Yasuhiro Ohara
 *
 * This file is part of GNU Zebra.
 *
 * GNU Zebra 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, or (at your option) any
 * later version.
 *
 * GNU Zebra 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 GNU Zebra; see the file COPYING.  If not, write to the 
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 
 * Boston, MA 02111-1307, USA.  
 */

#include <zebra.h>
#include "memory.h"
#include "log.h"
#include "sockunion.h"
#include "privs.h"

#include "ospf6d.h"
#include "ospf6_proto.h"

extern int errno;
extern struct sockaddr_in6 allspfrouters6;
extern struct sockaddr_in6 alldrouters6;
extern int ospf6_sock;
extern struct thread_master *master;
extern struct zebra_privs_t ospf6d_privs;

/* iovec functions */
void
iov_clear (struct iovec *iov, size_t iovlen)
{
  int i;
  for (i = 0; i < iovlen; i++)
    {
      iov[i].iov_base = NULL;
      iov[i].iov_len = 0;
    }
}

int
iov_count (struct iovec *iov)
{
  int i;
  for (i = 0; iov[i].iov_base; i++)
    ;
  return i;
}

int
iov_totallen (struct iovec *iov)
{
  int i;
  int totallen = 0;
  for (i = 0; iov[i].iov_base; i++)
    totallen += iov[i].iov_len;
  return totallen;
}

void *
iov_prepend (int mtype, struct iovec *iov, size_t len)
{
  int i, iovlen;
  void *base;

  base = (void *) XMALLOC (mtype, len);
  if (!base)
    {
      zlog_warn ("Network: iov_prepend failed");
      return NULL;
    }
  memset (base, 0, len);

  iovlen = iov_count (iov);
  for (i = iovlen; i; i--)
    {
      iov[i].iov_base = iov[i - 1].iov_base;
      iov[i].iov_len = iov[i - 1].iov_len;
    }
  iov[0].iov_base = (char *)base;
  iov[0].iov_len = len;

  return base;
}

void *
iov_append (int mtype, struct iovec *iov, size_t len)
{
  int i;
  void *base;

  base = (void *)XMALLOC (mtype, len);
  if (!base)
    {
      zlog_warn ("Network: iov_append failed");
      return NULL;
    }
  memset (base, 0, len);

  /* proceed to the end */
  i = iov_count (iov);

  iov[i].iov_base = (char *)base;
  iov[i].iov_len = len;

  return base;
}

void *
iov_attach_last (struct iovec *iov, void *base, size_t len)
{
  int i;
  i = iov_count (iov);
  iov[i].iov_base = (char *)base;
  iov[i].iov_len = len;
  return base;
}

void *
iov_detach_first (struct iovec *iov)
{
  int i, iovlen;
  void *base;
  size_t len;

  base = iov[0].iov_base;
  len = iov[0].iov_len;
  iovlen = iov_count (iov);
  for (i = 0; i < iovlen; i++)
    {
      iov[i].iov_base = iov[i + 1].iov_base;
      iov[i].iov_len = iov[i + 1].iov_len;
    }
  return base;
}

int
iov_free (int mtype, struct iovec *iov, u_int begin, u_int end)
{
  int i;

  for (i = begin; i < end; i++)
    {
      XFREE (mtype, iov[i].iov_base);
      iov[i].iov_base = NULL;
      iov[i].iov_len = 0;
    }

  return 0;
}

void
iov_trim_head (int mtype, struct iovec *iov)
{
  void *base;

  base = iov_detach_first (iov);
  XFREE (mtype, base);
  return;
}

void
iov_free_all (int mtype, struct iovec *iov)
{
  int i, end = iov_count (iov);
  for (i = 0; i < end; i++)
    {
      XFREE (mtype, iov[i].iov_base);
      iov[i].iov_base = NULL;
      iov[i].iov_len = 0;
    }
}

void
iov_copy_all (struct iovec *dst, struct iovec *src, size_t size)
{
  int i;
  for (i = 0; i < size; i++)
    {
      dst[i].iov_base = src[i].iov_base;
      dst[i].iov_len = src[i].iov_len;
    }
}


/* Make ospf6d's server socket. */
int
ospf6_serv_sock ()
{

  if (ospf6d_privs.change (ZPRIVS_RAISE))
      zlog_err ("ospf6_serv_sock: could not raise privs");
      
  ospf6_sock = socket (AF_INET6, SOCK_RAW, IPPROTO_OSPFIGP);
  if (ospf6_sock < 0)
    {
      zlog_warn ("Network: can't create OSPF6 socket.");
      return -1;
    }
  sockopt_reuseaddr (ospf6_sock);

  if (ospf6d_privs.change (ZPRIVS_LOWER))
      zlog_err ("ospf_sock_init: could not lower privs");
  
  /* setup global sockaddr_in6, allspf6 & alldr6 for later use */
  allspfrouters6.sin6_family = AF_INET6;
  alldrouters6.sin6_family = AF_INET6;
#ifdef SIN6_LEN
  allspfrouters6.sin6_len = sizeof (struct sockaddr_in6);
  alldrouters6.sin6_len = sizeof (struct sockaddr_in6);
#endif /* SIN6_LEN */
  inet_pton (AF_INET6, ALLSPFROUTERS6, &allspfrouters6.sin6_addr);
  inet_pton (AF_INET6, ALLDROUTERS6, &alldrouters6.sin6_addr);

  return 0;
}

/* returns 0 if succeed, else returns -1 */
int
ospf6_join_allspfrouters (u_int ifindex)
{
  struct ipv6_mreq mreq6;
  int retval;

  assert (ifindex);
  mreq6.ipv6mr_interface = ifindex;
  memcpy (&mreq6.ipv6mr_multiaddr, &allspfrouters6.sin6_addr,
          sizeof (struct in6_addr));

  retval = setsockopt (ospf6_sock, IPPROTO_IPV6, IPV6_JOIN_GROUP,
                       &mreq6, sizeof (mreq6));

  if (retval < 0)
    zlog_err ("Network: Join AllSPFRouters on ifindex %d failed: %s",
               ifindex, strerror (errno));
#if 0
  else
    zlog_info ("Network: Join AllSPFRouters on ifindex %d", ifindex);
#endif

  return retval;
}

void
ospf6_leave_allspfrouters (u_int ifindex)
{
  struct ipv6_mreq mreq6;

  assert (ifindex);
  mreq6.ipv6mr_interface = ifindex;
  memcpy (&mreq6.ipv6mr_multiaddr, &allspfrouters6.sin6_addr,
          sizeof (struct in6_addr));

  if (setsockopt (ospf6_sock, IPPROTO_IPV6, IPV6_LEAVE_GROUP,
                  &mreq6, sizeof (mreq6)) < 0)
    zlog_warn ("Network: Leave AllSPFRouters on ifindex %d Failed: %s",
               ifindex, strerror (errno));
  else
    zlog_info ("Network: Leave AllSPFRouters on ifindex %d", ifindex);
}

void
ospf6_join_alldrouters (u_int ifindex)
{
  struct ipv6_mreq mreq6;

  assert (ifindex);
  mreq6.ipv6mr_interface = ifindex;
  memcpy (&mreq6.ipv6mr_multiaddr, &alldrouters6.sin6_addr,
          sizeof (struct in6_addr));

  if (setsockopt (ospf6_sock, IPPROTO_IPV6, IPV6_JOIN_GROUP,
                  &mreq6, sizeof (mreq6)) < 0)
    zlog_warn ("Network: Join AllDRouters on ifindex %d Failed: %s",
               ifindex, strerror (errno));
  else
    zlog_info ("Network: Join AllDRouters on ifindex %d", ifindex);
}

void
ospf6_leave_alldrouters (u_int ifindex)
{
  struct ipv6_mreq mreq6;

  assert (ifindex);
  mreq6.ipv6mr_interface = ifindex;
  memcpy (&mreq6.ipv6mr_multiaddr, &alldrouters6.sin6_addr,
          sizeof (struct in6_addr));

  if (setsockopt (ospf6_sock, IPPROTO_IPV6, IPV6_LEAVE_GROUP,
                  &mreq6, sizeof (mreq6)) < 0)
    zlog_warn ("Network: Leave AllDRouters on ifindex %d Failed", ifindex);
  else
    zlog_info ("Network: Leave AllDRouters on ifindex %d", ifindex);
}

/* setsockopt ReUseAddr to on */
void
ospf6_set_reuseaddr ()
{
  u_int on = 0;
  if (setsockopt (ospf6_sock, SOL_SOCKET, SO_REUSEADDR, &on,
                  sizeof (u_int)) < 0)
    zlog_warn ("Network: set SO_REUSEADDR failed: %s", strerror (errno));
}

/* setsockopt MulticastLoop to off */
void
ospf6_reset_mcastloop ()
{
  u_int off = 0;
  if (setsockopt (ospf6_sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP,
                  &off, sizeof (u_int)) < 0)
    zlog_warn ("Network: reset IPV6_MULTICAST_LOOP failed: %s",
               strerror (errno));
}

void
ospf6_set_pktinfo ()
{
  u_int on = 1;
#ifdef IPV6_RECVPKTINFO	/*2292bis-01*/
  if (setsockopt (ospf6_sock, IPPROTO_IPV6, IPV6_RECVPKTINFO,
                  &on, sizeof (u_int)) < 0)
    zlog_warn ("Network: set IPV6_RECVPKTINFO failed: %s", strerror (errno));
#else /*RFC2292*/
  if (setsockopt (ospf6_sock, IPPROTO_IPV6, IPV6_PKTINFO,
                  &on, sizeof (u_int)) < 0)
    zlog_warn ("Network: set IPV6_PKTINFO failed: %s", strerror (errno));
#endif
}

void
ospf6_set_checksum ()
{
  int offset = 12;
#if !defined(DISABLE_IPV6_CHECKSUM)
  if (setsockopt (ospf6_sock, IPPROTO_IPV6, IPV6_CHECKSUM,
                  &offset, sizeof (offset)) < 0)
    zlog_warn ("Network: set IPV6_CHECKSUM failed: %s", strerror (errno));
#else
  zlog_warn ("Network: Don't set IPV6_CHECKSUM");
#endif /* DISABLE_IPV6_CHECKSUM */
}

void
ospf6_sendmsg (struct in6_addr *src, struct in6_addr *dst,
               unsigned int *ifindex, struct iovec *message)
{
  int retval;
  struct msghdr smsghdr;
  struct cmsghdr *scmsgp;
  u_char cmsgbuf[CMSG_SPACE(sizeof (struct in6_pktinfo))];
  struct in6_pktinfo *pktinfo;
  struct sockaddr_in6 dst_sin6;

  assert (dst);
  assert (*ifindex);

  scmsgp = (struct cmsghdr *)cmsgbuf;
  pktinfo = (struct in6_pktinfo *)(CMSG_DATA(scmsgp));
  memset (&dst_sin6, 0, sizeof (struct sockaddr_in6));

  /* source address */
  pktinfo->ipi6_ifindex = *ifindex;
  if (src)
    memcpy (&pktinfo->ipi6_addr, src, sizeof (struct in6_addr));
  else
    memset (&pktinfo->ipi6_addr, 0, sizeof (struct in6_addr));

  /* destination address */
  dst_sin6.sin6_family = AF_INET6;
#ifdef SIN6_LEN
  dst_sin6.sin6_len = sizeof (struct sockaddr_in6);
#endif /*SIN6_LEN*/
  memcpy (&dst_sin6.sin6_addr, dst, sizeof (struct in6_addr));
#ifdef HAVE_SIN6_SCOPE_ID
  dst_sin6.sin6_scope_id = *ifindex;
#endif

  /* send control msg */
  scmsgp->cmsg_level = IPPROTO_IPV6;
  scmsgp->cmsg_type = IPV6_PKTINFO;
  scmsgp->cmsg_len = CMSG_LEN (sizeof (struct in6_pktinfo));
  /* scmsgp = CMSG_NXTHDR (&smsghdr, scmsgp); */

  /* send msg hdr */
  smsghdr.msg_iov = message;
  smsghdr.msg_iovlen = iov_count (message);
  smsghdr.msg_name = (caddr_t) &dst_sin6;
  smsghdr.msg_namelen = sizeof (struct sockaddr_in6);
  smsghdr.msg_control = (caddr_t) cmsgbuf;
  smsghdr.msg_controllen = sizeof (cmsgbuf);

  retval = sendmsg (ospf6_sock, &smsghdr, 0);
  if (retval != iov_totallen (message))
    zlog_warn ("Network: sendmsg (ifindex: %d) failed: %s(%d)",
               *ifindex, strerror (errno), errno);
}

void
ospf6_recvmsg (struct in6_addr *src, struct in6_addr *dst,
               unsigned int *ifindex, struct iovec *message)
{
  int retval;
  struct msghdr rmsghdr;
  struct cmsghdr *rcmsgp;
  u_char cmsgbuf[CMSG_SPACE(sizeof (struct in6_pktinfo))];
  struct in6_pktinfo *pktinfo;
  struct sockaddr_in6 src_sin6;

  rcmsgp = (struct cmsghdr *)cmsgbuf;
  pktinfo = (struct in6_pktinfo *)(CMSG_DATA(rcmsgp));
  memset (&src_sin6, 0, sizeof (struct sockaddr_in6));

  /* receive control msg */
  rcmsgp->cmsg_level = IPPROTO_IPV6;
  rcmsgp->cmsg_type = IPV6_PKTINFO;
  rcmsgp->cmsg_len = CMSG_LEN (sizeof (struct in6_pktinfo));
  /* rcmsgp = CMSG_NXTHDR (&rmsghdr, rcmsgp); */

  /* receive msg hdr */
  rmsghdr.msg_iov = message;
  rmsghdr.msg_iovlen = iov_count (message);
  rmsghdr.msg_name = (caddr_t) &src_sin6;
  rmsghdr.msg_namelen = sizeof (struct sockaddr_in6);
  rmsghdr.msg_control = (caddr_t) cmsgbuf;
  rmsghdr.msg_controllen = sizeof (cmsgbuf);

  retval = recvmsg (ospf6_sock, &rmsghdr, 0);
  if (retval < 0)
    {
      zlog_warn ("Network: recvmsg failed: %s", strerror (errno));
    }
  else if (retval == iov_totallen (message))
    {
      zlog_warn ("Network: possibly buffer shortage: %d received, buffer size: %d",
                  retval, iov_totallen (message));
    }

  /* source address */
  assert (src);
  memcpy (src, &src_sin6.sin6_addr, sizeof (struct in6_addr));

  /* destination address */
  if (ifindex)
    *ifindex = pktinfo->ipi6_ifindex;
  if (dst)
    memcpy (dst, &pktinfo->ipi6_addr, sizeof (struct in6_addr));
}

void
ospf6_recvmsg_peek (struct in6_addr *src, struct in6_addr *dst,
                    unsigned int *ifindex, struct iovec *message)
{
  int retval;
  struct msghdr rmsghdr;
  struct cmsghdr *rcmsgp;
  u_char cmsgbuf[CMSG_SPACE(sizeof (struct in6_pktinfo))];
  struct in6_pktinfo *pktinfo;
  struct sockaddr_in6 src_sin6;

  rcmsgp = (struct cmsghdr *)cmsgbuf;
  pktinfo = (struct in6_pktinfo *)(CMSG_DATA(rcmsgp));
  memset (&src_sin6, 0, sizeof (struct sockaddr_in6));

  /* receive control msg */
  rcmsgp->cmsg_level = IPPROTO_IPV6;
  rcmsgp->cmsg_type = IPV6_PKTINFO;
  rcmsgp->cmsg_len = CMSG_LEN (sizeof (struct in6_pktinfo));
  /* rcmsgp = CMSG_NXTHDR (&rmsghdr, rcmsgp); */

  /* receive msg hdr */
  rmsghdr.msg_iov = message;
  rmsghdr.msg_iovlen = iov_count (message);
  rmsghdr.msg_name = (caddr_t) &src_sin6;
  rmsghdr.msg_namelen = sizeof (struct sockaddr_in6);
  rmsghdr.msg_control = (caddr_t) cmsgbuf;
  rmsghdr.msg_controllen = sizeof (cmsgbuf);

  retval = recvmsg (ospf6_sock, &rmsghdr, MSG_PEEK);
  if (retval != iov_totallen (message))
    zlog_warn ("Network: recvmsg failed: %s", strerror (errno));

  /* source address */
  assert (src);
  memcpy (src, &src_sin6.sin6_addr, sizeof (struct in6_addr));

  /* destination address */
  if (ifindex)
    *ifindex = pktinfo->ipi6_ifindex;
  if (dst)
    memcpy (dst, &pktinfo->ipi6_addr, sizeof (struct in6_addr));
}

