/*
 * API message handling module for OSPF daemon and client.
 * Copyright (C) 2001, 2002 Ralph Keller
 *
 * 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>

#ifdef SUPPORT_OSPF_API
#ifndef HAVE_OPAQUE_LSA
#error "Core Opaque-LSA module must be configured."
#endif /* HAVE_OPAQUE_LSA */

#include "linklist.h"
#include "prefix.h"
#include "if.h"
#include "table.h"
#include "memory.h"
#include "command.h"
#include "vty.h"
#include "stream.h"
#include "log.h"
#include "thread.h"
#include "hash.h"
#include "sockunion.h"		/* for inet_aton() */
#include "buffer.h"
#include "network.h"

#include "ospfd/ospfd.h"
#include "ospfd/ospf_interface.h"
#include "ospfd/ospf_ism.h"
#include "ospfd/ospf_asbr.h"
#include "ospfd/ospf_lsa.h"
#include "ospfd/ospf_lsdb.h"
#include "ospfd/ospf_neighbor.h"
#include "ospfd/ospf_nsm.h"
#include "ospfd/ospf_flood.h"
#include "ospfd/ospf_packet.h"
#include "ospfd/ospf_spf.h"
#include "ospfd/ospf_dump.h"
#include "ospfd/ospf_route.h"
#include "ospfd/ospf_ase.h"
#include "ospfd/ospf_zebra.h"

#include "ospfd/ospf_api.h"


/* For debugging only, will be removed */
void
api_opaque_lsa_print (struct lsa_header *data)
{
  struct opaque_lsa
  {
    struct lsa_header header;
    u_char mydata[];
  };

  struct opaque_lsa *olsa;
  int opaquelen;
  int i;

  ospf_lsa_header_dump (data);

  olsa = (struct opaque_lsa *) data;

  opaquelen = ntohs (data->length) - OSPF_LSA_HEADER_SIZE;
  zlog_debug ("apiserver_lsa_print: opaquelen=%d\n", opaquelen);

  for (i = 0; i < opaquelen; i++)
    {
      zlog_debug ("0x%x ", olsa->mydata[i]);
    }
  zlog_debug ("\n");
}

/* -----------------------------------------------------------
 * Generic messages
 * -----------------------------------------------------------
 */

struct msg *
msg_new (u_char msgtype, void *msgbody, u_int32_t seqnum, u_int16_t msglen)
{
  struct msg *new;

  new = XCALLOC (MTYPE_OSPF_API_MSG, sizeof (struct msg));

  new->hdr.version = OSPF_API_VERSION;
  new->hdr.msgtype = msgtype;
  new->hdr.msglen = htons (msglen);
  new->hdr.msgseq = htonl (seqnum);

  new->s = stream_new (msglen);
  assert (new->s);
  stream_put (new->s, msgbody, msglen);

  return new;
}


/* Duplicate a message by copying content. */
struct msg *
msg_dup (struct msg *msg)
{
  struct msg *new;

  assert (msg);

  new = msg_new (msg->hdr.msgtype, STREAM_DATA (msg->s),
		 ntohl (msg->hdr.msgseq), ntohs (msg->hdr.msglen));
  return new;
}


/* XXX only for testing, will be removed */

struct nametab {
  int value;
  const char *name;
};

const char *
ospf_api_typename (int msgtype)
{
  struct nametab NameTab[] = {
    { MSG_REGISTER_OPAQUETYPE,   "Register opaque-type",   },
    { MSG_UNREGISTER_OPAQUETYPE, "Unregister opaque-type", },
    { MSG_REGISTER_EVENT,        "Register event",         },
    { MSG_SYNC_LSDB,             "Sync LSDB",              },
    { MSG_ORIGINATE_REQUEST,     "Originate request",      },
    { MSG_DELETE_REQUEST,        "Delete request",         },
    { MSG_REPLY,                 "Reply",                  },
    { MSG_READY_NOTIFY,          "Ready notify",           },
    { MSG_LSA_UPDATE_NOTIFY,     "LSA update notify",      },
    { MSG_LSA_DELETE_NOTIFY,     "LSA delete notify",      },
    { MSG_NEW_IF,                "New interface",          },
    { MSG_DEL_IF,                "Del interface",          },
    { MSG_ISM_CHANGE,            "ISM change",             },
    { MSG_NSM_CHANGE,            "NSM change",             },
  };

  int i, n = array_size(NameTab);
  const char *name = NULL;

  for (i = 0; i < n; i++)
    {
      if (NameTab[i].value == msgtype)
        {
          name = NameTab[i].name;
          break;
        }
    }

  return name ? name : "?";
}

