/* RIPng peer support
 * Copyright (C) 2000 Kunihiro Ishiguro <kunihiro@zebra.org>
 *
 * 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.  
 */

/* RIPng support added by Vincent Jardin <vincent.jardin@6wind.com>
 * Copyright (C) 2002 6WIND
 */

#include <zebra.h>

#include "if.h"
#include "prefix.h"
#include "command.h"
#include "linklist.h"
#include "thread.h"
#include "memory.h"

#include "ripngd/ripngd.h"
#include "ripngd/ripng_nexthop.h"


/* Linked list of RIPng peer. */
struct list *peer_list;

struct ripng_peer *
ripng_peer_new ()
{
  struct ripng_peer *new;

  new = XMALLOC (MTYPE_RIPNG_PEER, sizeof (struct ripng_peer));
  memset (new, 0, sizeof (struct ripng_peer));
  return new;
}

void
ripng_peer_free (struct ripng_peer *peer)
{
  XFREE (MTYPE_RIPNG_PEER, peer);
}

struct ripng_peer *
ripng_peer_lookup (struct in6_addr *addr)
{
  struct ripng_peer *peer;
  struct listnode *node, *nnode;

  for (ALL_LIST_ELEMENTS (peer_list, node, nnode, peer))
    {
      if (IPV6_ADDR_SAME (&peer->addr, addr))
	return peer;
    }
  return NULL;
}

struct ripng_peer *
ripng_peer_lookup_next (struct in6_addr *addr)
{
  struct ripng_peer *peer;
  struct listnode *node, *nnode;

  for (ALL_LIST_ELEMENTS (peer_list, node, nnode, peer))
    {
      if (addr6_cmp(&peer->addr, addr) > 0) 
	return peer;
    }
  return NULL;
}

/* RIPng peer is timeout.
 * Garbage collector.
 **/
int
ripng_peer_timeout (struct thread *t)
{
  struct ripng_peer *peer;

  peer = THREAD_ARG (t);
  listnode_delete (peer_list, peer);
  ripng_peer_free (peer);

  return 0;
}

/* Get RIPng peer.  At the same time update timeout thread. */
struct ripng_peer *
ripng_peer_get (struct in6_addr *addr)
{
  struct ripng_peer *peer;

  peer = ripng_peer_lookup (addr);

  if (peer)
    {
      if (peer->t_timeout)
	thread_cancel (peer->t_timeout);
    }
  else
    {
      peer = ripng_peer_new ();
      peer->addr = *addr; /* XXX */
      listnode_add_sort (peer_list, peer);
    }

  /* Update timeout thread. */
  peer->t_timeout = thread_add_timer (master, ripng_peer_timeout, peer,
				      RIPNG_PEER_TIMER_DEFAULT);

  /* Last update time set. */
  time (&peer->uptime);
  
  return peer;
}

void
ripng_peer_update (struct sockaddr_in6 *from, u_char version)
{
  struct ripng_peer *peer;
  peer = ripng_peer_get (&from->sin6_addr);
  peer->version = version;
}

void
ripng_peer_bad_route (struct sockaddr_in6 *from)
{
  struct ripng_peer *peer;
  peer = ripng_peer_get (&from->sin6_addr);
  peer->recv_badroutes++;
}

void
ripng_peer_bad_packet (struct sockaddr_in6 *from)
{
  struct ripng_peer *peer;
  peer = ripng_peer_get (&from->sin6_addr);
  peer->recv_badpackets++;
}

/* Display peer uptime. */
char *
ripng_peer_uptime (struct ripng_peer *peer, char *buf, size_t len)
{
  time_t uptime;
  struct tm *tm;

  /* If there is no connection has been done before print `never'. */
  if (peer->uptime == 0)
    {
      snprintf (buf, len, "never   ");
      return buf;
    }

  /* Get current time. */
  uptime = time (NULL);
  uptime -= peer->uptime;
  tm = gmtime (&uptime);

  /* Making formatted timer strings. */
#define ONE_DAY_SECOND 60*60*24
#define ONE_WEEK_SECOND 60*60*24*7

  if (uptime < ONE_DAY_SECOND)
    snprintf (buf, len, "%02d:%02d:%02d", 
	      tm->tm_hour, tm->tm_min, tm->tm_sec);
  else if (uptime < ONE_WEEK_SECOND)
    snprintf (buf, len, "%dd%02dh%02dm", 
	      tm->tm_yday, tm->tm_hour, tm->tm_min);
  else
    snprintf (buf, len, "%02dw%dd%02dh", 
	      tm->tm_yday/7, tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
  return buf;
}

void
ripng_peer_display (struct vty *vty)
{
  struct ripng_peer *peer;
  struct listnode *node, *nnode;
#define RIPNG_UPTIME_LEN 25
  char timebuf[RIPNG_UPTIME_LEN];

  for (ALL_LIST_ELEMENTS (peer_list, node, nnode, peer))
    {
      vty_out (vty, "    %s %s%14s %10d %10d %10d      %s%s", inet6_ntoa (peer->addr),
               VTY_NEWLINE, " ",
	       peer->recv_badpackets, peer->recv_badroutes,
	       ZEBRA_RIPNG_DISTANCE_DEFAULT,
	       ripng_peer_uptime (peer, timebuf, RIPNG_UPTIME_LEN),
	       VTY_NEWLINE);
    }
}

int
ripng_peer_list_cmp (struct ripng_peer *p1, struct ripng_peer *p2)
{
  return addr6_cmp(&p1->addr, &p2->addr) > 0;
}

void
ripng_peer_init ()
{
  peer_list = list_new ();
  peer_list->cmp = (int (*)(void *, void *)) ripng_peer_list_cmp;
}
