Ethereal-dev: Re: [ethereal-dev] control field in v120 dissector

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

From: Guy Harris <gharris@xxxxxxxxxxxx>
Date: Wed, 15 Mar 2000 21:59:16 -0800
> The V.120 trace Bert sent out a while ago has what appears to be 16-bit
> control fields - and, in fact, the first V.120 frame in that trace is an
> SABME.  That frame is, of course, a U frame, which means the control
> field is only one octet - and would be treated as only one octet by
> "dissect_xdlc_control()" regardless of whether "is_extended" is true or
> not, so perhaps the V.120 dissector needn't check whether "v120len" is
> 3, and can just pass TRUE as the "is_extended" argument to
> "dissect_xdlc_control()".

I've attached a patch to "packet-v120.c" that:

	makes the "v120.control" field an FT_UINT16 field;

	always passes TRUE as the "is_extended" argument to
	"dissect_xdlc_control()";

	dissects the terminal adaptation sublayer header field after
	dissecting the control field, so that the V.120 tree shows the
	data in sequential order;

	calculates the length of the V.120 header based on the control
	field type (using the "XDLC_CONTROL_LEN()" macro) and the length
	of the terminal adaptation sublayer header
	("dissect_v120_header()" now returns the length of what it
	dissects);

	calls "dissect_data()" on the payload.

It seems to work, at least on Bert's capture.
Index: packet-v120.c
===================================================================
RCS file: /usr/local/cvsroot/ethereal/packet-v120.c,v
retrieving revision 1.4
diff -c -r1.4 packet-v120.c
*** packet-v120.c	2000/03/12 04:47:51	1.4
--- packet-v120.c	2000/03/16 05:52:42
***************
*** 50,56 ****
  static gint ett_v120_control = -1;
  static gint ett_v120_header = -1;
  
! void dissect_v120_header(const u_char *pd, int offset, frame_data *fd, proto_tree *tree);
  
  void
  dissect_v120(const u_char *pd, frame_data *fd, proto_tree *tree)
--- 50,56 ----
  static gint ett_v120_control = -1;
  static gint ett_v120_header = -1;
  
! static int dissect_v120_header(const u_char *pd, int offset, frame_data *fd, proto_tree *tree);
  
  void
  dissect_v120(const u_char *pd, frame_data *fd, proto_tree *tree)
***************
*** 60,65 ****
--- 60,66 ----
      int addr;
      char info[80];
      int v120len;
+     guint16 control;
  
      if (check_col(fd, COL_PROTOCOL))
  	col_add_str(fd, COL_PROTOCOL, "V.120");
***************
*** 95,106 ****
      else
  	is_response = FALSE;
  
-     if (fd->pkt_len <= 5)
- 	v120len = fd->pkt_len;
-     else
- 	v120len = 5;
      if (tree) {
! 	ti = proto_tree_add_protocol_format(tree, proto_v120, 0, v120len,
  					    "V.120");
  	v120_tree = proto_item_add_subtree(ti, ett_v120);
  	addr = pd[1] << 8 | pd[0];
--- 96,103 ----
      else
  	is_response = FALSE;
  
      if (tree) {
! 	ti = proto_tree_add_protocol_format(tree, proto_v120, 0, 0,
  					    "V.120");
  	v120_tree = proto_item_add_subtree(ti, ett_v120);
  	addr = pd[1] << 8 | pd[0];
***************
*** 123,138 ****
  	proto_tree_add_text(address_tree, 0, 2,
  		    decode_boolean_bitfield(addr, 0x0100, 2*8,
  			"EA1 = 1", "EA1 = 0 (Error)"), NULL);
- 	if (v120len == 5)
- 		dissect_v120_header(pd, 4, fd, v120_tree);
      }
!     else
  	v120_tree = NULL;
!     dissect_xdlc_control(pd, 2, fd, v120_tree, hf_v120_control,
! 	    ett_v120_control, is_response, v120len == 3 ? FALSE : TRUE);
  }
  
! void
  dissect_v120_header(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
  {
  	char info[80];
--- 120,143 ----
  	proto_tree_add_text(address_tree, 0, 2,
  		    decode_boolean_bitfield(addr, 0x0100, 2*8,
  			"EA1 = 1", "EA1 = 0 (Error)"), NULL);
      }
!     else {
  	v120_tree = NULL;
! 	ti = NULL;
!     }
!     control = dissect_xdlc_control(pd, 2, fd, v120_tree, hf_v120_control,
! 	    ett_v120_control, is_response, TRUE);
!     if (tree) {
! 	v120len = 2 + XDLC_CONTROL_LEN(control, TRUE);
! 	if (BYTES_ARE_IN_FRAME(v120len, 1))
! 		v120len += dissect_v120_header(pd, v120len, fd, v120_tree);
! 	proto_item_set_len(ti, v120len);
! 	if (IS_DATA_IN_FRAME(v120len))
! 		dissect_data(&pd[v120len], v120len, fd, v120_tree);
!     }
  }
  
! static int
  dissect_v120_header(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
  {
  	char info[80];
***************
*** 183,189 ****
--- 188,196 ----
  		    decode_boolean_bitfield(header, 0x1000, nbits,
  			"RR", "No RR"), NULL);
  	}
+ 	return header_len;
  }
+ 
  void
  proto_register_v120(void)
  {
***************
*** 192,198 ****
  	  { "Link Address", "v120.address", FT_UINT16, BASE_HEX, NULL,
  		  0x0, "" }},
  	{ &hf_v120_control,
! 	  { "Control Field", "v120.control", FT_STRING, BASE_NONE, NULL, 0x0,
  	  	"" }},
  	{ &hf_v120_header,
  	  { "Header Field", "v120.header", FT_STRING, BASE_NONE, NULL, 0x0,
--- 199,205 ----
  	  { "Link Address", "v120.address", FT_UINT16, BASE_HEX, NULL,
  		  0x0, "" }},
  	{ &hf_v120_control,
! 	  { "Control Field", "v120.control", FT_UINT16, BASE_HEX, NULL, 0x0,
  	  	"" }},
  	{ &hf_v120_header,
  	  { "Header Field", "v120.header", FT_STRING, BASE_NONE, NULL, 0x0,