Ethereal-dev: [ethereal-dev] Diffserv patch

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

From: Heikki Vatiainen <hessu@xxxxxxxxx>
Date: Mon, 24 Jan 2000 02:00:31 +0200
This patch adds the possibility to parse the original IPv4 TOS 
Field as the DiffServ Field. The DS Field is defined in RFC 2474.
The included codepoints are Class Selector, AF and EF codepoints.

By default the patch turns the new functionality on and adds a 
checkbox under Display menu so that it can be turned off. In 
tethereal the DiffServ parsing can be turned off with the new -D 
option.

The reason I enabled DiffServ aware parsing is that RFC 2474 
obsoletes the old TOS Field definition, RFC 1349. The other reason 
is that we currently do DiffServ testing, so having the DiffServ 
code on by default saves us a couple of mouse clicks or one 
commmand line option :-)

Here's the patch:

Index: globals.h
===================================================================
RCS file: /cvsroot/ethereal/globals.h,v
retrieving revision 1.14
diff -u -r1.14 globals.h
--- globals.h	2000/01/06 06:28:54	1.14
+++ globals.h	2000/01/23 23:23:11
@@ -85,6 +85,7 @@
 extern gchar       *last_open_dir;
 extern gboolean     auto_scroll_live;
 extern int          g_resolving_actif;
+extern int          g_ip_dscp_actif;
 extern field_info  *finfo_selected;
 
 extern ts_type timestamp_type;
Index: packet-ip.c
===================================================================
RCS file: /cvsroot/ethereal/packet-ip.c,v
retrieving revision 1.69
diff -u -r1.69 packet-ip.c
--- packet-ip.c	2000/01/20 21:34:12	1.69
+++ packet-ip.c	2000/01/23 23:23:12
@@ -54,9 +54,15 @@
 #include "packet-ip.h"
 #endif
 
+/* Decode the old IPv4 TOS field as the DiffServ DS Field */
+int g_ip_dscp_actif = 1;
+
 static int proto_ip = -1;
 static int hf_ip_version = -1;
 static int hf_ip_hdr_len = -1;
+static int hf_ip_dsfield = -1;
+static int hf_ip_dsfield_dscp = -1;
+static int hf_ip_dsfield_cu = -1;
 static int hf_ip_tos = -1;
 static int hf_ip_tos_precedence = -1;
 static int hf_ip_tos_delay = -1;
@@ -77,6 +83,7 @@
 static int hf_ip_checksum = -1;
 
 static gint ett_ip = -1;
+static gint ett_ip_dsfield = -1;
 static gint ett_ip_tos = -1;
 static gint ett_ip_off = -1;
 static gint ett_ip_options = -1;
@@ -242,6 +249,34 @@
 #define IP_MF		0x2000		/* Flag: "More Fragments"	*/
 #define IP_OFFSET	0x1FFF		/* "Fragment Offset" part	*/
 
+/* Differentiated Services Field. See RFCs 2474, 2597 and 2598. */
+#define IPDSFIELD_DSCP_MASK     0xFC
+#define IPDSFIELD_DSCP_SHIFT	2
+#define IPDSFIELD_DSCP(dsfield)	(((dsfield)&IPDSFIELD_DSCP_MASK)>>IPDSFIELD_DSCP_SHIFT)
+#define IPDSFIELD_DSCP_DEFAULT  0x00
+#define IPDSFIELD_DSCP_CS1      0x08
+#define IPDSFIELD_DSCP_CS2      0x10
+#define IPDSFIELD_DSCP_CS3      0x18
+#define IPDSFIELD_DSCP_CS4      0x20
+#define IPDSFIELD_DSCP_CS5      0x28
+#define IPDSFIELD_DSCP_CS6      0x30
+#define IPDSFIELD_DSCP_CS7      0x38
+#define IPDSFIELD_DSCP_AF11     0x0A
+#define IPDSFIELD_DSCP_AF12     0x0C
+#define IPDSFIELD_DSCP_AF13     0x0E
+#define IPDSFIELD_DSCP_AF21     0x12
+#define IPDSFIELD_DSCP_AF22     0x14
+#define IPDSFIELD_DSCP_AF23     0x16
+#define IPDSFIELD_DSCP_AF31     0x1A
+#define IPDSFIELD_DSCP_AF32     0x1C
+#define IPDSFIELD_DSCP_AF33     0x1E
+#define IPDSFIELD_DSCP_AF41     0x22
+#define IPDSFIELD_DSCP_AF42     0x24
+#define IPDSFIELD_DSCP_AF43     0x26
+#define IPDSFIELD_DSCP_EF       0x2E
+#define IPDSFIELD_CU_MASK	0x03
+
+/* IP TOS, superseded by the DS Field, RFC 2474. */
 #define IPTOS_TOS_MASK    0x1E
 #define IPTOS_TOS(tos)    ((tos) & IPTOS_TOS_MASK)
 #define IPTOS_NONE        0x00
