2005-04-15 Paul Jakma <paul@dishone.st>

	* memtypes.c: The new, unified location for memory type definitions.
	  The memtype enum and declarations for memory_lists are built from
          this automatically and put into memtypes.h.
        * memtypes.awk: New script to generate memtypes.h from memtypes.c
        * memory.h: Finally, the enum can banished!
        * memory.c: Finally, the seperate mtype memory_list definitions can
          be banished!
          (log_memstats) Increase width of fields
          (show_memory_zebra_cmd) display zebra specific memory types.
          Increase width of fields.
        * Makefile.am: Add memtypes.{c,h}, add BUILT_SOURCES for memtypes.h
          Add a rule to build memtypes.h using memtypes.awk.
          Add memtypes.awk to EXTRA_DIST.
diff --git a/lib/ChangeLog b/lib/ChangeLog
index 2bacff1..6f27b8d 100644
--- a/lib/ChangeLog
+++ b/lib/ChangeLog
@@ -1,3 +1,19 @@
+2005-04-15 Paul Jakma <paul@dishone.st>
+
+	* memtypes.c: The new, unified location for memory type definitions.
+	  The memtype enum and declarations for memory_lists are built from
+          this automatically and put into memtypes.h.
+        * memtypes.awk: New script to generate memtypes.h from memtypes.c
+        * memory.h: Finally, the enum can banished!
+        * memory.c: Finally, the seperate mtype memory_list definitions can
+          be banished!
+          (log_memstats) Increase width of fields
+          (show_memory_zebra_cmd) display zebra specific memory types.
+          Increase width of fields.
+        * Makefile.am: Add memtypes.{c,h}, add BUILT_SOURCES for memtypes.h
+          Add a rule to build memtypes.h using memtypes.awk.
+          Add memtypes.awk to EXTRA_DIST.
+
 2005-04-11 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
 
 	* zclient.h (struct zclient): Add two fields to support non-blocking
diff --git a/lib/Makefile.am b/lib/Makefile.am
index bc321b6..93442c8 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -12,7 +12,9 @@
 	sockunion.c prefix.c thread.c if.c memory.c buffer.c table.c hash.c \
 	filter.c routemap.c distribute.c stream.c str.c log.c plist.c \
 	zclient.c sockopt.c smux.c md5.c if_rmap.c keychain.c privs.c \
-	sigevent.c pqueue.c jhash.c
+	sigevent.c pqueue.c jhash.c memtypes.c
+
+BUILT_SOURCES = memtypes.h
 
 libzebra_la_DEPENDENCIES = @LIB_REGEX@
 
@@ -23,7 +25,9 @@
 	memory.h network.h prefix.h routemap.h distribute.h sockunion.h \
 	str.h stream.h table.h thread.h vector.h version.h vty.h zebra.h \
 	plist.h zclient.h sockopt.h smux.h md5-gnu.h if_rmap.h keychain.h \
-	privs.h sigevent.h pqueue.h jhash.h zassert.h
+	privs.h sigevent.h pqueue.h jhash.h zassert.h memtypes.h
 
-EXTRA_DIST = regex.c regex-gnu.h
+EXTRA_DIST = regex.c regex-gnu.h memtypes.awk
 
+memtypes.h: memtypes.c memtypes.awk
+	($(AWK) -f memtypes.awk memtypes.c > memtypes.h)
diff --git a/lib/memory.c b/lib/memory.c
index bad884e..335a921 100644
--- a/lib/memory.c
+++ b/lib/memory.c
@@ -233,200 +233,6 @@
 #include "vty.h"
 #include "command.h"
 
