bugfix to a bug reported by Ian Schorr:
[obnox/wireshark/wip.git] / packet-ndps.c
index 6de263938c6b35d3ba53d41720d827302158688a..43c210caed63bb1b6e3afa85bff714eb9d6d43f5 100644 (file)
@@ -3,7 +3,7 @@
  * Greg Morris <gmorris@novell.com>
  * Copyright (c) Novell, Inc. 2002-2003
  *
- * $Id: packet-ndps.c,v 1.22 2003/06/04 08:38:09 guy Exp $
+ * $Id: packet-ndps.c,v 1.25 2003/10/17 22:59:18 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -46,11 +46,7 @@ static GHashTable *ndps_reassembled_table = NULL;
 
 /* desegmentation of ndps */
 static gboolean ndps_defragment = TRUE;
-static guint32  frag_number = 0;
-static guint32  save_frag_length=0;
-static guint32  save_frag_seq=0;
-static gboolean ndps_fragmented = FALSE;
-static gboolean more_fragment = FALSE;
+
 static guint32  tid = 1;
 
 /* Show ID's value */
@@ -227,6 +223,7 @@ static int hf_ndps_training = -1;
 static int hf_ndps_colorant_set = -1;
 static int hf_ndps_card_enum_time = -1;
 static int hf_ndps_attrs_arg = -1;
+static int hf_ndps_context_len = -1;
 static int hf_ndps_context = -1;
 static int hf_ndps_filter = -1;
 static int hf_ndps_item_filter = -1;
@@ -1847,6 +1844,7 @@ name_or_id(tvbuff_t* tvb, proto_tree *ndps_tree, int foffset)
             foffset = ndps_string(tvb, hf_local_object_name, ndps_tree, foffset, NULL, 0);
             break;
     }
+    foffset += align_4(tvb, foffset);
     return foffset;
 }
 
@@ -2037,7 +2035,10 @@ credentials(tvbuff_t* tvb, proto_tree *ndps_tree, int foffset)
             atree = proto_item_add_subtree(aitem, ett_ndps);
             length = tvb_get_ntohl(tvb, foffset);
             foffset += 4;
-            proto_tree_add_item(atree, hf_ndps_password, tvb, foffset, length, FALSE);
+            if (length!=0)
+            {
+                proto_tree_add_item(atree, hf_ndps_password, tvb, foffset, length, FALSE);
+            }
             proto_item_set_end(aitem, tvb, foffset);
             foffset += length;
         }
@@ -2045,7 +2046,10 @@ credentials(tvbuff_t* tvb, proto_tree *ndps_tree, int foffset)
     case 1:
         length = tvb_get_ntohl(tvb, foffset);
         foffset += 4;
-        proto_tree_add_item(ndps_tree, hf_ndps_certified, tvb, foffset, length, FALSE);
+        if (length!=0)
+        {
+            proto_tree_add_item(ndps_tree, hf_ndps_certified, tvb, foffset, length, FALSE);
+        }
         foffset += length;
         break;
     case 2:
@@ -2173,7 +2177,10 @@ cardinal_seq(tvbuff_t* tvb, proto_tree *ndps_tree, int foffset)
         atree = proto_item_add_subtree(aitem, ett_ndps);
         length = tvb_get_ntohl(tvb, foffset);
         foffset += 4;
-        proto_tree_add_item(atree, hf_ndps_attribute_value, tvb, foffset, length, FALSE);
+        if (length!=0)
+        {
+            proto_tree_add_item(atree, hf_ndps_attribute_value, tvb, foffset, length, FALSE);
+        }
         foffset += length;
         foffset += (length%2);
         proto_item_set_end(aitem, tvb, foffset);
@@ -2365,7 +2372,10 @@ attribute_value(tvbuff_t* tvb, proto_tree *ndps_tree, int foffset)
         case 14:         /* Cardinal Seq */
             length = tvb_get_ntohl(tvb, foffset);
             foffset += 4;
-            proto_tree_add_item(ndps_tree, hf_info_int32, tvb, foffset, length, FALSE);
+            if (length!=0)
+            {
+                proto_tree_add_item(ndps_tree, hf_info_int32, tvb, foffset, length, FALSE);
+            }
             foffset += length;
             break;
         case 16:         /* Integer Range */
@@ -2603,11 +2613,15 @@ attribute_value(tvbuff_t* tvb, proto_tree *ndps_tree, int foffset)
             foffset = qualifiedname(tvb, ndps_tree, foffset);
             length = tvb_get_ntohl(tvb, foffset);
             foffset += 4;
-            proto_tree_add_item(ndps_tree, hf_ndps_attribute_value, tvb, foffset, length, FALSE);
+            if (length!=0)
+            {
+                proto_tree_add_item(ndps_tree, hf_ndps_attribute_value, tvb, foffset, length, FALSE);
+            }
             foffset += length;
             proto_tree_add_item(ndps_tree, hf_ndps_language_id, tvb, foffset, 4, FALSE);
             foffset += 4;
             foffset = name_or_id(tvb, ndps_tree, foffset);
+
             number_of_items = tvb_get_ntohl(tvb, foffset);
             proto_tree_add_uint(ndps_tree, hf_ndps_num_address_items, tvb, foffset, 4, number_of_items);
             foffset += 4;
@@ -2615,7 +2629,7 @@ attribute_value(tvbuff_t* tvb, proto_tree *ndps_tree, int foffset)
             {
                 aitem = proto_tree_add_text(ndps_tree, tvb, foffset, -1, "Address Item %u", i);
                 atree = proto_item_add_subtree(aitem, ett_ndps);
-                foffset += address_item(tvb, atree, foffset);
+                foffset = address_item(tvb, atree, foffset);
                 proto_item_set_end(aitem, tvb, foffset);
             }
             number_of_items = tvb_get_ntohl(tvb, foffset);
@@ -2628,15 +2642,27 @@ attribute_value(tvbuff_t* tvb, proto_tree *ndps_tree, int foffset)
                 proto_tree_add_item(atree, hf_ndps_event_type, tvb, foffset, 4, FALSE);
                 foffset += 4;
                 foffset = objectidentifier(tvb, atree, foffset);
