/*
 * $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.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)
{
  FILE *fp;

  if (argc == 1)
      usage_exit ();

  /* Establish connection to zebra. */
  zclient = zclient_new ();
  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;
}
