Merge isisd into the Quagga's framework:
  - add privs support
  - use misc quagga's definitions
  - make it compile"able"
  - fix segfault cases related to hostname()
  - add debug isis xxx command

This patch has been approved by Paul Jakma.
diff --git a/ChangeLog b/ChangeLog
index 7356ea8..e385a85 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2003-12-23 Vincent Jardin <jardin@6wind.com>
+
+	* isisd: Import isisd from Sampo Saaristo's source code.
+
 2003-12-22 Christian Hammers <ch@lathspell.de>
 
 	* configure.ac (and everywhere a regular file is opened for
diff --git a/HACKING b/HACKING
index c42c121..4fedb34 100644
--- a/HACKING
+++ b/HACKING
@@ -1,6 +1,6 @@
 -*- mode: text; -*-
 
-$Id: HACKING,v 1.2 2003/12/22 15:45:01 gdt Exp $
+$Id: HACKING,v 1.3 2003/12/23 08:56:18 jardin Exp $
 
 GUIDELINES FOR HACKING ON QUAGGA
 
@@ -71,3 +71,41 @@
 CHANGELOG
 
 [TBD: when to add to per-dir Changelog, when to add to top-level]
+
+IMPORT OR UPDATE VENDOR SPECIFIC ROUTING PROTOCOLS
+
+The source code of Quagga is based on two vendors:
+
+   zebra_org (http://www.zebra.org/)
+   isisd_sf (http://isisd.sf.net/)
+
+In order to import source code, the following procedure should be used:
+
+* Tag the Current Quagga CVS repository:
+
+    cvs tag import_isisd_sf_20031223
+
+* Import the source code into the Quagga's framework. You must not modified
+  this source code. It will be merged later.
+
+    cd dir_isisd
+    export CVSROOT=:pserver:LOGIN@anoncvs.quagga.net:/var/cvsroot 
+    cvs import quagga/isisd isisd_sf isisd_sf_20031223
+  ---COMMENTS---
+    Vendor: [isisd_sf] Sampo's ISISd from Sourceforge
+    Tag: [isisd_sf_20031217] Current CVS release
+  ---
+
+* Update your Quagga's directory:
+
+    cd dir_quagga
+    cvs update -dP
+
+  or
+
+    cvs co -d quagga_isisd quagga
+
+* Merge the code, then commit:
+
+    cvs commit
+
diff --git a/Makefile.am b/Makefile.am
index 699c530..46cabb2 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,10 +1,11 @@
 ## Process this file with automake to produce Makefile.in.
 
 SUBDIRS = lib @ZEBRA@ @BGPD@ @RIPD@ @RIPNGD@ @OSPFD@ @OSPF6D@ \
-         @VTYSH@ @OSPFCLIENT@ doc
+         @ISISD@ @VTYSH@ @OSPFCLIENT@ doc
 
 DIST_SUBDIRS = lib zebra bgpd ripd ripngd ospfd ospf6d vtysh \
-	       ospfclient doc
+	       ospfclient doc \
+	       isisd
 
 EXTRA_DIST = aclocal.m4 SERVICES TODO REPORTING-BUGS vtysh/Makefile.in \
 	vtysh/Makefile.am update-autotools doc/mpls
diff --git a/NEWS b/NEWS
index f5a9032..b6707ad 100644
--- a/NEWS
+++ b/NEWS
@@ -12,6 +12,9 @@
   --enable-logfile-mask to set umask values for config and log
   values.  Masks default to 0600, matching previous behavior.
 
+- Import current CVS isisd from SourceForge, then merge it with
+  the Quagga's Framework.
+
 * Changes in Quagga 0.96.4
 
 - Further fixes to ospfd, some relating to the PtP revert. Interface
diff --git a/SERVICES b/SERVICES
index 41d4b94..d74098f 100644
--- a/SERVICES
+++ b/SERVICES
@@ -15,3 +15,4 @@
 ospfd		2604/tcp
 bgpd		2605/tcp
 ospf6d		2606/tcp
+isisd		2607/tcp
diff --git a/configure.ac b/configure.ac
index 094da52..25012d5 100755
--- a/configure.ac
+++ b/configure.ac
@@ -82,6 +82,8 @@
 [  --disable-ospfd         do not build ospfd])
 AC_ARG_ENABLE(ospf6d,
 [  --disable-ospf6d        do not build ospf6d])
+AC_ARG_ENABLE(isisd,
+[  --disable-isisd         do not build isisd])
 AC_ARG_ENABLE(bgp-announce,
 [  --disable-bgp-announce, turn off BGP route announcement])
 AC_ARG_ENABLE(netlink,
@@ -702,6 +704,12 @@
   *    ) ;;
 esac
 
+case "${enable_isisd}" in
+  "yes") ISISD="isisd";;
+  "no" ) ISISD="";;
+  *    ) ISISD="isisd";;
+esac
+
 if test "${enable_bgp_announce}" = "no";then
   AC_DEFINE(DISABLE_BGP_ANNOUNCE,,Disable BGP installation to zebra)
 fi
@@ -712,6 +720,7 @@
 AC_SUBST(RIPNGD)
 AC_SUBST(OSPFD)
 AC_SUBST(OSPF6D)
+AC_SUBST(ISISD)
 AC_SUBST(VTYSH)
 AC_SUBST(INCLUDES)
 AC_SUBST(CURSES)
@@ -1034,6 +1043,7 @@
 AC_DEFINE_UNQUOTED(PATH_BGPD_PID, "$quagga_statedir/bgpd.pid",bgpd PID)
 AC_DEFINE_UNQUOTED(PATH_OSPFD_PID, "$quagga_statedir/ospfd.pid",ospfd PID)
 AC_DEFINE_UNQUOTED(PATH_OSPF6D_PID, "$quagga_statedir/ospf6d.pid",ospf6d PID)
+AC_DEFINE_UNQUOTED(PATH_ISISD_PID, "$quagga_statedir/isisd.pid",isisd PID)
 AC_DEFINE_UNQUOTED(ZEBRA_SERV_PATH, "$quagga_statedir/zserv.api",zebra api socket)
 AC_DEFINE_UNQUOTED(ZEBRA_VTYSH_PATH, "$quagga_statedir/zebra.vty",zebra vty socket)
 AC_DEFINE_UNQUOTED(RIP_VTYSH_PATH, "$quagga_statedir/ripd.vty",rip vty socket)
@@ -1041,6 +1051,7 @@
 AC_DEFINE_UNQUOTED(BGP_VTYSH_PATH, "$quagga_statedir/bgpd.vty",bgpd vty socket)
 AC_DEFINE_UNQUOTED(OSPF_VTYSH_PATH, "$quagga_statedir/ospfd.vty",ospfd vty socket)
 AC_DEFINE_UNQUOTED(OSPF6_VTYSH_PATH, "$quagga_statedir/ospf6d.vty",ospf6d vty socket)