+                foffset += align_4(tvb, foffset);
                 foffset = objectidentification(tvb, atree, foffset);
                 proto_tree_add_item(atree, hf_ndps_object_op, tvb, foffset, 4, FALSE);
                 foffset += 4;
-                
                 event_object_type = tvb_get_ntohl(tvb, foffset);
                 proto_tree_add_uint(atree, hf_ndps_event_object_identifier, tvb, foffset, 4, event_object_type);
                 foffset += 4;
                 switch (event_object_type)
                 {
+                    case 2:
+                        /* Number of Objects */
+                        number_of_items2 = tvb_get_ntohl(tvb, foffset);
+                        proto_tree_add_uint(atree, hf_ndps_num_objects, tvb, foffset, 4, number_of_items2);
+                        foffset += 4;
+                        for (j = 1 ; j <= number_of_items2; j++ )
+                        {
+                            foffset = objectidentifier(tvb, atree, foffset);
+                        }
+                        foffset += 4;
+                        break;
+
                     case 1:
                         foffset = objectidentifier(tvb, atree, foffset);
                         break;
@@ -2722,7 +2748,10 @@ attribute_value(tvbuff_t* tvb, proto_tree *ndps_tree, int foffset)
                 atree = proto_item_add_subtree(aitem, ett_ndps);
                 length = tvb_get_ntohl(tvb, foffset);
                 foffset += 4;
-                proto_tree_add_item(atree, hf_ndps_attribute_value, tvb, foffset, length, FALSE);
+                if (length!=0)
+                {
+                    proto_tree_add_item(atree, hf_ndps_attribute_value, tvb, foffset, length, FALSE);
+                }
                 foffset += length;
                 foffset += (length%2);
                 proto_item_set_end(aitem, tvb, foffset);
@@ -2891,7 +2920,10 @@ attribute_value(tvbuff_t* tvb, proto_tree *ndps_tree, int foffset)
             {
                 length = tvb_get_ntohl(tvb, foffset);
                 foffset += 4;
-                proto_tree_add_item(ndps_tree, hf_ndps_octet_string, tvb, foffset, length, FALSE);
+                if (length!=0)
+                {
+                    proto_tree_add_item(ndps_tree, hf_ndps_octet_string, tvb, foffset, length, FALSE);
+                }
                 foffset += length;
                 foffset += (length%2);
             }
@@ -3024,7 +3056,10 @@ attribute_value(tvbuff_t* tvb, proto_tree *ndps_tree, int foffset)
                 atree = proto_item_add_subtree(aitem, ett_ndps);
                 length = tvb_get_ntohl(tvb, foffset);
                 foffset += 4;
-                proto_tree_add_item(atree, hf_ndps_attribute_value, tvb, foffset, length, FALSE);
+                if (length!=0)
+                {
+                    proto_tree_add_item(atree, hf_ndps_attribute_value, tvb, foffset, length, FALSE);
+                }
                 foffset += length;
                 foffset += (length%2);
             }
@@ -3037,7 +3072,10 @@ attribute_value(tvbuff_t* tvb, proto_tree *ndps_tree, int foffset)
                 atree = proto_item_add_subtree(aitem, ett_ndps);
                 length = tvb_get_ntohl(tvb, foffset);
                 foffset += 4;
-                proto_tree_add_item(atree, hf_ndps_attribute_value, tvb, foffset, length, FALSE);
+                if (length!=0)
+                {
+                    proto_tree_add_item(atree, hf_ndps_attribute_value, tvb, foffset, length, FALSE);
+                }
                 foffset += length;
                 foffset += (length%2);
                 proto_item_set_end(aitem, tvb, foffset);
@@ -3088,7 +3126,10 @@ attribute_value(tvbuff_t* tvb, proto_tree *ndps_tree, int foffset)
             foffset += 4;
             length = tvb_get_ntohl(tvb, foffset);
             foffset += 4;
-            proto_tree_add_item(ndps_tree, hf_ndps_add_bytes, tvb, foffset, 4, FALSE);
+            if (length!=0)
+            {
+                proto_tree_add_item(ndps_tree, hf_ndps_add_bytes, tvb, foffset, 4, FALSE);
+            }
             foffset += length;
             break;
         case 92:         /* XY Dimensions Value */
@@ -3241,19 +3282,28 @@ attribute_value(tvbuff_t* tvb, proto_tree *ndps_tree, int foffset)
         case 106:         /* Octet String Pair */
             length = tvb_get_ntohl(tvb, foffset);
             foffset += 4;
-            proto_tree_add_item(ndps_tree, hf_ndps_octet_string, tvb, foffset, length, FALSE);
+            if (length!=0)
+            {
+                proto_tree_add_item(ndps_tree, hf_ndps_octet_string, tvb, foffset, length, FALSE);
+            }
             foffset += length;
             foffset += (length%2);
             length = tvb_get_ntohl(tvb, foffset);
             foffset += 4;
-            proto_tree_add_item(ndps_tree, hf_ndps_octet_string, tvb, foffset, length, FALSE);
+            if (length!=0)
+            {
+                proto_tree_add_item(ndps_tree, hf_ndps_octet_string, tvb, foffset, length, FALSE);
+            }
             foffset += length;
             foffset += (length%2);
             break;
         case 107:         /* Octet String Integer Pair */
             length = tvb_get_ntohl(tvb, foffset);
             foffset += 4;
-            proto_tree_add_item(ndps_tree, hf_ndps_octet_string, tvb, foffset, length, FALSE);
+            if (length!=0)
+            {
+                proto_tree_add_item(ndps_tree, hf_ndps_octet_string, tvb, foffset, length, FALSE);
+            }
             foffset += length;
             foffset += (length%2);
             proto_tree_add_item(ndps_tree, hf_ndps_attribute_value, tvb, foffset, 4, FALSE);
@@ -3269,7 +3319,10 @@ attribute_value(tvbuff_t* tvb, proto_tree *ndps_tree, int foffset)
             foffset = qualifiedname(tvb, ndps_tree, foffset);
             length = tvb_get_ntohl(tvb, foffset);
             foffset += 4;