const char *
ospf_api_errname (int errcode)
{
  struct nametab NameTab[] = {
    { OSPF_API_OK,                      "OK",                         },
    { OSPF_API_NOSUCHINTERFACE,         "No such interface",          },
    { OSPF_API_NOSUCHAREA,              "No such area",               },
    { OSPF_API_NOSUCHLSA,               "No such LSA",                },
    { OSPF_API_ILLEGALLSATYPE,          "Illegal LSA type",           },
    { OSPF_API_OPAQUETYPEINUSE,         "Opaque type in use",         },
    { OSPF_API_OPAQUETYPENOTREGISTERED, "Opaque type not registered", },
    { OSPF_API_NOTREADY,                "Not ready",                  },
    { OSPF_API_NOMEMORY,                "No memory",                  },
    { OSPF_API_ERROR,                   "Other error",                },
    { OSPF_API_UNDEF,                   "Undefined",                  },
  };

  int i, n = array_size(NameTab);
  const char *name = NULL;

  for (i = 0; i < n; i++)
    {
      if (NameTab[i].value == errcode)
        {
          name = NameTab[i].name;
          break;
        }
    }

  return name ? name : "?";
}

void
msg_print (struct msg *msg)
{
  if (!msg)
    {
      zlog_debug ("msg_print msg=NULL!\n");
      return;
    }

#ifdef ORIGINAL_CODING
  zlog_debug
    ("msg=%p msgtype=%d msglen=%d msgseq=%d streamdata=%p streamsize=%lu\n",
     msg, msg->hdr.msgtype, ntohs (msg->hdr.msglen), ntohl (msg->hdr.msgseq),
     STREAM_DATA (msg->s), STREAM_SIZE (msg->s));
#else /* ORIGINAL_CODING */
  /* API message common header part. */
  zlog_debug
    ("API-msg [%s]: type(%d),len(%d),seq(%lu),data(%p),size(%zd)",
     ospf_api_typename (msg->hdr.msgtype), msg->hdr.msgtype, 
     ntohs (msg->hdr.msglen), (unsigned long) ntohl (msg->hdr.msgseq),
     STREAM_DATA (msg->s), STREAM_SIZE (msg->s));

  /* API message body part. */
#ifdef ndef
  /* Generic Hex/Ascii dump */
  DumpBuf (STREAM_DATA (msg->s), STREAM_SIZE (msg->s)); /* Sorry, deleted! */
#else /* ndef */
  /* Message-type dependent dump function. */
#endif /* ndef */

  return;
#endif /* ORIGINAL_CODING */
}

void
msg_free (struct msg *msg)
{
  if (msg->s)
    stream_free (msg->s);

  XFREE (MTYPE_OSPF_API_MSG, msg);
}


/* Set sequence number of message */
void
msg_set_seq (struct msg *msg, u_int32_t seqnr)
{
  assert (msg);
  msg->hdr.msgseq = htonl (seqnr);
}

/* Get sequence number of message */
u_int32_t
msg_get_seq (struct msg *msg)
{
  assert (msg);
  return ntohl (msg->hdr.msgseq);
}

/* -----------------------------------------------------------
 * Message fifo queues
 * -----------------------------------------------------------
 */

struct msg_fifo *
msg_fifo_new ()
{
  return XCALLOC (MTYPE_OSPF_API_FIFO, sizeof (struct msg_fifo));
}

/* Add new message to fifo. */
void
msg_fifo_push (struct msg_fifo *fifo, struct msg *msg)
{
  if (fifo->tail)
    fifo->tail->next = msg;
  else
    fifo->head = msg;

  fifo->tail = msg;
  fifo->count++;
}


/* Remove first message from fifo. */
struct msg *
msg_fifo_pop (struct msg_fifo *fifo)
{
  struct msg *msg;

  msg = fifo->head;
  if (msg)
    {
      fifo->head = msg->next;

      if (fifo->head == NULL)
	fifo->tail = NULL;

      fifo->count--;
    }
  return msg;
}

/* Return first fifo entry but do not remove it. */
struct msg *
msg_fifo_head (struct msg_fifo *fifo)
{
  return fifo->head;
}

/* Flush message fifo. */
void
msg_fifo_flush (struct msg_fifo *fifo)
{
  struct msg *op;
  struct msg *next;

  for (op = fifo->head; op; op = next)
    {
      next = op->next;
      msg_free (op);
    }

  fifo->head = fifo->tail = NULL;
  fifo->count = 0;
}

/* Free API message fifo. */
void
msg_fifo_free (struct msg_fifo *fifo)
{
  msg_fifo_flush (fifo);

  XFREE (MTYPE_OSPF_API_FIFO, fifo);
}

