SIP: Refactoring too many if-else branches by table-driven method

When there are a lot of if-else branch judgments, the table-driven method can be used to optimize to facilitate subsequent maintenance.
The original function remain unchanged.
This commit is contained in:
easonweii 2022-05-10 11:00:26 +08:00 committed by Gerald Combs
parent 7b749f5e15
commit eedf82cd97
1 changed files with 53 additions and 75 deletions

View File

@ -791,6 +791,31 @@ static header_parameter_t via_parameters_hf_array[] =
{"oc-algo", &hf_sip_via_oc_algo} {"oc-algo", &hf_sip_via_oc_algo}
}; };
typedef enum {
MECH_PARA_STRING = 0,
MECH_PARA_UINT = 1,
} mech_parameter_type_t;
/* Track associations between parameter name and hf item for security mechanism*/
typedef struct {
const char *param_name;
const gint para_type;
const gint *hf_item;
} mech_parameter_t;
static mech_parameter_t sec_mechanism_parameters_hf_array[] =
{
{"alg", MECH_PARA_STRING, &hf_sip_sec_mechanism_alg},
{"ealg", MECH_PARA_STRING, &hf_sip_sec_mechanism_ealg},
{"prot", MECH_PARA_STRING, &hf_sip_sec_mechanism_prot},
{"spi-c", MECH_PARA_UINT, &hf_sip_sec_mechanism_spi_c},
{"spi-s", MECH_PARA_UINT, &hf_sip_sec_mechanism_spi_s},
{"port1", MECH_PARA_UINT, &hf_sip_sec_mechanism_port1},
{"port-c", MECH_PARA_UINT, &hf_sip_sec_mechanism_port_c},
{"port2", MECH_PARA_UINT, &hf_sip_sec_mechanism_port2},
{"port-s", MECH_PARA_UINT, &hf_sip_sec_mechanism_port_s},
{NULL, 0, 0}
};
typedef struct { typedef struct {
gint *hf_sip_display; gint *hf_sip_display;
@ -2408,9 +2433,6 @@ static void
dissect_sip_sec_mechanism(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, gint start_offset, gint line_end_offset){ dissect_sip_sec_mechanism(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, gint start_offset, gint line_end_offset){
gint current_offset, semi_colon_offset, length, par_name_end_offset, equals_offset; gint current_offset, semi_colon_offset, length, par_name_end_offset, equals_offset;
guint32 spi_c;
guint32 spi_s;
guint16 port;
/* skip Spaces and Tabs */ /* skip Spaces and Tabs */
start_offset = tvb_skip_wsp(tvb, start_offset, line_end_offset - start_offset); start_offset = tvb_skip_wsp(tvb, start_offset, line_end_offset - start_offset);
@ -2437,7 +2459,7 @@ dissect_sip_sec_mechanism(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, g
while(current_offset < line_end_offset){ while(current_offset < line_end_offset){
gchar *param_name = NULL, *value = NULL; gchar *param_name = NULL, *value = NULL;
guint8 hf_index = 0;
/* skip Spaces and Tabs */ /* skip Spaces and Tabs */
current_offset = tvb_skip_wsp(tvb, current_offset, line_end_offset - current_offset); current_offset = tvb_skip_wsp(tvb, current_offset, line_end_offset - current_offset);
@ -2461,82 +2483,38 @@ dissect_sip_sec_mechanism(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, g
} }
while (sec_mechanism_parameters_hf_array[hf_index].param_name) {
/* Protection algorithm to be used */ /* Protection algorithm to be used */
if (g_ascii_strcasecmp(param_name, "alg") == 0){ if (g_ascii_strcasecmp(param_name, sec_mechanism_parameters_hf_array[hf_index].param_name) == 0) {
proto_tree_add_item(tree, hf_sip_sec_mechanism_alg, tvb, switch (sec_mechanism_parameters_hf_array[hf_index].para_type) {
equals_offset+1, semi_colon_offset-equals_offset-1, case MECH_PARA_STRING:
ENC_UTF_8); proto_tree_add_item(tree, *sec_mechanism_parameters_hf_array[hf_index].hf_item, tvb,
equals_offset+1, semi_colon_offset-equals_offset-1,
}else if (g_ascii_strcasecmp(param_name, "ealg") == 0){ ENC_UTF_8);
proto_tree_add_item(tree, hf_sip_sec_mechanism_ealg, tvb, break;
equals_offset+1, semi_colon_offset-equals_offset-1, case MECH_PARA_UINT:
ENC_UTF_8); if (!value) {
proto_tree_add_expert(tree, pinfo, &ei_sip_sipsec_malformed,
}else if (g_ascii_strcasecmp(param_name, "prot") == 0){ tvb, current_offset, -1);
proto_tree_add_item(tree, hf_sip_sec_mechanism_prot, tvb, } else {
equals_offset+1, semi_colon_offset-equals_offset-1, guint32 semi_para;
ENC_UTF_8); semi_para = (guint32)strtoul(value, NULL, 10);
proto_tree_add_uint(tree, *sec_mechanism_parameters_hf_array[hf_index].hf_item, tvb,
}else if (g_ascii_strcasecmp(param_name, "spi-c") == 0){ equals_offset+1, semi_colon_offset-equals_offset-1, semi_para);
if (!value) { }
proto_tree_add_expert(tree, pinfo, &ei_sip_sipsec_malformed, break;
tvb, current_offset, -1); default:
} else { break;
spi_c = (guint32)strtoul(value, NULL, 10); }
proto_tree_add_uint(tree, hf_sip_sec_mechanism_spi_c, tvb, break;
equals_offset+1, semi_colon_offset-equals_offset-1, spi_c);
}
}else if (g_ascii_strcasecmp(param_name, "spi-s") == 0){
if (!value) {
proto_tree_add_expert(tree, pinfo, &ei_sip_sipsec_malformed,
tvb, current_offset, -1);
} else {
spi_s = (guint32)strtoul(value, NULL, 10);
proto_tree_add_uint(tree, hf_sip_sec_mechanism_spi_s, tvb,
equals_offset+1, semi_colon_offset-equals_offset-1, spi_s);
}
}else if (g_ascii_strcasecmp(param_name, "port1") == 0){
if (!value) {
proto_tree_add_expert(tree, pinfo, &ei_sip_sipsec_malformed,
tvb, current_offset, -1);
} else {
port = (guint16)strtoul(value, NULL, 10);
proto_tree_add_uint(tree, hf_sip_sec_mechanism_port1, tvb,
equals_offset+1, semi_colon_offset-equals_offset-1, port);
}
}else if (g_ascii_strcasecmp(param_name, "port-c") == 0){
if (!value) {
proto_tree_add_expert(tree, pinfo, &ei_sip_sipsec_malformed,
tvb, current_offset, -1);
} else {
port = (guint32)strtoul(value, NULL, 10);
proto_tree_add_uint(tree, hf_sip_sec_mechanism_port_c, tvb,
equals_offset+1, semi_colon_offset-equals_offset-1, port);
}
}else if (g_ascii_strcasecmp(param_name, "port2") == 0){
if (!value) {
proto_tree_add_expert(tree, pinfo, &ei_sip_sipsec_malformed,
tvb, current_offset, -1);
} else {
port = (guint32)strtoul(value, NULL, 10);
proto_tree_add_uint(tree, hf_sip_sec_mechanism_port2, tvb,
equals_offset+1, semi_colon_offset-equals_offset-1, port);
}
}else if (g_ascii_strcasecmp(param_name, "port-s") == 0){
if (!value) {
proto_tree_add_expert(tree, pinfo, &ei_sip_sipsec_malformed,
tvb, current_offset, -1);
} else {
port = (guint32)strtoul(value, NULL, 10);
proto_tree_add_uint(tree, hf_sip_sec_mechanism_port_s, tvb,
equals_offset+1, semi_colon_offset-equals_offset-1, port);
} }
hf_index++;
} }
else{ if (!sec_mechanism_parameters_hf_array[hf_index].param_name) {
proto_tree_add_format_text(tree, tvb, current_offset, length); proto_tree_add_format_text(tree, tvb, current_offset, length);
} }
current_offset = semi_colon_offset+1; current_offset = semi_colon_offset+1;
} }