-            proto_tree_add_item(ndps_tree, hf_ndps_octet_string, tvb, foffset, length, FALSE);
+            if (length!=0)
+            {
+                proto_tree_add_item(ndps_tree, hf_ndps_octet_string, tvb, foffset, length, FALSE);
+            }
             foffset += length;
             foffset += (length%2);
             proto_tree_add_item(ndps_tree, hf_ndps_attribute_value, tvb, foffset, 4, FALSE);
@@ -3288,7 +3341,10 @@ attribute_value(tvbuff_t* tvb, proto_tree *ndps_tree, int foffset)
                 case 3:     /*OCTET_STRING*/
                     length = tvb_get_ntohl(tvb, foffset);
                     foffset += 4;
-                    proto_tree_add_item(ndps_tree, hf_ndps_octet_string, tvb, foffset, length, FALSE);
+                    if (length!=0)
+                    {
+                        proto_tree_add_item(ndps_tree, hf_ndps_octet_string, tvb, foffset, length, FALSE);
+                    }
                     foffset += length;
                     foffset += (length%2);
                     break;
@@ -3459,6 +3515,8 @@ typedef struct {
         guint32             ndps_prog;
         guint32             ndps_func;
         guint32             ndps_frame_num;
+        gboolean            ndps_frag;
+        guint32             ndps_end_frag;
 } ndps_req_hash_value;
 
 static GHashTable *ndps_req_hash = NULL;
@@ -3548,6 +3606,8 @@ ndps_hash_insert(conversation_t *conversation, guint32 ndps_xport)
        request_value->ndps_prog = 0;
        request_value->ndps_func = 0;
        request_value->ndps_frame_num = 0;
+    request_value->ndps_frag = FALSE;
+    request_value->ndps_end_frag = 0;
        
        g_hash_table_insert(ndps_req_hash, request_key, request_value);
 
@@ -3696,20 +3756,7 @@ dissect_ndps(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ndps_tree)
 static guint
 get_ndps_pdu_len(tvbuff_t *tvb, int offset)
 {
-    guint16 plen;
-
-    /*
-     * Get the length of the NDPS packet.
-     */
-    plen = tvb_get_ntohs(tvb, offset + 2);
-
-    /*
-     * That length doesn't include the length of the record mark field
-     * or the length field itself; add that in.
-     * (XXX - is the field really a 31-bit length with the uppermost bit
-     * being a record mark bit?)
-     */
-    return plen + 4;
+    return tvb_get_ntohs(tvb, offset +2) + 4;
 }
 
 static void
@@ -3731,43 +3778,91 @@ dissect_ndps_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
     dissect_ndps(tvb, pinfo, ndps_tree);
 }
 
