Ethereal-dev: [Ethereal-dev] LDP multi-PDUs in one TCP segement support

Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.

From: Motonori Shindo <mshindo@xxxxxxxxxxx>
Date: Mon, 26 Nov 2001 07:43:01 +0900 (JST)
Hi,

Since LDP works on top of TCP, there's a possibility that multiple
PDUs are sent as one TCP segment. However, current LDP dissector
simply assumes that one TCP segment has only one PDU in it.

I'm not sure that this is the right way to address the issue but
here's a patch anyway. Comments are welcome.

Regards,

=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=
 +----+----+     
 |.. .|    |     Motonori Shindo
 |_~__|    |     
 | .. |~~_~|     Sr. Systems Engineer
 | .  |    |     CoSine Communications Inc.
 +----+----+     
 C o S i n e     e-mail:  mshindo@xxxxxxxxxxxxx 
Communications
=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=

Index: packet-ldp.c
===================================================================
RCS file: /cvsroot/ethereal/packet-ldp.c,v
retrieving revision 1.19
diff -u -r1.19 packet-ldp.c
--- packet-ldp.c	2001/07/21 10:27:12	1.19
+++ packet-ldp.c	2001/11/25 22:38:06
@@ -565,6 +565,13 @@
     ti = proto_tree_add_item(tree, proto_ldp, tvb, offset,
 			     tvb_length_remaining(tvb, offset), FALSE);
     ldp_tree = proto_item_add_subtree(ti, ett_ldp);