@@ -716,6 +751,30 @@
                                            {IP_PROTO_VINES,"VINES"},
                                            {0,             NULL  } };
 
+static const value_string dscp_vals[] = {
+		  { IPDSFIELD_DSCP_DEFAULT, "Default"               },
+		  { IPDSFIELD_DSCP_CS1,     "Class Selector 1"      },
+		  { IPDSFIELD_DSCP_CS2,     "Class Selector 2"      },
+		  { IPDSFIELD_DSCP_CS3,     "Class Selector 3"      },
+		  { IPDSFIELD_DSCP_CS4,     "Class Selector 4"      },
+		  { IPDSFIELD_DSCP_CS5,     "Class Selector 5"      },
+		  { IPDSFIELD_DSCP_CS6,     "Class Selector 6"      },
+		  { IPDSFIELD_DSCP_CS7,     "Class Selector 7"      },
+		  { IPDSFIELD_DSCP_AF11,    "Assured Forwarding 11" },
+		  { IPDSFIELD_DSCP_AF12,    "Assured Forwarding 12" },
+		  { IPDSFIELD_DSCP_AF13,    "Assured Forwarding 13" },
+		  { IPDSFIELD_DSCP_AF21,    "Assured Forwarding 21" },
+		  { IPDSFIELD_DSCP_AF22,    "Assured Forwarding 22" },
+		  { IPDSFIELD_DSCP_AF23,    "Assured Forwarding 23" },
+		  { IPDSFIELD_DSCP_AF31,    "Assured Forwarding 31" },
+		  { IPDSFIELD_DSCP_AF32,    "Assured Forwarding 32" },
+		  { IPDSFIELD_DSCP_AF33,    "Assured Forwarding 33" },
+		  { IPDSFIELD_DSCP_AF41,    "Assured Forwarding 41" },
+		  { IPDSFIELD_DSCP_AF42,    "Assured Forwarding 42" },
+		  { IPDSFIELD_DSCP_AF43,    "Assured Forwarding 43" },
+		  { IPDSFIELD_DSCP_EF,      "Expedited Forwarding"  },
+		  { 0,                      NULL                    } };
+
 static const value_string precedence_vals[] = {
 		  { IPTOS_PREC_ROUTINE,         "routine"              },
 		  { IPTOS_PREC_PRIORITY,        "priority"             },
@@ -866,16 +925,28 @@
     proto_tree_add_item(ip_tree, hf_ip_version, offset, 1, hi_nibble(iph.ip_v_hl));
     proto_tree_add_item_format(ip_tree, hf_ip_hdr_len, offset, 1, hlen,
 	"Header length: %u bytes", hlen);
-    tf = proto_tree_add_item_format(ip_tree, hf_ip_tos, offset + 1, 1, iph.ip_tos,
-	"Type of service: 0x%02x (%s)", iph.ip_tos,
-	val_to_str( IPTOS_TOS(iph.ip_tos), iptos_vals, "Unknown") );
-
-    field_tree = proto_item_add_subtree(tf, ett_ip_tos);
-    proto_tree_add_item(field_tree, hf_ip_tos_precedence, offset + 1, 1, iph.ip_tos);
-    proto_tree_add_item(field_tree, hf_ip_tos_delay, offset + 1, 1, iph.ip_tos);
-    proto_tree_add_item(field_tree, hf_ip_tos_throughput, offset + 1, 1, iph.ip_tos);
-    proto_tree_add_item(field_tree, hf_ip_tos_reliability, offset + 1, 1, iph.ip_tos);
-    proto_tree_add_item(field_tree, hf_ip_tos_cost, offset + 1, 1, iph.ip_tos);
+
+    if (g_ip_dscp_actif) {
+      tf = proto_tree_add_item_format(ip_tree, hf_ip_dsfield, offset + 1, 1, iph.ip_tos,
+	   "Differentiated Services Field: 0x%02x (DSCP 0x%02x: %s)", iph.ip_tos,
+	   IPDSFIELD_DSCP(iph.ip_tos), val_to_str(IPDSFIELD_DSCP(iph.ip_tos), dscp_vals,
+	   "Unknown DSCP"));
+
+      field_tree = proto_item_add_subtree(tf, ett_ip_dsfield);
+      proto_tree_add_item(field_tree, hf_ip_dsfield_dscp, offset + 1, 1, iph.ip_tos);
+      proto_tree_add_item(field_tree, hf_ip_dsfield_cu, offset + 1, 1, iph.ip_tos);
+    } else {
+      tf = proto_tree_add_item_format(ip_tree, hf_ip_tos, offset + 1, 1, iph.ip_tos,
+	  "Type of service: 0x%02x (%s)", iph.ip_tos,
+	  val_to_str( IPTOS_TOS(iph.ip_tos), iptos_vals, "Unknown") );
+
+      field_tree = proto_item_add_subtree(tf, ett_ip_tos);
+      proto_tree_add_item(field_tree, hf_ip_tos_precedence, offset + 1, 1, iph.ip_tos);
+      proto_tree_add_item(field_tree, hf_ip_tos_delay, offset + 1, 1, iph.ip_tos);
+      proto_tree_add_item(field_tree, hf_ip_tos_throughput, offset + 1, 1, iph.ip_tos);
+      proto_tree_add_item(field_tree, hf_ip_tos_reliability, offset + 1, 1, iph.ip_tos);
+      proto_tree_add_item(field_tree, hf_ip_tos_cost, offset + 1, 1, iph.ip_tos);
+    }
     proto_tree_add_item(ip_tree, hf_ip_len, offset +  2, 2, iph.ip_len);
     proto_tree_add_item(ip_tree, hf_ip_id, offset +  4, 2, iph.ip_id);
 
@@ -1340,6 +1411,20 @@
 		{ "Header Length",	"ip.hdr_len", FT_UINT8, BASE_DEC, NULL, 0x0,
 			"" }},
 
