/*
 * 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[0];
  };

  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_warn ("apiserver_lsa_print: opaquelen=%d\n", opaquelen);

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

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

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

  new = XMALLOC (MTYPE_OSPF_API_MSG, sizeof (struct msg));
  memset (new, 0, 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 = sizeof (NameTab) / sizeof (NameTab[0]);
  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 = sizeof (NameTab) / sizeof (NameTab[0]);
  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_warn ("msg_print msg=NULL!\n");
      return;
    }

#ifdef ORIGINAL_CODING
  zlog_warn
    ("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_info
    ("API-msg [%s]: type(%d),len(%d),seq(%lu),data(%p),size(%lu)",
     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 ()
{
  struct msg_fifo *new;

  new = XMALLOC (MTYPE_OSPF_API_FIFO, sizeof (struct msg_fifo));
  memset (new, 0, sizeof (struct msg_fifo));

  return new;
}

/* 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;
  char buf[OSPF_API_MAX_MSG_SIZE];
  int bodylen;
  int rlen;

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

  if (rlen < 0)
    {
      zlog_warn ("msg_read: readn %s", 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", 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", 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 */