struct msg *
msg_read (int fd)
{
  struct msg *msg;
  struct apimsghdr hdr;
  u_char buf[OSPF_API_MAX_MSG_SIZE];
  int bodylen;
  int rlen;

  /* Read message header */
  rlen = readn (fd, (u_char *) &hdr, sizeof (struct apimsghdr));

  if (rlen < 0)
    {
      zlog_warn ("msg_read: readn %s", safe_strerror (errno));
      return NULL;
    }
  else if (rlen == 0)
    {
      zlog_warn ("msg_read: Connection closed by peer");
      return NULL;
    }
  else if (rlen != sizeof (struct apimsghdr))
    {
      zlog_warn ("msg_read: Cannot read message header!");
      return NULL;
    }

  /* Check version of API protocol */
  if (hdr.version != OSPF_API_VERSION)
    {
      zlog_warn ("msg_read: OSPF API protocol version mismatch");
      return NULL;
    }

  /* Determine body length. */
  bodylen = ntohs (hdr.msglen);
  if (bodylen > 0)
    {

      /* Read message body */
      rlen = readn (fd, buf, bodylen);
      if (rlen < 0)
	{
	  zlog_warn ("msg_read: readn %s", safe_strerror (errno));
	  return NULL;
	}
      else if (rlen == 0)
	{
	  zlog_warn ("msg_read: Connection closed by peer");
	  return NULL;
	}
      else if (rlen != bodylen)
	{
	  zlog_warn ("msg_read: Cannot read message body!");
	  return NULL;
	}
    }

  /* Allocate new message */
  msg = msg_new (hdr.msgtype, buf, ntohl (hdr.msgseq), ntohs (hdr.msglen));

  return msg;
}

int
msg_write (int fd, struct msg *msg)
{
  u_char buf[OSPF_API_MAX_MSG_SIZE];
  int l;
  int wlen;

  assert (msg);
  assert (msg->s);

  /* Length of message including header */
  l = sizeof (struct apimsghdr) + ntohs (msg->hdr.msglen);

  /* Make contiguous memory buffer for message */
  memcpy (buf, &msg->hdr, sizeof (struct apimsghdr));
  memcpy (buf + sizeof (struct apimsghdr), STREAM_DATA (msg->s),
	  ntohs (msg->hdr.msglen));

  wlen = writen (fd, buf, l);
  if (wlen < 0)
    {
      zlog_warn ("msg_write: writen %s", safe_strerror (errno));
      return -1;
    }
  else if (wlen == 0)
    {
      zlog_warn ("msg_write: Connection closed by peer");
      return -1;
    }
  else if (wlen != l)
    {
      zlog_warn ("msg_write: Cannot write API message");
      return -1;
    }
  return 0;
}

/* -----------------------------------------------------------
 * Specific messages
 * -----------------------------------------------------------
 */

struct msg *
new_msg_register_opaque_type (u_int32_t seqnum, u_char ltype, u_char otype)
{
  struct msg_register_opaque_type rmsg;

  rmsg.lsatype = ltype;
  rmsg.opaquetype = otype;
  memset (&rmsg.pad, 0, sizeof (rmsg.pad));

  return msg_new (MSG_REGISTER_OPAQUETYPE, &rmsg, seqnum,
		  sizeof (struct msg_register_opaque_type));
}

struct msg *
new_msg_register_event (u_int32_t seqnum, struct lsa_filter_type *filter)
{
  u_char buf[OSPF_API_MAX_MSG_SIZE];
  struct msg_register_event *emsg;
  int len;

  emsg = (struct msg_register_event *) buf;
  len = sizeof (struct msg_register_event) +
    filter->num_areas * sizeof (struct in_addr);
  emsg->filter.typemask = htons (filter->typemask);
  emsg->filter.origin = filter->origin;
  emsg->filter.num_areas = filter->num_areas;
  return msg_new (MSG_REGISTER_EVENT, emsg, seqnum, len);
}

struct msg *
new_msg_sync_lsdb (u_int32_t seqnum, struct lsa_filter_type *filter)
{
  u_char buf[OSPF_API_MAX_MSG_SIZE];
  struct msg_sync_lsdb *smsg;
  int len;

  smsg = (struct msg_sync_lsdb *) buf;
  len = sizeof (struct msg_sync_lsdb) +
    filter->num_areas * sizeof (struct in_addr);
  smsg->filter.typemask = htons (filter->typemask);
  smsg->filter.origin = filter->origin;
  smsg->filter.num_areas = filter->num_areas;
  return msg_new (MSG_SYNC_LSDB, smsg, seqnum, len);
}


struct msg *
new_msg_originate_request (u_int32_t seqnum,
			   struct in_addr ifaddr,
			   struct in_addr area_id, struct lsa_header *data)
{
  struct msg_originate_request *omsg;
  int omsglen;
  char buf[OSPF_API_MAX_MSG_SIZE];