+  }
+
+  while (tvb_length_remaining(tvb, offset) > 0) { /* Dissect LDP PDUs */
+
+    guint pdu_len;
+
+    /* Dissect LDP Header */
 
     ti = proto_tree_add_text(ldp_tree, tvb, 0, 10, "Header");
 
@@ -575,6 +582,7 @@
     offset += 2;
 
     proto_tree_add_item(hdr_tree, hf_ldp_pdu_len, tvb, offset, 2, FALSE);
+    pdu_len = tvb_get_ntohs(tvb, offset);
 
     offset += 2;
 
@@ -589,129 +597,127 @@
     proto_tree_add_item(ldpid_tree, hf_ldp_ls_id, tvb, offset, 2, FALSE);
 
     offset += 2;
-
-  }
-
-  offset = 10;
-
-  while (tvb_length_remaining(tvb, offset) > 0) { /* Dissect a message */
 
-    guint msg_len;
+    while (pdu_len > 0) { /* Dissect LDP TLV */
 
-    ldp_message = tvb_get_ntohs(tvb, offset) & 0x7FFF; /* Get the message type */
+      guint msg_len;
 
-    msg_len = tvb_get_ntohs(tvb, offset + 2);
+      ldp_message = tvb_get_ntohs(tvb, offset) & 0x7FFF; /* Get the message type */
 
-    if (check_col(pinfo->fd, COL_INFO)) {  /* Check the type ... */
+      msg_len = tvb_get_ntohs(tvb, offset + 2);
 
-      if (msg_cnt > 0) 
-	col_append_fstr(pinfo->fd, COL_INFO, ", %s",
-			val_to_str(ldp_message, ldp_message_types, "Unknown Message (0x%04X)"));
-      else
-	col_add_fstr(pinfo->fd, COL_INFO, "%s", 
-		     val_to_str(ldp_message, ldp_message_types, "Unknown Message (0x%04X)"));
+      if (check_col(pinfo->fd, COL_INFO)) {  /* Check the type ... */
 
-    }
-
-    msg_cnt++;
-
-    if (tree) {
+	if (msg_cnt > 0) 
+	  col_append_fstr(pinfo->fd, COL_INFO, ", %s",
+			  val_to_str(ldp_message, ldp_message_types, "Unknown Message (0x%04X)"));
+	else
+	  col_add_fstr(pinfo->fd, COL_INFO, "%s", 
+		       val_to_str(ldp_message, ldp_message_types, "Unknown Message (0x%04X)"));
+	
+      }
 
-      proto_tree *ti = NULL, *msg_tree = NULL;
+      msg_cnt++;
 
-      /* FIXME: Account for vendor and experimental messages */
+      if (tree) {
 
-      ti = proto_tree_add_text(ldp_tree, tvb, offset, msg_len + 4, "%s",
-			       val_to_str(ldp_message, ldp_message_types, "Unknown Message (0x%04X)"));
+	proto_tree *ti = NULL, *msg_tree = NULL;
 
-      msg_tree = proto_item_add_subtree(ti, ett_ldp_message);
+	/* FIXME: Account for vendor and experimental messages */
 
-      proto_tree_add_item(msg_tree, hf_ldp_msg_type, tvb, offset, 2, FALSE);
+	ti = proto_tree_add_text(ldp_tree, tvb, offset, msg_len + 4, "%s",
+				 val_to_str(ldp_message, ldp_message_types, "Unknown Message (0x%04X)"));
 
-      proto_tree_add_item(msg_tree, hf_ldp_msg_len, tvb, offset + 2, 2, FALSE);
+	msg_tree = proto_item_add_subtree(ti, ett_ldp_message);
+	
+	proto_tree_add_item(msg_tree, hf_ldp_msg_type, tvb, offset, 2, FALSE);
 
-      proto_tree_add_item(msg_tree, hf_ldp_msg_id, tvb, offset + 4, 4, FALSE);
+	proto_tree_add_item(msg_tree, hf_ldp_msg_len, tvb, offset + 2, 2, FALSE);
 
-      switch (ldp_message) {
+	proto_tree_add_item(msg_tree, hf_ldp_msg_id, tvb, offset + 4, 4, FALSE);
 
-      case LDP_NOTIFICATION:
+	switch (ldp_message) {
 
-	dissect_ldp_notification(tvb, offset + 8, pinfo, msg_tree, msg_len - 4); 
+	case LDP_NOTIFICATION:
 
-	break;
+	  dissect_ldp_notification(tvb, offset + 8, pinfo, msg_tree, msg_len - 4); 
 
-      case LDP_HELLO:
+	  break;
 
-	dissect_ldp_hello(tvb, offset + 8, pinfo, msg_tree, msg_len - 4);
+	case LDP_HELLO:
 
-	break;
+	  dissect_ldp_hello(tvb, offset + 8, pinfo, msg_tree, msg_len - 4);
 
-      case LDP_INITIALIZATION:
+	  break;
 
-	dissect_ldp_initialization(tvb, offset + 8, pinfo, msg_tree, msg_len - 4);
+	case LDP_INITIALIZATION:
 
-	break;
+	  dissect_ldp_initialization(tvb, offset + 8, pinfo, msg_tree, msg_len - 4);
 
-      case LDP_KEEPALIVE:
+	  break;
 
-	dissect_ldp_keepalive(tvb, offset + 8, pinfo, msg_tree, msg_len - 4);
+	case LDP_KEEPALIVE:
 
-	break;
+	  dissect_ldp_keepalive(tvb, offset + 8, pinfo, msg_tree, msg_len - 4);
+	  
+	  break;
 
-      case LDP_ADDRESS:
+	case LDP_ADDRESS:
 
-	dissect_ldp_address(tvb, offset + 8, pinfo, msg_tree, msg_len - 4);
+	  dissect_ldp_address(tvb, offset + 8, pinfo, msg_tree, msg_len - 4);
 
-	break;
+	  break;
 
-      case LDP_ADDRESS_WITHDRAWAL:
+	case LDP_ADDRESS_WITHDRAWAL:
 
-	dissect_ldp_address_withdrawal(tvb, offset + 8, pinfo, msg_tree, msg_len - 4);
+	  dissect_ldp_address_withdrawal(tvb, offset + 8, pinfo, msg_tree, msg_len - 4);
 
-	break;
+	  break;
 
-      case LDP_LABEL_MAPPING:
+	case LDP_LABEL_MAPPING:
 
-	dissect_ldp_label_mapping(tvb, offset + 8, pinfo, msg_tree, msg_len - 4);
+	  dissect_ldp_label_mapping(tvb, offset + 8, pinfo, msg_tree, msg_len - 4);
 
-	break;
+	  break;
 
-      case LDP_LABEL_REQUEST:
+	case LDP_LABEL_REQUEST:
 
-	dissect_ldp_label_request(tvb, offset + 8, pinfo, msg_tree, msg_len - 4);
+	  dissect_ldp_label_request(tvb, offset + 8, pinfo, msg_tree, msg_len - 4);
 
-	break;
+	  break;
 
-      case LDP_LABEL_WITHDRAWAL:
+	case LDP_LABEL_WITHDRAWAL:
 
-	dissect_ldp_label_withdrawal(tvb, offset + 8, pinfo, msg_tree, msg_len - 4);
+	  dissect_ldp_label_withdrawal(tvb, offset + 8, pinfo, msg_tree, msg_len - 4);
 
-	break;
+	  break;
 
-      case LDP_LABEL_RELEASE:
+	case LDP_LABEL_RELEASE:
 
-	dissect_ldp_label_release(tvb, offset + 8, pinfo, msg_tree, msg_len - 4);
+	  dissect_ldp_label_release(tvb, offset + 8, pinfo, msg_tree, msg_len - 4);
 
-	break;
+	  break;
 
-      case LDP_LABEL_ABORT_REQUEST:
+	case LDP_LABEL_ABORT_REQUEST:
 
-	dissect_ldp_label_abort_request(tvb, offset + 8, pinfo, msg_tree, msg_len - 4);
+	  dissect_ldp_label_abort_request(tvb, offset + 8, pinfo, msg_tree, msg_len - 4);
 
-	break;
+	  break;
 
-      default:
+	default:
 
-	/* Some sort of unknown message, treat as undissected data */
+	  /* Some sort of unknown message, treat as undissected data */
 
-	break;
+	  break;
 
-      }
+	}
     
-    }
+      }
 
-    offset += msg_len + 4;
+      offset += msg_len + 4;
+      pdu_len -= (msg_len + 10);  	/* 10 octets LDP Header*/
 
+    }
   }
 }