+AC_DEFINE_UNQUOTED(ISIS_VTYSH_PATH, "$quagga_statedir/isisd.vty",isisd vty socket)
 
 dnl ---------------------------
 dnl Check htonl works correctly
@@ -1063,7 +1074,7 @@
 
 AC_OUTPUT(Makefile lib/Makefile zebra/Makefile ripd/Makefile 
 	  ripngd/Makefile bgpd/Makefile ospfd/Makefile 
-	  ospf6d/Makefile vtysh/Makefile doc/Makefile 
+	  ospf6d/Makefile isisd/Makefile vtysh/Makefile doc/Makefile 
 	  ospfclient/Makefile
 	  redhat/quagga.spec
 	  lib/version.h)
diff --git a/isisd/Makefile.am b/isisd/Makefile.am
index b9a0c7c..fd4c199 100644
--- a/isisd/Makefile.am
+++ b/isisd/Makefile.am
@@ -43,13 +43,3 @@
 	  fi; fi; \
 	done
 
-depend:
-	@$(CPP) -MM $(INCLUDES) $(LDFLAGS) *.c
-
-## File dependency.
-isis_adjacency.o : isis_adjacency.c ../lib/version.h ../lib/log.h \
- ../isisd/isis_adjacency.h
-isis_pdu.o : isis_pdu.c ../lib/log.h ../isisd/isisd.h \
- ../isisd/isis_constants.h ../isisd/isis_adjacency.h \
- ../isisd/isis_pdu.h
-isis_circuit.o : isis_circuit.c ../isisd/isis_circuit.h
diff --git a/isisd/Makefile.in b/isisd/Makefile.in
index 46aae73..7cb2e59 100644
--- a/isisd/Makefile.in
+++ b/isisd/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.6.2 from Makefile.am.
+# Makefile.in generated by automake 1.7.9 from Makefile.am.
 # @configure_input@
 
-# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
 # Free Software Foundation, Inc.
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -13,98 +13,138 @@
 # PARTICULAR PURPOSE.
 
 @SET_MAKE@
-SHELL = @SHELL@
 
 srcdir = @srcdir@
 top_srcdir = @top_srcdir@
 VPATH = @srcdir@
-prefix = @prefix@
-exec_prefix = @exec_prefix@
-
-bindir = @bindir@
-sbindir = @sbindir@
-libexecdir = @libexecdir@
-datadir = @datadir@
-sysconfdir = @sysconfdir@
-sharedstatedir = @sharedstatedir@
-localstatedir = @localstatedir@
-libdir = @libdir@
-infodir = @infodir@
-mandir = @mandir@
-includedir = @includedir@
-oldincludedir = /usr/include
 pkgdatadir = $(datadir)/@PACKAGE@
 pkglibdir = $(libdir)/@PACKAGE@
 pkgincludedir = $(includedir)/@PACKAGE@
 top_builddir = ..
 
-ACLOCAL = @ACLOCAL@
-AUTOCONF = @AUTOCONF@
-AUTOMAKE = @AUTOMAKE@
-AUTOHEADER = @AUTOHEADER@
-
 am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
 INSTALL = @INSTALL@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@
-INSTALL_DATA = @INSTALL_DATA@
 install_sh_DATA = $(install_sh) -c -m 644
 install_sh_PROGRAM = $(install_sh) -c
 install_sh_SCRIPT = $(install_sh) -c
-INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_HEADER = $(INSTALL_DATA)
-transform = @program_transform_name@
+transform = $(program_transform_name)
 NORMAL_INSTALL = :
 PRE_INSTALL = :
 POST_INSTALL = :
 NORMAL_UNINSTALL = :
 PRE_UNINSTALL = :
 POST_UNINSTALL = :
-host_alias = @host_alias@
 host_triplet = @host@
-
-EXEEXT = @EXEEXT@
-OBJEXT = @OBJEXT@
-PATH_SEPARATOR = @PATH_SEPARATOR@
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
 AMTAR = @AMTAR@
 AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
 AWK = @AWK@
 BGPD = @BGPD@
 CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CONFDATE = @CONFDATE@
 CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
 CURSES = @CURSES@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\"
 DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
 IF_METHOD = @IF_METHOD@
 IF_PROC = @IF_PROC@
 
 # INCLUDES = @INCLUDES@ -I.. -I$(top_srcdir) -I$(top_srcdir)/lib -Itopology
 INCLUDES = @INCLUDES@ -I.. -I$(top_srcdir) -I$(top_srcdir)/lib 
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
 IPFORWARD = @IPFORWARD@
 ISISD = @ISISD@
 KERNEL_METHOD = @KERNEL_METHOD@
+LDFLAGS = @LDFLAGS@
+LIBCAP = @LIBCAP@
+LIBOBJS = @LIBOBJS@
 LIBPAM = @LIBPAM@
+LIBS = @LIBS@ 
 LIB_IPV6 = @LIB_IPV6@
 LIB_REGEX = @LIB_REGEX@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
 MULTIPATH_NUM = @MULTIPATH_NUM@
+OBJEXT = @OBJEXT@
 OSPF6D = @OSPF6D@
+OSPFAPI = @OSPFAPI@
+OSPFCLIENT = @OSPFCLIENT@
 OSPFD = @OSPFD@
 OTHER_METHOD = @OTHER_METHOD@
 PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
 RANLIB = @RANLIB@
 RIPD = @RIPD@
 RIPNGD = @RIPNGD@
 RTREAD_METHOD = @RTREAD_METHOD@
 RT_METHOD = @RT_METHOD@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
 STRIP = @STRIP@
 VERSION = @VERSION@
 VTYSH = @VTYSH@
 ZEBRA = @ZEBRA@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
 am__include = @am__include@
+am__leading_dot = @am__leading_dot@
 am__quote = @am__quote@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+datadir = @datadir@
+exampledir = @exampledir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
 install_sh = @install_sh@
-DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\"
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
 INSTALL_SDATA = @INSTALL@ -m 600
-LIBS = @LIBS@ 
 noinst_LIBRARIES = libisis.a
 sbin_PROGRAMS = isisd 
 
@@ -132,6 +172,7 @@
 
 EXTRA_DIST = $(sysconf_DATA)
 subdir = isisd
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
@@ -161,9 +202,8 @@
 isisd_OBJECTS = $(am_isisd_OBJECTS)
 isisd_DEPENDENCIES = ../lib/libzebra.a
 isisd_LDFLAGS =
+
 DEFAULT_INCLUDES =  -I. -I$(srcdir) -I$(top_builddir)
-CPPFLAGS = @CPPFLAGS@
-LDFLAGS = @LDFLAGS@
 depcomp = $(SHELL) $(top_srcdir)/depcomp
 am__depfiles_maybe = depfiles
 @AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/dict.Po \
@@ -183,23 +223,22 @@
 	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
 CCLD = $(CC)
 LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
