/*
 * $Quagga: $Format:%an, %ai, %h$ $
 *
 * GNU Zebra client test main routine.
 * Copyright (C) 1997 Kunihiro Ishiguro
 *
 * 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>

#include "prefix.h"
#include "stream.h"
#include "zclient.h"
#include "thread.h"
#include "table.h"
#include "zebra/rib.h"
#include "zebra/zserv.h"

struct thread *master;

/* Zebra client structure. */
struct zclient *zclient = NULL;

/* Zebra socket. */
int sock;

/* IPv4 route add and delete test. */
void
zebra_test_ipv4 (int command, int type, char *prefix, char *gateway,
		 u_char distance)
{
  struct zapi_ipv4 api;
  struct prefix_ipv4 p;
  struct in_addr gate;
  struct in_addr *gpnt;

  str2prefix_ipv4 (prefix, &p);
  inet_aton (gateway, &gate);
  gpnt = &gate;

  api.vrf_id = VRF_DEFAULT;
  api.type = type;
  api.flags = 0;

  api.message = 0;
  SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
  api.nexthop_num = 1;
  api.nexthop = &gpnt;
  api.ifindex_num = 0;
  if (distance)
    {
      SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);
      api.distance = distance;
    }
  

  switch (command)
    {
    case ZEBRA_IPV4_ROUTE_ADD:
      zapi_ipv4_add (zclient, &p, &api);
      break;
    case ZEBRA_IPV4_ROUTE_DELETE:
      zapi_ipv4_delete (zclient, &p, &api);
      break;
    }
}

#ifdef HAVE_IPV6
/* IPv6 route add and delete test. */
void
zebra_test_v6 (int sock)
{
  struct prefix_ipv6 p;
  struct in6_addr nexthop;

  str2prefix_ipv6 ("3ffe:506::2/128", &p);
  inet_pton (AF_INET6, "::1", &nexthop);

  /* zebra_ipv6_add (sock, ZEBRA_ROUTE_STATIC, 0, &p, &nexthop, 1); */

  sleep (5);
  /* zebra_ipv6_delete (sock, ZEBRA_ROUTE_STATIC, 0, &p, &nexthop, 1); */
}
#endif /* HAVE_IPV6 */

/* Print out usage and exit. */
void
usage_exit ()
{
  fprintf (stderr, "Usage: client filename\n");
  exit (1);
}

struct zebra_info 
{
  char *str;
  int type;
} zebra_type[] = 
{
  { "static", ZEBRA_ROUTE_STATIC },
  { "rip",    ZEBRA_ROUTE_RIP },
  { "ripng",  ZEBRA_ROUTE_RIPNG },
  { "babel",  ZEBRA_ROUTE_BABEL },
  { "ospf",   ZEBRA_ROUTE_OSPF },
  { "ospf6",  ZEBRA_ROUTE_OSPF6 },
  { "bgp",    ZEBRA_ROUTE_BGP },
  { NULL,     0 }
};

/* Zebra route simulator. */
void
zebra_sim (FILE *fp)
{
  char buf[BUFSIZ];
  char distance_str[BUFSIZ];
  u_char distance;

  while (fgets (buf, sizeof buf, fp))
    {
      int i;
      int ret;
      int type;
      char str[BUFSIZ], command[BUFSIZ], prefix[BUFSIZ], gateway[BUFSIZ];

      distance = 0;

      if (*buf == '#')
	continue;

      type = ZEBRA_ROUTE_STATIC;

      ret = sscanf (buf, "%s %s %s %s %s\n", command, str, prefix, gateway,
		    distance_str);

      if (ret == 5)
	{
	  distance = atoi (distance_str);
	}
      else
	{
	  ret = sscanf (buf, "%s %s %s %s\n", command, str, prefix, gateway);

	  if (ret != 4)
	    continue;
	}

      for (i = 0; i < 10; i++)
	{
	  if (!zebra_type[i].str)
	    break;
	  if (strcmp (zebra_type[i].str, str) == 0)
	    {
	      type = zebra_type[i].type;
	      break;
	    }
	}
      
      if (strcmp (command, "add") == 0)
	{
	  zebra_test_ipv4 (ZEBRA_IPV4_ROUTE_ADD, type, prefix, gateway,
			   distance);
	  printf ("%s", buf);
	  continue;
	}

      if (strcmp (command, "del") == 0)
	{
	  zebra_test_ipv4 (ZEBRA_IPV4_ROUTE_DELETE, type, prefix, gateway,
			   distance);
	  printf ("%s", buf);
	  continue;
	}
    }
}

/* Test zebra client main routine. */
int
main (int argc, char **argv)
{
  struct thread_master *master;
  FILE *fp;

  if (argc == 1)
      usage_exit ();

  master = thread_master_create ();
  /* Establish connection to zebra. */
  zclient = zclient_new (master);
  zclient->enable = 1;
#ifdef HAVE_TCP_ZEBRA
  zclient->sock = zclient_socket ();
#else
  zclient->sock = zclient_socket_un (ZEBRA_SERV_PATH);
#endif /* HAVE_TCP_ZEBRA */

  /* Open simulation file. */
  fp = fopen (argv[1], "r");
  if (fp == NULL)
    {
      fprintf (stderr, "can't open %s\n", argv[1]);
      exit (1);
    }

  /* Do main work. */
  zebra_sim (fp);

  sleep (100);

  fclose (fp);
  close (sock);

  return 0;
}