+		{ &hf_ip_dsfield,
+		{ "Differentiated Services field",	"ip.dsfield", FT_UINT8, BASE_DEC, NULL, 0x0,
+			"" }},
+
+		{ &hf_ip_dsfield_dscp,
+		{ "Differentiated Services Codepoint",	"ip.dsfield.dscp", FT_UINT8, BASE_HEX,
+			VALS(dscp_vals), IPDSFIELD_DSCP_MASK,
+			"" }},
+
+		{ &hf_ip_dsfield_cu,
+		{ "Currently Unused",	"ip.dsfield.cu", FT_UINT8, BASE_DEC, NULL,
+			IPDSFIELD_CU_MASK,
+			"" }},
+
 		{ &hf_ip_tos,
 		{ "Type of Service",	"ip.tos", FT_UINT8, BASE_DEC, NULL, 0x0,
 			"" }},
@@ -1419,6 +1504,7 @@
 	};
 	static gint *ett[] = {
 		&ett_ip,
+		&ett_ip_dsfield,
 		&ett_ip_tos,
 		&ett_ip_off,
 		&ett_ip_options,
Index: tethereal.c
===================================================================
RCS file: /cvsroot/ethereal/tethereal.c,v
retrieving revision 1.12
diff -u -r1.12 tethereal.c
--- tethereal.c	2000/01/22 07:19:26	1.12
+++ tethereal.c	2000/01/23 23:23:12
@@ -144,8 +144,8 @@
   fprintf(stderr, "This is GNU t%s %s, compiled with %s\n", PACKAGE,
 	  VERSION, comp_info_str);
 
-  fprintf(stderr, "t%s [ -vVh ] [ -c count ] [ -f <filter expression> ] [ -F <capture type> ]\n", PACKAGE);
-  fprintf(stderr, "\t[ -i iface ] [ -r infile ] [ -R <filter expression> ]\n");
+  fprintf(stderr, "t%s [ -vVh ] [ -c count ] [ -D ] [ -f <filter expression> ] [ -F <capture type> ]\n", PACKAGE);
+  fprintf(stderr, "\t[ -i iface ] [ -n ] [ -r infile ] [ -R <filter expression> ]\n");
   fprintf(stderr, "\t[ -s snaplen ] [ -t <time stamp format> ] [ -w savefile ] [ -x ]\n");
   fprintf(stderr, "Valid file type arguments to the \"-F\" flag:\n");
   for (i = 0; i < WTAP_NUM_FILE_TYPES; i++) {
@@ -266,7 +266,7 @@
    );
     
   /* Now get our args */
-  while ((opt = getopt(argc, argv, "c:f:F:hi:nr:R:s:t:vw:Vx")) != EOF) {
+  while ((opt = getopt(argc, argv, "c:Df:F:hi:nr:R:s:t:vw:Vx")) != EOF) {
     switch (opt) {
       case 'c':        /* Capture xxx packets */
 #ifdef HAVE_LIBPCAP
@@ -276,6 +276,9 @@
         arg_error = TRUE;
 #endif
         break;
+      case 'D':        /* Turn off DSCP printing */
+	g_ip_dscp_actif = 0;
+	break;
       case 'f':
 #ifdef HAVE_LIBPCAP
 	cf.cfilter = g_strdup(optarg);
Index: doc/tethereal.pod.template
===================================================================
RCS file: /cvsroot/ethereal/doc/tethereal.pod.template,v
retrieving revision 1.7
diff -u -r1.7 tethereal.pod.template
--- tethereal.pod.template	2000/01/22 07:19:34	1.7
+++ tethereal.pod.template	2000/01/23 23:23:13
@@ -7,6 +7,7 @@
 
 B<tethereal>
 S<[ B<-c> count ]>
+S<[ B<-D> ]>
 S<[ B<-f> filter expression ]>
 S<[ B<-F> file format ]>
 S<[ B<-h> ]>
@@ -90,6 +91,11 @@
 
 Sets the default number of packets to read when capturing live
 data.
+
+=item -D
+
+Turns off treating the original IPv4 TOS field as the Differentiated
+Services Field. The structure of the DS Field is defined in RFC 2474.
 
 =item -f
 
Index: gtk/display_opts.c
===================================================================
RCS file: /cvsroot/ethereal/gtk/display_opts.c,v
retrieving revision 1.1
diff -u -r1.1 display_opts.c
--- display_opts.c	1999/10/18 12:48:13	1.1
+++ display_opts.c	2000/01/23 23:23:13
@@ -92,6 +92,7 @@
 #define E_DISPLAY_TIME_DELTA_KEY "display_time_delta"
 #define E_DISPLAY_AUTO_SCROLL_KEY "display_auto_scroll"
 #define E_DISPLAY_NAME_RESOLUTION_KEY "display_name_resolution"
+#define E_DISPLAY_IP_DSCP_KEY "display_ip_dscp"
 
 static void display_opt_ok_cb(GtkWidget *, gpointer);
 static void display_opt_apply_cb(GtkWidget *, gpointer);
@@ -172,6 +173,13 @@
   gtk_box_pack_start(GTK_BOX(main_vb), button, TRUE, TRUE, 0);
   gtk_widget_show(button);
   
+  button = gtk_check_button_new_with_label("Decode IPv4 TOS field as DiffServ Field");
+  gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button), g_ip_dscp_actif);
+  gtk_object_set_data(GTK_OBJECT(display_opt_w), E_DISPLAY_IP_DSCP_KEY,
+		      button);
+  gtk_box_pack_start(GTK_BOX(main_vb), button, TRUE, TRUE, 0);
+  gtk_widget_show(button);
+  
   /* Button row: OK, Apply, and Cancel buttons */
   bbox = gtk_hbutton_box_new();
   gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_END);
@@ -232,6 +240,10 @@
 					     E_DISPLAY_NAME_RESOLUTION_KEY);
   g_resolving_actif = (GTK_TOGGLE_BUTTON (button)->active);
 
+  button = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w),
+					     E_DISPLAY_IP_DSCP_KEY);
+  g_ip_dscp_actif = (GTK_TOGGLE_BUTTON (button)->active);
+
   gtk_widget_destroy(GTK_WIDGET(parent_w));
   display_opt_window_active = FALSE;
 
@@ -264,6 +276,10 @@
   button = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w),
 					     E_DISPLAY_NAME_RESOLUTION_KEY);
   g_resolving_actif = (GTK_TOGGLE_BUTTON (button)->active);
+
+  button = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w),
+					     E_DISPLAY_IP_DSCP_KEY);
+  g_ip_dscp_actif = (GTK_TOGGLE_BUTTON (button)->active);
 
   change_time_formats(&cf);
 }