-CFLAGS = @CFLAGS@
 DIST_SOURCES = $(libisis_a_SOURCES) $(isisd_SOURCES)
 DATA = $(sysconf_DATA)
 
 HEADERS = $(noinst_HEADERS)
 
-DIST_COMMON = README $(noinst_HEADERS) AUTHORS COPYING ChangeLog \
-	Makefile.am Makefile.in TODO
+DIST_COMMON = README $(noinst_HEADERS) $(srcdir)/Makefile.in AUTHORS \
+	COPYING ChangeLog Makefile.am TODO
 SOURCES = $(libisis_a_SOURCES) $(isisd_SOURCES)
 
 all: all-am
 
 .SUFFIXES:
 .SUFFIXES: .c .o .obj
-$(srcdir)/Makefile.in:  Makefile.am  $(top_srcdir)/configure.in $(ACLOCAL_M4)
+$(srcdir)/Makefile.in:  Makefile.am  $(top_srcdir)/configure.ac $(ACLOCAL_M4)
 	cd $(top_srcdir) && \
-	  $(AUTOMAKE) --gnu  isisd/Makefile
+	  $(AUTOMAKE) --foreign  isisd/Makefile
 Makefile:  $(srcdir)/Makefile.in  $(top_builddir)/config.status
 	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
 
@@ -217,18 +256,16 @@
 	  p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
 	  if test -f $$p \
 	  ; then \
-	    p1=`echo "$$p1" | sed -e 's,^.*/,,'`; \
-	    f=`echo $$p1|sed '$(transform);s/$$/$(EXEEXT)/'`; \
+	    f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
 	   echo " $(INSTALL_PROGRAM_ENV) $(sbinPROGRAMS_INSTALL) $$p $(DESTDIR)$(sbindir)/$$f"; \
-	   $(INSTALL_PROGRAM_ENV) $(sbinPROGRAMS_INSTALL) $$p $(DESTDIR)$(sbindir)/$$f; \
+	   $(INSTALL_PROGRAM_ENV) $(sbinPROGRAMS_INSTALL) $$p $(DESTDIR)$(sbindir)/$$f || exit 1; \
 	  else :; fi; \
 	done
 
 uninstall-sbinPROGRAMS:
 	@$(NORMAL_UNINSTALL)
 	@list='$(sbin_PROGRAMS)'; for p in $$list; do \
-	  f=`echo $$p|sed 's/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
-	  f=`echo "$$f" | sed -e 's,^.*/,,'`; \
+	  f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
 	  echo " rm -f $(DESTDIR)$(sbindir)/$$f"; \
 	  rm -f $(DESTDIR)$(sbindir)/$$f; \
 	done
@@ -266,21 +303,27 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isisd.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iso_checksum.Po@am__quote@
 
-distclean-depend:
-	-rm -rf ./$(DEPDIR)
-
 .c.o:
-@AMDEP_TRUE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@	depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
-@AMDEP_TRUE@	$(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-	$(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$<
+@am__fastdepCC_TRUE@	if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
+@am__fastdepCC_TRUE@	  -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
+@am__fastdepCC_TRUE@	else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
+@am__fastdepCC_TRUE@	fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$<
 
 .c.obj:
-@AMDEP_TRUE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@	depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
-@AMDEP_TRUE@	$(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-	$(COMPILE) -c `cygpath -w $<`
-CCDEPMODE = @CCDEPMODE@
+@am__fastdepCC_TRUE@	if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
+@am__fastdepCC_TRUE@	  -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
+@am__fastdepCC_TRUE@	else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
+@am__fastdepCC_TRUE@	fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(COMPILE) -c `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`
 uninstall-info-am:
 sysconfDATA_INSTALL = $(INSTALL_DATA)
 
@@ -295,6 +338,9 @@
 ETAGS = etags
 ETAGSFLAGS =
 
+CTAGS = ctags
+CTAGSFLAGS =
+
 tags: TAGS
 
 ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
@@ -320,20 +366,41 @@
 	  || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
 	     $$tags $$unique
 
+ctags: CTAGS
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	tags=; \
+	here=`pwd`; \
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '    { files[$$0] = 1; } \
+	       END { for (i in files) print i; }'`; \
+	test -z "$(CTAGS_ARGS)$$tags$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$tags $$unique
+
 GTAGS:
 	here=`$(am__cd) $(top_builddir) && pwd` \
 	  && cd $(top_srcdir) \
 	  && gtags -i $(GTAGS_ARGS) $$here
 
 distclean-tags:
-	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 
 top_distdir = ..
 distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
 
 distdir: $(DISTFILES)
-	@list='$(DISTFILES)'; for file in $$list; do \
+	@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+	list='$(DISTFILES)'; for file in $$list; do \
+	  case $$file in \
+	    $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+	    $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+	  esac; \
 	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
 	  dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
 	  if test "$$dir" != "$$file" && test "$$dir" != "."; then \
@@ -359,7 +426,6 @@
 
 installdirs:
 	$(mkinstalldirs) $(DESTDIR)$(sbindir) $(DESTDIR)$(sysconfdir)
-
 install: install-am
 install-exec: install-exec-am
 install-data: install-data-am