-/* For pretty printng of memory allocate information. */
-struct memory_list
-{
-  int index;
-  const char *format;
-};
-
-static struct memory_list memory_list_lib[] =
-{
-  { MTYPE_TMP,                "Temporary memory" },
-  { MTYPE_ROUTE_TABLE,        "Route table     " },
-  { MTYPE_ROUTE_NODE,         "Route node      " },
-  { MTYPE_RIB,                "RIB             " },
-  { MTYPE_DISTRIBUTE,         "Distribute list " },
-  { MTYPE_DISTRIBUTE_IFNAME,  "Dist-list ifname" },
-  { MTYPE_NEXTHOP,            "Nexthop         " },
-  { MTYPE_LINK_LIST,          "Link List       " },
-  { MTYPE_LINK_NODE,          "Link Node       " },
-  { MTYPE_HASH,               "Hash            " },
-  { MTYPE_HASH_BACKET,        "Hash Bucket     " },
-  { MTYPE_ACCESS_LIST,        "Access List     " },
-  { MTYPE_ACCESS_LIST_STR,    "Access List Str " },
-  { MTYPE_ACCESS_FILTER,      "Access Filter   " },
-  { MTYPE_PREFIX_LIST,        "Prefix List     " },
-  { MTYPE_PREFIX_LIST_STR,    "Prefix List Str " },
-  { MTYPE_PREFIX_LIST_ENTRY,  "Prefix List Entry "},
-  { MTYPE_ROUTE_MAP,          "Route map       " },
-  { MTYPE_ROUTE_MAP_NAME,     "Route map name  " },
-  { MTYPE_ROUTE_MAP_INDEX,    "Route map index " },
-  { MTYPE_ROUTE_MAP_RULE,     "Route map rule  " },
-  { MTYPE_ROUTE_MAP_RULE_STR, "Route map rule str" },
-  { MTYPE_ROUTE_MAP_COMPILED, "Route map compiled" },
-  { MTYPE_DESC,               "Command desc    " },
-  { MTYPE_BUFFER,             "Buffer          " },
-  { MTYPE_BUFFER_DATA,        "Buffer data     " },
-  { MTYPE_STREAM,             "Stream          " },
-  { MTYPE_KEYCHAIN,           "Key chain       " },
-  { MTYPE_KEY,                "Key             " },
-  { MTYPE_VTY,                "VTY             " },
-  { -1, NULL }
-};
-
-static struct memory_list memory_list_bgp[] =
-{
-  { MTYPE_BGP_PEER,               "BGP peer" },
-  { MTYPE_ATTR,                   "BGP attribute" },
-  { MTYPE_AS_PATH,                "BGP aspath" },
-  { MTYPE_AS_SEG,                 "BGP aspath seg" },
-  { MTYPE_AS_STR,                 "BGP aspath str" },
-  { 0, NULL },
-  { MTYPE_BGP_TABLE,              "BGP table" },
-  { MTYPE_BGP_NODE,               "BGP node" },
-  { MTYPE_BGP_ADVERTISE_ATTR,     "BGP adv attr" },
-  { MTYPE_BGP_ADVERTISE,          "BGP adv" },
-  { MTYPE_BGP_ADJ_IN,             "BGP adj in" },
-  { MTYPE_BGP_ADJ_OUT,            "BGP adj out" },
-  { 0, NULL },
-  { MTYPE_AS_LIST,                "BGP AS list" },
-  { MTYPE_AS_FILTER,              "BGP AS filter" },
-  { MTYPE_AS_FILTER_STR,          "BGP AS filter str" },
-  { 0, NULL },
-  { MTYPE_COMMUNITY,              "community" },
-  { MTYPE_COMMUNITY_VAL,          "community val" },
-  { MTYPE_COMMUNITY_STR,          "community str" },
-  { 0, NULL },
-  { MTYPE_ECOMMUNITY,             "extcommunity" },
-  { MTYPE_ECOMMUNITY_VAL,         "extcommunity val" },
-  { MTYPE_ECOMMUNITY_STR,         "extcommunity str" },
-  { 0, NULL },
-  { MTYPE_COMMUNITY_LIST,         "community-list" },
-  { MTYPE_COMMUNITY_LIST_NAME,    "community-list name" },
-  { MTYPE_COMMUNITY_LIST_ENTRY,   "community-list entry" },
-  { MTYPE_COMMUNITY_LIST_CONFIG,  "community-list config" },
-  { 0, NULL },
-  { MTYPE_CLUSTER,                "Cluster list" },
-  { MTYPE_CLUSTER_VAL,            "Cluster list val" },
-  { 0, NULL },
-  { MTYPE_TRANSIT,                "BGP transit attr" },
-  { MTYPE_TRANSIT_VAL,            "BGP transit val" },
-  { 0, NULL },
-  { MTYPE_BGP_DISTANCE,           "BGP distance" },
-  { MTYPE_BGP_NEXTHOP_CACHE,      "BGP nexthop" },
-  { MTYPE_BGP_CONFED_LIST,        "BGP confed list" },
-  { MTYPE_PEER_UPDATE_SOURCE,     "peer update if" },
-  { MTYPE_BGP_DAMP_INFO,          "Dampening info" },
-  { MTYPE_BGP_REGEXP,             "BGP regexp" },
-  { -1, NULL }
-};
-
-static struct memory_list memory_list_rip[] =
-{
-  { MTYPE_RIP,                "RIP structure   " },
-  { MTYPE_RIP_INFO,           "RIP route info  " },
-  { MTYPE_RIP_INTERFACE,      "RIP interface   " },
-  { MTYPE_RIP_PEER,           "RIP peer        " },
-  { MTYPE_RIP_OFFSET_LIST,    "RIP offset list " },
-  { MTYPE_RIP_DISTANCE,       "RIP distance    " },
-  { -1, NULL }
-};
-
-static struct memory_list memory_list_ripng[] =
-{
-  { MTYPE_RIPNG,              "RIPng structure " },
-  { MTYPE_RIPNG_ROUTE,        "RIPng route info" },
-  { MTYPE_RIPNG_AGGREGATE,    "RIPng aggregate " },
-  { MTYPE_RIPNG_PEER,         "RIPng peer      " },
-  { MTYPE_RIPNG_OFFSET_LIST,  "RIPng offset lst" },
-  { MTYPE_RIPNG_RTE_DATA,     "RIPng rte data  " },
-  { -1, NULL }
-};
-
-static struct memory_list memory_list_ospf[] =
-{
-  { MTYPE_OSPF_TOP,           "OSPF top        " },
-  { MTYPE_OSPF_AREA,          "OSPF area       " },
-  { MTYPE_OSPF_AREA_RANGE,    "OSPF area range " },
-  { MTYPE_OSPF_NETWORK,       "OSPF network    " },
-#ifdef NBMA_ENABLE
-  { MTYPE_OSPF_NEIGHBOR_STATIC,"OSPF static nbr " },
-#endif  /* NBMA_ENABLE */
-  { MTYPE_OSPF_IF,            "OSPF interface  " },
-  { MTYPE_OSPF_NEIGHBOR,      "OSPF neighbor   " },
-  { MTYPE_OSPF_ROUTE,         "OSPF route      " },
-  { MTYPE_OSPF_TMP,           "OSPF tmp mem    " },
-  { MTYPE_OSPF_LSA,           "OSPF LSA        " },
-  { MTYPE_OSPF_LSA_DATA,      "OSPF LSA data   " },
-  { MTYPE_OSPF_LSDB,          "OSPF LSDB       " },
-  { MTYPE_OSPF_PACKET,        "OSPF packet     " },
-  { MTYPE_OSPF_FIFO,          "OSPF FIFO queue " },
-  { MTYPE_OSPF_VERTEX,        "OSPF vertex     " },
-  { MTYPE_OSPF_NEXTHOP,       "OSPF nexthop    " },
-  { MTYPE_OSPF_PATH,	      "OSPF path       " },
-  { MTYPE_OSPF_VL_DATA,       "OSPF VL data    " },
-  { MTYPE_OSPF_CRYPT_KEY,     "OSPF crypt key  " },
-  { MTYPE_OSPF_EXTERNAL_INFO, "OSPF ext. info  " },
-  { MTYPE_OSPF_DISTANCE,      "OSPF distance   " },
-  { MTYPE_OSPF_IF_INFO,       "OSPF if info    " },
-  { MTYPE_OSPF_IF_PARAMS,     "OSPF if params  " },
-  { -1, NULL },
-};
-
-static struct memory_list memory_list_ospf6[] =
-{
-  { MTYPE_OSPF6_TOP,          "OSPF6 top         " },
-  { MTYPE_OSPF6_AREA,         "OSPF6 area        " },
-  { MTYPE_OSPF6_IF,           "OSPF6 interface   " },
-  { MTYPE_OSPF6_NEIGHBOR,     "OSPF6 neighbor    " },
-  { MTYPE_OSPF6_ROUTE,        "OSPF6 route       " },
-  { MTYPE_OSPF6_PREFIX,       "OSPF6 prefix      " },
-  { MTYPE_OSPF6_MESSAGE,      "OSPF6 message     " },
-  { MTYPE_OSPF6_LSA,          "OSPF6 LSA         " },
-  { MTYPE_OSPF6_LSA_SUMMARY,  "OSPF6 LSA summary " },
-  { MTYPE_OSPF6_LSDB,         "OSPF6 LSA database" },
-  { MTYPE_OSPF6_VERTEX,       "OSPF6 vertex      " },
-  { MTYPE_OSPF6_SPFTREE,      "OSPF6 SPF tree    " },
-  { MTYPE_OSPF6_NEXTHOP,      "OSPF6 nexthop     " },
-  { MTYPE_OSPF6_EXTERNAL_INFO,"OSPF6 ext. info   " },
-  { MTYPE_OSPF6_OTHER,        "OSPF6 other       " },
-  { -1, NULL },
-};
-
-static struct memory_list memory_list_isis[] =
-{
-  { MTYPE_ISIS,               "ISIS              " },
-  { MTYPE_ISIS_TMP,           "ISIS TMP          " },
-  { MTYPE_ISIS_CIRCUIT,       "ISIS circuit      " },
-  { MTYPE_ISIS_LSP,           "ISIS LSP          " },
-  { MTYPE_ISIS_ADJACENCY,     "ISIS adjacency    " },
-  { MTYPE_ISIS_AREA,          "ISIS area         " },
-  { MTYPE_ISIS_AREA_ADDR,     "ISIS area address " },
-  { MTYPE_ISIS_TLV,           "ISIS TLV          " },
-  { MTYPE_ISIS_DYNHN,         "ISIS dyn hostname " },
-  { MTYPE_ISIS_SPFTREE,       "ISIS SPFtree      " },
-  { MTYPE_ISIS_VERTEX,        "ISIS vertex       " },
-  { MTYPE_ISIS_ROUTE_INFO,    "ISIS route info   " },
-  { MTYPE_ISIS_NEXTHOP,       "ISIS nexthop      " },
-  { MTYPE_ISIS_NEXTHOP6,      "ISIS nexthop6     " },
-  { -1, NULL },
-};
-
-static struct mlist {
-  struct memory_list *list;
-  const char *name;
-} mlists[] = {
-  { memory_list_lib,   "LIB"},
-  { memory_list_rip,   "RIP"},
-  { memory_list_ripng, "RIPNG"},
-  { memory_list_ospf,  "OSPF"},
-  { memory_list_ospf6, "OSPF6"},
-  { memory_list_isis,  "ISIS"},
-  { memory_list_bgp,   "BGP"},
-  { NULL, NULL},
-};
-
 static void
 log_memstats(int pri)
 {
@@ -439,7 +245,7 @@
       zlog (NULL, pri, "Memory utilization in module %s:", ml->name);
       for (m = ml->list; m->index >= 0; m++)
 	if (m->index && mstat[m->index].alloc)
-	  zlog (NULL, pri, "  %-22s: %5ld", m->format, mstat[m->index].alloc);
+	  zlog (NULL, pri, "  %-30s: %10ld", m->format, mstat[m->index].alloc);
     }
 }
 
