diff options
author | Guy Harris <guy@alum.mit.edu> | 2001-06-27 20:38:56 +0000 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2001-06-27 20:38:56 +0000 |
commit | 6c26a854355203e5497ac90f824584d83f6bf3fc (patch) | |
tree | 1bc2b65b0373a786b022124067bb74a90ca69c04 | |
parent | db974f9b065aa8a6f5695f3e50c1a71aad90155b (diff) | |
download | wireshark-6c26a854355203e5497ac90f824584d83f6bf3fc.tar.gz wireshark-6c26a854355203e5497ac90f824584d83f6bf3fc.tar.bz2 wireshark-6c26a854355203e5497ac90f824584d83f6bf3fc.zip |
Improved support for CORBA IDL "fixed" types, and fix to handling of
explicit and heuristic GIOP dissectors, from Frank Singleton.
svn path=/trunk/; revision=3615
-rw-r--r-- | packet-giop.c | 250 | ||||
-rw-r--r-- | packet-giop.h | 41 |
2 files changed, 247 insertions, 44 deletions
diff --git a/packet-giop.c b/packet-giop.c index 5c98c06c8e..73c2df61cf 100644 --- a/packet-giop.c +++ b/packet-giop.c @@ -9,7 +9,7 @@ * Frank Singleton <frank.singleton@ericsson.com> * Trevor Shepherd <eustrsd@am1.ericsson.se> * - * $Id: packet-giop.c,v 1.37 2001/06/23 19:14:42 guy Exp $ + * $Id: packet-giop.c,v 1.38 2001/06/27 20:38:56 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@ethereal.com> @@ -312,13 +312,14 @@ /* - * Set to 1 for DEBUG output + * Set to 1 for DEBUG output - TODO make this a runtime option */ #define DEBUG 0 /* * To allow calling (or not) of subdissectors, for testing buggy stuff. + * TODO - make this a runtime option in GUI */ #define DEBUG_CALL_SUB_DISSECTORS 1 @@ -1556,7 +1557,7 @@ static void display_complete_reply_hash(gpointer key, gpointer val, gpointer use */ static void display_objkey_hash(gpointer key, gpointer val, gpointer user_data) { - int i; + guint32 i; struct giop_object_val *mv = (struct giop_object_val *) val; struct giop_object_key *mk = (struct giop_object_key *) key; @@ -1722,7 +1723,7 @@ static void giop_dump_collection(collection_data_t collection_type) { * it return FALSE */ -gboolean try_heuristic_giop_dissector(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int *offset, +static gboolean try_heuristic_giop_dissector(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int *offset, MessageHeader *header, gchar *operation ) { int i,len; @@ -1758,11 +1759,11 @@ gboolean try_heuristic_giop_dissector(tvbuff_t *tvb, packet_info *pinfo, proto_t * */ -static void try_explicit_giop_dissector(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int *offset, - MessageHeader *header, gchar *operation, gchar *repoid ) { +static gboolean try_explicit_giop_dissector(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int *offset, + MessageHeader *header, gchar *operation, gchar *repoid ) { giop_sub_handle_t *subdiss = NULL; /* handle */ - gboolean res; + gboolean res = FALSE; gchar *modname = NULL; struct giop_module_key module_key; struct giop_module_val *module_val = NULL; @@ -1781,7 +1782,7 @@ static void try_explicit_giop_dissector(tvbuff_t *tvb, packet_info *pinfo, prot module_val = (struct giop_module_val *)g_hash_table_lookup(giop_module_hash, &module_key); if (module_val == NULL) { - return; /* module not registered */ + return res; /* module not registered */ } subdiss = (giop_sub_handle_t *) module_val->subh; /* grab dissector handle */ @@ -1805,7 +1806,7 @@ static void try_explicit_giop_dissector(tvbuff_t *tvb, packet_info *pinfo, prot } /* offset exists */ } /* subdiss */ - return; + return res; /* return result */ } @@ -2035,29 +2036,195 @@ guint32 get_CDR_enum(tvbuff_t *tvb, int *offset, gboolean stream_is_big_endian, /* - * Copy an "n" octet sequence from the tvbuff - * which represents a Fixed point decimal type, and convert - * it to a Fixed point decimal type. There are no alignment restrictions. - * Size of fixed decimal type is determined by IDL, but this routine - * will just process octets until it hits the "sign configuration" as - * the last octet. + * Copy an octet sequence from the tvbuff + * which represents a Fixed point decimal type, and create a string representing + * a Fixed point decimal type. There are no alignment restrictions. + * Size and scale of fixed decimal type is determined by IDL. + * + * digits - IDL specified number of "digits" for this fixed type + * scale - IDL specified "scale" for this fixed type + * + * + * eg: typedef fixed <5,2> fixed_t; + * could represent numbers like 123.45, 789.12, + * * - * This value is either - * 0xd - positive value - * 0xc - negative value + * As the fixed type could be any size, I will not try to fit it into our + * simple types like gdouble or glong etc. I will just create a string buffer holding + * a representation (after scale is applied), and with a decimal point or zero padding + * inserted at the right place if necessary. The string is null terminated * - * offset is then incremented past the sign octet. + * so string may look like * - * TODO - pass in parameters from IDL, eg: scale etc.. + * + * "+1.234" or "-3456.78" or "1234567309475760377365465897891" or "-2789000000" etc + * + * According to spec, digits <= 31 + * and scale is positive (except for constants eg: 1000 has digit=1 and implied scale = -3) + * or <4,0> ? + * + * User must remember to free the buffer * */ -void get_CDR_fixed(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint *offset, guint32 n) { +void get_CDR_fixed(tvbuff_t *tvb, gchar **seq, gint *offset, guint32 digits, gint32 scale) { + + guint8 sign; /* 0x0c is positive, 0x0d is negative */ + guint32 i ; /* loop */ + guint32 slen; /* number of bytes to hold digits + extra 0's if scale <0 */ + /* this does not include sign, decimal point and \0 */ + guint32 sindex = 0; /* string index */ + gchar *tmpbuf = NULL; /* temp buff, holds string without scaling */ + guint8 tval; /* temp val storage */ + + /* + * how many bytes to hold digits and scale (if scale <0) + * + * eg: fixed <5,2> = 5 digits + * fixed <5,-2> = 7 digits (5 + 2 added 0's) + */ + +#if DEBUG + printf("giop:get_CDR_fixed() called , digits = %u, scale = %u \n", digits, scale); +#endif + + if (scale <0) { + slen = digits - scale; /* allow for digits + padding 0's for negative scal */ + } else { + slen = digits; /* digits */ + } + +#if DEBUG + printf("giop:get_CDR_fixed(): slen = %.2x \n", slen); +#endif + + tmpbuf = g_new0(gchar, slen); /* allocate temp buffer */ + + /* If even , grab 1st dig */ + + if (!(digits & 0x01)) { + tval = get_CDR_octet(tvb,offset); +#if DEBUG + printf("giop:get_CDR_fixed():even: octet = %.2x \n", tval); +#endif + tmpbuf[sindex] = (tval & 0x0f) + 0x30; /* convert top nibble to ascii */ + sindex++; + } + + /* + * Loop, but stop BEFORE we hit last digit and sign + * if digits = 1 or 2, then this part is skipped + */ + + if (digits>2) { + for(i=0; i< ((digits-1)/2 ); i++) { + tval = get_CDR_octet(tvb,offset); +#if DEBUG + printf("giop:get_CDR_fixed():odd: octet = %.2x \n", tval); +#endif + + tmpbuf[sindex] = ((tval & 0xf0) >> 4) + 0x30; /* convert top nibble to ascii */ + sindex++; + tmpbuf[sindex] = (tval & 0x0f) + 0x30; /* convert bot nibble to ascii */ + sindex++; + + } + } /* digits > 3 */ + +#if DEBUG + printf("giop:get_CDR_fixed(): before last digit \n"); +#endif + + + /* Last digit and sign if digits >1, or 1st dig and sign if digits = 1 */ + + tval = get_CDR_octet(tvb,offset); +#if DEBUG + printf("giop:get_CDR_fixed(): octet = %.2x \n", tval); +#endif + tmpbuf[sindex] = (( tval & 0xf0)>> 4) + 0x30; /* convert top nibble to ascii */ + sindex++; + + sign = tval & 0x0f; /* get sign */ + + /* So now, we have all digits in an array, and the sign byte + * so lets generate a printable string, taking into account the scale + * and sign values. + */ + + sindex = 0; /* reset */ + *seq = g_new0(gchar, slen + 3); /* allocate temp buffer , including space for sign, decimal point and + * \0 -- TODO check slen is reasonable first */ +#if DEBUG + printf("giop:get_CDR_fixed(): sign = %.2x \n", sign); +#endif + + switch(sign) { + case 0x0c: + (*seq)[sindex] = '+'; /* put sign in first string position */ + break; + case 0x0d: + (*seq)[sindex] = '-'; + break; + default: + g_warning("giop: Unknown sign value in fixed type %u \n", sign); + (*seq)[sindex] = '*'; /* flag as sign unkown */ + break; + } + + sindex++; + + /* Add decimal point or padding 0's, depending if scale is positive or + * negative, respectively + */ + + if (scale>0) { + for (i=0; i<digits-scale; i++) { + (*seq)[sindex] = tmpbuf[i]; /* digits to the left of the decimal point */ + sindex++; + } + + (*seq)[sindex] = '.'; /* decimal point */ + sindex++; + + for (i=digits-scale; i<digits; i++) { + (*seq)[sindex] = tmpbuf[i]; /* remaining digits to the right of the decimal point */ + sindex++; + } + + (*seq)[sindex] = '\0'; /* string terminator */ + + } else { + + /* negative scale, dump digits and pad out with 0's */ + + for (i=0; i<digits-scale; i++) { + if (i<digits) { + (*seq)[sindex] = tmpbuf[i]; /* save digits */ + } else { + (*seq)[sindex] = '0'; /* all digits used up, so pad with 0's */ + } + sindex++; + } + + (*seq)[sindex] = '\0'; /* string terminator */ + + } + + g_free(tmpbuf); /* release temp buffer */ + + +#if DEBUG + printf("giop:get_CDR_fixed(): value = %s \n", *seq); +#endif + + return; } + /* * Floating Point Data Type float IEEE 754-1985 * @@ -2693,7 +2860,7 @@ dissect_reply_body (tvbuff_t *tvb, u_int offset, packet_info *pinfo, guint32 reply_status, MessageHeader *header, proto_tree *clnp_tree) { u_int sequence_length; - + gboolean exres = FALSE; /* result of trying explicit dissectors */ gchar * repoid = NULL; /* Repositor ID looked up from objkey */ /* @@ -2792,12 +2959,14 @@ dissect_reply_body (tvbuff_t *tvb, u_int offset, packet_info *pinfo, #if DEBUG_CALL_SUB_DISSECTORS if(entry->repoid) { - try_explicit_giop_dissector(tvb,pinfo,clnp_tree, &offset, header, entry->operation, entry->repoid ); - break; - - } else { + exres = try_explicit_giop_dissector(tvb,pinfo,clnp_tree, &offset, header, entry->operation, entry->repoid ); + } + + /* Only call heuristic if no explicit dixxector was found */ + + if(! exres) { try_heuristic_giop_dissector(tvb,pinfo,clnp_tree,&offset,header,entry->operation); - } /* repoid */ + } #endif @@ -3068,6 +3237,7 @@ dissect_giop_request_1_1 (tvbuff_t * tvb, packet_info * pinfo, guint32 objkey_len = 0; /* object key length */ gchar *objkey = NULL; /* object key sequence */ gchar *print_objkey = NULL; /* printable object key sequence */ + gboolean exres = FALSE; /* result of trying explicit dissectors */ gchar *operation = NULL; gchar *requesting_principal = NULL; @@ -3219,7 +3389,7 @@ dissect_giop_request_1_1 (tvbuff_t * tvb, packet_info * pinfo, /* * Call subdissector here before freeing "operation" and "key" - * pass request_id also. But only if anything remains in tvbuff. + * pass request_id also. * First try an find an explicit sub_dissector, then if that * fails, try the heuristic method. * @@ -3232,8 +3402,12 @@ dissect_giop_request_1_1 (tvbuff_t * tvb, packet_info * pinfo, #if DEBUG_CALL_SUB_DISSECTORS if(repoid) { - try_explicit_giop_dissector(tvb,pinfo,tree,&offset,header,operation,repoid); - } else { + exres = try_explicit_giop_dissector(tvb,pinfo,tree,&offset,header,operation,repoid); + } + + /* Only call heuristic if no explicit dissector was found */ + + if (! exres) { try_heuristic_giop_dissector(tvb,pinfo,tree,&offset,header,operation); } @@ -3273,6 +3447,7 @@ dissect_giop_request_1_2 (tvbuff_t * tvb, packet_info * pinfo, gchar *operation = NULL; proto_tree *request_tree = NULL; proto_item *tf; + gboolean exres = FALSE; /* result of trying explicit dissectors */ gchar *repoid = NULL; @@ -3360,12 +3535,23 @@ dissect_giop_request_1_2 (tvbuff_t * tvb, packet_info * pinfo, if (! pinfo->fd->flags.visited) giop_complete_request_list = insert_in_comp_req_list(giop_complete_request_list,pinfo->fd->num, request_id,operation,NULL); + + /* + * + * Call sub dissector. + * First try an find a explicit sub_dissector, then if that + * fails, try the heuristic method. + */ #if DEBUG_CALL_SUB_DISSECTORS if(repoid) { - try_explicit_giop_dissector(tvb,pinfo,tree,&offset,header,operation,repoid); - } else { + exres = try_explicit_giop_dissector(tvb,pinfo,tree,&offset,header,operation,repoid); + } + + /* Only call heuristic if no explicit dissector was found */ + + if (! exres) { try_heuristic_giop_dissector(tvb,pinfo,tree,&offset,header,operation); } diff --git a/packet-giop.h b/packet-giop.h index 2326d3a803..dd3f74c78c 100644 --- a/packet-giop.h +++ b/packet-giop.h @@ -4,7 +4,7 @@ * * Based on CORBAv2.4.2 Chapter 15 GIOP Description. * - * $Id: packet-giop.h,v 1.3 2001/06/18 05:27:16 guy Exp $ + * $Id: packet-giop.h,v 1.4 2001/06/27 20:38:56 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@ethereal.com> @@ -220,23 +220,40 @@ gdouble get_CDR_double(tvbuff_t *tvb, int *offset, gboolean stream_is_big_endian guint32 get_CDR_enum(tvbuff_t *tvb, int *offset, gboolean stream_is_big_endian, int boundary); + /* - * Copy an "n" octet sequence from the tvbuff - * which represents a Fixed point decimal type, and convert - * it to a Fixed point decimal type. There are no alignment restrictions. - * Size of fixed decimal type is determined by IDL, but this routine - * will just process octets until it hits the "sign configuration" as - * the last octet. + * Copy an octet sequence from the tvbuff + * which represents a Fixed point decimal type, and create a string representing + * a Fixed point decimal type. There are no alignment restrictions. + * Size and scale of fixed decimal type is determined by IDL. + * + * digits - IDL specified number of "digits" for this fixed type + * scale - IDL specified "scale" for this fixed type + * + * + * eg: typedef fixed <5,2> fixed_t; + * could represent numbers like 123.45, 789.12, + * + * + * As the fixed type could be any size, I will not try to fit it into our + * simple types like gdouble or glong etc. I will just create a string buffer holding + * a representation (after scale is applied), and with a decimal point or zero padding + * inserted at the right place if necessary. The string is null terminated + * + * so string may look like + * + * + * "+1.234" or "-3456.78" or "1234567309475760377365465897891" or "-2789000000" etc * - * This value is either - * 0xd - positive value - * 0xc - negative value + * According to spec, digits <= 31 + * and scale is positive (except for constants eg: 1000 has digit=1 and implied scale = -3) + * or <4,0> ? * - * offset is then incremented past the sign octet. + * User must remember to free the buffer * */ -void get_CDR_fixed(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint *offset, guint32 n); +void get_CDR_fixed(tvbuff_t *tvb, gchar **seq, gint *offset, guint32 digits, gint32 scale); |