@@ -371,7 +437,7 @@
 installcheck: installcheck-am
 install-strip:
 	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-	  INSTALL_STRIP_FLAG=-s \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
 	  `test -z '$(STRIP)' || \
 	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
 mostlyclean-generic:
@@ -379,7 +445,7 @@
 clean-generic:
 
 distclean-generic:
-	-rm -f Makefile $(CONFIG_CLEAN_FILES)
+	-rm -f $(CONFIG_CLEAN_FILES)
 
 maintainer-clean-generic:
 	@echo "This command is intended for maintainers to use"
@@ -390,9 +456,10 @@
 	mostlyclean-am
 
 distclean: distclean-am
-
-distclean-am: clean-am distclean-compile distclean-depend \
-	distclean-generic distclean-tags
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-tags
 
 dvi: dvi-am
 
@@ -413,27 +480,36 @@
 installcheck-am:
 
 maintainer-clean: maintainer-clean-am
-
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
 maintainer-clean-am: distclean-am maintainer-clean-generic
 
 mostlyclean: mostlyclean-am
 
 mostlyclean-am: mostlyclean-compile mostlyclean-generic
 
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
 uninstall-am: uninstall-info-am uninstall-sbinPROGRAMS \
 	uninstall-sysconfDATA
 
-.PHONY: GTAGS all all-am check check-am clean clean-generic \
-	clean-noinstLIBRARIES clean-sbinPROGRAMS distclean \
-	distclean-compile distclean-depend distclean-generic \
-	distclean-tags distdir dvi dvi-am info info-am install \
-	install-am install-data install-data-am install-exec \
-	install-exec-am install-info install-info-am install-man \
-	install-sbinPROGRAMS install-strip install-sysconfDATA \
-	installcheck installcheck-am installdirs maintainer-clean \
-	maintainer-clean-generic mostlyclean mostlyclean-compile \
-	mostlyclean-generic tags uninstall uninstall-am \
-	uninstall-info-am uninstall-sbinPROGRAMS uninstall-sysconfDATA
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+	clean-noinstLIBRARIES clean-sbinPROGRAMS ctags distclean \
+	distclean-compile distclean-generic distclean-tags distdir dvi \
+	dvi-am info info-am install install-am install-data \
+	install-data-am install-exec install-exec-am install-info \
+	install-info-am install-man install-sbinPROGRAMS install-strip \
+	install-sysconfDATA installcheck installcheck-am installdirs \
+	maintainer-clean maintainer-clean-generic mostlyclean \
+	mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \
+	tags uninstall uninstall-am uninstall-info-am \
+	uninstall-sbinPROGRAMS uninstall-sysconfDATA
 
 
 install-sysconfDATA: $(sysconf_DATA)
@@ -448,16 +524,6 @@
 	    $(INSTALL_SDATA) $$p $(DESTDIR)$(sysconfdir)/$$p; \
 	  fi; fi; \
 	done
-
-depend:
-	@$(CPP) -MM $(INCLUDES) $(LDFLAGS) *.c
-
-isis_adjacency.o : isis_adjacency.c ../lib/version.h ../lib/log.h \
- ../isisd/isis_adjacency.h
-isis_pdu.o : isis_pdu.c ../lib/log.h ../isisd/isisd.h \
- ../isisd/isis_constants.h ../isisd/isis_adjacency.h \
- ../isisd/isis_pdu.h
-isis_circuit.o : isis_circuit.c ../isisd/isis_circuit.h
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
 .NOEXPORT:
diff --git a/isisd/isis_dynhn.c b/isisd/isis_dynhn.c
index 9e151d0..0ba1842 100644
--- a/isisd/isis_dynhn.c
+++ b/isisd/isis_dynhn.c
@@ -117,7 +117,7 @@
 	     VTY_NEWLINE);
   }
   
-  vty_out (vty,  "     * %s %s%s", sysid_print (isis->sysid), host.name, 
+  vty_out (vty,  "     * %s %s%s", sysid_print (isis->sysid), unix_hostname(), 
 	   VTY_NEWLINE);
   return;
 }
diff --git a/isisd/isis_lsp.c b/isisd/isis_lsp.c
index 6bfb0fd..f797b9e 100644
--- a/isisd/isis_lsp.c
+++ b/isisd/isis_lsp.c
@@ -60,7 +60,6 @@
 
 extern struct isis *isis;
 extern struct thread_master *master;
-extern struct host host;
 
 int 
 lsp_id_cmp (u_char *id1, u_char *id2)
@@ -638,7 +637,7 @@
   if (dyn)
     sprintf (id, "%.14s", dyn->name.name);
   else if (!memcmp (isis->sysid, lsp_id, ISIS_SYS_ID_LEN) & dynhost)
-    sprintf (id, "%.14s", host.name);
+    sprintf (id, "%.14s", unix_hostname());
    else {
     memcpy(id, sysid_print (lsp_id), 15);
   }
@@ -1053,8 +1052,9 @@
   if (area->dynhostname) {
     lsp->tlv_data.hostname = XMALLOC (MTYPE_ISIS_TLV, 
                                       sizeof (struct hostname));
-    memcpy (&lsp->tlv_data.hostname->name, host.name, strlen(host.name));
-    lsp->tlv_data.hostname->namelen = strlen (host.name);
+    memcpy (&lsp->tlv_data.hostname->name, unix_hostname(),
+            strlen(unix_hostname()));
+    lsp->tlv_data.hostname->namelen = strlen (unix_hostname());
   }
 #ifdef TOPOLOGY_GENERATE
   /*
@@ -1337,8 +1337,10 @@
   if (area->dynhostname) {
     lsp->tlv_data.hostname = XMALLOC (MTYPE_ISIS_TLV, 
                                       sizeof (struct hostname));
-    memcpy (lsp->tlv_data.hostname->name, host.name, strlen (host.name));
-    lsp->tlv_data.hostname->namelen = strlen (host.name);
+
+    memcpy (lsp->tlv_data.hostname->name, unix_hostname(),
+            strlen (unix_hostname()));
+    lsp->tlv_data.hostname->namelen = strlen (unix_hostname());
   }
 
   /*
@@ -1553,13 +1555,14 @@
   if (area->dynhostname) {
     tlv_ptr = lsppdu_realloc (lsp,MTYPE_ISIS_TLV, 2); /* the 2 is for the TL */
     *tlv_ptr = DYNAMIC_HOSTNAME; /* Type */
-    *(tlv_ptr+1) = strlen (host.name); /* Length */
+    *(tlv_ptr+1) = strlen (unix_hostname()); /* Length */
     lsp->tlv_data.hostname = (struct hostname *)
       (lsppdu_realloc(lsp,
 		      MTYPE_ISIS_TLV,
 		      /* the -1 is to fit the length in the struct */
-		      strlen (host.name)) - 1); 
-    memcpy (lsp->tlv_data.hostname->name, host.name, strlen(host.name));
+		      strlen (unix_hostname())) - 1); 
+    memcpy (lsp->tlv_data.hostname->name, unix_hostname(),
+            strlen(unix_hostname()));
   }
 
 }
diff --git a/isisd/isis_main.c b/isisd/isis_main.c
index baf5f38..8106492 100644
--- a/isisd/isis_main.c
+++ b/isisd/isis_main.c
@@ -33,6 +33,7 @@
 #include "memory.h"
 #include "stream.h"
 #include "if.h"
+#include "privs.h"
 
 #include "isisd/dict.h"
 #include "include-netbsd/iso.h"
@@ -48,12 +49,36 @@
 /* Default vty port */
 #define ISISD_VTY_PORT       2607
 
+/* isisd privileges */
+zebra_capabilities_t _caps_p [] = 
+{
+  ZCAP_RAW,
+  ZCAP_BIND
+};
+
+struct zebra_privs_t isisd_privs =
+{
+#if defined(QUAGGA_USER)
+  .user = QUAGGA_USER,
+#endif
+#if defined QUAGGA_GROUP
+  .group = QUAGGA_GROUP,
+#endif
+#ifdef VTY_GROUP
+  .vty_group = VTY_GROUP,
+#endif
+  .caps_p = _caps_p,
+  .cap_num_p = 2,
+  .cap_num_i = 0
+};
+
 /* isisd options */
 struct option longopts[] = 
 {
   { "daemon",      no_argument,       NULL, 'd'},
   { "config_file", required_argument, NULL, 'f'},
   { "vty_port",    required_argument, NULL, 'P'},
+  { "user",        required_argument, NULL, 'u'},
   { "version",     no_argument,       NULL, 'v'},
   { "help",        no_argument,       NULL, 'h'},
   { 0 }
@@ -94,6 +119,7 @@
 -d, --daemon       Runs in daemon mode\n\
 -f, --config_file  Set configuration file name\n\
 -P, --vty_port     Set vty's port number\n\
+-u, --user         User and group to run as\n\
 -v, --version      Print program version\n\
 -h, --help         Display this help and exit\n\
 \n\
@@ -230,7 +256,7 @@
   /* Command line argument treatment. */
   while (1) 
     {
-      opt = getopt_long (argc, argv, "df:hAp:P:v", longopts, 0);
+      opt = getopt_long (argc, argv, "df:hAp:P:u:v", longopts, 0);
     
       if (opt == EOF)
         break;
@@ -249,7 +275,19 @@
           vty_addr = optarg;
           break;
         case 'P':
+         /* Deal with atoi() returning 0 on failure, and isisd not
+             listening on isisd port... */
+          if (strcmp(optarg, "0") == 0) 
+            {
+              vty_port = 0;
+              break;
+            } 
           vty_port = atoi (optarg);
+          vty_port = (vty_port ? vty_port : ISISD_VTY_PORT);
+	  break;
+        case 'u':
+          isisd_privs.user = isisd_privs.group = optarg;
+          break;
           break;
         case 'v':
 	  printf("ISISd version %s\n", ISISD_VERSION);
@@ -276,9 +314,10 @@
   /*
    *  initializations
    */
+  zprivs_init (&isisd_privs);
   signal_init ();
   cmd_init (1);
-  vty_init ();
+  vty_init (master);
   memory_init ();
   isis_init ();
   dyn_cache_init ();
@@ -295,19 +334,18 @@
   if (daemon_mode)
     daemon (0, 0);
 
-  /* Problems with the build env ?*/
-#ifndef PATH_ISISD_PID
-#define PATH_ISISD_PID "/var/run/isisd.pid"
-#endif
   /* Process ID file creation. */
   pid_output (PATH_ISISD_PID);
 
   /* Make isis vty socket. */
-  vty_serv_sock (vty_addr, vty_port ? vty_port : ISISD_VTY_PORT, 
-                 ISIS_VTYSH_PATH);
+  vty_serv_sock (vty_addr, vty_port, ISIS_VTYSH_PATH);
   
   /* Print banner. */
+#if defined(ZEBRA_VERSION)
   zlog_info ("ISISd %s starting: vty@%d", ZEBRA_VERSION, vty_port);
+#elif defined(QUAGGA_VERSION)
+  zlog_info ("Quagga-ISISd %s starting: vty@%d", QUAGGA_VERSION, vty_port);
+#endif
 #ifdef HAVE_IPV6
   zlog_info ("IPv6 enabled");
 #endif
diff --git a/isisd/isis_misc.c b/isisd/isis_misc.c
index 763ae24..cf558e8 100644
--- a/isisd/isis_misc.c
+++ b/isisd/isis_misc.c
@@ -28,12 +28,13 @@
 #include <ctype.h>
 #include <zebra.h>
 #include <net/ethernet.h>
-
+#include <sys/utsname.h>
 
 #include "stream.h"
 #include "vty.h"
 #include "hash.h"
 #include "if.h"
+#include "command.h"
 
 #include "isisd/dict.h"
 #include "isisd/isis_constants.h"
@@ -432,7 +433,22 @@
   return new_prefix;
 }
 
+/*
+ * Returns host.name if any, otherwise
+ * it returns the system hostname.
+ */
+const char *
+unix_hostname(void)
+{
+  static struct utsname names;
+  const char *hostname;
+  extern struct host host;
 
+  hostname = host.name;
+  if (!hostname) { 
+    uname(&names);
+    hostname = names.nodename;
+  }
 
-
-
+  return hostname;
+}
diff --git a/isisd/isis_misc.h b/isisd/isis_misc.h
index 0e219c6..ca0c0ae 100644
--- a/isisd/isis_misc.h
+++ b/isisd/isis_misc.h
@@ -53,6 +53,8 @@
  */
 int  speaks (struct nlpids *nlpids, int family);
 unsigned long isis_jitter (unsigned long timer, unsigned long jitter);
+const char * unix_hostname(void);
+
 
 /*
  * macros
diff --git a/isisd/isis_network.c b/isisd/isis_network.c
index d22f3dd..c10aeeb 100644
--- a/isisd/isis_network.c
+++ b/isisd/isis_network.c
@@ -42,6 +42,10 @@
 #include "isisd/isis_circuit.h"
 #include "isisd/isis_network.h"
 
+#include "privs.h"
+
+extern struct zebra_privs_t isisd_privs;
+
 /*
  * On linux we can use the packet(7) sockets, in other OSs we have to do with
  * Berkley Packet Filter (BPF). Please tell me if you can think of a better 
@@ -297,28 +301,39 @@
 {
   int retval = ISIS_OK;
 
+  if ( isisd_privs.change (ZPRIVS_RAISE) )
+    zlog_err ("%s: could not raise privs, %s", __func__,
+               strerror (errno) );
 
 #ifdef GNU_LINUX
   retval = open_packet_socket (circuit);
 #else
   retval = open_bpf_dev (circuit);
 #endif
-  
-  if (retval == ISIS_OK) {
-    if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
-      circuit->tx = isis_send_pdu_bcast;
-      circuit->rx = isis_recv_pdu_bcast;
-    }
-    else if (circuit->circ_type == CIRCUIT_T_P2P) {
-      circuit->tx = isis_send_pdu_p2p;
-      circuit->rx = isis_recv_pdu_p2p;
-    }
-    else {
-      zlog_warn ("isis_sock_init(): unknown circuit type");
-      retval = ISIS_WARNING;
-    }
+
+  if (retval != ISIS_OK) {
+    zlog_warn("%s: could not initialize the socket",
+              __func__);
+    goto end;
   }
-  
+ 
+  if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
+    circuit->tx = isis_send_pdu_bcast;
+    circuit->rx = isis_recv_pdu_bcast;
+  } else if (circuit->circ_type == CIRCUIT_T_P2P) {
+    circuit->tx = isis_send_pdu_p2p;
+    circuit->rx = isis_recv_pdu_p2p;
+  } else {
+    zlog_warn ("isis_sock_init(): unknown circuit type");
+    retval = ISIS_WARNING;
+    goto end;
+  }
+ 
+end:
+  if ( isisd_privs.change (ZPRIVS_LOWER) )
+    zlog_err ("%s: could not lower privs, %s", __func__,
+               strerror (errno) );
+
   return retval;
 }
 
diff --git a/isisd/isisd.c b/isisd/isisd.c
index 8794a12..3b8a0a6 100644
--- a/isisd/isisd.c
+++ b/isisd/isisd.c
@@ -506,6 +506,79 @@
   return CMD_SUCCESS;
 }
 
+/* Debug node. */
+static struct cmd_node debug_node =
+{
+  DEBUG_NODE,
+ "",
+ 1
+};
+
+static int
+config_write_debug (struct vty *vty)
+{
+  int write = 0;
+  int flags = isis->debugs;
+
+  if (flags & DEBUG_ADJ_PACKETS) {
+    vty_out (vty, "debug isis adj-packets%s",
+             VTY_NEWLINE);
+    write++;
+  }
+  if (flags & DEBUG_CHECKSUM_ERRORS) {
+    vty_out (vty, "debug isis checksum-errors%s",
+             VTY_NEWLINE);
+    write++;
+  }
+  if (flags & DEBUG_LOCAL_UPDATES) {
+    vty_out (vty, "debug isis local-updates%s",
+             VTY_NEWLINE);
+    write++;
+  }
+  if (flags & DEBUG_PROTOCOL_ERRORS) {
+    vty_out (vty, "debug isis protocol-errors%s",  
+             VTY_NEWLINE);
+    write++;
+  }
+  if (flags & DEBUG_SNP_PACKETS) {
+    vty_out (vty, "debug isis snp-packets%s",
+             VTY_NEWLINE);
+    write++;
+  }
+  if (flags & DEBUG_SPF_EVENTS) {
+    vty_out (vty, "debug isis spf-events%s",
+             VTY_NEWLINE);
+    write++;
+  }
+  if (flags & DEBUG_SPF_STATS) {
+    vty_out (vty, "debug isis spf-statistics%s",
+             VTY_NEWLINE);
+    write++;
+  }
+  if (flags & DEBUG_SPF_TRIGGERS) {
+    vty_out (vty, "debug isis spf-triggers%s",
+             VTY_NEWLINE);
+    write++;
+  }
+  if (flags & DEBUG_UPDATE_PACKETS) {
+    vty_out (vty, "debug isis update-packets%s",
+             VTY_NEWLINE);
+    write++;
+  }
+  if (flags & DEBUG_RTE_EVENTS) {
+    vty_out (vty, "debug isis route-events%s",
+             VTY_NEWLINE);
+    write++;
+  }
+  if (flags & DEBUG_EVENTS) {
+    vty_out (vty, "debug isis events%s",
+             VTY_NEWLINE);
+    write++;
+  }
+
+  return write;
+}
+
 DEFUN (debug_isis_adj,
        debug_isis_adj_cmd,
        "debug isis adj-packets",
@@ -1893,6 +1966,8 @@
   install_element (ENABLE_NODE, &show_database_detail_cmd);
   install_element (ENABLE_NODE, &show_debugging_cmd);
 
+  install_node(&debug_node, config_write_debug);
+
   install_element (ENABLE_NODE, &debug_isis_adj_cmd);
   install_element (ENABLE_NODE, &no_debug_isis_adj_cmd);
   install_element (ENABLE_NODE, &debug_isis_csum_cmd);
@@ -1916,6 +1991,29 @@
   install_element (ENABLE_NODE, &debug_isis_events_cmd);
   install_element (ENABLE_NODE, &no_debug_isis_events_cmd);
 
+  install_element (CONFIG_NODE, &debug_isis_adj_cmd);
+  install_element (CONFIG_NODE, &no_debug_isis_adj_cmd);
+  install_element (CONFIG_NODE, &debug_isis_csum_cmd);
+  install_element (CONFIG_NODE, &no_debug_isis_csum_cmd);
+  install_element (CONFIG_NODE, &debug_isis_lupd_cmd);
+  install_element (CONFIG_NODE, &no_debug_isis_lupd_cmd);
+  install_element (CONFIG_NODE, &debug_isis_err_cmd);
+  install_element (CONFIG_NODE, &no_debug_isis_err_cmd);
+  install_element (CONFIG_NODE, &debug_isis_snp_cmd);
+  install_element (CONFIG_NODE, &no_debug_isis_snp_cmd);
+  install_element (CONFIG_NODE, &debug_isis_upd_cmd);
+  install_element (CONFIG_NODE, &no_debug_isis_upd_cmd);
+  install_element (CONFIG_NODE, &debug_isis_spfevents_cmd);
+  install_element (CONFIG_NODE, &no_debug_isis_spfevents_cmd);
+  install_element (CONFIG_NODE, &debug_isis_spfstats_cmd);
+  install_element (CONFIG_NODE, &no_debug_isis_spfstats_cmd);
+  install_element (CONFIG_NODE, &debug_isis_spftrigg_cmd);
+  install_element (CONFIG_NODE, &no_debug_isis_spftrigg_cmd);
+  install_element (CONFIG_NODE, &debug_isis_rtevents_cmd);
+  install_element (CONFIG_NODE, &no_debug_isis_rtevents_cmd);
+  install_element (CONFIG_NODE, &debug_isis_events_cmd);
+  install_element (CONFIG_NODE, &no_debug_isis_events_cmd);
+
   install_element (CONFIG_NODE, &router_isis_cmd);
   install_element (CONFIG_NODE, &no_router_isis_cmd);
 
diff --git a/isisd/isisd.h b/isisd/isisd.h
index 67bf8d6..3ca421a 100644
--- a/isisd/isisd.h
+++ b/isisd/isisd.h
@@ -24,7 +24,6 @@
 #define ISISD_H
 
 #define ISISD_VERSION "0.0.7"
-#define ISIS_VTYSH_PATH        "/tmp/.isisd"
 
 /* uncomment if you are a developer in bug hunt */
 /* #define EXTREME_DEBUG  */
diff --git a/lib/command.c b/lib/command.c
index 43a0bb3..2411306 100644
--- a/lib/command.c
+++ b/lib/command.c
@@ -2325,6 +2325,7 @@
     case RIPNG_NODE:
     case OSPF_NODE:
     case OSPF6_NODE:
+    case ISIS_NODE:
     case KEYCHAIN_NODE:
     case MASC_NODE:
     case RMAP_NODE:
@@ -2377,6 +2378,7 @@
     case RMAP_NODE:
     case OSPF_NODE:
     case OSPF6_NODE:
+    case ISIS_NODE:
     case KEYCHAIN_NODE:
     case KEYCHAIN_KEY_NODE:
     case MASC_NODE:
diff --git a/lib/command.h b/lib/command.h
index 3009b26..32a347f 100644
--- a/lib/command.h
+++ b/lib/command.h
@@ -87,6 +87,7 @@
   BGP_IPV6_NODE,		/* BGP IPv6 address family */
   OSPF_NODE,			/* OSPF protocol mode */
   OSPF6_NODE,			/* OSPF protocol for IPv6 mode */
+  ISIS_NODE,			/* ISIS protocol mode */
   MASC_NODE,			/* MASC for multicast.  */
   IRDP_NODE,			/* ICMP Router Discovery Protocol mode. */ 
   IP_NODE,			/* Static ip route node. */
@@ -255,6 +256,8 @@
 #define PREFIX_LIST_STR "Build a prefix list\n"
 #define OSPF6_DUMP_TYPE_LIST \
 "(neighbor|interface|area|lsa|zebra|config|dbex|spf|route|lsdb|redistribute|hook|asbr|prefix|abr)"
+#define ISIS_STR "IS-IS information\n"
+#define AREA_TAG_STR "[area tag]\n"
 
 #define CONF_BACKUP_EXT ".sav"
 
diff --git a/lib/log.c b/lib/log.c
index aedab3c..5f6b32f 100644
--- a/lib/log.c
+++ b/lib/log.c
@@ -37,6 +37,7 @@
   "OSPF",
   "RIPNG",
   "OSPF6",
+  "ISIS",
   "MASC",
   NULL,
 };
diff --git a/lib/log.h b/lib/log.h
index 69919b4..8948ea0 100644
--- a/lib/log.h
+++ b/lib/log.h
@@ -47,6 +47,7 @@
   ZLOG_OSPF,
   ZLOG_RIPNG,  
   ZLOG_OSPF6,
+  ZLOG_ISIS,
   ZLOG_MASC
 } zlog_proto_t;
 
diff --git a/lib/memory.c b/lib/memory.c
index 9383311..faf3f26 100644
--- a/lib/memory.c
+++ b/lib/memory.c
@@ -385,6 +385,25 @@
   { -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_separator[] =
 {
   { 0, NULL},
@@ -420,6 +439,8 @@
   show_memory_vty (vty, memory_list_separator);
   show_memory_vty (vty, memory_list_ospf6);
   show_memory_vty (vty, memory_list_separator);
+  show_memory_vty (vty, memory_list_isis);
+  show_memory_vty (vty, memory_list_separator);
   show_memory_vty (vty, memory_list_bgp);
 
   return CMD_SUCCESS;
@@ -497,6 +518,17 @@
   return CMD_SUCCESS;
 }
 
+DEFUN (show_memory_isis,
+       show_memory_isis_cmd,
+       "show memory isis",
+       SHOW_STR
+       "Memory statistics\n"
+       "ISIS memory\n")
+{
+  show_memory_vty (vty, memory_list_isis);
+  return CMD_SUCCESS;
+}
+
 void
 memory_init ()
 {
@@ -508,6 +540,7 @@
   install_element (VIEW_NODE, &show_memory_bgp_cmd);
   install_element (VIEW_NODE, &show_memory_ospf_cmd);
   install_element (VIEW_NODE, &show_memory_ospf6_cmd);
+  install_element (VIEW_NODE, &show_memory_isis_cmd);
 
   install_element (ENABLE_NODE, &show_memory_cmd);
   install_element (ENABLE_NODE, &show_memory_all_cmd);
@@ -517,4 +550,5 @@
   install_element (ENABLE_NODE, &show_memory_bgp_cmd);
   install_element (ENABLE_NODE, &show_memory_ospf_cmd);
   install_element (ENABLE_NODE, &show_memory_ospf6_cmd);
+  install_element (ENABLE_NODE, &show_memory_isis_cmd);
 }
diff --git a/lib/memory.h b/lib/memory.h
index 925f6b6..96b5f6c 100644
--- a/lib/memory.h
+++ b/lib/memory.h
@@ -126,6 +126,22 @@
   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,
diff --git a/lib/thread.c b/lib/thread.c
index 402167c..93809f2 100644
--- a/lib/thread.c
+++ b/lib/thread.c
@@ -518,6 +518,46 @@
   return thread;
 }
 
+/* Add timer event thread with "millisecond" resolution */
+struct thread *
+funcname_thread_add_timer_msec (struct thread_master *m,
+		  int (*func) (struct thread *), void *arg, long timer, char* funcname)
+{
+  struct timeval timer_now;
+  struct thread *thread;
+#ifndef TIMER_NO_SORT
+  struct thread *tt;
+#endif /* TIMER_NO_SORT */
+
+  assert (m != NULL);
+
+  thread = thread_get (m, THREAD_TIMER, func, arg, funcname);
+
+  timer = 1000*timer; /* milli -> micro */
+
+  /* Do we need jitter here? */
+  gettimeofday (&timer_now, NULL);
+  timer_now.tv_sec += timer / TIMER_SECOND_MICRO;
+  timer_now.tv_usec += (timer % TIMER_SECOND_MICRO);
+  thread->u.sands = timer_now;
+
+  /* Sort by timeval. */
+#ifdef TIMER_NO_SORT
+  thread_list_add (&m->timer, thread);
+#else
+  for (tt = m->timer.head; tt; tt = tt->next)
+    if (timeval_cmp (thread->u.sands, tt->u.sands) <= 0)
+      break;
+
+  if (tt)
+    thread_list_add_before (&m->timer, tt, thread);
+  else
+    thread_list_add (&m->timer, thread);
+#endif /* TIMER_NO_SORT */
+
+  return thread;
+}
+
 /* Add simple event thread. */
 struct thread *
 funcname_thread_add_event (struct thread_master *m,
diff --git a/lib/thread.h b/lib/thread.h
index 0a45d8f..9a8c2be 100644
--- a/lib/thread.h
+++ b/lib/thread.h
@@ -131,6 +131,7 @@
 #define thread_add_read(m,f,a,v) funcname_thread_add_read(m,f,a,v,#f)
 #define thread_add_write(m,f,a,v) funcname_thread_add_write(m,f,a,v,#f)
 #define thread_add_timer(m,f,a,v) funcname_thread_add_timer(m,f,a,v,#f)
+#define thread_add_timer_msec(m,f,a,v) funcname_thread_add_timer_msec(m,f,a,v,#f)
 #define thread_add_event(m,f,a,v) funcname_thread_add_event(m,f,a,v,#f)
 #define thread_execute(m,f,a,v) funcname_thread_execute(m,f,a,v,#f)
 
@@ -142,6 +143,8 @@
 				 int (*)(struct thread *), void *, int, char*);
 struct thread *funcname_thread_add_timer (struct thread_master *,
 				 int (*)(struct thread *), void *, long, char*);
+struct thread *funcname_thread_add_timer_msec (struct thread_master *,
+				 int (*)(struct thread *), void *, long, char*);
 struct thread *funcname_thread_add_event (struct thread_master *,
 				 int (*)(struct thread *), void *, int, char*);
 void thread_cancel (struct thread *);
diff --git a/lib/vty.c b/lib/vty.c
index 6063290..2b823e0 100644
--- a/lib/vty.c
+++ b/lib/vty.c
@@ -626,6 +626,7 @@
     case RMAP_NODE:
     case OSPF_NODE:
     case OSPF6_NODE:
+    case ISIS_NODE:
     case KEYCHAIN_NODE:
     case KEYCHAIN_KEY_NODE:
     case MASC_NODE:
@@ -1030,6 +1031,7 @@
     case RMAP_NODE:
     case OSPF_NODE:
     case OSPF6_NODE:
+    case ISIS_NODE:
     case KEYCHAIN_NODE:
     case KEYCHAIN_KEY_NODE:
     case MASC_NODE:
diff --git a/lib/zebra.h b/lib/zebra.h
index 51bdc88..997237d 100644
--- a/lib/zebra.h
+++ b/lib/zebra.h
@@ -261,8 +261,9 @@
 #define ZEBRA_ROUTE_RIPNG                5
 #define ZEBRA_ROUTE_OSPF                 6
 #define ZEBRA_ROUTE_OSPF6                7
-#define ZEBRA_ROUTE_BGP                  8
-#define ZEBRA_ROUTE_MAX                  9
+#define ZEBRA_ROUTE_ISIS                 8
+#define ZEBRA_ROUTE_BGP                  9
+#define ZEBRA_ROUTE_MAX                  10
 
 /* Zebra's family types. */
 #define ZEBRA_FAMILY_IPV4                1
@@ -325,6 +326,7 @@
 #define ZEBRA_RIPNG_DISTANCE_DEFAULT     120
 #define ZEBRA_OSPF_DISTANCE_DEFAULT      110
 #define ZEBRA_OSPF6_DISTANCE_DEFAULT     110
+#define ZEBRA_ISIS_DISTANCE_DEFAULT      115
 #define ZEBRA_IBGP_DISTANCE_DEFAULT      200
 #define ZEBRA_EBGP_DISTANCE_DEFAULT       20
 
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index 16102e5..93a13f8 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -54,6 +54,7 @@
   {ZEBRA_ROUTE_RIPNG,   120},
   {ZEBRA_ROUTE_OSPF,    110},
   {ZEBRA_ROUTE_OSPF6,   110},
+  {ZEBRA_ROUTE_ISIS,    115},
   {ZEBRA_ROUTE_BGP,      20  /* IBGP is 200. */}
 };
 
diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c
index ebb3694..4bcd29f 100644
--- a/zebra/zebra_vty.c
+++ b/zebra/zebra_vty.c
@@ -49,6 +49,8 @@
       return "ospf";
     case ZEBRA_ROUTE_OSPF6:
       return "ospf";
+    case ZEBRA_ROUTE_ISIS:
+      return "isis";
     case ZEBRA_ROUTE_BGP:
       return "bgp";
     default:
@@ -78,6 +80,8 @@
       return 'O';
     case ZEBRA_ROUTE_OSPF6:
       return 'O';
+    case ZEBRA_ROUTE_ISIS:
+      return 'I';
     case ZEBRA_ROUTE_BGP:
       return 'B';
     default:
@@ -558,6 +562,7 @@
 #define ONE_WEEK_SECOND 60*60*24*7
       if (rib->type == ZEBRA_ROUTE_RIP
 	  || rib->type == ZEBRA_ROUTE_OSPF
+	  || rib->type == ZEBRA_ROUTE_ISIS
 	  || rib->type == ZEBRA_ROUTE_BGP)
 	{
 	  time_t uptime;
@@ -721,6 +726,7 @@
 
       if (rib->type == ZEBRA_ROUTE_RIP
 	  || rib->type == ZEBRA_ROUTE_OSPF
+	  || rib->type == ZEBRA_ROUTE_ISIS
 	  || rib->type == ZEBRA_ROUTE_BGP)
 	{
 	  time_t uptime;
@@ -748,7 +754,7 @@
     }
 }
 
-#define SHOW_ROUTE_V4_HEADER "Codes: K - kernel route, C - connected, S - static, R - RIP, O - OSPF,%s       B - BGP, > - selected route, * - FIB route%s%s"
+#define SHOW_ROUTE_V4_HEADER "Codes: K - kernel route, C - connected, S - static, R - RIP, O - OSPF,%s       I - ISIS, B - BGP, > - selected route, * - FIB route%s%s"
 
 DEFUN (show_ip_route,
        show_ip_route_cmd,
@@ -874,6 +880,7 @@
        "Connected\n"
        "Kernel\n"
        "Open Shortest Path First (OSPF)\n"
+       "ISO IS-IS (ISIS)\n"
        "Routing Information Protocol (RIP)\n"
        "Static routes\n")
 {
@@ -891,6 +898,8 @@
     type = ZEBRA_ROUTE_KERNEL;
   else if (strncmp (argv[0], "o", 1) == 0)
     type = ZEBRA_ROUTE_OSPF;
+  else if (strncmp (argv[0], "i", 1) == 0)
+    type = ZEBRA_ROUTE_ISIS;
   else if (strncmp (argv[0], "r", 1) == 0)
     type = ZEBRA_ROUTE_RIP;
   else if (strncmp (argv[0], "s", 1) == 0)
@@ -1437,6 +1446,7 @@
 #define ONE_WEEK_SECOND 60*60*24*7
       if (rib->type == ZEBRA_ROUTE_RIPNG
 	  || rib->type == ZEBRA_ROUTE_OSPF6
+	  || rib->type == ZEBRA_ROUTE_ISIS
 	  || rib->type == ZEBRA_ROUTE_BGP)
 	{
 	  time_t uptime;
@@ -1615,6 +1625,7 @@
       
       if (rib->type == ZEBRA_ROUTE_RIPNG
 	  || rib->type == ZEBRA_ROUTE_OSPF6
+	  || rib->type == ZEBRA_ROUTE_ISIS
 	  || rib->type == ZEBRA_ROUTE_BGP)
 	{
 	  time_t uptime;
@@ -1642,7 +1653,7 @@
     }
 }
 
-#define SHOW_ROUTE_V6_HEADER "Codes: K - kernel route, C - connected, S - static, R - RIPng, O - OSPFv3,%s       B - BGP, * - FIB route.%s%s"
+#define SHOW_ROUTE_V6_HEADER "Codes: K - kernel route, C - connected, S - static, R - RIPng, O - OSPFv3,%s       I - ISIS, B - BGP, * - FIB route.%s%s"
 
 DEFUN (show_ipv6_route,
        show_ipv6_route_cmd,
@@ -1726,6 +1737,7 @@
        "Connected\n"
        "Kernel\n"
        "Open Shortest Path First (OSPFv3)\n"
+       "ISO IS-IS (ISIS)\n"
        "Routing Information Protocol (RIPng)\n"
        "Static routes\n")
 {
@@ -1743,6 +1755,8 @@
     type = ZEBRA_ROUTE_KERNEL;
   else if (strncmp (argv[0], "o", 1) == 0)
     type = ZEBRA_ROUTE_OSPF6;
+  else if (strncmp (argv[0], "i", 1) == 0)
+    type = ZEBRA_ROUTE_ISIS;
   else if (strncmp (argv[0], "r", 1) == 0)
     type = ZEBRA_ROUTE_RIPNG;
   else if (strncmp (argv[0], "s", 1) == 0)