From 8652762738f1bc4a4b5bac221463bb77718b6531 Mon Sep 17 00:00:00 2001 From: Guy Harris Date: Sat, 20 Oct 2018 13:36:56 -0700 Subject: [PATCH] Separate signed and unsigned decimal UAT fields. Most of them are unsigned; do the appropriate fetching, checking, and writing-to-UAT-file for them. Have separate macros and routines for the one signed one, which is the drbid in the LTE MAC dissector. Use the Wireshark string-to-number routines; they do the appropriate bounds checking, and make sure unsigned numbers don't start with a -. Change-Id: I4f137aa31d631c5b5622b2c320574b8ab3333f31 Reviewed-on: https://code.wireshark.org/review/30288 Petri-Dish: Guy Harris Tested-by: Petri Dish Buildbot Reviewed-by: Guy Harris --- epan/dissectors/packet-mac-lte.c | 2 +- epan/dissectors/packet-mac-nr.c | 4 +-- epan/dissectors/packet-pdcp-lte.c | 2 +- epan/uat.c | 58 ++++++++++++++++++------------- epan/uat.h | 25 ++++++++++--- 5 files changed, 58 insertions(+), 33 deletions(-) diff --git a/epan/dissectors/packet-mac-lte.c b/epan/dissectors/packet-mac-lte.c index 88334ef4ea..d4d1ffa8f1 100644 --- a/epan/dissectors/packet-mac-lte.c +++ b/epan/dissectors/packet-mac-lte.c @@ -1515,7 +1515,7 @@ static lcid_drb_mapping_t *lcid_drb_mappings = NULL; static guint num_lcid_drb_mappings = 0; UAT_VS_DEF(lcid_drb_mappings, lcid, lcid_drb_mapping_t, guint16, 3, "LCID 3") -UAT_DEC_CB_DEF(lcid_drb_mappings, drbid, lcid_drb_mapping_t) +UAT_SIGNED_DEC_CB_DEF(lcid_drb_mappings, drbid, lcid_drb_mapping_t) UAT_VS_DEF(lcid_drb_mappings, channel_type, lcid_drb_mapping_t, rlc_channel_type_t, rlcAM, "AM") /* UAT object */ diff --git a/epan/dissectors/packet-mac-nr.c b/epan/dissectors/packet-mac-nr.c index ee653ae9e6..ae9e9eb26a 100644 --- a/epan/dissectors/packet-mac-nr.c +++ b/epan/dissectors/packet-mac-nr.c @@ -404,8 +404,8 @@ static const value_string rlc_bearer_type_vals[] = { /* Mapping type */ typedef struct lcid_drb_mapping_t { - guint8 lcid; - guint8 drbid; + guint32 lcid; + guint32 drbid; rlc_bearer_type_t bearer_type; } lcid_drb_mapping_t; diff --git a/epan/dissectors/packet-pdcp-lte.c b/epan/dissectors/packet-pdcp-lte.c index 82db99e32e..5eb493133a 100644 --- a/epan/dissectors/packet-pdcp-lte.c +++ b/epan/dissectors/packet-pdcp-lte.c @@ -157,7 +157,7 @@ static expert_field ei_pdcp_lte_missing_udp_framing_tag = EI_INIT; */ /* UAT entry structure. */ typedef struct { - guint16 ueid; + guint32 ueid; gchar *rrcCipherKeyString; gchar *upCipherKeyString; gchar *rrcIntegrityKeyString; diff --git a/epan/uat.c b/epan/uat.c index 893d91eb3b..fb88ab7b56 100644 --- a/epan/uat.c +++ b/epan/uat.c @@ -606,32 +606,36 @@ gboolean uat_fld_chk_proto(void* u1 _U_, const char* strptr, guint len, const vo static gboolean uat_fld_chk_num(int base, const char* strptr, guint len, char** err) { if (len > 0) { - char* str = g_strndup(strptr,len); - char* strn; - long i; + char* str = g_strndup(strptr, len); + const char* strn; + gboolean result; + guint32 value; - errno = 0; - i = strtol(str,&strn,base); + result = ws_basestrtou32(str, &strn, &value, base); + if (result && ((*strn != '\0') && (*strn != ' '))) { + /* string valid, but followed by something other than a space */ + result = FALSE; + errno = EINVAL; + } + if (!result) { + switch (errno) { - if (((i == G_MAXLONG || i == G_MINLONG) && errno == ERANGE) - || (errno != 0 && i == 0)) { - *err = g_strdup(g_strerror(errno)); - g_free(str); - return FALSE; - } - if ((*strn != '\0') && (*strn != ' ')) { - *err = g_strdup("Invalid value"); - g_free(str); - return FALSE; - } - /* Allow only 32bit values */ - if ((sizeof(long) > 4) && ((i < G_MININT) || (i > G_MAXINT))) { - *err = g_strdup("Value too large"); - g_free(str); - return FALSE; - } + case EINVAL: + *err = g_strdup("Invalid value"); + break; + case ERANGE: + *err = g_strdup("Value too large"); + break; + + default: + *err = g_strdup(g_strerror(errno)); + break; + } + } g_free(str); + + return result; } *err = NULL; @@ -643,13 +647,17 @@ gboolean uat_fld_chk_num_dec(void* u1 _U_, const char* strptr, guint len, const } gboolean uat_fld_chk_num_hex(void* u1 _U_, const char* strptr, guint len, const void* u2 _U_, const void* u3 _U_, char** err) { + return uat_fld_chk_num(16, strptr, len, err); +} + +gboolean uat_fld_chk_num_signed_dec(void* u1 _U_, const char* strptr, guint len, const void* u2 _U_, const void* u3 _U_, char** err) { if (len > 0) { - char* str = g_strndup(strptr, len); + char* str = g_strndup(strptr,len); const char* strn; gboolean result; - guint32 value; + gint32 value; - result = ws_hexstrtou32(str, &strn, &value); + result = ws_strtoi32(str, &strn, &value); if (result && ((*strn != '\0') && (*strn != ' '))) { /* string valid, but followed by something other than a space */ result = FALSE; diff --git a/epan/uat.h b/epan/uat.h index c20b545de8..e90ff62672 100644 --- a/epan/uat.h +++ b/epan/uat.h @@ -344,6 +344,8 @@ gboolean uat_fld_chk_num_dec(void*, const char*, unsigned, const void*, const vo WS_DLL_PUBLIC gboolean uat_fld_chk_num_hex(void*, const char*, unsigned, const void*, const void*, char** err); WS_DLL_PUBLIC +gboolean uat_fld_chk_num_signed_dec(void*, const char*, unsigned, const void*, const void*, char** err); +WS_DLL_PUBLIC gboolean uat_fld_chk_bool(void*, const char*, unsigned, const void*, const void*, char** err); WS_DLL_PUBLIC gboolean uat_fld_chk_enum(void*, const char*, unsigned, const void*, const void*, char**); @@ -509,19 +511,34 @@ static void basename ## _ ## field_name ## _tostr_cb(void* rec, char** out_ptr, /* * DEC Macros, - * a signed decimal number contained in (((rec_t*)rec)->(field_name)) + * an unsigned decimal number contained in (((rec_t*)rec)->(field_name)) */ #define UAT_DEC_CB_DEF(basename,field_name,rec_t) \ static void basename ## _ ## field_name ## _set_cb(void* rec, const char* buf, guint len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\ char* tmp_str = g_strndup(buf,len); \ - ((rec_t*)rec)->field_name = (guint)strtol(tmp_str,NULL,10); \ + ws_strtou32(tmp_str, NULL, &((rec_t*)rec)->field_name); \ + g_free(tmp_str); } \ +static void basename ## _ ## field_name ## _tostr_cb(void* rec, char** out_ptr, unsigned* out_len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\ + *out_ptr = g_strdup_printf("%u",((rec_t*)rec)->field_name); \ + *out_len = (unsigned)strlen(*out_ptr); } + +#define UAT_FLD_DEC(basename,field_name,title,desc) \ + {#field_name, title, PT_TXTMOD_STRING,{uat_fld_chk_num_dec,basename ## _ ## field_name ## _set_cb,basename ## _ ## field_name ## _tostr_cb},{0,0,0},0,desc,FLDFILL} + +/* + * and a *signed* decimal number contained in (((rec_t*)rec)->(field_name)) + */ +#define UAT_SIGNED_DEC_CB_DEF(basename,field_name,rec_t) \ +static void basename ## _ ## field_name ## _set_cb(void* rec, const char* buf, guint len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\ + char* tmp_str = g_strndup(buf,len); \ + ws_strtoi32(tmp_str, NULL, &((rec_t*)rec)->field_name); \ g_free(tmp_str); } \ static void basename ## _ ## field_name ## _tostr_cb(void* rec, char** out_ptr, unsigned* out_len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\ *out_ptr = g_strdup_printf("%d",((rec_t*)rec)->field_name); \ *out_len = (unsigned)strlen(*out_ptr); } -#define UAT_FLD_DEC(basename,field_name,title,desc) \ - {#field_name, title, PT_TXTMOD_STRING,{uat_fld_chk_num_dec,basename ## _ ## field_name ## _set_cb,basename ## _ ## field_name ## _tostr_cb},{0,0,0},0,desc,FLDFILL} +#define UAT_FLD_SIGNED_DEC(basename,field_name,title,desc) \ + {#field_name, title, PT_TXTMOD_STRING,{uat_fld_chk_num_signed_dec,basename ## _ ## field_name ## _set_cb,basename ## _ ## field_name ## _tostr_cb},{0,0,0},0,desc,FLDFILL} #define UAT_FLD_NONE(basename,field_name,title,desc) \ {#field_name, title, PT_TXTMOD_NONE,{uat_fld_chk_num_dec,basename ## _ ## field_name ## _set_cb,basename ## _ ## field_name ## _tostr_cb},{0,0,0},0,desc,FLDFILL}