isisd: add Google's changes to IS-IS
diff --git a/isisd/isis_tlv.c b/isisd/isis_tlv.c
index 94fa65e..bb57bd6 100644
--- a/isisd/isis_tlv.c
+++ b/isisd/isis_tlv.c
@@ -43,13 +43,6 @@
 #include "isisd/isis_pdu.h"
 #include "isisd/isis_lsp.h"
 
-extern struct isis *isis;
-
-/*
- * Prototypes.
- */
-int add_tlv (u_char, u_char, u_char *, struct stream *);
-
 void
 free_tlv (void *val)
 {
@@ -75,10 +68,10 @@
     list_delete (tlvs->es_neighs);
   if (tlvs->lsp_entries)
     list_delete (tlvs->lsp_entries);
-  if (tlvs->lan_neighs)
-    list_delete (tlvs->lan_neighs);
   if (tlvs->prefix_neighs)
     list_delete (tlvs->prefix_neighs);
+  if (tlvs->lan_neighs)
+    list_delete (tlvs->lan_neighs);
   if (tlvs->ipv4_addrs)
     list_delete (tlvs->ipv4_addrs);
   if (tlvs->ipv4_int_reachs)
@@ -93,7 +86,9 @@
   if (tlvs->ipv6_reachs)
     list_delete (tlvs->ipv6_reachs);
 #endif /* HAVE_IPV6 */
-  
+
+  memset (tlvs, 0, sizeof (struct tlvs));
+
   return;
 }
 
@@ -103,7 +98,7 @@
  */
 int
 parse_tlvs (char *areatag, u_char * stream, int size, u_int32_t * expected,
-	    u_int32_t * found, struct tlvs *tlvs)
+	    u_int32_t * found, struct tlvs *tlvs, u_int32_t *auth_tlv_offset)
 {
   u_char type, length;
   struct lan_neigh *lan_nei;
@@ -122,7 +117,7 @@
 #endif /* HAVE_IPV6 */
   u_char virtual;
   int value_len, retval = ISIS_OK;
-  u_char *pnt = stream;
+  u_char *start = stream, *pnt = stream;
 
   *found = 0;
   memset (tlvs, 0, sizeof (struct tlvs));
@@ -443,10 +438,22 @@
 	  if (*expected & TLVFLAG_AUTH_INFO)
 	    {
 	      tlvs->auth_info.type = *pnt;
-	      tlvs->auth_info.len = length-1;
+              if (length == 0)
+                {
+                  zlog_warn ("ISIS-TLV (%s): TLV (type %d, length %d) "
+                             "incorrect.", areatag, type, length);
+                  return ISIS_WARNING;
+                }
+              --length;
+	      tlvs->auth_info.len = length;
 	      pnt++;
-	      memcpy (tlvs->auth_info.passwd, pnt, length - 1);
-	      pnt += length - 1;
+	      memcpy (tlvs->auth_info.passwd, pnt, length);
+              /* Return the authentication tlv pos for later computation
+               * of MD5 (RFC 5304, 2)
+               */
+              if (auth_tlv_offset)
+                *auth_tlv_offset += (pnt - start - 3);
+              pnt += length;
 	    }
 	  else
 	    {
@@ -730,10 +737,14 @@
 int
 add_tlv (u_char tag, u_char len, u_char * value, struct stream *stream)
 {
-
-  if (STREAM_SIZE (stream) - stream_get_endp (stream) < (unsigned) len + 2)
+  if ((stream_get_size (stream) - stream_get_endp (stream)) <
+      (((unsigned)len) + 2))
     {
-      zlog_warn ("No room for TLV of type %d", tag);
+      zlog_warn ("No room for TLV of type %d "
+                 "(total size %d available %d required %d)",
+                 tag, (int)stream_get_size (stream),
+                 (int)(stream_get_size (stream) - stream_get_endp (stream)),
+                 len+2);
       return ISIS_WARNING;
     }
 
@@ -873,12 +884,12 @@
 }
 
 int
-tlv_add_authinfo (char auth_type, char auth_len, u_char *auth_value,
+tlv_add_authinfo (u_char auth_type, u_char auth_len, u_char *auth_value,
 		  struct stream *stream)
 {
   u_char value[255];
   u_char *pos = value;
-  *pos++ = ISIS_PASSWD_TYPE_CLEARTXT;
+  *pos++ = auth_type;
   memcpy (pos, auth_value, auth_len);
 
   return add_tlv (AUTH_INFO, auth_len + 1, value, stream);
@@ -1002,7 +1013,6 @@
       pos += IPV4_MAX_BYTELEN;
     }
 
-
   return add_tlv (IPV4_INT_REACHABILITY, pos - value, value, stream);
 }
 
@@ -1023,7 +1033,7 @@
       if (pos - value + (5 + prefix_size) > 255)
 	{
 	  retval =
-	    add_tlv (IPV4_INT_REACHABILITY, pos - value, value, stream);
+	    add_tlv (TE_IPV4_REACHABILITY, pos - value, value, stream);
 	  if (retval != ISIS_OK)
 	    return retval;
 	  pos = value;
@@ -1106,7 +1116,7 @@
   /*
    * How many times can we add full padding ?
    */
-  fullpads = (STREAM_SIZE (stream) - stream_get_endp (stream)) / 257;
+  fullpads = (stream_get_size (stream) - stream_get_endp (stream)) / 257;
   for (i = 0; i < fullpads; i++)
     {
       if (!stream_putc (stream, (u_char) PADDING))	/* TAG */
@@ -1116,7 +1126,7 @@
       stream_put (stream, NULL, 255);		/* zero padding */
     }
 
-  left = STREAM_SIZE (stream) - stream_get_endp (stream);
+  left = stream_get_size (stream) - stream_get_endp (stream);
 
   if (left < 2)
     return ISIS_OK;