2005-10-01 Andrew J. Schorr <ajschorr@alumni.princeton.edu>

	* zebra.h: Declare new functions zebra_route_string() and
	  zebra_route_char().
	* log.c: (zroute_lookup,zebra_route_string,zebra_route_char) New
	  functions to map zebra route numbers to strings.
	* zebra_vty.c: (route_type_str) Remove obsolete function: use new
	  library function zebra_route_string() instead.  Note that there
	  are a few differences: for IPv6 routes, we now get "ripng" and
	  "ospf6" instead of the old behavior ("rip" and "ospf").
	  (route_type_char) Remove obsolete function: ues new library function
	  zebra_route_char() instead.  Note that there is one difference:
	  the old function returned 'S' for a ZEBRA_ROUTE_SYSTEM route,
	  whereas the new one returns 'X'.
	  (vty_show_ip_route_detail,vty_show_ipv6_route_detail) Replace
	  route_type_str() with zebra_route_string().
	  (vty_show_ip_route,vty_show_ipv6_route) Replace route_type_char()
	  with zebra_route_char().
	* bgp_vty.c: (bgp_config_write_redistribute) Use new library function
	  zebra_route_string instead of a local hard-coded table.
	* ospf6_asbr.c: Remove local hard-coded tables zroute_name and
	  zroute_abname. Change the ZROUTE_NAME macro to use new library
	  function zebra_route_string().  Remove the ZROUTE_ABNAME macro.
	  (ospf6_asbr_external_route_show): Replace ZROUTE_ABNAME() with
	  a call to zebra_route_char(), and be sure to fix the format string,
	  since we now have a char instead of a char *.
	* ospf6_zebra.c: Remove local hard-coded tables zebra_route_name and
	  zebra_route_abname.  Note that the zebra_route_name[] table
	  contained mixed-case strings, whereas the zebra_route_string()
	  function returns lower-case strings.
	  (ospf6_zebra_read_ipv6): Change debug message to use new library
	  function zebra_route_string() instead of zebra_route_name[].
	  (show_zebra): Use new library function zebra_route_string() instead
	  of zebra_route_name[].
	* ospf_dump.c: Remove local hard-coded table ospf_redistributed_proto.
	  (ospf_redist_string) New function implemented using new library
	  function zebra_route_string().  Note that there are a few differences
	  in the output that will result: the new function returns strings
	  that are lower-case, whereas the old table was mixed case.  Also,
	  the old table mapped ZEBRA_ROUTE_OSPF6 to "OSPFv3", whereas the
	  new function returns "ospf6".
	* ospfd.h: Remove extern struct message ospf_redistributed_proto[],
	  and add extern const char *ospf_redist_string(u_int route_type)
	  instead.
	* ospf_asbr.c: (ospf_external_info_add) In two messages, use
	  ospf_redist_string instead of LOOKUP(ospf_redistributed_proto).
	* ospf_vty.c: Remove local hard-coded table distribute_str.
	  (config_write_ospf_redistribute,config_write_ospf_distribute): Use
	  new library function zebra_route_string() instead of distribute_str[].
	* ospf_zebra.c: (ospf_redistribute_set,ospf_redistribute_unset,
	  ospf_redistribute_default_set,ospf_redistribute_check)
	  In debug messages, use ospf_redist_string() instead of
	  LOOKUP(ospf_redistributed_proto).
	* rip_zebra.c: (config_write_rip_redistribute): Remove local hard-coded
	  table str[]. Replace str[] with calls to new library function
	  zebra_route_string().
	* ripd.c: Remove local hard-coded table route_info[].
	  (show_ip_rip) Replace uses of str[] with calls to new library
	  functions zebra_route_char and zebra_route_string.
	* ripng_zebra.c: (ripng_redistribute_write) Remove local hard-coded
	  table str[].  Replace str[i] with new library function
	  zebra_route_string(i).
	* ripngd.c: Remove local hard-coded table route_info[].
	  (show_ipv6_ripng) Use new library function zebra_route_char() instead
	  of table route_info[].
diff --git a/lib/log.c b/lib/log.c
index 2c4b399..6748dbc 100644
--- a/lib/log.c
+++ b/lib/log.c
@@ -1,5 +1,5 @@
 /*
- * $Id: log.c,v 1.25 2005/02/03 19:22:05 ajs Exp $
+ * $Id: log.c,v 1.26 2005/10/01 17:38:07 ajs Exp $
  *
  * Logging of zebra
  * Copyright (C) 1997, 1998, 1999 Kunihiro Ishiguro
@@ -703,3 +703,60 @@
   const char *s = strerror(errnum);
   return (s != NULL) ? s : "Unknown error";
 }
+
+/* Note: this table must match the ordering in lib/zebra.h */
+static const struct zebra_route_desc {
+  u_int zroute;
+  const char *string;
+  char chr;
+} route_types[] = {
+  { ZEBRA_ROUTE_SYSTEM, "system", 'X' },
+  { ZEBRA_ROUTE_KERNEL, "kernel", 'K' },
+  { ZEBRA_ROUTE_CONNECT, "connected", 'C' },
+  { ZEBRA_ROUTE_STATIC, "static", 'S' },
+  { ZEBRA_ROUTE_RIP, "rip", 'R' },
+  { ZEBRA_ROUTE_RIPNG, "ripng", 'R' },
+  { ZEBRA_ROUTE_OSPF, "ospf", 'O' },
+  { ZEBRA_ROUTE_OSPF6, "ospf6", 'O' },
+  { ZEBRA_ROUTE_ISIS, "isis", 'I' },
+  { ZEBRA_ROUTE_BGP, "bgp", 'B' },
+  { ZEBRA_ROUTE_HSLS, "hsls", 'H' },
+};
+
+static const struct zebra_route_desc *
+zroute_lookup(u_int zroute)
+{
+  static const struct zebra_route_desc unknown = { 0, "unknown", '?' };
+  u_int i;
+
+  if (zroute >= sizeof(route_types)/sizeof(route_types[0]))
+    {
+      zlog_err("unknown zebra route type: %u", zroute);
+      return &unknown;
+    }
+  if (zroute == route_types[zroute].zroute)
+    return &route_types[zroute];
+  for (i = 0; i < sizeof(route_types)/sizeof(route_types[0]); i++)
+    {
+      if (zroute == route_types[i].zroute)
+        {
+	  zlog_warn("internal error: route type table out of order "
+		    "while searching for %u, please notify developers", zroute);
+	  return &route_types[i];
+        }
+    }
+  zlog_err("internal error: cannot find route type %u in table!", zroute);
+  return &unknown;
+}
+
+const char *
+zebra_route_string(u_int zroute)
+{
+  return zroute_lookup(zroute)->string;
+}
+
+char
+zebra_route_char(u_int zroute)
+{
+  return zroute_lookup(zroute)->chr;
+}