/*
 * 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 = 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_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(%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 ()
{
  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 */