+/*
+ * Defrag logic 
+ *
+ * SPX EOM not being set indicates we are inside or at the 
+ * beginning of a fragment. But when the end of the fragment 
+ * is encounterd the flag is set. So we must mark what the
+ * frame number is of the end fragment so that we will be
+ * able to redissect if the user clicks on the packet
+ * or resorts/filters the trace. 
+ *
+ * Once we are certain that we are in a fragment sequence
+ * then we can just process each fragment in this conversation
+ * until we reach the eom message packet. We can tell we are at
+ * the final fragment because it is flagged as SPX EOM.
+ *
+ * We will be able to easily determine if a conversation is a fragment
+ * with the exception of the last packet in the fragment. So remember
+ * the last fragment packet number.
+ */         
 static void
 ndps_defrag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 {
-    guint16         record_mark=0;
-    guint16         ndps_length=0;
-    int             len=0;
-    tvbuff_t        *next_tvb = NULL;
-    fragment_data   *fd_head;
-    spx_info        *spx_info;
+    int                 len=0;
+    tvbuff_t            *next_tvb = NULL;
+    fragment_data       *fd_head;
+    spx_info            *spx_info;
+    ndps_req_hash_value        *request_value = NULL;
+    conversation_t      *conversation;
 
+    /* Get SPX info from SPX dissector */
     spx_info = pinfo->private_data;
+    /* Check to see if defragmentation is enabled in the dissector */
     if (!ndps_defragment) {
         dissect_ndps(tvb, pinfo, tree);
         return;
     }
-    record_mark = tvb_get_ntohs(tvb, 0);
-    ndps_length = tvb_get_ntohs(tvb, 2);
-    if (ndps_length > tvb_length_remaining(tvb, 0) || ndps_fragmented || ndps_length==0) 
+    /* Has this already been dissected? */
+    if (!pinfo->fd->flags.visited) 
+    {
+        /* Lets see if this is a new conversation */
+        conversation = find_conversation(&pinfo->src, &pinfo->dst,
+            PT_NCP, (guint32) pinfo->srcport, (guint32) pinfo->srcport, 0);
+    
+        if (conversation == NULL) 
+        {
+            /* It's not part of any conversation - create a new one. */
+            conversation = conversation_new(&pinfo->src, &pinfo->dst,
+                PT_NCP, (guint32) pinfo->srcport, (guint32) pinfo->srcport, 0);
+            /* Create new request value hash */
+            request_value = ndps_hash_insert(conversation, (guint32) pinfo->srcport);
+        }
+        /* So now we need to get the request info for this conversation */
+        request_value = ndps_hash_lookup(conversation, (guint32) pinfo->srcport);
+        if (request_value == NULL) 
+        {
+            /* We haven't seen a packet with this conversation yet so create one. */
+            request_value = ndps_hash_insert(conversation, (guint32) pinfo->srcport);
+        }
+        /* Add it to pinfo so we can get it on further dissection requests */
+        p_add_proto_data(pinfo->fd, proto_ndps, (void*) request_value);
+    }
+    else
+    {
+        /* Get request value data */
+        request_value = p_get_proto_data(pinfo->fd, proto_ndps);
+    }
+    /* Check to see of this is a fragment. If so then mark as a fragment. */
+    if (!spx_info->eom) {
+        request_value->ndps_frag = TRUE;
+    }
+    /* Now we process the fragments */
+    if (request_value->ndps_frag || (request_value->ndps_end_frag == pinfo->fd->num)) 
     {
-        more_fragment = TRUE;
-        ndps_fragmented = TRUE;
-
         /*   
          * Fragment
          */
         tid = (pinfo->srcport+pinfo->destport);
         len = tvb_reported_length_remaining(tvb, 0);
-        if ((frag_number + tvb_length_remaining(tvb, 0)-save_frag_length)<=10)
-        {
-            more_fragment = FALSE;
-        }
         if (tvb_bytes_exist(tvb, 0, len))
         {
-            fd_head = fragment_add_seq_next(tvb, 0, pinfo, tid, ndps_fragment_table, ndps_reassembled_table, len, more_fragment);
+            fd_head = fragment_add_seq_next(tvb, 0, pinfo, tid, ndps_fragment_table, ndps_reassembled_table, len, !spx_info->eom);
             if (fd_head != NULL) 
             {
-                if (fd_head->next != NULL) 
+                /* Is this the last fragment? EOM will indicate */
+                if (fd_head->next != NULL && spx_info->eom) 
                 {
                     next_tvb = tvb_new_real_data(fd_head->data,
                         fd_head->len, fd_head->len);
@@ -3785,78 +3880,62 @@ ndps_defrag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                             next_tvb);
                         tid++;
                     }
-                    more_fragment = FALSE;
-                    save_frag_length = 0;
-                    frag_number=0;
-                    ndps_fragmented=FALSE;
+                    /* Remember this fragment number so we can dissect again */
+                    request_value->ndps_end_frag = pinfo->fd->num;
+
                 } 
                 else 
                 {
+                    /* This is either a beggining or middle fragment on second dissection */
                     next_tvb = tvb_new_subset(tvb, 0, -1, -1);
-                }
-            }
-            else 
-            {
-                if (save_frag_length == 0) 
-                {
-                    save_frag_length = ndps_length;                 /* First Fragment */
-                    save_frag_seq = tid;
-                }
-                if ((pinfo->srcport+pinfo->destport) == save_frag_seq) 
-                {
-                    if (!pinfo->fd->flags.visited) 
-                    {
-                        frag_number += tvb_length_remaining(tvb, 0);    /* Current offset */
-                    }
                     if (check_col(pinfo->cinfo, COL_INFO))
                     {
-                      if (more_fragment)
+                      if (!spx_info->eom)
                       {
-                        col_append_fstr(pinfo->cinfo, COL_INFO, " [NDPS Fragment]");
+                        col_append_fstr(pinfo->cinfo, COL_INFO, "[NDPS Fragment]");
                       }
                     }
                 }
+            }
+            else 
+            {
+                /* Fragment from first pass of dissection */
+                if (check_col(pinfo->cinfo, COL_INFO))
+                {
+                  if (!spx_info->eom)
+                  {
+                    col_append_fstr(pinfo->cinfo, COL_INFO, "[NDPS Fragment]");
+                  }
+                }
                 next_tvb = NULL;
             }
         }
         else 
         {
             /*
-             * Dissect this
+             * There are no bytes so Dissect this
              */
             next_tvb = tvb_new_subset(tvb, 0, -1, -1);
         }
         if (next_tvb == NULL)
         {
-            if ((pinfo->srcport+pinfo->destport) == save_frag_seq) 
-            {
-                next_tvb = tvb_new_subset (tvb, 0, -1, -1);
-                call_dissector(ndps_data_handle, next_tvb, pinfo, tree);
-            }
-            else
-            {
-                if (spx_info->eom) 
-                {
-                    ndps_fragmented=FALSE;
-                }
-                dissect_ndps(tvb, pinfo, tree);
-            }
+            /* This is a fragment packet */
+            next_tvb = tvb_new_subset (tvb, 0, -1, -1);
+            call_dissector(ndps_data_handle, next_tvb, pinfo, tree);
         }
         else
         {
-            if (spx_info->eom) 
-            {
-                ndps_fragmented=FALSE;
+            /* This is the end fragment so dissect and mark end */
+            if (spx_info->eom) {
+                request_value->ndps_frag = FALSE;
+                dissect_ndps(next_tvb, pinfo, tree);
             }
-            dissect_ndps(next_tvb, pinfo, tree);
         }
     }
     else
     {
-        if (spx_info->eom) 
-        {
-            ndps_fragmented=FALSE;
-        }
+        /* This is not any fragment packet */
+        request_value->ndps_frag = FALSE;
         dissect_ndps(tvb, pinfo, tree);
     }
 }
@@ -3915,6 +3994,7 @@ dissect_ndps_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ndps_tree, g
     guint32             profiles_choice_type;
     guint32             integer_type_flag;
     guint32             local_servers_type;
+    gint               length_remaining;
     proto_tree          *atree;
     proto_item          *aitem;
     proto_tree          *btree;
@@ -3926,7 +4006,6 @@ dissect_ndps_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ndps_tree, g
 
     if (!pinfo->fd->flags.visited) 
     {
-
         /* This is the first time we've looked at this packet.
         Keep track of the Program and connection whence the request
         came, and the address and connection to which the request
@@ -3940,7 +4019,7 @@ dissect_ndps_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ndps_tree, g
             PT_NCP, (guint32) pinfo->srcport, (guint32) pinfo->srcport, 0);
 
         if (conversation == NULL) 
-            {
+        {
             /* It's not part of any conversation - create a new one. */
             conversation = conversation_new(&pinfo->src, &pinfo->dst,
                 PT_NCP, (guint32) pinfo->srcport, (guint32) pinfo->srcport, 0);
@@ -3971,7 +4050,10 @@ dissect_ndps_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ndps_tree, g
                 aitem = proto_tree_add_text(ndps_tree, tvb, foffset, -1, "Security %u", i);
                 atree = proto_item_add_subtree(aitem, ett_ndps);
                 length = tvb_get_ntohl(tvb, foffset);
-                proto_tree_add_uint(atree, hf_bind_security, tvb, foffset, 4, length);
+                if (length!=0)
+                {
+                    proto_tree_add_uint(atree, hf_bind_security, tvb, foffset, 4, length);
+                }
                 foffset += 4;
                 proto_item_set_end(aitem, tvb, foffset);
             }