@@ -458,7 +264,7 @@
     if (m->index == 0)
       vty_out (vty, "-----------------------------\r\n");
     else
-      vty_out (vty, "%-22s: %5ld\r\n", m->format, mstat[m->index].alloc);
+      vty_out (vty, "%-22s: %10ld\r\n", m->format, mstat[m->index].alloc);
 }
 
 DEFUN (show_memory_all,
@@ -497,6 +303,17 @@
   return CMD_SUCCESS;
 }
 
+DEFUN (show_memory_zebra,
+       show_memory_zebra_cmd,
+       "show memory zebra",
+       SHOW_STR
+       "Memory statistics\n"
+       "Zebra memory\n")
+{
+  show_memory_vty (vty, memory_list_zebra);
+  return CMD_SUCCESS;
+}
+
 DEFUN (show_memory_rip,
        show_memory_rip_cmd,
        "show memory rip",
@@ -579,6 +396,7 @@
   install_element (ENABLE_NODE, &show_memory_cmd);
   install_element (ENABLE_NODE, &show_memory_all_cmd);
   install_element (ENABLE_NODE, &show_memory_lib_cmd);
+  install_element (ENABLE_NODE, &show_memory_zebra_cmd);
   install_element (ENABLE_NODE, &show_memory_rip_cmd);
   install_element (ENABLE_NODE, &show_memory_ripng_cmd);
   install_element (ENABLE_NODE, &show_memory_bgp_cmd);
diff --git a/lib/memory.h b/lib/memory.h
index 3ef0f48..7b47197 100644
--- a/lib/memory.h
+++ b/lib/memory.h
@@ -21,201 +21,23 @@
 #ifndef _ZEBRA_MEMORY_H
 #define _ZEBRA_MEMORY_H
 
-/* #define MEMORY_LOG */
+#include "memtypes.h"
 
-/* For tagging memory, below is the type of the memory. */
-enum
+/* For pretty printing of memory allocate information. */
+struct memory_list
 {
-  MTYPE_TMP = 1,
-  MTYPE_STRVEC,
-  MTYPE_VECTOR,
-  MTYPE_VECTOR_INDEX,
-  MTYPE_LINK_LIST,
-  MTYPE_LINK_NODE,
-  MTYPE_THREAD,
-  MTYPE_THREAD_MASTER,
-  MTYPE_THREAD_STATS,
-  MTYPE_THREAD_FUNCNAME,
-  MTYPE_VTY,
-  MTYPE_VTY_HIST,
-  MTYPE_VTY_OUT_BUF,
-  MTYPE_IF,
-  MTYPE_IF_IRDP,
-  MTYPE_CONNECTED,
-  MTYPE_AS_SEG,
-  MTYPE_AS_STR,
-  MTYPE_AS_PATH,
-  MTYPE_CLUSTER,
-  MTYPE_CLUSTER_VAL,
-  MTYPE_ATTR,
-  MTYPE_TRANSIT,
-  MTYPE_TRANSIT_VAL,
-  MTYPE_BUFFER,
-  MTYPE_BUFFER_DATA,
-  MTYPE_STREAM,
-  MTYPE_STREAM_DATA,
-  MTYPE_STREAM_FIFO,
-  MTYPE_PREFIX,
-  MTYPE_PREFIX_IPV4,
-  MTYPE_PREFIX_IPV6,
-  MTYPE_HASH,
-  MTYPE_HASH_INDEX,
-  MTYPE_HASH_BACKET,
-  MTYPE_ROUTE_TABLE,
-  MTYPE_ROUTE_NODE,
-  MTYPE_ACCESS_LIST,
-  MTYPE_ACCESS_LIST_STR,
-  MTYPE_ACCESS_FILTER,
-  MTYPE_PREFIX_LIST,
-  MTYPE_PREFIX_LIST_STR,
-  MTYPE_PREFIX_LIST_ENTRY,
-  MTYPE_ROUTE_MAP,
-  MTYPE_ROUTE_MAP_NAME,
-  MTYPE_ROUTE_MAP_INDEX,
-  MTYPE_ROUTE_MAP_RULE,
-  MTYPE_ROUTE_MAP_RULE_STR,
-  MTYPE_ROUTE_MAP_COMPILED,
-
-  MTYPE_RIB,
-  
-  MTYPE_DISTRIBUTE,
-  MTYPE_DISTRIBUTE_IFNAME,
-  MTYPE_ZLOG,
-  MTYPE_ZCLIENT,
-  MTYPE_NEXTHOP,
-  MTYPE_RTADV_PREFIX,
-  MTYPE_IF_RMAP,
-  MTYPE_SOCKUNION,
-  MTYPE_STATIC_IPV4,
-  MTYPE_STATIC_IPV6,
-
-  MTYPE_DESC,
-  MTYPE_OSPF_TOP,
-  MTYPE_OSPF_AREA,
-  MTYPE_OSPF_AREA_RANGE,
-  MTYPE_OSPF_NETWORK,
-  MTYPE_OSPF_NEIGHBOR_STATIC,
-  MTYPE_OSPF_IF,
-  MTYPE_OSPF_NEIGHBOR,
-  MTYPE_OSPF_ROUTE,
-  MTYPE_OSPF_TMP,
-  MTYPE_OSPF_LSA,
-  MTYPE_OSPF_LSA_DATA,
-  MTYPE_OSPF_LSDB,
-  MTYPE_OSPF_PACKET,
-  MTYPE_OSPF_FIFO,
-  MTYPE_OSPF_VERTEX,
-  MTYPE_OSPF_NEXTHOP,
-  MTYPE_OSPF_PATH,
-  MTYPE_OSPF_VL_DATA,
-  MTYPE_OSPF_CRYPT_KEY,
-  MTYPE_OSPF_EXTERNAL_INFO,
-  MTYPE_OSPF_MESSAGE,
-  MTYPE_OSPF_DISTANCE,
-  MTYPE_OSPF_IF_INFO,
-  MTYPE_OSPF_IF_PARAMS,
-
-  MTYPE_OSPF6_TOP,
-  MTYPE_OSPF6_AREA,
-  MTYPE_OSPF6_IF,
-  MTYPE_OSPF6_NEIGHBOR,
-  MTYPE_OSPF6_ROUTE,
-  MTYPE_OSPF6_PREFIX,
-  MTYPE_OSPF6_MESSAGE,
-  MTYPE_OSPF6_LSA,
-  MTYPE_OSPF6_LSA_SUMMARY,
-  MTYPE_OSPF6_LSDB,
-  MTYPE_OSPF6_VERTEX,
-  MTYPE_OSPF6_SPFTREE,
-  MTYPE_OSPF6_NEXTHOP,
-  MTYPE_OSPF6_EXTERNAL_INFO,
-  MTYPE_OSPF6_OTHER,
-
-  
-  MTYPE_ISIS,
-  MTYPE_ISIS_TMP,
-  MTYPE_ISIS_CIRCUIT,
-  MTYPE_ISIS_LSP,
-  MTYPE_ISIS_ADJACENCY,
-  MTYPE_ISIS_AREA,
-  MTYPE_ISIS_AREA_ADDR,
-  MTYPE_ISIS_TLV,
-  MTYPE_ISIS_DYNHN,
-  MTYPE_ISIS_SPFTREE,
-  MTYPE_ISIS_VERTEX,
-  MTYPE_ISIS_ROUTE_INFO,
-  MTYPE_ISIS_NEXTHOP,
-  MTYPE_ISIS_NEXTHOP6,
-
-  MTYPE_BGP,
-  MTYPE_BGP_PEER,
-  MTYPE_PEER_GROUP,
-  MTYPE_PEER_DESC,
-  MTYPE_PEER_UPDATE_SOURCE,
-  MTYPE_BGP_STATIC,
-  MTYPE_BGP_AGGREGATE,
-  MTYPE_BGP_CONFED_LIST,
-  MTYPE_BGP_NEXTHOP_CACHE,
-  MTYPE_BGP_DAMP_INFO,
-  MTYPE_BGP_DAMP_ARRAY,
-  MTYPE_BGP_ANNOUNCE,
-  MTYPE_BGP_ATTR_QUEUE,
-  MTYPE_BGP_ROUTE_QUEUE,
-  MTYPE_BGP_DISTANCE,
-  MTYPE_BGP_ROUTE,
-  MTYPE_BGP_TABLE,
-  MTYPE_BGP_NODE,
-  MTYPE_BGP_ADVERTISE_ATTR,
-  MTYPE_BGP_ADVERTISE,
-  MTYPE_BGP_ADJ_IN,
-  MTYPE_BGP_ADJ_OUT,
-  MTYPE_BGP_REGEXP,
-  MTYPE_AS_FILTER,
-  MTYPE_AS_FILTER_STR,
-  MTYPE_AS_LIST,
-
-  MTYPE_COMMUNITY,
-  MTYPE_COMMUNITY_VAL,
-  MTYPE_COMMUNITY_STR,
-
-  MTYPE_ECOMMUNITY,
-  MTYPE_ECOMMUNITY_VAL,
-  MTYPE_ECOMMUNITY_STR,
-
-  /* community-list and extcommunity-list.  */
-  MTYPE_COMMUNITY_LIST_HANDLER,
-  MTYPE_COMMUNITY_LIST,
-  MTYPE_COMMUNITY_LIST_NAME,
-  MTYPE_COMMUNITY_LIST_ENTRY,
-  MTYPE_COMMUNITY_LIST_CONFIG,
-
-  MTYPE_RIP,
-  MTYPE_RIP_INTERFACE,
-  MTYPE_RIP_DISTANCE,
-  MTYPE_RIP_OFFSET_LIST,
-  MTYPE_RIP_INFO,
-  MTYPE_RIP_PEER,
-  MTYPE_KEYCHAIN,
-  MTYPE_KEY,
-
-  MTYPE_RIPNG,
-  MTYPE_RIPNG_ROUTE,
-  MTYPE_RIPNG_AGGREGATE,
-  MTYPE_RIPNG_PEER,
-  MTYPE_RIPNG_OFFSET_LIST,
-  MTYPE_RIPNG_RTE_DATA,
-
-  MTYPE_VTYSH_CONFIG,
-  MTYPE_VTYSH_CONFIG_LINE,
-
-  MTYPE_VRF,
-  MTYPE_VRF_NAME,
-  
-  MTYPE_PRIVS,
-
-  MTYPE_MAX
+  int index;
+  const char *format;
 };
 
+struct mlist {
+  struct memory_list *list;
+  const char *name;
+};
+ 
+extern struct mlist mlists[];
+
+/* #define MEMORY_LOG */
 #ifdef MEMORY_LOG
 #define XMALLOC(mtype, size) \
   mtype_zmalloc (__FILE__, __LINE__, (mtype), (size))
diff --git a/lib/memtypes.awk b/lib/memtypes.awk
new file mode 100644
index 0000000..2da6547
--- /dev/null
+++ b/lib/memtypes.awk
@@ -0,0 +1,40 @@
+# $Id: memtypes.awk,v 1.1 2005/04/15 11:47:15 paul Exp $
+#
+# Scan a file of memory definitions (see eg memtypes.c) and generate
+# a corresponding header file with an enum of the MTYPE's and declarations
+# for the struct memory_list arrays
+#
+
+BEGIN {
+	mlistregex = "memory_list_(.*)\\[\\]";
+	mtyperegex = "^.*(MTYPE_[A-Z_0-9]+).*$";
+	header = "/* Auto-generated from memtypes.c by " ARGV[0] ". */\n";
+	header = header "/* Do not edit! */\n";
+	header = header "\n#ifndef _QUAGGA_MEMTYPES_H\n";
+	header = header "#define _QUAGGA_MEMTYPES_H\n";
+	footer = "\n#endif /* _QUAGGA_MEMTYPES_H */\n\n";
+	mlistformat = "extern struct memory_list memory_list_%s[];";
+	printf ("%s\n", header);
+}
+
+($0 ~ /^struct memory_list /) && (NF >= 3) {
+	mlists[lcount++] = gensub(mlistregex,"\\1",g,$3);
+}
+
+($1 != "/*") && ($1 != "*") && ($2 ~ /MTYPE_/) { 
+	mtype[tcount++] = gensub(mtyperegex,"\\1",1, $0);
+} 
+
+END {
+	printf("enum\n{\n  MTYPE_TMP = 1,\n"); 
+	for (i = 0; i < tcount; i++) {
+		if (mtype[i] != "" && mtype[i] != "MTYPE_TMP")
+			printf ("  %s,\n", mtype[i]);
+	}
+	printf ("  MTYPE_MAX,\n};\n\n");
+	for (i = 0; i < lcount; i++) {
+		if (mlists[i] != "")
+			printf (mlistformat "\n", mlists[i]);
+	}
+	printf (footer);
+}
diff --git a/lib/memtypes.c b/lib/memtypes.c
new file mode 100644
index 0000000..a643d43
--- /dev/null
+++ b/lib/memtypes.c
@@ -0,0 +1,244 @@
+/*
+ * Memory type definitions. This file is parsed by memtypes.awk to extract
+ * MTYPE_ and memory_list_.. information in order to autogenerate 
+ * memtypes.h.
+ *
+ * The script is sensitive to the format (though not whitespace), so 
+ * be careful. Comment lines /must/ start with either /* or *.
+ *
+ * $Id: memtypes.c,v 1.1 2005/04/15 11:47:15 paul Exp $
+ */
+
+#include "zebra.h"
+#include "memory.h"
+
+struct memory_list memory_list_lib[] =
+{
+  { MTYPE_TMP,			"Temporary memory"		},
+  { MTYPE_STRVEC,		"String vector"			},
+  { MTYPE_VECTOR,		"Vector"			},
+  { MTYPE_VECTOR_INDEX,		"Vector index"			},
+  { MTYPE_LINK_LIST,		"Link List"			},
+  { MTYPE_LINK_NODE,		"Link Node"			},
+  { MTYPE_THREAD,		"Thread"			},
+  { MTYPE_THREAD_MASTER,	"Thread master"			},
+  { MTYPE_THREAD_STATS,		"Thread stats"			},
+  { MTYPE_THREAD_FUNCNAME,	"Thread function name" 		},
+  { MTYPE_VTY,			"VTY"				},
+  { MTYPE_VTY_OUT_BUF,		"VTY output buffer"		},
+  { MTYPE_VTY_HIST,		"VTY history"			},
+  { MTYPE_IF,			"Interface"			},
+  { MTYPE_CONNECTED,		"Connected" 			},
+  { MTYPE_BUFFER,		"Buffer"			},
+  { MTYPE_BUFFER_DATA,		"Buffer data"			},
+  { MTYPE_STREAM,		"Stream"			},
+  { MTYPE_STREAM_DATA,		"Stream data"			},
+  { MTYPE_STREAM_FIFO,		"Stream FIFO"			},
+  { MTYPE_PREFIX,		"Prefix"			},
+  { MTYPE_PREFIX_IPV4,		"Prefix IPv4"			},
+  { MTYPE_PREFIX_IPV6,		"Prefix IPv6"			},
+  { MTYPE_HASH,			"Hash"				},
+  { MTYPE_HASH_BACKET,		"Hash Bucket"			},
+  { MTYPE_HASH_INDEX,		"Hash Index"			},
+  { MTYPE_ROUTE_TABLE,		"Route table"			},
+  { MTYPE_ROUTE_NODE,		"Route node"			},
+  { MTYPE_DISTRIBUTE,		"Distribute list"		},
+  { MTYPE_DISTRIBUTE_IFNAME,	"Dist-list ifname"		},
+  { MTYPE_ACCESS_LIST,		"Access List"			},
+  { MTYPE_ACCESS_LIST_STR,	"Access List Str"		},
+  { MTYPE_ACCESS_FILTER,	"Access Filter"			},
+  { MTYPE_PREFIX_LIST,		"Prefix List"			},
+  { MTYPE_PREFIX_LIST_ENTRY,	"Prefix List Str"		},
+  { MTYPE_PREFIX_LIST_STR,	"Prefix List Entry"		},
+  { MTYPE_ROUTE_MAP,		"Route map"			},
+  { MTYPE_ROUTE_MAP_NAME,	"Route map name"		},
+  { MTYPE_ROUTE_MAP_INDEX,	"Route map index"		},
+  { MTYPE_ROUTE_MAP_RULE,	"Route map rule"		},
+  { MTYPE_ROUTE_MAP_RULE_STR,	"Route map rule str"		},
+  { MTYPE_ROUTE_MAP_COMPILED,	"Route map compiled"		},
+  { MTYPE_DESC,			"Command desc"			},
+  { MTYPE_KEY,			"Key"				},
+  { MTYPE_KEYCHAIN,		"Key chain"			},
+  { MTYPE_IF_RMAP,		"Interface route map"		},
+  { MTYPE_SOCKUNION,		"Socket union"			},
+  { MTYPE_PRIVS,		"Privilege information"		},
+  { MTYPE_ZLOG,			"Logging"			},
+  { MTYPE_ZCLIENT,		"Zclient"			},
+  { -1, NULL },
+};
+
+struct memory_list memory_list_zebra[] = 
+{
+  { MTYPE_RTADV_PREFIX,		"Router Advertisement Prefix"	},
+  { MTYPE_VRF,			"VRF"				},
+  { MTYPE_VRF_NAME,		"VRF name"			},
+  { MTYPE_NEXTHOP,		"Nexthop"			},
+  { MTYPE_RIB,			"RIB"				},
+  { MTYPE_STATIC_IPV4,		"Static IPv4 route"		},
+  { MTYPE_STATIC_IPV6,		"Static IPv6 route"		},
+  { -1, NULL },
+};
+
+struct memory_list memory_list_bgp[] =
+{
+  { MTYPE_BGP,			"BGP instance"			},
+  { MTYPE_BGP_PEER,		"BGP peer"			},
+  { MTYPE_PEER_GROUP,		"Peer group"			},
+  { MTYPE_PEER_DESC,		"Peer description"		},
+  { MTYPE_ATTR,			"BGP attribute"			},
+  { MTYPE_AS_PATH,		"BGP aspath"			},
+  { MTYPE_AS_SEG,		"BGP aspath seg"		},
+  { MTYPE_AS_STR,		"BGP aspath str"		},
+  { 0, NULL },
+  { MTYPE_BGP_TABLE,		"BGP table"			},
+  { MTYPE_BGP_NODE,		"BGP node"			},
+  { MTYPE_BGP_ROUTE,		"BGP route"			},
+  { MTYPE_BGP_STATIC,		"BGP static"			},
+  { MTYPE_BGP_ADVERTISE_ATTR,	"BGP adv attr"			},
+  { MTYPE_BGP_ADVERTISE,	"BGP adv"			},
+  { MTYPE_BGP_ADJ_IN,		"BGP adj in"			},
+  { MTYPE_BGP_ADJ_OUT,		"BGP adj out"			},
+  { 0, NULL },
+  { MTYPE_AS_LIST,		"BGP AS list"			},
+  { MTYPE_AS_FILTER,		"BGP AS filter"			},
+  { MTYPE_AS_FILTER_STR,	"BGP AS filter str"		},
+  { 0, NULL },
+  { MTYPE_COMMUNITY,		"community"			},
+  { MTYPE_COMMUNITY_VAL,	"community val"			},
+  { MTYPE_COMMUNITY_STR,	"community str"			},
+  { 0, NULL },
+  { MTYPE_ECOMMUNITY,		"extcommunity"			},
+  { MTYPE_ECOMMUNITY_VAL,	"extcommunity val"		},
+  { MTYPE_ECOMMUNITY_STR,	"extcommunity str"		},
+  { 0, NULL },
+  { MTYPE_COMMUNITY_LIST,	"community-list"		},
+  { MTYPE_COMMUNITY_LIST_NAME,	"community-list name"		},
+  { MTYPE_COMMUNITY_LIST_ENTRY,	"community-list entry"		},
+  { MTYPE_COMMUNITY_LIST_CONFIG,  "community-list config"	},
+  { MTYPE_COMMUNITY_LIST_HANDLER, "community-list handler"	},
+  { 0, NULL },
+  { MTYPE_CLUSTER,		"Cluster list"			},
+  { MTYPE_CLUSTER_VAL,		"Cluster list val"		},
+  { 0, NULL },
+  { MTYPE_TRANSIT,		"BGP transit attr"		},
+  { MTYPE_TRANSIT_VAL,		"BGP transit val"		},
+  { 0, NULL },
+  { MTYPE_BGP_DISTANCE,		"BGP distance"			},
+  { MTYPE_BGP_NEXTHOP_CACHE,	"BGP nexthop"			},
+  { MTYPE_BGP_CONFED_LIST,	"BGP confed list"		},
+  { MTYPE_PEER_UPDATE_SOURCE,	"BGP peer update interface"	},
+  { MTYPE_BGP_DAMP_INFO,	"Dampening info"		},
+  { MTYPE_BGP_DAMP_ARRAY,	"BGP Dampening array"		},
+  { MTYPE_BGP_REGEXP,		"BGP regexp"			},
+  { MTYPE_BGP_AGGREGATE,	"BGP aggregate"			},
+  { -1, NULL }
+};
+
+struct memory_list memory_list_rip[] =
+{
+  { MTYPE_RIP,                "RIP structure"			},
+  { MTYPE_RIP_INFO,           "RIP route info"			},
+  { MTYPE_RIP_INTERFACE,      "RIP interface"			},
+  { MTYPE_RIP_PEER,           "RIP peer"			},
+  { MTYPE_RIP_OFFSET_LIST,    "RIP offset list"			},
+  { MTYPE_RIP_DISTANCE,       "RIP distance"			},
+  { -1, NULL }
+};
+
+struct memory_list memory_list_ripng[] =
+{
+  { MTYPE_RIPNG,              "RIPng structure"			},
+  { MTYPE_RIPNG_ROUTE,        "RIPng route info"		},
+  { MTYPE_RIPNG_AGGREGATE,    "RIPng aggregate"			},
+  { MTYPE_RIPNG_PEER,         "RIPng peer"			},
+  { MTYPE_RIPNG_OFFSET_LIST,  "RIPng offset lst"		},
+  { MTYPE_RIPNG_RTE_DATA,     "RIPng rte data"			},
+  { -1, NULL }
+};
+
+struct memory_list memory_list_ospf[] =
+{
+  { MTYPE_OSPF_TOP,           "OSPF top"			},
+  { MTYPE_OSPF_AREA,          "OSPF area"			},
+  { MTYPE_OSPF_AREA_RANGE,    "OSPF area range"			},
+  { MTYPE_OSPF_NETWORK,       "OSPF network"			},
+  { MTYPE_OSPF_NEIGHBOR_STATIC,"OSPF static nbr"		},
+  { MTYPE_OSPF_IF,            "OSPF interface"			},
+  { MTYPE_OSPF_NEIGHBOR,      "OSPF neighbor"			},
+  { MTYPE_OSPF_ROUTE,         "OSPF route"			},
+  { MTYPE_OSPF_TMP,           "OSPF tmp mem"			},
+  { MTYPE_OSPF_LSA,           "OSPF LSA"			},
+  { MTYPE_OSPF_LSA_DATA,      "OSPF LSA data"			},
+  { MTYPE_OSPF_LSDB,          "OSPF LSDB"			},
+  { MTYPE_OSPF_PACKET,        "OSPF packet"			},
+  { MTYPE_OSPF_FIFO,          "OSPF FIFO queue"			},
+  { MTYPE_OSPF_VERTEX,        "OSPF vertex"			},
+  { MTYPE_OSPF_NEXTHOP,       "OSPF nexthop"			},
+  { MTYPE_OSPF_PATH,	      "OSPF path"			},
+  { MTYPE_OSPF_VL_DATA,       "OSPF VL data"			},
+  { MTYPE_OSPF_CRYPT_KEY,     "OSPF crypt key"			},
+  { MTYPE_OSPF_EXTERNAL_INFO, "OSPF ext. info"			},
+  { MTYPE_OSPF_DISTANCE,      "OSPF distance"			},
+  { MTYPE_OSPF_IF_INFO,       "OSPF if info"			},
+  { MTYPE_OSPF_IF_PARAMS,     "OSPF if params"			},
+  { MTYPE_OSPF_MESSAGE,		"OSPF message"			},
+  { -1, NULL },
+};
+
+struct memory_list memory_list_ospf6[] =
+{
+  { MTYPE_OSPF6_TOP,          "OSPF6 top"			},
+  { MTYPE_OSPF6_AREA,         "OSPF6 area"			},
+  { MTYPE_OSPF6_IF,           "OSPF6 interface"			},
+  { MTYPE_OSPF6_NEIGHBOR,     "OSPF6 neighbor"			},
+  { MTYPE_OSPF6_ROUTE,        "OSPF6 route"			},
+  { MTYPE_OSPF6_PREFIX,       "OSPF6 prefix"			},
+  { MTYPE_OSPF6_MESSAGE,      "OSPF6 message"			},
+  { MTYPE_OSPF6_LSA,          "OSPF6 LSA"			},
+  { MTYPE_OSPF6_LSA_SUMMARY,  "OSPF6 LSA summary"		},
+  { MTYPE_OSPF6_LSDB,         "OSPF6 LSA database"		},
+  { MTYPE_OSPF6_VERTEX,       "OSPF6 vertex"			},
+  { MTYPE_OSPF6_SPFTREE,      "OSPF6 SPF tree"			},
+  { MTYPE_OSPF6_NEXTHOP,      "OSPF6 nexthop"			},
+  { MTYPE_OSPF6_EXTERNAL_INFO,"OSPF6 ext. info"			},
+  { MTYPE_OSPF6_OTHER,        "OSPF6 other"			},
+  { -1, NULL },
+};
+
+struct memory_list memory_list_isis[] =
+{
+  { MTYPE_ISIS,               "ISIS"				},
+  { MTYPE_ISIS_TMP,           "ISIS TMP"			},
+  { MTYPE_ISIS_CIRCUIT,       "ISIS circuit"			},
+  { MTYPE_ISIS_LSP,           "ISIS LSP"			},
+  { MTYPE_ISIS_ADJACENCY,     "ISIS adjacency"			},
+  { MTYPE_ISIS_AREA,          "ISIS area"			},
+  { MTYPE_ISIS_AREA_ADDR,     "ISIS area address"		},
+  { MTYPE_ISIS_TLV,           "ISIS TLV"			},
+  { MTYPE_ISIS_DYNHN,         "ISIS dyn hostname"		},
+  { MTYPE_ISIS_SPFTREE,       "ISIS SPFtree"			},
+  { MTYPE_ISIS_VERTEX,        "ISIS vertex"			},
+  { MTYPE_ISIS_ROUTE_INFO,    "ISIS route info"			},
+  { MTYPE_ISIS_NEXTHOP,       "ISIS nexthop"			},
+  { MTYPE_ISIS_NEXTHOP6,      "ISIS nexthop6"			},
+  { -1, NULL },
+};
+
+struct memory_list memory_list_vtysh[] =
+{
+  { MTYPE_VTYSH_CONFIG,		"Vtysh configuration",		},
+  { MTYPE_VTYSH_CONFIG_LINE,	"Vtysh configuration line"	},
+  { -1, NULL },
+};
+
+struct mlist mlists[] __attribute__ ((unused)) = {
+  { memory_list_lib,	"LIB"	},
+  { memory_list_zebra,	"ZEBRA"	},
+  { memory_list_rip,	"RIP"	},
+  { memory_list_ripng,	"RIPNG"	},
+  { memory_list_ospf,	"OSPF"	},
+  { memory_list_ospf6,	"OSPF6"	},
+  { memory_list_isis,	"ISIS"	},
+  { memory_list_bgp,	"BGP"	},
+  { NULL, NULL},
+};