  omsglen = sizeof (struct msg_originate_request) - sizeof (struct lsa_header)
    + ntohs (data->length);

  omsg = (struct msg_originate_request *) buf;
  omsg->ifaddr = ifaddr;
  omsg->area_id = area_id;
  memcpy (&omsg->data, data, ntohs (data->length));

  return msg_new (MSG_ORIGINATE_REQUEST, omsg, seqnum, omsglen);
}

struct msg *
new_msg_delete_request (u_int32_t seqnum,
			struct in_addr area_id, u_char lsa_type,
			u_char opaque_type, u_int32_t opaque_id)
{
  struct msg_delete_request dmsg;
  dmsg.area_id = area_id;
  dmsg.lsa_type = lsa_type;
  dmsg.opaque_type = opaque_type;
  dmsg.opaque_id = htonl (opaque_id);
  memset (&dmsg.pad, 0, sizeof (dmsg.pad));

  return msg_new (MSG_DELETE_REQUEST, &dmsg, seqnum,
		  sizeof (struct msg_delete_request));
}


struct msg *
new_msg_reply (u_int32_t seqnr, u_char rc)
{
  struct msg *msg;
  struct msg_reply rmsg;

  /* Set return code */
  rmsg.errcode = rc;
  memset (&rmsg.pad, 0, sizeof (rmsg.pad));

  msg = msg_new (MSG_REPLY, &rmsg, seqnr, sizeof (struct msg_reply));

  return msg;
}

struct msg *
new_msg_ready_notify (u_int32_t seqnr, u_char lsa_type,
		      u_char opaque_type, struct in_addr addr)
{
  struct msg_ready_notify rmsg;

  rmsg.lsa_type = lsa_type;
  rmsg.opaque_type = opaque_type;
  memset (&rmsg.pad, 0, sizeof (rmsg.pad));
  rmsg.addr = addr;

  return msg_new (MSG_READY_NOTIFY, &rmsg, seqnr,
		  sizeof (struct msg_ready_notify));
}

struct msg *
new_msg_new_if (u_int32_t seqnr,
		struct in_addr ifaddr, struct in_addr area_id)
{
  struct msg_new_if nmsg;

  nmsg.ifaddr = ifaddr;
  nmsg.area_id = area_id;

  return msg_new (MSG_NEW_IF, &nmsg, seqnr, sizeof (struct msg_new_if));
}

struct msg *
new_msg_del_if (u_int32_t seqnr, struct in_addr ifaddr)
{
  struct msg_del_if dmsg;

  dmsg.ifaddr = ifaddr;

  return msg_new (MSG_DEL_IF, &dmsg, seqnr, sizeof (struct msg_del_if));
}

struct msg *
new_msg_ism_change (u_int32_t seqnr, struct in_addr ifaddr,
		    struct in_addr area_id, u_char status)
{
  struct msg_ism_change imsg;

  imsg.ifaddr = ifaddr;
  imsg.area_id = area_id;
  imsg.status = status;
  memset (&imsg.pad, 0, sizeof (imsg.pad));

  return msg_new (MSG_ISM_CHANGE, &imsg, seqnr,
		  sizeof (struct msg_ism_change));
}

struct msg *
new_msg_nsm_change (u_int32_t seqnr, struct in_addr ifaddr,
		    struct in_addr nbraddr,
		    struct in_addr router_id, u_char status)
{
  struct msg_nsm_change nmsg;

  nmsg.ifaddr = ifaddr;
  nmsg.nbraddr = nbraddr;
  nmsg.router_id = router_id;
  nmsg.status = status;
  memset (&nmsg.pad, 0, sizeof (nmsg.pad));

  return msg_new (MSG_NSM_CHANGE, &nmsg, seqnr,
		  sizeof (struct msg_nsm_change));
}

struct msg *
new_msg_lsa_change_notify (u_char msgtype,
			   u_int32_t seqnum,
			   struct in_addr ifaddr,
			   struct in_addr area_id,
			   u_char is_self_originated, struct lsa_header *data)
{
  u_char buf[OSPF_API_MAX_MSG_SIZE];
  struct msg_lsa_change_notify *nmsg;
  int len;

  assert (data);

  nmsg = (struct msg_lsa_change_notify *) buf;
  len = ntohs (data->length) + sizeof (struct msg_lsa_change_notify)
    - sizeof (struct lsa_header);
  nmsg->ifaddr = ifaddr;
  nmsg->area_id = area_id;
  nmsg->is_self_originated = is_self_originated;
  memset (&nmsg->pad, 0, sizeof (nmsg->pad));
  memcpy (&nmsg->data, data, ntohs (data->length));

  return msg_new (msgtype, nmsg, seqnum, len);
}

#endif /* SUPPORT_OSPF_API */