@@ -4046,12 +4128,16 @@ dissect_ndps_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ndps_tree, g
                         length = tvb_get_ntohl(tvb, foffset);
                         proto_tree_add_uint(btree, hf_ndps_included_doc_len, tvb, foffset, 4, length);
                         foffset += 4;
-                        if (length > tvb_length_remaining(tvb, foffset)) /* Segmented Data */
+                        length_remaining = tvb_length_remaining(tvb, foffset);
+                        if (length_remaining == -1 || length > (guint32) length_remaining) /* Segmented Data */
                         {
                             proto_tree_add_item(btree, hf_ndps_data, tvb, foffset, -1, FALSE);
                             return;
                         }
-                        proto_tree_add_item(btree, hf_ndps_included_doc, tvb, foffset, length, FALSE);
+                        if (length!=0)
+                        {
+                            proto_tree_add_item(btree, hf_ndps_included_doc, tvb, foffset, length, FALSE);
+                        }
                         foffset += length;
                         foffset += (length%2);
                     }
@@ -4233,7 +4319,12 @@ dissect_ndps_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ndps_tree, g
             if (list_attr_op==0) /* Continuation */
             {
                 length = tvb_get_ntohl(tvb, foffset);
-                proto_tree_add_item(ndps_tree, hf_ndps_context, tvb, foffset, length, FALSE);
+                proto_tree_add_uint(ndps_tree, hf_ndps_context_len, tvb, foffset, 4, length);
+                foffset += 4;
+                if (length!=0)
+                {
+                    proto_tree_add_item(ndps_tree, hf_ndps_context, tvb, foffset, length, FALSE);
+                }
                 foffset += length;
                 foffset += (length%2);
                 proto_tree_add_item(ndps_tree, hf_ndps_abort_flag, tvb, foffset, 4, FALSE);
@@ -4741,7 +4832,10 @@ dissect_ndps_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ndps_tree, g
                 atree = proto_item_add_subtree(aitem, ett_ndps);
                 length = tvb_get_ntohl(tvb, foffset);
                 foffset += 4;
-                proto_tree_add_item(atree, hf_ndps_attribute_value, tvb, foffset, length, FALSE);
+                if (length!=0)
+                {
+                    proto_tree_add_item(atree, hf_ndps_attribute_value, tvb, foffset, length, FALSE);
+                }
                 foffset += length;
                 proto_item_set_end(aitem, tvb, foffset);
             }
@@ -4824,7 +4918,12 @@ dissect_ndps_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ndps_tree, g
             else                                    /* Cont */
             {
                 length = tvb_get_ntohl(tvb, foffset);
-                proto_tree_add_item(ndps_tree, hf_ndps_context, tvb, foffset, length, FALSE);
+                proto_tree_add_uint(ndps_tree, hf_ndps_context_len, tvb, foffset, 4, length);
+                foffset += 4;
+                if (length!=0)
+                {
+                    proto_tree_add_item(ndps_tree, hf_ndps_context, tvb, foffset, length, FALSE);
+                }
                 foffset += length;
                 foffset += (length%2);
                 proto_tree_add_item(ndps_tree, hf_ndps_abort_flag, tvb, foffset, 4, FALSE);
@@ -4867,7 +4966,10 @@ dissect_ndps_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ndps_tree, g
         case 0x00000022:    /* Map GUID to NDS Name */
             length = tvb_get_ntohl(tvb, foffset);
             foffset += 4;
-            proto_tree_add_item(ndps_tree, hf_ndps_guid, tvb, foffset, length, FALSE);
+            if (length!=0)
+            {
+                proto_tree_add_item(ndps_tree, hf_ndps_guid, tvb, foffset, length, FALSE);
+            }
             foffset += length;
             break;
         case 0x00000023:    /* AddEventProfile2 */
@@ -4984,7 +5086,12 @@ dissect_ndps_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ndps_tree, g
             else                                    /* Cont */
             {
                 length = tvb_get_ntohl(tvb, foffset);
-                proto_tree_add_item(ndps_tree, hf_ndps_context, tvb, foffset, length, FALSE);
+                proto_tree_add_uint(ndps_tree, hf_ndps_context_len, tvb, foffset, 4, length);
+                foffset += 4;
+                if (length!=0)
+                {
+                    proto_tree_add_item(ndps_tree, hf_ndps_context, tvb, foffset, length, FALSE);
+                }
                 foffset += length;
                 foffset += (length%2);
                 proto_tree_add_item(ndps_tree, hf_ndps_abort_flag, tvb, foffset, 4, FALSE);
@@ -5011,7 +5118,10 @@ dissect_ndps_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ndps_tree, g
                 atree = proto_item_add_subtree(aitem, ett_ndps);
                 length = tvb_get_ntohl(tvb, foffset);
                 foffset += 4;
-                proto_tree_add_item(atree, hf_bind_security, tvb, foffset, length, FALSE);
+                if (length!=0)
+                {
+                    proto_tree_add_item(atree, hf_bind_security, tvb, foffset, length, FALSE);
+                }
                 proto_item_set_end(aitem, tvb, foffset);
             }
             break;
@@ -5033,7 +5143,10 @@ dissect_ndps_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ndps_tree, g
             {
                 length = tvb_get_ntohl(tvb, foffset);
                 foffset += 4;
-                proto_tree_add_item(atree, hf_ndps_item_bytes, tvb, foffset, length, FALSE);
+                if (length!=0)
+                {
+                    proto_tree_add_item(atree, hf_ndps_item_bytes, tvb, foffset, length, FALSE);
+                }
                 foffset += length;
             }
             proto_item_set_end(aitem, tvb, foffset);
@@ -5065,7 +5178,10 @@ dissect_ndps_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ndps_tree, g
                 atree = proto_item_add_subtree(aitem, ett_ndps);
                 length = tvb_get_ntohl(tvb, foffset);
                 foffset += 4;
-                proto_tree_add_item(atree, hf_bind_security, tvb, foffset, length, FALSE);
+                if (length!=0)
+                {
+                    proto_tree_add_item(atree, hf_bind_security, tvb, foffset, length, FALSE);
+                }
                 proto_item_set_end(aitem, tvb, foffset);
             }
             break;
