aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-etch.c
diff options
context:
space:
mode:
authorwmeier <wmeier@f5534014-38df-0310-8fa8-9805f1628bb7>2010-10-19 14:31:05 +0000
committerwmeier <wmeier@f5534014-38df-0310-8fa8-9805f1628bb7>2010-10-19 14:31:05 +0000
commitc127b934a0e34c14c01c31afe1cb979326b1d7f3 (patch)
treecde9a527298be837fb89514f99394e606289ce31 /epan/dissectors/packet-etch.c
parentb98f23866e762683c9ee636c0d938d1749912506 (diff)
Use dynamically created value_string_ext to store hash/symbol value_strings;
Also: minor code reformatting and re-arrangement. git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@34569 f5534014-38df-0310-8fa8-9805f1628bb7
Diffstat (limited to 'epan/dissectors/packet-etch.c')
-rw-r--r--epan/dissectors/packet-etch.c305
1 files changed, 166 insertions, 139 deletions
diff --git a/epan/dissectors/packet-etch.c b/epan/dissectors/packet-etch.c
index 8c68771c92..dffa624a5f 100644
--- a/epan/dissectors/packet-etch.c
+++ b/epan/dissectors/packet-etch.c
@@ -52,7 +52,6 @@
* maximum numbers for symbols from config files
*/
#define ETCH_MAX_SYMBOL_LENGTH "256"
-#define ETCH_MAX_SYMBOLS 1000
/*
* Magic Number for Etch
@@ -143,17 +142,15 @@ static int hf_etch_symbol = 0;
* internal fields/defines for dissector
*/
-static const char* gbl_keytab_folder = "";
-static guint gbl_etch_port = 0;
-static char* gbl_current_keytab_folder = NULL;
-static int gbl_symbols_count = 0;
-static value_string* gbl_symbols = NULL;
+static const char *gbl_keytab_folder = "";
+static guint gbl_etch_port = 0;
+static char *gbl_current_keytab_folder = NULL;
static int gbl_pdu_counter;
static guint32 gbl_old_frame_num;
-static emem_strbuf_t* gbl_symbol_buffer = NULL;
-static gboolean gbl_have_symbol = FALSE;
+static emem_strbuf_t *gbl_symbol_buffer = NULL;
+static gboolean gbl_have_symbol = FALSE;
/***************************************************************************/
/* Methods */
@@ -161,14 +158,80 @@ static gboolean gbl_have_symbol = FALSE;
/*
* forward declared dissector methods
*/
-static void read_key_value(unsigned int *offset, tvbuff_t * tvb,
- proto_tree * etch_tree);
-static void read_struct(unsigned int *offset, tvbuff_t * tvb,
- proto_tree * etch_tree, int add_type_field);
-static int read_value(unsigned int *offset, tvbuff_t * tvb, proto_tree * etch_tree,
+static void read_key_value(unsigned int *offset, tvbuff_t *tvb,
+ proto_tree *etch_tree);
+static void read_struct(unsigned int *offset, tvbuff_t *tvb,
+ proto_tree *etch_tree, int add_type_field);
+static int read_value(unsigned int *offset, tvbuff_t *tvb, proto_tree *etch_tree,
int asWhat);
void proto_reg_handoff_etch(void);
+/************************************************************************
+ * Symbol value-string functions
+ * Essentially: Build a value_string_ext at runtime:
+ * a. Upon startup & whenever symbol folder changed: Read from file(s)
+ * and add all hash/symbol pairs to a GArray;
+ * b. When file reads complete, sort the GArray and then create a
+ * value_string_ext from the array for use by match_strval_ext & friends.
+ * (Code based upon code in packet-diameter.c)
+ */
+static GArray *gbl_symbols_array = NULL;
+static value_string_ext *gbl_symbols_vs_ext = NULL;
+
+static void
+gbl_symbols_new(void) {
+ g_assert(gbl_symbols_array == NULL);
+ gbl_symbols_array = g_array_new(TRUE, TRUE, sizeof(value_string));
+}
+
+static void
+gbl_symbols_free(void) {
+ g_free(gbl_symbols_vs_ext);
+ gbl_symbols_vs_ext = NULL;
+
+ if (gbl_symbols_array != NULL) {
+ value_string *vs_p;
+ guint i;
+ vs_p = (value_string *)gbl_symbols_array->data;
+ for (i=0; i<gbl_symbols_array->len; i++) {
+ g_free((gchar *)vs_p[i].strptr);
+ }
+ g_array_free(gbl_symbols_array, TRUE);
+ gbl_symbols_array = NULL;
+ }
+}
+
+static void
+gbl_symbols_array_append(int hash, gchar *symbol) {
+ value_string vs = {hash, symbol};
+ g_assert(gbl_symbols_array != NULL);
+ g_array_append_val(gbl_symbols_array, vs);
+}
+
+static gint
+gbl_symbols_compare_vs(gconstpointer a, gconstpointer b)
+{
+ value_string *vsa = (value_string *)a;
+ value_string *vsb = (value_string *)b;
+
+ if(vsa->value > vsb->value)
+ return 1;
+ if(vsa->value < vsb->value)
+ return -1;
+
+ return 0;
+}
+
+static void
+gbl_symbols_vs_ext_new(void) {
+ g_assert(gbl_symbols_vs_ext == NULL);
+ g_assert(gbl_symbols_array != NULL);
+ g_array_sort(gbl_symbols_array, gbl_symbols_compare_vs);
+ gbl_symbols_vs_ext = value_string_ext_new((value_string *)gbl_symbols_array->data,
+ gbl_symbols_array->len+1,
+ "etch-global-symbols" );
+}
+
/*********************************************************************************/
/* Aux Functions */
@@ -180,15 +243,12 @@ get_byte_length(guint8 typecode)
{
switch (typecode) {
case ETCH_TC_NULL:
- return 0;
- break;
case ETCH_TC_NONE:
- return 0;
- break;
case ETCH_TC_BOOLEAN_FALSE:
- return 0;
- break;
case ETCH_TC_BOOLEAN_TRUE:
+ case ETCH_TC_EMPTY_STRING:
+ case ETCH_TC_MIN_TINY_INT:
+ case ETCH_TC_MAX_TINY_INT:
return 0;
break;
case ETCH_TC_BYTE:
@@ -198,59 +258,25 @@ get_byte_length(guint8 typecode)
return 2;
break;
case ETCH_TC_INT:
- return 4;
- break;
- case ETCH_TC_LONG:
- return 8;
- break;
case ETCH_TC_FLOAT:
return 4;
break;
+ case ETCH_TC_LONG:
case ETCH_TC_DOUBLE:
return 8;
break;
case ETCH_TC_BYTES:
- return -1;
- break;
case ETCH_TC_ARRAY:
- return -1;
- break;
- case ETCH_TC_EMPTY_STRING:
- return 0;
- break;
case ETCH_TC_STRING:
- return -1;
- break;
case ETCH_TC_STRUCT:
- return -1;
- break;
case ETCH_TC_CUSTOM:
- return -1;
- break;
case ETCH_TC_ANY:
return -1;
break;
- case ETCH_TC_MIN_TINY_INT:
- return 0;
- break;
- case ETCH_TC_MAX_TINY_INT:
- return 0;
+ default:
+ return 0;
break;
}
- return 0;
-}
-
-/*
- * add a etch symbol to our symbol cache
- */
-static void
-add_symbol(int hash, const gchar *symbol)
-{
- if (gbl_symbols_count < ETCH_MAX_SYMBOLS - 1) {
- gbl_symbols[gbl_symbols_count].value = hash;
- gbl_symbols[gbl_symbols_count].strptr = g_strdup_printf("%." ETCH_MAX_SYMBOL_LENGTH "s", symbol);
- gbl_symbols_count++;
- }
}
/*
@@ -287,7 +313,8 @@ add_symbols_of_file(const char *filename)
/* And read the symbol */
pos = strcspn(line, ",");
if ((line[pos] != '\0') && (line[pos+1] !='\0')) /* require at least 1 char in symbol */
- add_symbol(hash, &line[pos+1]);
+ gbl_symbols_array_append(hash,
+ g_strdup_printf("%." ETCH_MAX_SYMBOL_LENGTH "s", &line[pos+1]));
}
fclose(pFile);
}
@@ -299,30 +326,25 @@ add_symbols_of_file(const char *filename)
static void
read_hashed_symbols_from_dir(const char *dirname)
{
- WS_DIR *dir;
- WS_DIRENT *file;
- const char *name;
- char *filename;
- GError *err_p = NULL;
- int i;
+ WS_DIR *dir;
+ WS_DIRENT *file;
+ const char *name;
+ char *filename;
+ GError *err_p = NULL;
if(gbl_current_keytab_folder != NULL) {
g_free(gbl_current_keytab_folder);
gbl_current_keytab_folder = NULL;
}
- for(i = 0; i < gbl_symbols_count; i++){
- value_string tmp = {0, NULL};
- g_free((gchar *)gbl_symbols[i].strptr);
- gbl_symbols[i] = tmp;
- }
- /* Reset all symbols */
- gbl_symbols_count = 0;
+ gbl_symbols_free();
if ((dirname == NULL) || (dirname[0] == '\0'))
return;
if ((dir = ws_dir_open(dirname, 0, &err_p)) != NULL) {
+ gbl_symbols_new();
+
gbl_current_keytab_folder = g_strdup(dirname);
while ((file = ws_dir_read_name(dir)) != NULL) {
name = ws_dir_get_name(file);
@@ -336,6 +358,7 @@ read_hashed_symbols_from_dir(const char *dirname)
}
}
ws_dir_close(dir);
+ gbl_symbols_vs_ext_new();
}else{
report_failure("%s", err_p->message);
g_error_free(err_p);
@@ -343,17 +366,17 @@ read_hashed_symbols_from_dir(const char *dirname)
}
/***********************************************************************************/
-/* Etch Protocol Functions*/
+/* Etch Protocol Functions */
/*
* read a type flag from tvb and add it to tree
*/
static guint8
-read_type(unsigned int *offset, tvbuff_t * tvb, proto_tree * etch_tree)
+read_type(unsigned int *offset, tvbuff_t *tvb, proto_tree *etch_tree)
{
- guint32 type_code;
- const gchar* type_as_string;
+ guint32 type_code;
+ const gchar *type_as_string;
type_code = tvb_get_guint8(tvb, *offset);
type_as_string = val_to_str(type_code, tc_lookup_table, "Etch TypeCode: 0x%02x");
@@ -366,14 +389,14 @@ read_type(unsigned int *offset, tvbuff_t * tvb, proto_tree * etch_tree)
* read a array type flag and add it to tree
*/
static void
-read_array_type(unsigned int *offset, tvbuff_t * tvb, proto_tree * etch_tree)
+read_array_type(unsigned int *offset, tvbuff_t *tvb, proto_tree *etch_tree)
{
guint32 type_code;
type_code = tvb_get_guint8(tvb, *offset);
read_type(offset, tvb, etch_tree);
- if (type_code == (guint8) ETCH_TC_CUSTOM) {
+ if (type_code == ETCH_TC_CUSTOM) {
type_code = read_type(offset, tvb, etch_tree);
proto_tree_add_item(etch_tree, hf_etch_value, tvb, *offset, 4,
ENC_BIG_ENDIAN);
@@ -386,7 +409,7 @@ read_array_type(unsigned int *offset, tvbuff_t * tvb, proto_tree * etch_tree)
* read the length of an array and add it to tree
*/
static guint32
-read_length(unsigned int *offset, tvbuff_t * tvb, proto_tree * etch_tree)
+read_length(unsigned int *offset, tvbuff_t *tvb, proto_tree *etch_tree)
{
guint32 length;
int length_of_array_length_type;
@@ -394,7 +417,7 @@ read_length(unsigned int *offset, tvbuff_t * tvb, proto_tree * etch_tree)
tiny = tvb_get_guint8(tvb, *offset);
- /* Is this the value already?*/
+ /* Is this the value already? */
if ( tiny <= ETCH_TC_MAX_TINY_INT
|| tiny >= ETCH_TC_MIN_TINY_INT) {
length = tiny;
@@ -406,16 +429,16 @@ read_length(unsigned int *offset, tvbuff_t * tvb, proto_tree * etch_tree)
switch (length_of_array_length_type) {
case 1:
- length = (guint32) tvb_get_guint8(tvb, *offset);
+ length = tvb_get_guint8(tvb, *offset);
break;
case 2:
- length = (guint32) tvb_get_ntohs(tvb, *offset);
+ length = tvb_get_ntohs(tvb, *offset);
break;
case 4:
- length = (guint32) tvb_get_ntohl(tvb, *offset);
+ length = tvb_get_ntohl(tvb, *offset);
break;
default:
- return 0; /* error!*/
+ return 0; /* error! */
}
}
proto_tree_add_item(etch_tree, hf_etch_length, tvb, *offset,
@@ -429,27 +452,27 @@ read_length(unsigned int *offset, tvbuff_t * tvb, proto_tree * etch_tree)
* read an array from tvb and add it to tree
*/
static void
-read_array(unsigned int *offset, tvbuff_t * tvb, proto_tree * etch_tree)
+read_array(unsigned int *offset, tvbuff_t *tvb, proto_tree *etch_tree)
{
int length;
- /* array type*/
+ /* array type */
read_type(offset, tvb, etch_tree);
- /* Array of type:*/
+ /* Array of type: */
read_array_type(offset, tvb, etch_tree);
- /* Array dim*/
+ /* Array dim */
proto_tree_add_item(etch_tree, hf_etch_dim, tvb, *offset, 1, ENC_NA);
(*offset)++;
- /* Array length*/
+ /* Array length */
length = read_length(offset, tvb, etch_tree);
for (; length > 0; length--) {
read_value(offset, tvb, etch_tree, hf_etch_value);
}
- /* terminaton*/
+ /* terminaton */
read_type(offset, tvb, etch_tree);
}
@@ -458,7 +481,7 @@ read_array(unsigned int *offset, tvbuff_t * tvb, proto_tree * etch_tree)
* read a sequence of bytes and add them to tree
*/
static void
-read_bytes(unsigned int *offset, tvbuff_t * tvb, proto_tree * etch_tree)
+read_bytes(unsigned int *offset, tvbuff_t *tvb, proto_tree *etch_tree)
{
int length;
read_type(offset, tvb, etch_tree);
@@ -472,7 +495,7 @@ read_bytes(unsigned int *offset, tvbuff_t * tvb, proto_tree * etch_tree)
* read a string and add it to tree
*/
static void
-read_string(unsigned int *offset, tvbuff_t * tvb, proto_tree * etch_tree)
+read_string(unsigned int *offset, tvbuff_t *tvb, proto_tree *etch_tree)
{
int byteLength;
read_type(offset, tvb, etch_tree);
@@ -488,7 +511,7 @@ read_string(unsigned int *offset, tvbuff_t * tvb, proto_tree * etch_tree)
* read a number and add it to tree
*/
static void
-read_number(unsigned int *offset, tvbuff_t * tvb, proto_tree * etch_tree,
+read_number(unsigned int *offset, tvbuff_t *tvb, proto_tree *etch_tree,
int asWhat, guint8 type_code)
{
int byteLength;
@@ -496,14 +519,14 @@ read_number(unsigned int *offset, tvbuff_t * tvb, proto_tree * etch_tree,
read_type(offset, tvb, etch_tree);
byteLength = get_byte_length(type_code);
if (byteLength > 0) {
- proto_item *ti;
- const gchar* symbol = NULL;
- guint32 hash = 0;
+ proto_item *ti;
+ const gchar *symbol = NULL;
+ guint32 hash = 0;
gbl_symbol_buffer = ep_strbuf_new_label(""); /* no symbol found yet */
if (byteLength == 4) {
hash = tvb_get_ntohl(tvb, *offset);
- symbol = match_strval((const guint32)hash, gbl_symbols);
+ symbol = match_strval_ext(hash, gbl_symbols_vs_ext);
if(symbol != NULL) {
asWhat = hf_etch_symbol;
gbl_have_symbol = TRUE;
@@ -523,7 +546,7 @@ read_number(unsigned int *offset, tvbuff_t * tvb, proto_tree * etch_tree,
* read a value and add it to tree
*/
static int
-read_value(unsigned int *offset, tvbuff_t * tvb, proto_tree * etch_tree,
+read_value(unsigned int *offset, tvbuff_t *tvb, proto_tree *etch_tree,
int asWhat)
{
guint8 type_code;
@@ -535,30 +558,40 @@ read_value(unsigned int *offset, tvbuff_t * tvb, proto_tree * etch_tree,
proto_tree_add_item(etch_tree, asWhat, tvb, *offset, 1, ENC_BIG_ENDIAN);
(*offset)++;
return type_code;
- } else if (type_code == ETCH_TC_CUSTOM) {
+ }
+
+ switch(type_code) {
+ case ETCH_TC_CUSTOM:
read_struct(offset, tvb, etch_tree, 1);
- return 0;
- } else if (type_code == ETCH_TC_ARRAY) {
+ break;
+ case ETCH_TC_ARRAY:
read_array(offset, tvb, etch_tree);
- return 0;
- } else if (type_code == ETCH_TC_STRING) {
+ break;
+ case ETCH_TC_STRING:
read_string(offset, tvb, etch_tree);
- return 0;
- } else if (type_code == ETCH_TC_FLOAT) {
+ break;
+ case ETCH_TC_FLOAT:
read_number(offset, tvb, etch_tree, hf_etch_float, type_code);
- } else if (type_code == ETCH_TC_DOUBLE) {
+ break;
+ case ETCH_TC_DOUBLE:
read_number(offset, tvb, etch_tree, hf_etch_double, type_code);
- } else if (type_code == ETCH_TC_SHORT) {
+ break;
+ case ETCH_TC_SHORT:
read_number(offset, tvb, etch_tree, hf_etch_short, type_code);
- } else if (type_code == ETCH_TC_INT) {
+ break;
+ case ETCH_TC_INT:
read_number(offset, tvb, etch_tree, hf_etch_int, type_code);
- } else if (type_code == ETCH_TC_LONG) {
+ break;
+ case ETCH_TC_LONG:
read_number(offset, tvb, etch_tree, hf_etch_long, type_code);
- } else if (type_code == ETCH_TC_BYTE) {
+ break;
+ case ETCH_TC_BYTE:
read_number(offset, tvb, etch_tree, hf_etch_byte, type_code);
- } else if (type_code == ETCH_TC_BYTES) {
+ break;
+ case ETCH_TC_BYTES:
read_bytes(offset, tvb, etch_tree);
- } else {
+ break;
+ default:
read_number(offset, tvb, etch_tree, asWhat, type_code);
}
return 0;
@@ -568,7 +601,7 @@ read_value(unsigned int *offset, tvbuff_t * tvb, proto_tree * etch_tree,
* read a struct and add it to tree
*/
static void
-read_struct(unsigned int *offset, tvbuff_t * tvb, proto_tree * etch_tree,
+read_struct(unsigned int *offset, tvbuff_t *tvb, proto_tree *etch_tree,
int add_type_field)
{
proto_item *ti;
@@ -583,10 +616,10 @@ read_struct(unsigned int *offset, tvbuff_t * tvb, proto_tree * etch_tree,
if (add_type_field) {
read_type(offset, tvb, new_tree);
}
- /* struct type as hash*/
+ /* struct type as hash */
read_value(offset, tvb, new_tree, hf_etch_value);
- /* struct length */
+ /* struct length */
length = read_value(offset, tvb, new_tree, hf_etch_length);
for (i = 0; i < length; i++) {
@@ -601,7 +634,7 @@ read_struct(unsigned int *offset, tvbuff_t * tvb, proto_tree * etch_tree,
* read a key value pair and add it to tree
*/
static void
-read_key_value(unsigned int *offset, tvbuff_t * tvb, proto_tree * etch_tree)
+read_key_value(unsigned int *offset, tvbuff_t *tvb, proto_tree *etch_tree)
{
proto_tree *new_tree;
proto_tree *new_tree_bck;
@@ -633,17 +666,17 @@ read_key_value(unsigned int *offset, tvbuff_t * tvb, proto_tree * etch_tree)
read_value(offset, tvb, new_tree, hf_etch_value);
}
-/****************************************************************************************************/
+/*************************************************************************/
/*
* Preparse the message for the info column
*/
static emem_strbuf_t*
-get_column_info(tvbuff_t * tvb)
+get_column_info(tvbuff_t *tvb)
{
int byte_length;
- guint8 type_code;
- emem_strbuf_t* result_buf;
- int my_offset = 0;
+ guint8 type_code;
+ emem_strbuf_t *result_buf;
+ int my_offset = 0;
/* We've a full PDU: 8 bytes + pdu_packetlen bytes */
result_buf = ep_strbuf_new_label("");
@@ -655,10 +688,10 @@ get_column_info(tvbuff_t * tvb)
my_offset++;
if (byte_length == 4) {
- const gchar* symbol;
- guint32 hash;
+ const gchar *symbol;
+ guint32 hash;
hash = tvb_get_ntohl(tvb, my_offset);
- symbol = val_to_str((const guint32) hash, gbl_symbols, "%x");
+ symbol = match_strval_ext(hash, gbl_symbols_vs_ext);
if (symbol != NULL) {
ep_strbuf_append_printf(result_buf, "%s()", symbol);
}
@@ -673,10 +706,10 @@ get_column_info(tvbuff_t * tvb)
* main dissector function for an etch message
*/
static void
-dissect_etch_message(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
+dissect_etch_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
/* We've a full PDU: 8 bytes + pdu_packetlen bytes */
- emem_strbuf_t* colInfo = NULL;
+ emem_strbuf_t *colInfo = NULL;
if (pinfo->cinfo || tree) {
colInfo = get_column_info(tvb); /* get current symbol */
@@ -720,7 +753,7 @@ dissect_etch_message(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
* determine PDU length of protocol etch
*/
static guint
-get_etch_message_len(packet_info * pinfo _U_, tvbuff_t * tvb, int offset)
+get_etch_message_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
{
/* length is at offset 4. we add magic bytes length + length size */
return tvb_get_ntohl(tvb, offset + 4) + 8;
@@ -731,7 +764,7 @@ get_etch_message_len(packet_info * pinfo _U_, tvbuff_t * tvb, int offset)
* main dissector function for the etch protocol
*/
static int
-dissect_etch(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
+dissect_etch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
if (tvb_length(tvb) < 4) {
/* Too small for an etch packet. */
@@ -764,7 +797,6 @@ etch_dissector_init(void)
void proto_register_etch(void)
{
module_t *etch_module;
- int i = 0;
static hf_register_info hf[] = {
{&hf_etch_sig,
@@ -793,7 +825,7 @@ void proto_register_etch(void)
},
{&hf_etch_typecode,
{"Etch TypeCode", "etch.typecode",
- FT_STRING, BASE_NONE, /* FT_INT8*/
+ FT_STRING, BASE_NONE, /* FT_INT8 */
NULL, 0x0,
NULL, HFILL}
},
@@ -898,16 +930,9 @@ void proto_register_etch(void)
&ett_etch_value,
};
- gbl_symbols = (value_string*) g_malloc(ETCH_MAX_SYMBOLS * sizeof(value_string));
-
- for(i = 0; i < ETCH_MAX_SYMBOLS; i++){
- value_string tmp = {0, NULL};
- gbl_symbols[i] = tmp;
- }
-
- proto_etch = proto_register_protocol("Apache Etch Protocol", /* name */
- "ETCH", /* short name */
- "etch" /* abbrev */
+ proto_etch = proto_register_protocol("Apache Etch Protocol", /* name */
+ "ETCH", /* short name */
+ "etch" /* abbrev */
);
proto_register_field_array(proto_etch, hf, array_length(hf));
@@ -921,7 +946,9 @@ void proto_register_etch(void)
prefs_register_string_preference(etch_module, "file",
"Apache Etch symbol folder",
- "Place the hash/symbol files (generated by the Apache Etch compiler) ending with .ewh here",
+ "Place the hash/symbol files "
+ "(generated by the Apache Etch compiler) "
+ "ending with .ewh here",
&gbl_keytab_folder);
prefs_register_uint_preference(etch_module, "tcp.port",
"etch TCP Port",