Initial revision
diff --git a/isisd/isis_misc.c b/isisd/isis_misc.c
new file mode 100644
index 0000000..763ae24
--- /dev/null
+++ b/isisd/isis_misc.c
@@ -0,0 +1,438 @@
+/*
+ * IS-IS Rout(e)ing protocol - isis_misc.h
+ *                             Miscellanous routines
+ *
+ * Copyright (C) 2001,2002   Sampo Saaristo
+ *                           Tampere University of Technology      
+ *                           Institute of Communications Engineering
+ *
+ * This program is free software; you can redistribute it and/or modify it 
+ * under the terms of the GNU General Public Licenseas published by the Free 
+ * Software Foundation; either version 2 of the License, or (at your option) 
+ * any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software Foundation, Inc., 
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include <ctype.h>
+#include <zebra.h>
+#include <net/ethernet.h>
+
+
+#include "stream.h"
+#include "vty.h"
+#include "hash.h"
+#include "if.h"
+
+#include "isisd/dict.h"
+#include "isisd/isis_constants.h"
+#include "isisd/isis_common.h"
+#include "isisd/isis_circuit.h"
+#include "isisd/isisd.h"
+#include "isisd/isis_misc.h"
+
+#include "isisd/isis_tlv.h"
+#include "isisd/isis_lsp.h"
+#include "isisd/isis_constants.h"
+#include "isisd/isis_adjacency.h"
+
+/*
+ * This converts the isonet to its printable format
+ */
+char * isonet_print (u_char *from, int len) {
+  int i = 0;
+  char *pos = isonet;
+
+  if(!from)
+    return "unknown";
+
+  while (i < len) {
+    if (i & 1) {
+      sprintf ( pos, "%02x", *(from + i));
+      pos += 2;
+    } else {
+      if (i == 0) { /* if the area addr is just one byte, eg. 47. */
+        sprintf ( pos, "%02x", *(from + i));
+        pos += 2;
+      } else {
+        sprintf ( pos, "%02x.", *(from + i));
+        pos += 3;
+      }
+    }
+    i++;
+  }
+  *(pos) = '\0';
+  return isonet;
+}
+
+/*
+ * Returns 0 on error, length of buff on ok
+ * extract dot from the dotted str, and insert all the number in a buff 
+ */
+int
+dotformat2buff (u_char *buff, u_char *dotted)
+{
+  int dotlen, len = 0;
+  u_char *pos = dotted;
+  u_char number[3];
+  int nextdotpos = 2;
+
+  number[2] = '\0';
+  dotlen = strlen(dotted);
+  if (dotlen > 50) {
+    /* this can't be an iso net, its too long */
+    return 0;
+  }
+
+  while ( (pos - dotted) < dotlen && len < 20 ) {
+    if (*pos == '.') {
+      /* we expect the . at 2, and than every 5 */
+      if ((pos - dotted) != nextdotpos) {
+        len = 0;
+        break;
+      }
+      nextdotpos += 5;
+      pos++;
+      continue;
+    }
+    /* we must have at least two chars left here */
+    if (dotlen - (pos - dotted) < 2) {
+      len = 0;
+      break;
+    }
+
+    if ((isxdigit((int)*pos)) && (isxdigit((int)*(pos+1)))){
+      memcpy (number, pos ,2);
+      pos+=2;
+    } else {
+      len = 0;
+      break;
+    }
+
+    *(buff + len) = (char)strtol(number, NULL, 16);
+    len++;
+  }
+  
+  return len;
+}
+/*
+ * conversion of XXXX.XXXX.XXXX to memory
+ */
+int
+sysid2buff (u_char *buff, u_char *dotted)
+ {
+  int len = 0;
+  u_char *pos = dotted;
+  u_char number[3];
+
+  number[2] = '\0';
+  // surely not a sysid_string if not 14 length
+  if (strlen(dotted) != 14) {
+    return 0;
+  }
+
+  while ( len < ISIS_SYS_ID_LEN ) {
+    if (*pos == '.') {
+      /* the . is not positioned correctly */
+      if (((pos - dotted) !=4) && ((pos - dotted) != 9)) { 
+        len = 0;
+        break;
+      }
+      pos++;
+      continue;
+    }
+    if ((isxdigit((int)*pos)) && (isxdigit((int)*(pos+1)))){
+      memcpy (number, pos ,2);
+      pos+=2;
+    } else {
+      len = 0;
+      break;
+    }
+
+    *(buff + len) = (char)strtol(number, NULL, 16);
+    len++;
+  }
+
+  return len;
+
+}
+
+/*
+ * converts the nlpids struct (filled by TLV #129)
+ * into a string
+ */
+
+char *
+nlpid2string (struct nlpids *nlpids) {
+  char *pos = nlpidstring;
+  int i;
+
+  for (i=0;i<nlpids->count;i++) {
+    switch (nlpids->nlpids[i]) {
+    case NLPID_IP:
+      pos += sprintf (pos, "IPv4");
+      break;
+    case NLPID_IPV6:
+      pos += sprintf (pos, "IPv6");
+      break;
+    default:
+      pos += sprintf (pos, "unknown");
+      break;
+    }
+    if (nlpids->count-i>1)
+      pos += sprintf (pos, ", ");
+    
+  }
+
+  *(pos) = '\0';
+  
+  return nlpidstring;
+}
+
+/*
+ *  supports the given af ?
+ */
+int 
+speaks (struct nlpids *nlpids, int family)
+{
+  int i, speaks = 0;
+  
+  if (nlpids == (struct nlpids*)NULL)
+    return speaks;
+  for (i = 0;i < nlpids->count; i++) {
+    if (family == AF_INET && nlpids->nlpids[i] == NLPID_IP)
+      speaks = 1;
+    if (family == AF_INET6 && nlpids->nlpids[i] == NLPID_IPV6)
+      speaks = 1;
+  }
+
+  return speaks;
+}
+
+
+/*
+ * Returns 0 on error, IS-IS Circuit Type on ok
+ */
+int 
+string2circuit_t (u_char *str)
+{
+  
+  if (!str)
+    return 0;
+  
+  if (!strcmp(str,"level-1"))
+    return IS_LEVEL_1;
+
+  if (!strcmp(str,"level-2-only") || !strcmp(str,"level-2"))
+    return IS_LEVEL_2;
+  
+  if (!strcmp(str,"level-1-2"))
+    return IS_LEVEL_1_AND_2;
+
+  return 0;
+}
+
+const char *
+circuit_t2string (int circuit_t)
+{
+  switch (circuit_t) {
+  case IS_LEVEL_1:
+    return "L1";
+  case IS_LEVEL_2:
+    return "L2";
+  case IS_LEVEL_1_AND_2:
+    return "L1L2";
+  default:
+    return "??";
+  }
+
+  return NULL; /* not reached */
+}
+
+const char *
+syst2string (int type)
+{
+  switch (type) {
+  case ISIS_SYSTYPE_ES:
+    return "ES";
+  case ISIS_SYSTYPE_IS:
+    return "IS";
+  case ISIS_SYSTYPE_L1_IS:
+    return "1";
+  case ISIS_SYSTYPE_L2_IS:
+    return "2";
+  default:
+    return "??";
+  }
+
+  return NULL; /* not reached */
+}
+
+/*
+ * Print functions - we print to static vars
+ */
+char *
+snpa_print (u_char *from)
+{
+  int i = 0;
+  u_char *pos = snpa;
+
+  if(!from)
+    return "unknown";
+  
+  while (i < ETH_ALEN - 1) {
+    if (i & 1) {
+      sprintf ( pos, "%02x.", *(from + i));
+      pos += 3;
+    } else {
+      sprintf ( pos, "%02x", *(from + i));
+      pos += 2;
+
+    }
+    i++;
+  }
+
+  sprintf (pos, "%02x", *(from + (ISIS_SYS_ID_LEN - 1)));
+  pos += 2;
+  *(pos) = '\0';
+
+  return snpa;
+}
+
+char *
+sysid_print (u_char *from)
+{
+  int i = 0;
+  char *pos = sysid;
+
+  if(!from)
+    return "unknown";
+
+  while (i < ISIS_SYS_ID_LEN - 1) {
+    if (i & 1) {
+      sprintf ( pos, "%02x.", *(from + i));
+      pos += 3;
+    } else {
+      sprintf ( pos, "%02x", *(from + i));
+      pos += 2;
+    
+    } 
+    i++;
+  }
+
+  sprintf (pos, "%02x", *(from + (ISIS_SYS_ID_LEN - 1)));
+  pos += 2;
+  *(pos) = '\0';
+  
+  return sysid;
+}
+
+char *
+rawlspid_print (u_char *from)
+{
+  char *pos = lspid;
+  if(!from)
+    return "unknown";
+  memcpy(pos, sysid_print(from), 15);
+  pos += 14;
+  sprintf (pos, ".%02x", LSP_PSEUDO_ID(from));
+  pos += 3;
+  sprintf (pos, "-%02x", LSP_FRAGMENT(from));
+  pos += 3;
+
+  *(pos) = '\0';
+
+  return lspid;
+}
+
+char *
+time2string (u_int32_t time) {
+  char *pos = datestring; 
+  u_int32_t rest;
+
+  if (time==0)
+    return "-";
+
+  if(time/SECS_PER_YEAR)
+    pos += sprintf (pos, "%uY",time/SECS_PER_YEAR);
+  rest=time%SECS_PER_YEAR;    
+  if(rest/SECS_PER_MONTH)
+    pos += sprintf (pos, "%uM",rest/SECS_PER_MONTH);
+  rest=rest%SECS_PER_MONTH;  
+  if(rest/SECS_PER_WEEK)
+    pos += sprintf (pos, "%uw",rest/SECS_PER_WEEK);
+  rest=rest%SECS_PER_WEEK;    
+  if(rest/SECS_PER_DAY)
+    pos += sprintf (pos, "%ud",rest/SECS_PER_DAY);
+  rest=rest%SECS_PER_DAY;    
+  if(rest/SECS_PER_HOUR)
+    pos += sprintf (pos, "%uh",rest/SECS_PER_HOUR);
+  rest=rest%SECS_PER_HOUR;    
+  if(rest/SECS_PER_MINUTE)
+    pos += sprintf (pos, "%um",rest/SECS_PER_MINUTE);
+  rest=rest%SECS_PER_MINUTE;    
+  if(rest)
+    pos += sprintf (pos, "%us",rest);   
+ 
+  *(pos) = 0;
+
+  return datestring;
+}
+
+/*
+ * routine to decrement a timer by a random
+ * number
+ *
+ * first argument is the timer and the second is
+ * the jitter
+ */
+unsigned long 
+isis_jitter (unsigned long timer, unsigned long jitter)
+{
+  int j,k;
+
+  if (jitter>=100)
+    return timer;
+
+  if (timer == 1)
+    return timer;
+  /* 
+   * randomizing just the percent value provides
+   * no good random numbers - hence the spread
+   * to RANDOM_SPREAD (100000), which is ok as
+   * most IS-IS timers are no longer than 16 bit
+   */
+
+  j = 1 + (int) ((RANDOM_SPREAD * rand()) / (RAND_MAX + 1.0 )); 
+
+  k = timer - (timer * (100 - jitter))/100;
+
+  timer = timer - (k * j / RANDOM_SPREAD);
+
+  return timer;
+}
+
+struct in_addr
+newprefix2inaddr (u_char *prefix_start, u_char prefix_masklen) 
+{
+  memset(&new_prefix, 0, sizeof (new_prefix));
+  memcpy(&new_prefix, prefix_start, (prefix_masklen & 0x3F) ? 
+	 ((((prefix_masklen & 0x3F)-1)>>3)+1) : 0);
+  return new_prefix;
+}
+
+
+
+
+