@@ -5134,7 +5250,12 @@ dissect_ndps_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ndps_tree, g
             else
             {
                 length = tvb_get_ntohl(tvb, foffset);
-                proto_tree_add_item(ndps_tree, hf_ndps_context, tvb, foffset, length, FALSE);
+                proto_tree_add_uint(ndps_tree, hf_ndps_context_len, tvb, foffset, 4, length);
+                foffset += 4;
+                if (length!=0)
+                {
+                    proto_tree_add_item(ndps_tree, hf_ndps_context, tvb, foffset, length, FALSE);
+                }
                 foffset += length;
                 foffset += (length%2);
                 proto_tree_add_item(ndps_tree, hf_ndps_abort_flag, tvb, foffset, 4, FALSE);
@@ -5160,7 +5281,10 @@ dissect_ndps_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ndps_tree, g
                 atree = proto_item_add_subtree(aitem, ett_ndps);
                 length = tvb_get_ntohl(tvb, foffset);
                 foffset += 4;
-                proto_tree_add_item(atree, hf_bind_security, tvb, foffset, length, FALSE);
+                if (length!=0)
+                {
+                    proto_tree_add_item(atree, hf_bind_security, tvb, foffset, length, FALSE);
+                }
                 proto_item_set_end(aitem, tvb, foffset);
             }
             break;
@@ -5207,7 +5331,10 @@ dissect_ndps_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ndps_tree, g
             proto_item_set_end(aitem, tvb, foffset);
             length = tvb_get_ntohl(tvb, foffset);
             foffset += 4;
-            proto_tree_add_item(ndps_tree, hf_ndps_attribute_value, tvb, foffset, length, FALSE);
+            if (length!=0)
+            {
+                proto_tree_add_item(ndps_tree, hf_ndps_attribute_value, tvb, foffset, length, FALSE);
+            }
             foffset += length;
             proto_tree_add_item(ndps_tree, hf_ndps_language_id, tvb, foffset, 4, FALSE);
             foffset += 4;
@@ -5226,7 +5353,7 @@ dissect_ndps_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ndps_tree, g
             {
                 bitem = proto_tree_add_text(atree, tvb, foffset, -1, "Address %d", i);
                 btree = proto_item_add_subtree(bitem, ett_ndps);
-                foffset += address_item(tvb, btree, foffset);
+                foffset = address_item(tvb, btree, foffset);
                 proto_item_set_end(bitem, tvb, foffset);
             }
             proto_item_set_end(aitem, tvb, foffset);
@@ -5253,7 +5380,10 @@ dissect_ndps_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ndps_tree, g
                 atree = proto_item_add_subtree(aitem, ett_ndps);
                 length = tvb_get_ntohl(tvb, foffset);
                 foffset += 4;
-                proto_tree_add_item(atree, hf_ndps_attribute_value, tvb, foffset, length, FALSE);
+                if (length!=0)
+                {
+                    proto_tree_add_item(atree, hf_ndps_attribute_value, tvb, foffset, length, FALSE);
+                }
                 foffset += length;
                 proto_item_set_end(aitem, tvb, foffset);
             }
@@ -5336,7 +5466,12 @@ dissect_ndps_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ndps_tree, g
             else                                    /* Cont */
             {
                 length = tvb_get_ntohl(tvb, foffset);
-                proto_tree_add_item(ndps_tree, hf_ndps_context, tvb, foffset, length, FALSE);
+                proto_tree_add_uint(ndps_tree, hf_ndps_context_len, tvb, foffset, 4, length);
+                foffset += 4;
+                if (length!=0)
+                {
+                    proto_tree_add_item(ndps_tree, hf_ndps_context, tvb, foffset, length, FALSE);
+                }
                 foffset += length;
                 foffset += (length%2);
                 proto_tree_add_item(ndps_tree, hf_ndps_abort_flag, tvb, foffset, 4, FALSE);
@@ -5514,7 +5649,12 @@ dissect_ndps_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ndps_tree, g
                 break;
             case 1:       /* Continuation */
                 length = tvb_get_ntohl(tvb, foffset);
-                proto_tree_add_item(ndps_tree, hf_ndps_context, tvb, foffset, length, FALSE);
+                proto_tree_add_uint(ndps_tree, hf_ndps_context_len, tvb, foffset, 4, length);
+                foffset += 4;
+                if (length!=0)
+                {
+                    proto_tree_add_item(ndps_tree, hf_ndps_context, tvb, foffset, length, FALSE);
+                }
                 foffset += length;
                 foffset += (length%2);
                 proto_tree_add_item(ndps_tree, hf_ndps_abort_flag, tvb, foffset, 4, FALSE);
@@ -5554,7 +5694,10 @@ dissect_ndps_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ndps_tree, g
                 atree = proto_item_add_subtree(aitem, ett_ndps);
                 length = tvb_get_ntohl(tvb, foffset);
                 foffset += 4;
-                proto_tree_add_item(atree, hf_bind_security, tvb, foffset, length, FALSE);
+                if (length!=0)
+                {
+                    proto_tree_add_item(atree, hf_bind_security, tvb, foffset, length, FALSE);
+                }
                 proto_item_set_end(aitem, tvb, foffset);
             }
             break;
@@ -5579,7 +5722,8 @@ dissect_ndps_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ndps_tree, g
                 aitem = proto_tree_add_text(ndps_tree, tvb, foffset, -1, "Item %d", i);
                 atree = proto_item_add_subtree(aitem, ett_ndps);
                 length=tvb_get_ntohl(tvb, foffset);
-                if(tvb_length_remaining(tvb, foffset) < length)
+                length_remaining = tvb_length_remaining(tvb, foffset);
+                if(length_remaining == -1 || (guint32) length_remaining < length)
                 {
                     return;
                 }
