/* 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 *nn;

  LIST_LOOP (peer_list, peer, nn)
    {
      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 *nn;

  LIST_LOOP (peer_list, peer, nn)
    {
      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 *nn;
#define RIPNG_UPTIME_LEN 25
  char timebuf[RIPNG_UPTIME_LEN];

  LIST_LOOP (peer_list, peer, nn)
    {
      vty_out (vty, "    %s %s%14s %10d %10d %10d      %s%s", inet6_ntop (&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;
}
