Ethereal-dev: [ethereal-dev] Patch to add a wrapper around "match_strval()"

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

From: guy@xxxxxxxxxx (Guy Harris)
Date: Fri, 16 Oct 1998 00:44:28 -0700 (PDT)
This adds a routine "val_to_str()", which takes, as arguments:

	a number;

	a list of values and corresponding strings, of the sort
	"match_strval()" takes;

	a format string;

and:

	calls "match_strval()" on the number and the list;

	if that succeeds, returns the return value of "match_strval()";

	if it fails, uses the format string and the number to generate a
	string, and returns that.

(Idea shamelessly stolen from "tcpdump"s "tok2str()".)

This lets you simplify some calls to "match_strval()".

This also changes "dissect_ospf()" to use "match_strval()", and to
handle the case of it returning NULL, removing the "gcc -Wall" warning
from "packet-ospf.c".  (The output of "dissect_ospf()" remains the same,
except that it should handle the case of an invalid packet type, but
that means it's a call to "match_strval()" that can't be replaced by a
call to "val_to_str()".)

(Patch not yet checked in; awaiting comments, or a timeout....)

Index: packet-atalk.c
===================================================================
RCS file: /usr/local/cvsroot/ethereal/packet-atalk.c,v
retrieving revision 1.1
diff -c -r1.1 packet-atalk.c
*** packet-atalk.c	1998/10/16 01:18:31	1.1
--- packet-atalk.c	1998/10/16 07:39:21
***************
*** 82,100 ****
    
    if (fd->win_info[COL_NUM]) {
      strcpy(fd->win_info[COL_PROTOCOL], "DDP");
!     switch (ddp.type) {
!       case DDP_RTMPDATA:
!       case DDP_RTMPREQ:
!       case DDP_NBP:
!       case DDP_ATP:
!       case DDP_AEP:
!       case DDP_ZIP:
!       case DDP_ADSP:
!         strcpy(fd->win_info[COL_INFO], match_strval(ddp.type,op_vals));
!         break;
!       default:
!         sprintf(fd->win_info[COL_INFO], "Unknown DDP protocol (%02x)", ddp.type);
!     }
  
      sprintf(fd->win_info[COL_SOURCE],"%d.%d:%d",ddp.snet,ddp.snode,ddp.sport);
      sprintf(fd->win_info[COL_DESTINATION], "%d.%d:%d",ddp.dnet,ddp.dnode,ddp.dport);
--- 82,89 ----
    
    if (fd->win_info[COL_NUM]) {
      strcpy(fd->win_info[COL_PROTOCOL], "DDP");
!     strcpy(fd->win_info[COL_INFO],
!       val_to_str(ddp.type, op_vals, "Unknown DDP protocol (%02x)"));
  
      sprintf(fd->win_info[COL_SOURCE],"%d.%d:%d",ddp.snet,ddp.snode,ddp.sport);
      sprintf(fd->win_info[COL_DESTINATION], "%d.%d:%d",ddp.dnet,ddp.dnode,ddp.dport);

Index: packet-ip.c
===================================================================
RCS file: /usr/local/cvsroot/ethereal/packet-ip.c,v
retrieving revision 1.8
diff -c -r1.8 packet-ip.c
*** packet-ip.c	1998/10/16 01:18:31	1.8
--- packet-ip.c	1998/10/16 07:39:21
***************
*** 53,59 ****
  {
    GtkWidget *field_tree = NULL, *tf;
    guint      val;
-   gchar     *secl_str;
    static value_string secl_vals[] = {
      {IPSEC_UNCLASSIFIED, "Unclassified"},
      {IPSEC_CONFIDENTIAL, "Confidential"},
--- 53,58 ----
***************
*** 78,89 ****
    offset += 2;
  
    val = pntohs(opd);
!   if ((secl_str = match_strval(val, secl_vals)))
!     add_item_to_tree(field_tree, offset,       2,
!               "Security: %s", secl_str);
!   else
!     add_item_to_tree(field_tree, offset,       2,
!               "Security: Unknown (0x%x)", val);
    offset += 2;
    opd += 2;
  
--- 77,84 ----
    offset += 2;
  
    val = pntohs(opd);
!   add_item_to_tree(field_tree, offset,       2,
!               "Security: %s", val_to_str(val, secl_vals, "Unknown (0x%x)"));
    offset += 2;
    opd += 2;
  
***************
*** 166,172 ****
    int        ptr;
    int        optoffset = 0;
    int        flg;
-   gchar     *flg_str;
    static value_string flag_vals[] = {
      {IPOPT_TS_TSONLY,    "Time stamps only"                      },
      {IPOPT_TS_TSANDADDR, "Time stamp and address"                },
--- 161,166 ----
***************
*** 197,208 ****
    add_item_to_tree(field_tree, offset + optoffset,   1,
          "Overflow: %d", flg >> 4);
    flg &= 0xF;
!   if ((flg_str = match_strval(flg, flag_vals)))
!     add_item_to_tree(field_tree, offset + optoffset, 1,
!         "Flag: %s", flg_str);
!   else
!     add_item_to_tree(field_tree, offset + optoffset, 1,
!         "Flag: Unknown (0x%x)", flg);
    optoffset++;
    opd++;
    optlen--;
--- 191,198 ----
    add_item_to_tree(field_tree, offset + optoffset,   1,
          "Overflow: %d", flg >> 4);
    flg &= 0xF;
!   add_item_to_tree(field_tree, offset + optoffset, 1,
!         "Flag: %s", val_to_str(flg, flag_vals, "Unknown (0x%x)"));
    optoffset++;
    opd++;
    optlen--;
***************
*** 396,402 ****
    GtkWidget *ip_tree, *ti, *field_tree, *tf;
    gchar      tos_str[32];
    guint      hlen, optlen;
-   gchar     *proto_str;
    static value_string proto_vals[] = { {IP_PROTO_ICMP, "ICMP"},
                                         {IP_PROTO_IGMP, "IGMP"},
                                         {IP_PROTO_TCP,  "TCP" },
--- 386,391 ----
***************
*** 471,481 ****
        iph.ip_off & IP_OFFSET);
      add_item_to_tree(ip_tree, offset +  8, 1, "Time to live: %d",
        iph.ip_ttl);
!     if ((proto_str = match_strval(iph.ip_p, proto_vals)))
!       add_item_to_tree(ip_tree, offset +  9, 1, "Protocol: %s", proto_str);
!     else
!       add_item_to_tree(ip_tree, offset +  9, 1, "Protocol: Unknown (%x)",
!         iph.ip_p);
      add_item_to_tree(ip_tree, offset + 10, 2, "Header checksum: 0x%04x",
        iph.ip_sum);
      add_item_to_tree(ip_tree, offset + 12, 4, "Source address: %s",
--- 460,467 ----
        iph.ip_off & IP_OFFSET);
      add_item_to_tree(ip_tree, offset +  8, 1, "Time to live: %d",
        iph.ip_ttl);
!     add_item_to_tree(ip_tree, offset +  9, 1, "Protocol: %s",
!       val_to_str(iph.ip_p, proto_vals, "Unknown (%x)"));
      add_item_to_tree(ip_tree, offset + 10, 2, "Header checksum: 0x%04x",
        iph.ip_sum);
      add_item_to_tree(ip_tree, offset + 12, 4, "Source address: %s",

Index: packet-ospf.c
===================================================================
RCS file: /usr/local/cvsroot/ethereal/packet-ospf.c,v
retrieving revision 1.6
diff -c -r1.6 packet-ospf.c
*** packet-ospf.c	1998/10/13 07:03:34	1.6
--- packet-ospf.c	1998/10/16 07:39:22
***************
*** 61,93 ****
      GtkWidget *ospf_header_tree;
      char auth_data[9]="";
      char *packet_type;
  
      memcpy(&ospfh, &pd[offset], sizeof(e_ospfhdr));
  
!     switch(ospfh.packet_type) {
!         case OSPF_HELLO:
! 	    packet_type="Hello Packet";
!             break;
!         case OSPF_DB_DESC:
! 	    packet_type="DB Descr.";
!             break;
!         case OSPF_LS_REQ:
! 	    packet_type="LS Request";
!             break;
!         case OSPF_LS_UPD:
! 	    packet_type="LS Update";
!             break;
!         case OSPF_LS_ACK:
! 	    packet_type="LS Acknowledge";
!             break;
!        default:
! 	    /* XXX - set it to some string with the value of
! 	       "ospfh.packet_type"? */
!             break;
!     }
      if (fd->win_info[COL_NUM]) {
          strcpy(fd->win_info[COL_PROTOCOL], "OSPF");
!         sprintf(fd->win_info[COL_INFO], "%s", packet_type); 
      }  
  
      if (tree) {
--- 61,82 ----
      GtkWidget *ospf_header_tree;
      char auth_data[9]="";
      char *packet_type;
+     static value_string pt_vals[] = { {OSPF_HELLO,   "Hello Packet"   },
+                                       {OSPF_DB_DESC, "DB Descr."      },
+                                       {OSPF_LS_REQ,  "LS Request"     },
+                                       {OSPF_LS_UPD,  "LS Update"      },
+                                       {OSPF_LS_ACK,  "LS Acknowledge" },
+                                       {0,             NULL            } };
  
      memcpy(&ospfh, &pd[offset], sizeof(e_ospfhdr));
  
!     packet_type = match_strval(ospfh.packet_type, pt_vals);
      if (fd->win_info[COL_NUM]) {
          strcpy(fd->win_info[COL_PROTOCOL], "OSPF");
!         if (packet_type != NULL)
!             sprintf(fd->win_info[COL_INFO], "%s", packet_type); 
!         else
!             sprintf(fd->win_info[COL_INFO], "Unknown (%d)", ospfh.packet_type); 
      }  
  
      if (tree) {
***************
*** 101,107 ****
  
          add_item_to_tree(ospf_header_tree, offset, 1, "OSPF Version: %d", ospfh.version);  
  	add_item_to_tree(ospf_header_tree, offset + 1 , 1, "OSPF Packet Type: %d (%s)", 
! 	                                                   ospfh.packet_type, packet_type);
  	add_item_to_tree(ospf_header_tree, offset + 2 , 2, "Packet Legth: %d", 
  	                                                   ntohs(ospfh.length));
  	add_item_to_tree(ospf_header_tree, offset + 4 , 4, "Source OSPF Router ID: %s", 
--- 90,99 ----
  
          add_item_to_tree(ospf_header_tree, offset, 1, "OSPF Version: %d", ospfh.version);  
  	add_item_to_tree(ospf_header_tree, offset + 1 , 1, "OSPF Packet Type: %d (%s)", 
! 	                                                   ospfh.packet_type,
! 							   (packet_type != NULL ?
! 							     packet_type :
! 							     "Unknown"));
  	add_item_to_tree(ospf_header_tree, offset + 2 , 2, "Packet Legth: %d", 
  	                                                   ntohs(ospfh.length));
  	add_item_to_tree(ospf_header_tree, offset + 4 , 4, "Source OSPF Router ID: %s", 

Index: packet.c
===================================================================
RCS file: /usr/local/cvsroot/ethereal/packet.c,v
retrieving revision 1.7
diff -c -r1.7 packet.c
*** packet.c	1998/10/16 01:18:32	1.7
--- packet.c	1998/10/16 07:39:22
***************
*** 195,202 ****
  }
  
  /* Tries to match val against each element in the value_string array vs.
!    Returns the associated string ptr on a match, or NULL on failure.
!    Len is the length of the array. */
  gchar*
  match_strval(guint32 val, value_string *vs) {
    gint i = 0;
--- 195,224 ----
  }
  
  /* Tries to match val against each element in the value_string array vs.
!    Returns the associated string ptr on a match.
!    Formats val with fmt, and returns the resulting string, on failure. */
! gchar*
! val_to_str(guint32 val, value_string *vs, char *fmt) {
!   gchar *ret;
!   static gchar  str[3][64];
!   static gchar *cur;
! 
!   ret = match_strval(val, vs);
!   if (ret != NULL)
!     return ret;
!   if (cur == &str[0][0]) {
!     cur = &str[1][0];
!   } else if (cur == &str[1][0]) {  
!     cur = &str[2][0];
!   } else {  
!     cur = &str[0][0];
!   }
!   snprintf(cur, 64, fmt, val);
!   return cur;
! }
! 
! /* Tries to match val against each element in the value_string array vs.
!    Returns the associated string ptr on a match, or NULL on failure. */
  gchar*
  match_strval(guint32 val, value_string *vs) {
    gint i = 0;

Index: packet.h
===================================================================
RCS file: /usr/local/cvsroot/ethereal/packet.h,v
retrieving revision 1.20
diff -c -r1.20 packet.h
*** packet.h	1998/10/16 06:46:55	1.20
--- packet.h	1998/10/16 07:39:22
***************
*** 486,491 ****
--- 486,492 ----
  #else
  GtkWidget* add_item_to_tree(GtkWidget *, gint, gint, gchar *, ...);
  #endif
+ gchar*     val_to_str(guint32 val, value_string *vs, char *fmt);
  gchar*     match_strval(guint32, value_string*);
  
  /* Routines in packet.c */