@@ -5738,7 +5882,10 @@ dissect_ndps_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ndps_tree, g
                 btree = proto_item_add_subtree(bitem, ett_ndps);
                 length = tvb_get_ntohl(tvb, foffset);
                 foffset += 4;
-                proto_tree_add_item(btree, hf_ndps_attribute_value, tvb, foffset, length, FALSE);
+                if (length!=0)
+                {
+                    proto_tree_add_item(btree, hf_ndps_attribute_value, tvb, foffset, length, FALSE);
+                }
                 foffset += length;
                 proto_tree_add_item(btree, hf_ndps_event_type, tvb, foffset, 4, FALSE);
                 foffset += 4;
@@ -5792,7 +5939,10 @@ dissect_ndps_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ndps_tree, g
                 btree = proto_item_add_subtree(bitem, ett_ndps);
                 length = tvb_get_ntohl(tvb, foffset);
                 foffset += 4;
-                proto_tree_add_item(btree, hf_ndps_attribute_value, tvb, foffset, length, FALSE);
+                if (length!=0)
+                {
+                    proto_tree_add_item(btree, hf_ndps_attribute_value, tvb, foffset, length, FALSE);
+                }
                 foffset += length;
                 proto_tree_add_item(atree, hf_ndps_event_type, tvb, foffset, 4, FALSE);
                 foffset += 4;
@@ -6093,6 +6243,7 @@ dissect_ndps_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ndps_tree, int
     guint32                 ndps_prog=0;
     guint32                 error_val=0;
     guint32                 resource_type=0;
+    gint                   length_remaining;
     
     if (!pinfo->fd->flags.visited) {
         /* Find the conversation whence the request would have come. */
@@ -6243,7 +6394,8 @@ dissect_ndps_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ndps_tree, int
                 bitem = proto_tree_add_text(atree, tvb, foffset, -1, "Option %d", i);
                 btree = proto_item_add_subtree(bitem, ett_ndps);
                 length=tvb_get_ntohl(tvb, foffset);
-                if(tvb_length_remaining(tvb, foffset) < length)
+                length_remaining = tvb_length_remaining(tvb, foffset);
+                if(length_remaining == -1 || (guint32) length_remaining < length)
                 {
                     return;
                 }
@@ -6459,7 +6611,10 @@ dissect_ndps_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ndps_tree, int
         case 0x0000001d:    /* List Event Profiles */
             length = tvb_get_ntohl(tvb, foffset);
             foffset += 4;
-            proto_tree_add_item(ndps_tree, hf_ndps_attribute_value, tvb, foffset, length, FALSE);
+            if (length!=0)
+            {
+                proto_tree_add_item(ndps_tree, hf_ndps_attribute_value, tvb, foffset, length, FALSE);
+            }
             foffset += length;
             /* Start of Eventhandling */
             proto_tree_add_item(ndps_tree, hf_ndps_profile_id, tvb, foffset, 4, FALSE);
@@ -6471,7 +6626,10 @@ dissect_ndps_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ndps_tree, int
             foffset = qualifiedname(tvb, atree, foffset);
             length = tvb_get_ntohl(tvb, foffset);
             foffset += 4;
-            proto_tree_add_item(ndps_tree, hf_ndps_attribute_value, tvb, foffset, length, FALSE);
+            if (length!=0)
+            {
+                proto_tree_add_item(ndps_tree, hf_ndps_attribute_value, tvb, foffset, length, FALSE);
+            }
             foffset += length;
             proto_tree_add_item(ndps_tree, hf_ndps_language_id, tvb, foffset, 4, FALSE);
             foffset += 4;
@@ -6491,7 +6649,7 @@ dissect_ndps_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ndps_tree, int
             {
                 bitem = proto_tree_add_text(atree, tvb, foffset, -1, "Address %d", i);
                 btree = proto_item_add_subtree(bitem, ett_ndps);
-                foffset += address_item(tvb, btree, foffset);
+                foffset = address_item(tvb, btree, foffset);
                 proto_item_set_end(bitem, tvb, foffset);
             }
             proto_item_set_end(aitem, tvb, foffset);
@@ -6499,7 +6657,10 @@ dissect_ndps_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ndps_tree, int
             /* End of Eventhandling */
             length = tvb_get_ntohl(tvb, foffset);
             foffset += 4;
-            proto_tree_add_item(ndps_tree, hf_ndps_continuation_option, tvb, foffset, length, FALSE);
+            if (length!=0)
+            {
+                proto_tree_add_item(ndps_tree, hf_ndps_continuation_option, tvb, foffset, length, FALSE);
+            }
             foffset += length;
             if(error_val != 0)
             {
@@ -6595,7 +6756,12 @@ dissect_ndps_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ndps_tree, int
                 foffset = ndps_string(tvb, hf_notify_printer_uri, atree, foffset, NULL, 0);
                 proto_item_set_end(aitem, tvb, foffset);
                 /* End of Eventhandling2 */
-                proto_tree_add_item(ndps_tree, hf_ndps_continuation_option, tvb, foffset, length, FALSE);
+                length = tvb_get_ntohl(tvb, foffset); /* Added on 10-17-03 */
+                foffset += 4;
+                if (length!=0)
+                {
+                    proto_tree_add_item(ndps_tree, hf_ndps_continuation_option, tvb, foffset, length, FALSE);
+                }
                 foffset += length;
                 if(error_val != 0)
                 {
@@ -6659,7 +6825,10 @@ dissect_ndps_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ndps_tree, int
                 atree = proto_item_add_subtree(aitem, ett_ndps);
                 length = tvb_get_ntohl(tvb, foffset);
                 foffset += 4;
-                proto_tree_add_item(atree, hf_ndps_attribute_set, tvb, foffset, length, FALSE);
+                if (length!=0)
+                {
+                    proto_tree_add_item(atree, hf_ndps_attribute_set, tvb, foffset, length, FALSE);
+                }
                 proto_item_set_end(aitem, tvb, foffset);
             }
             break;
@@ -6687,7 +6856,10 @@ dissect_ndps_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ndps_tree, int
             }
             length = tvb_get_ntohl(tvb, foffset);
             foffset += 4;
-            proto_tree_add_item(ndps_tree, hf_ndps_continuation_option, tvb, foffset, length, FALSE);
+            if (length!=0)
+            {
+                proto_tree_add_item(ndps_tree, hf_ndps_continuation_option, tvb, foffset, length, FALSE);
+            }
             foffset += length;
             foffset = return_code(tvb, pinfo, ndps_tree, foffset);
             break;
@@ -6705,7 +6877,10 @@ dissect_ndps_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ndps_tree, int
             }
             length = tvb_get_ntohl(tvb, foffset);
             foffset += 4;
-            proto_tree_add_item(ndps_tree, hf_ndps_continuation_option, tvb, foffset, length, FALSE);
+            if (length!=0)
+            {
+                proto_tree_add_item(ndps_tree, hf_ndps_continuation_option, tvb, foffset, length, FALSE);
+            }
             foffset += length;
             foffset = return_code(tvb, pinfo, ndps_tree, foffset);
             break;
@@ -6740,7 +6915,10 @@ dissect_ndps_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ndps_tree, int
                 atree = proto_item_add_subtree(aitem, ett_ndps);
                 length = tvb_get_ntohl(tvb, foffset);
                 foffset += 4;
-                proto_tree_add_item(atree, hf_ndps_attribute_set, tvb, foffset, length, FALSE);
+                if (length!=0)
+                {
+                    proto_tree_add_item(atree, hf_ndps_attribute_set, tvb, foffset, length, FALSE);
+                }
                 proto_item_set_end(aitem, tvb, foffset);
             }
             break;
@@ -6785,7 +6963,10 @@ dissect_ndps_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ndps_tree, int
             proto_item_set_end(aitem, tvb, foffset);
             length = tvb_get_ntohl(tvb, foffset);
             foffset += 4;
-            proto_tree_add_item(ndps_tree, hf_ndps_attribute_value, tvb, foffset, length, FALSE);
+            if (length!=0)
+            {
+                proto_tree_add_item(ndps_tree, hf_ndps_attribute_value, tvb, foffset, length, FALSE);
+            }
             foffset += length;
             proto_tree_add_item(ndps_tree, hf_ndps_language_id, tvb, foffset, 4, FALSE);
             foffset += 4;
@@ -6804,7 +6985,7 @@ dissect_ndps_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ndps_tree, int
             {
                 bitem = proto_tree_add_text(atree, tvb, foffset, -1, "Address %d", i);
                 btree = proto_item_add_subtree(bitem, ett_ndps);
-                foffset += address_item(tvb, btree, foffset);
+                foffset = address_item(tvb, btree, foffset);
                 proto_item_set_end(bitem, tvb, foffset);
             }
             proto_item_set_end(aitem, tvb, foffset);
@@ -6813,7 +6994,10 @@ dissect_ndps_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ndps_tree, int
             /* End of ProfileResultSet */
             length = tvb_get_ntohl(tvb, foffset);
             foffset += 4;
-            proto_tree_add_item(ndps_tree, hf_ndps_continuation_option, tvb, foffset, length, FALSE);
+            if (length!=0)
+            {
+                proto_tree_add_item(ndps_tree, hf_ndps_continuation_option, tvb, foffset, length, FALSE);
+            }
             foffset += length;
             foffset = return_code(tvb, pinfo, ndps_tree, foffset);
             break;
@@ -6821,7 +7005,10 @@ dissect_ndps_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ndps_tree, int
             /* Start of IntegerSeq */
             length = tvb_get_ntohl(tvb, foffset);
             foffset += 4;
-            proto_tree_add_item(ndps_tree, hf_ndps_language_id, tvb, foffset, length, FALSE);
+            if (length!=0)
+            {
+                proto_tree_add_item(ndps_tree, hf_ndps_language_id, tvb, foffset, length, FALSE);
+            }
             foffset += length;
             /* End of IntegerSeq */
             foffset = return_code(tvb, pinfo, ndps_tree, foffset);
@@ -6886,7 +7073,7 @@ dissect_ndps_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ndps_tree, int
             {
                 bitem = proto_tree_add_text(atree, tvb, foffset, -1, "Address %d", i);
                 btree = proto_item_add_subtree(bitem, ett_ndps);
-                foffset += address_item(tvb, btree, foffset);
+                foffset = address_item(tvb, btree, foffset);
                 proto_item_set_end(bitem, tvb, foffset);
             }
             proto_item_set_end(aitem, tvb, foffset);
@@ -6917,7 +7104,10 @@ dissect_ndps_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ndps_tree, int
         case 0x00000001:    /* Bind */
             length = tvb_get_ntohl(tvb, foffset);
             foffset += 4;
-            proto_tree_add_item(ndps_tree, hf_ndps_attribute_set, tvb, foffset, length, FALSE);
+            if (length!=0)
+            {
+                proto_tree_add_item(ndps_tree, hf_ndps_attribute_set, tvb, foffset, length, FALSE);
+            }
             break;
         case 0x00000002:    /* Unbind */
             /* NoOp */
@@ -7215,7 +7405,8 @@ dissect_ndps_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ndps_tree, int
                 bitem = proto_tree_add_text(atree, tvb, foffset, -1, "Item %d", i);
                 btree = proto_item_add_subtree(bitem, ett_ndps);
                 length=tvb_get_ntohl(tvb, foffset);
-                if(tvb_length_remaining(tvb, foffset) < length)
+                length_remaining = tvb_length_remaining(tvb, foffset);
+                if(length_remaining == -1 || (guint32) length_remaining < length)
                 {
                     return;
                 }
@@ -8033,6 +8224,11 @@ proto_register_ndps(void)
           FT_UINT32,    BASE_HEX,   VALS(ndps_attrs_arg_enum),   0x0,
           "List Attribute Operation", HFILL }},
         
+        { &hf_ndps_context_len,
+        { "Context Length",    "ndps.context_len",
+          FT_UINT32,    BASE_DEC,   NULL,   0x0,
+          "Context Length", HFILL }},
+
         { &hf_ndps_context,
         { "Context",    "ndps.context",
           FT_BYTES,    BASE_NONE,   NULL,   0x0,