diff options
author | lego <lego@f5534014-38df-0310-8fa8-9805f1628bb7> | 2007-02-23 20:57:22 +0000 |
---|---|---|
committer | lego <lego@f5534014-38df-0310-8fa8-9805f1628bb7> | 2007-02-23 20:57:22 +0000 |
commit | 94a53a63bf53c25ab3299f10f6cec34fc3aee86d (patch) | |
tree | a7618957318c3e089821169d5637db26a1079712 /epan | |
parent | e3f0f1f39aebbf0367fbae5f67d94cfd7b9167e5 (diff) |
fix some bugs introduced in the latest releases and add value_strings for param, evt, sig and stat ids s well as "sub-parameters".
git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@20908 f5534014-38df-0310-8fa8-9805f1628bb7
Diffstat (limited to 'epan')
-rw-r--r-- | epan/dissectors/packet-h248.c | 72 | ||||
-rw-r--r-- | epan/dissectors/packet-h248.h | 34 | ||||
-rw-r--r-- | epan/dissectors/packet-h248_3gpp.c | 142 | ||||
-rw-r--r-- | epan/dissectors/packet-h248_annex_c.c | 8 | ||||
-rw-r--r-- | epan/dissectors/packet-h248_annex_e.c | 113 | ||||
-rw-r--r-- | epan/dissectors/packet-h248_q1950.c | 34 | ||||
-rw-r--r-- | epan/dissectors/packet-sctp.c | 546 |
7 files changed, 762 insertions, 187 deletions
diff --git a/epan/dissectors/packet-h248.c b/epan/dissectors/packet-h248.c index dbca0ff97b..b0135c7691 100644 --- a/epan/dissectors/packet-h248.c +++ b/epan/dissectors/packet-h248.c @@ -47,7 +47,7 @@ static int proto_h248 = -1; static int hf_h248_mtpaddress_ni = -1; static int hf_h248_mtpaddress_pc = -1; static int hf_h248_pkg_name = -1; -static int hf_248_no_pkg_param = -1; +static int hf_248_pkg_param = -1; static int hf_h248_event_name = -1; static int hf_h248_signal_name = -1; static int hf_h248_pkg_bcp_BNCChar_PDU = -1; @@ -71,7 +71,7 @@ static int hf_h248_ctx_cmd = -1; static int hf_h248_no_pkg = -1; static int hf_h248_no_sig = -1; static int hf_h248_no_evt = -1; -static int hf_h248_no_param = -1; +static int hf_h248_param = -1; static int hf_h248_serviceChangeReasonStr = -1; @@ -1017,7 +1017,7 @@ static const value_string cmd_type[] = { { 0, NULL } }; -h248_curr_info_t curr_info = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}; +static h248_curr_info_t curr_info = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}; static guint32 error_code; static h248_wildcard_t wild_term; @@ -1049,10 +1049,10 @@ extern void h248_param_external_dissector(proto_tree* tree, tvbuff_t* tvb, packe } -static h248_package_t no_package = { 0xffff, &hf_h248_no_pkg, &hf_248_no_pkg_param, &ett_h248_no_pkg, NULL, NULL, NULL, NULL }; -static h248_pkg_sig_t no_signal = { 0, &hf_h248_no_sig, &ett_h248_no_sig, NULL }; -static h248_pkg_param_t no_param = { 0, &hf_h248_no_param, h248_param_item, NULL }; -static h248_pkg_evt_t no_event = { 0, &hf_h248_no_evt, &ett_h248_no_evt, NULL }; +static h248_package_t no_package = { 0xffff, &hf_h248_no_pkg, &ett_h248_no_pkg, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; +static h248_pkg_sig_t no_signal = { 0, &hf_h248_no_sig, &ett_h248_no_sig, NULL, NULL }; +static h248_pkg_param_t no_param = { 0, &hf_h248_param, h248_param_item, NULL }; +static h248_pkg_evt_t no_event = { 0, &hf_h248_no_evt, &ett_h248_no_evt, NULL, NULL }; static int dissect_h248_trx_id(gboolean implicit_tag, packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset, guint32* trx_id_p) { guint64 trx_id = 0; @@ -1156,12 +1156,12 @@ static const value_string BNCChar_vals[] = { static GPtrArray* packages = NULL; -void h248_register_package(h248_package_t* pkg) { +void h248_register_package(const h248_package_t* pkg) { if (! packages) packages = g_ptr_array_new(); g_assert(pkg != NULL); - g_ptr_array_add(packages,pkg); + g_ptr_array_add(packages,(void*)pkg); } static guint32 packageandid; @@ -1171,8 +1171,7 @@ static int dissect_h248_PkgdName(gboolean implicit_tag, tvbuff_t *tvb, int offse proto_tree *package_tree=NULL; guint16 name_major, name_minor; int old_offset; - int hf_param; - h248_package_t* pkg = NULL; + const h248_package_t* pkg = NULL; guint i; old_offset=offset; @@ -1203,13 +1202,19 @@ static int dissect_h248_PkgdName(gboolean implicit_tag, tvbuff_t *tvb, int offse } if (! pkg ) pkg = &no_package; - - hf_param = *(pkg->hfid_params); - - if (hf_param > 0) - /* TODO: Will this ever happen now ??*/ - proto_tree_add_uint(package_tree, hf_h248_pkg_name, tvb, offset-2, 2, name_minor); - + + { + proto_item* pi = proto_tree_add_uint(package_tree, hf_248_pkg_param, tvb, offset-2, 2, name_minor); + const gchar* strval; + + if (pkg->param_names && ( strval = match_strval(name_minor, pkg->param_names) )) { + strval = ep_strdup_printf("%s (%d)",strval,name_minor); + } else { + strval = ep_strdup_printf("Unknown (%d)",name_minor); + } + + proto_item_set_text(pi,"Parameter: %s", strval); + } } else { pkg = &no_package; } @@ -1226,8 +1231,8 @@ dissect_h248_EventName(gboolean implicit_tag, tvbuff_t *tvb, int offset, packet_ proto_tree *package_tree=NULL; guint16 name_major, name_minor; int old_offset; - h248_package_t* pkg = NULL; - h248_pkg_evt_t* evt = NULL; + const h248_package_t* pkg = NULL; + const h248_pkg_evt_t* evt = NULL; guint i; old_offset=offset; @@ -1291,8 +1296,8 @@ dissect_h248_SignalName(gboolean implicit_tag , tvbuff_t *tvb, int offset, packe proto_tree *package_tree=NULL; guint16 name_major, name_minor; int old_offset; - h248_package_t* pkg = NULL; - h248_pkg_sig_t* sig; + const h248_package_t* pkg = NULL; + const h248_pkg_sig_t* sig; guint i; old_offset=offset; @@ -1358,8 +1363,8 @@ dissect_h248_PropertyID(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, pa guint16 name_minor; int old_offset, end_offset; tvbuff_t *next_tvb; - h248_package_t* pkg; - h248_pkg_param_t* prop; + const h248_package_t* pkg; + const h248_pkg_param_t* prop; old_offset=offset; offset=dissect_ber_identifier(pinfo, tree, tvb, offset, &class, &pc, &tag); @@ -1402,7 +1407,7 @@ static int dissect_h248_SigParameterName(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) { tvbuff_t *next_tvb; guint32 param_id = 0xffffffff; - h248_pkg_param_t* sigpar; + const h248_pkg_param_t* sigpar; offset = dissect_ber_octet_string(implicit_tag, pinfo, tree, tvb, offset, hf_index, &next_tvb); switch(tvb_length(next_tvb)) { @@ -1461,7 +1466,7 @@ static int dissect_h248_EventParameterName(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) { tvbuff_t *next_tvb; guint32 param_id = 0xffffffff; - h248_pkg_param_t* evtpar; + const h248_pkg_param_t* evtpar; offset = dissect_ber_octet_string(implicit_tag, pinfo, tree, tvb, offset, hf_index, &next_tvb); @@ -6343,7 +6348,7 @@ dissect_h248_ServiceChangeReasonStr(gboolean implicit_tag _U_, tvbuff_t *tvb, in /*--- End of included file: packet-h248-fn.c ---*/ -#line 1756 "packet-h248-template.c" +#line 1761 "packet-h248-template.c" static void dissect_h248(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) @@ -6426,9 +6431,9 @@ void proto_register_h248(void) { { &hf_h248_pkg_name, { "Package", "h248.package_name", FT_UINT16, BASE_HEX, VALS(package_name_vals), 0, "Package", HFILL }}, - { &hf_248_no_pkg_param, { + { &hf_248_pkg_param, { "Parameter ID", "h248.package_paramid", FT_UINT16, BASE_HEX, - NULL, 0, "Unknown Package Parameter ID", HFILL }}, + NULL, 0, "Parameter ID", HFILL }}, { &hf_h248_event_name, { "Package and Event name", "h248.event_name", FT_UINT32, BASE_HEX, VALS(event_name_vals), 0, "Package", HFILL }}, @@ -6473,8 +6478,8 @@ void proto_register_h248(void) { { "Unknown Event", "h248.pkg.unknown.evt", FT_BYTES, BASE_HEX, NULL, 0, "", HFILL }}, - { &hf_h248_no_param, - { "Unknown Parameter", "h248.pkg.unknown.param", + { &hf_h248_param, + { "Parameter", "h248.pkg.unknown.param", FT_BYTES, BASE_HEX, NULL, 0, "", HFILL }}, { &hf_h248_serviceChangeReasonStr, @@ -7699,7 +7704,7 @@ void proto_register_h248(void) { "", HFILL }}, /*--- End of included file: packet-h248-hfarr.c ---*/ -#line 1895 "packet-h248-template.c" +#line 1900 "packet-h248-template.c" { &hf_h248_ctx, { "Context", "h248.ctx", FT_UINT32, BASE_HEX, NULL, 0, "", HFILL }}, { &hf_h248_ctx_term, { "Termination", "h248.ctx.term", FT_STRING, BASE_NONE, NULL, 0, "", HFILL }}, @@ -7868,7 +7873,7 @@ void proto_register_h248(void) { &ett_h248_Value, /*--- End of included file: packet-h248-ettarr.c ---*/ -#line 1920 "packet-h248-template.c" +#line 1925 "packet-h248-template.c" }; module_t *h248_module; @@ -7913,3 +7918,4 @@ void proto_reg_handoff_h248(void) { dissector_add("udp.port", udp_port, h248_handle); } + diff --git a/epan/dissectors/packet-h248.h b/epan/dissectors/packet-h248.h index 9f63cdb745..9e7815994c 100644 --- a/epan/dissectors/packet-h248.h +++ b/epan/dissectors/packet-h248.h @@ -208,32 +208,38 @@ typedef struct _h248_pkg_sig_t { guint32 id; int* hfid; gint* ett; - h248_pkg_param_t* parameters; + const h248_pkg_param_t* parameters; + const value_string* param_names; } h248_pkg_sig_t; typedef struct _h248_pkg_evt_t { guint32 id; int* hfid; gint* ett; - h248_pkg_param_t* parameters; + const h248_pkg_param_t* parameters; + const value_string* param_names; } h248_pkg_evt_t; typedef struct _h248_pkg_stat_t { guint32 id; int* hfid; gint* ett; - h248_pkg_param_t* parameters; + const h248_pkg_param_t* parameters; + const value_string* param_names; } h248_pkg_stat_t; typedef struct _h248_package_t { guint32 id; int* hfid; - int* hfid_params; gint* ett; - h248_pkg_param_t* properties; - h248_pkg_sig_t* signals; - h248_pkg_evt_t* events; - h248_pkg_stat_t* statistics; + const value_string* param_names; + const value_string* signal_names; + const value_string* event_names; + const value_string* stats_names; + const h248_pkg_param_t* properties; + const h248_pkg_sig_t* signals; + const h248_pkg_evt_t* events; + const h248_pkg_stat_t* statistics; } h248_package_t; struct _h248_curr_info_t { @@ -242,13 +248,13 @@ struct _h248_curr_info_t { h248_msg_t* msg; h248_term_t* term; h248_cmd_t* cmd; - h248_package_t* pkg; - h248_pkg_evt_t* evt; - h248_pkg_sig_t* sig; - h248_pkg_stat_t* stat; - h248_pkg_param_t* par; + const h248_package_t* pkg; + const h248_pkg_evt_t* evt; + const h248_pkg_sig_t* sig; + const h248_pkg_stat_t* stat; + const h248_pkg_param_t* par; }; -void h248_register_package(h248_package_t*); +void h248_register_package(const h248_package_t*); #endif /* PACKET_H248_H */ diff --git a/epan/dissectors/packet-h248_3gpp.c b/epan/dissectors/packet-h248_3gpp.c index 1524de7a4a..59650fabb4 100644 --- a/epan/dissectors/packet-h248_3gpp.c +++ b/epan/dissectors/packet-h248_3gpp.c @@ -36,7 +36,6 @@ * 3GPP TS 29.232 -- 15.1.1 */ static int hf_h248_package_3GUP = -1; -static int hf_h248_package_3GUP_parameters = -1; static int hf_h248_package_3GUP_Mode = -1; static int hf_h248_package_3GUP_UPversions = -1; @@ -48,6 +47,15 @@ static gint ett_h248_package_3GUP = -1; static gboolean implicit = FALSE; +static const value_string h248_3GUP_properties_vals[] = { + { 0x0001, "Mode" }, + { 0x0002, "Versions" }, + { 0x0003, "delerrsdu" }, + { 0x0004, "interface" }, + { 0x0005, "initdir" }, + {0, NULL} +}; + static const value_string h248_3GUP_Mode_vals[] = { { 0x00000001, "Transparent mode" }, { 0x00000002, "Support mode for predefined SDU sizes" }, @@ -102,7 +110,7 @@ static const value_string h248_3GUP_parameters[] = { {0, NULL} }; -h248_pkg_param_t h248_package_3GUP_properties[] = { +static const h248_pkg_param_t h248_package_3GUP_properties[] = { { 0x0001, &hf_h248_package_3GUP_Mode, h248_param_ber_integer, &implicit }, { 0x0002, &hf_h248_package_3GUP_UPversions, h248_param_ber_integer, &implicit }, { 0x0003, &hf_h248_package_3GUP_delerrsdu, h248_param_ber_integer, &implicit }, @@ -111,11 +119,14 @@ h248_pkg_param_t h248_package_3GUP_properties[] = { { 0x0000, NULL, NULL, NULL } }; -static h248_package_t h248_package_3GUP = { +static const h248_package_t h248_package_3GUP = { 0x002f, &hf_h248_package_3GUP, - &hf_h248_package_3GUP_parameters, &ett_h248_package_3GUP, + h248_3GUP_properties_vals, + NULL, + NULL, + NULL, h248_package_3GUP_properties, NULL, NULL, @@ -129,7 +140,6 @@ static h248_package_t h248_package_3GUP = { */ static int hf_h248_package_3GCSD = -1; -static int hf_h248_package_3GCSD_parameters = -1; static int hf_h248_package_3GCSD_plmnbc = -1; static int hf_h248_package_3GCSD_gsmchancod = -1; @@ -146,6 +156,40 @@ static gint ett_h248_3GCSD_evt_protres = -1; static gint ett_h248_3GCSD_evt_ratechg = -1; static gint ett_pkg_3GCSD_sig_actprot = -1; +static const value_string h248_3GCSD_properties_vals[] = { + { 0x0001, "plmnbc"}, + { 0x0002, "gsmchancod"}, + {0, NULL} +}; + +static const value_string h248_3GCSD_signals_vals[] = { + { 0x0001, "actprot" }, + {0, NULL} +}; + +static const value_string h248_3GCSD_signal_actprot_vals[] = { + { 0x0001, "localpeer" }, + {0, NULL} +}; + + +static const value_string h248_3GCSD_events_vals[] = { + { 0x0001, "protres"}, + { 0x0002, "ratechg"}, + {0, NULL} +}; + +static const value_string h248_3GCSD_event_protres_vals[] = { + { 0x0001, "result"}, + { 0x0002, "cause"}, + {0, NULL} +}; + +static const value_string h248_3GCSD_event_ratechg_vals[] = { + { 0x0001, "rate"}, + {0, NULL} +}; + static const value_string h248_3GCSD_evt_protres_result_vals[] = { {1,"Success"}, {0,"Failure"}, @@ -164,48 +208,52 @@ static const value_string h248_3GCSD_actprot_sig_localpeer_vals[] = { {0,NULL} }; -static h248_pkg_param_t h248_package_3GCSD_props[] = { - { 0x0001, &hf_h248_package_3GCSD_plmnbc, h248_param_ber_octetstring, &implicit }, +static const h248_pkg_param_t h248_package_3GCSD_props[] = { + { 0x0001, &hf_h248_package_3GCSD_plmnbc, h248_param_ber_octetstring, &implicit}, { 0x0002, &hf_h248_package_3GCSD_gsmchancod, h248_param_ber_octetstring, &implicit }, { 0x0000, NULL, NULL, NULL } }; -static h248_pkg_param_t h248_pkg_3GCSD_evt_protres_params[] = { +static const h248_pkg_param_t h248_pkg_3GCSD_evt_protres_params[] = { { 0x0001, &hf_h248_pkg_3GCSD_evt_protres_result, h248_param_ber_integer, &implicit }, { 0x0002, &hf_h248_pkg_3GCSD_evt_protres_cause, h248_param_ber_integer, &implicit }, { 0, NULL, NULL, NULL} }; -static h248_pkg_param_t h248_pkg_3GCSD_evt_ratechg_params[] = { +static const h248_pkg_param_t h248_pkg_3GCSD_evt_ratechg_params[] = { { 0x0001, &hf_h248_pkg_3GCSD_evt_ratechg_rate, h248_param_ber_integer, &implicit }, { 0, NULL, NULL, NULL} }; -static h248_pkg_evt_t h248_package_3GCSD_evts[] = { - { 0x0001, &hf_h248_pkg_3GCSD_evt_protres, &ett_h248_3GCSD_evt_protres, h248_pkg_3GCSD_evt_protres_params}, - { 0x0002, &hf_h248_pkg_3GCSD_evt_ratechg, &ett_h248_3GCSD_evt_ratechg, h248_pkg_3GCSD_evt_ratechg_params}, +static const h248_pkg_evt_t h248_package_3GCSD_evts[] = { + { 0x0001, &hf_h248_pkg_3GCSD_evt_protres, &ett_h248_3GCSD_evt_protres, h248_pkg_3GCSD_evt_protres_params, h248_3GCSD_event_protres_vals}, + { 0x0002, &hf_h248_pkg_3GCSD_evt_ratechg, &ett_h248_3GCSD_evt_ratechg, h248_pkg_3GCSD_evt_ratechg_params, h248_3GCSD_event_ratechg_vals}, { 0, NULL, NULL, NULL} }; -static h248_pkg_param_t h248_pkg_3GCSD_actprot_sig_params[] = { +static const h248_pkg_param_t h248_pkg_3GCSD_actprot_sig_params[] = { { 0x0001, &hf_h248_pkg_3GCSD_actprot_sig_localpeer, h248_param_ber_integer, &implicit }, { 0, NULL, NULL, NULL} }; -static h248_pkg_sig_t h248_package_3GCSD_sigs[] = { +static const h248_pkg_sig_t h248_package_3GCSD_sigs[] = { { 0x0010, &hf_h248_pkg_3GCSD_sig_actprot, &ett_pkg_3GCSD_sig_actprot, h248_pkg_3GCSD_actprot_sig_params }, { 0, NULL, NULL, NULL} }; -static h248_package_t h248_package_3GCSD = { +static const h248_package_t h248_package_3GCSD = { 0x0030, &hf_h248_package_3GCSD, - &hf_h248_package_3GCSD_parameters, &ett_h248_package_3GCSD, + h248_3GCSD_properties_vals, + NULL, + NULL, + NULL, h248_package_3GCSD_props, h248_package_3GCSD_sigs, h248_package_3GCSD_evts, - NULL}; + NULL +}; /* @@ -213,7 +261,7 @@ static h248_package_t h248_package_3GCSD = { * 3GPP TS 29.232 -- 15.2.2 */ static int hf_h248_package_3GTFO = -1; -static int hf_h248_package_3GTFO_parameters = -1; + static int hf_h248_pkg_3GTFO_evt_codec_modify = -1; static int hf_h248_pkg_3GTFO_evt_distant_codec_list = -1; static int hf_h248_pkg_3GTFO_evt_status = -1; @@ -228,47 +276,74 @@ static gint ett_h248_3GTFO_evt_status = -1; static gint ett_h248_3GTFO_evt_distant_codec_list = -1; static gint ett_h248_3GTFO_evt_codec_modify = -1; +static const value_string h248_package_3GTFO_props_vals[] = { + {1,"enable"}, + {2,"codeclist"}, + {0,NULL} +}; + +static const value_string h248_pkg_3GTFO_evt_codec_modify_params_vals[] = { + {11,"optimalcodec"}, + {0,NULL} +}; + + +static const value_string h248_pkg_3GTFO_evt_distant_codec_list_params_vals[] = { + {13,"distlist"}, + {0,NULL} +}; + +static const value_string h248_package_3GTFO_evts_vals[] = { + {10,"codec_modify"}, + {12,"distant_codec_list"}, + {14,"status"}, + {0,NULL} +}; + static const value_string tfoenable_vals[] = { {1,"On"}, {2,"Off"}, {0,NULL} }; -static h248_pkg_param_t h248_package_3GTFO_props[] = { +static const h248_pkg_param_t h248_package_3GTFO_props[] = { { 0x0001, &hf_h248_pkg_3GTFO_enable, h248_param_ber_integer, &implicit }, { 0x0002, &hf_h248_pkg_3GTFO_codeclist, h248_param_item, &implicit }, /* Sub-list of Octet string Q.765.5 + TS 26.103 .*/ { 0, NULL, NULL, NULL} }; -static h248_pkg_param_t h248_pkg_3GTFO_evt_codec_modify_params[] = { +static const h248_pkg_param_t h248_pkg_3GTFO_evt_codec_modify_params[] = { { 0x0011, &hf_h248_pkg_3GTFO_evt_codec_modify_optimalcodec, h248_param_ber_octetstring, &implicit }, /* Q.765.5 + TS 26.103 .*/ { 0, NULL, NULL, NULL} }; -static h248_pkg_param_t h248_pkg_3GTFO_evt_distant_codec_list_params[] = { +static const h248_pkg_param_t h248_pkg_3GTFO_evt_distant_codec_list_params[] = { { 0x0013, &hf_h248_pkg_3GTFO_evt_distant_codec_list_distlist, h248_param_item, &implicit }, /* Sub-list of Octet string Q.765.5 + TS 26.103 .*/ { 0, NULL, NULL, NULL} }; -static h248_pkg_param_t h248_pkg_3GTFO_evt_status_params[] = { +static const h248_pkg_param_t h248_pkg_3GTFO_evt_status_params[] = { { 0x0001, &hf_h248_pkg_3GTFO_evt_status_tfostatus, h248_param_ber_boolean, &implicit }, { 0, NULL, NULL, NULL} }; -static h248_pkg_evt_t h248_package_3GTFO_evts[] = { - { 0x0010, &hf_h248_pkg_3GTFO_evt_codec_modify, &ett_h248_3GTFO_evt_codec_modify, h248_pkg_3GTFO_evt_codec_modify_params}, - { 0x0012, &hf_h248_pkg_3GTFO_evt_distant_codec_list, &ett_h248_3GTFO_evt_distant_codec_list, h248_pkg_3GTFO_evt_distant_codec_list_params}, +static const h248_pkg_evt_t h248_package_3GTFO_evts[] = { + { 0x0010, &hf_h248_pkg_3GTFO_evt_codec_modify, &ett_h248_3GTFO_evt_codec_modify, h248_pkg_3GTFO_evt_codec_modify_params, h248_pkg_3GTFO_evt_codec_modify_params_vals}, + { 0x0012, &hf_h248_pkg_3GTFO_evt_distant_codec_list, &ett_h248_3GTFO_evt_distant_codec_list, h248_pkg_3GTFO_evt_distant_codec_list_params, h248_pkg_3GTFO_evt_distant_codec_list_params_vals}, { 0x0014, &hf_h248_pkg_3GTFO_evt_status, &ett_h248_3GTFO_evt_status, h248_pkg_3GTFO_evt_status_params}, { 0, NULL, NULL, NULL} }; -static h248_package_t h248_package_3GTFO = { +static const h248_package_t h248_package_3GTFO = { 0x0031, &hf_h248_package_3GTFO, - &hf_h248_package_3GTFO_parameters, &ett_h248_package_3GTFO, + h248_package_3GTFO_props_vals, + NULL, + h248_package_3GTFO_evts_vals, + NULL, h248_package_3GTFO_props, NULL, h248_package_3GTFO_evts, @@ -314,10 +389,6 @@ void proto_register_h248_3gpp(void) { { "Mode", "h248.package_3GUP.Mode", FT_UINT32, BASE_DEC, VALS(h248_3GUP_Mode_vals), 0, "Mode", HFILL }}, - { &hf_h248_package_3GUP_parameters, - { "Parameter", "h248.package_3GUP.parameter", - FT_UINT16, BASE_HEX, VALS(h248_3GUP_parameters), 0, - "Parameter", HFILL }}, { &hf_h248_package_3GUP_UPversions, { "UPversions", "h248.package_3GUP.upversions", FT_UINT32, BASE_DEC, VALS(h248_3GUP_upversions_vals), 0, @@ -340,10 +411,6 @@ void proto_register_h248_3gpp(void) { { "CSD Package", "h248.package_3GCSD", FT_BYTES, BASE_HEX, NULL, 0, "Circuit Switched Data Package", HFILL }}, - { &hf_h248_package_3GCSD_parameters, - { "CSD Package params", "h248.package_3GCSD.params", - FT_BYTES, BASE_DEC, NULL, 0, - "", HFILL }}, { &hf_h248_package_3GCSD_plmnbc, { "PLMN Bearer Capability", "h248.package_3GCSD.plmnbc", FT_BYTES, BASE_DEC, NULL, 0, @@ -386,10 +453,6 @@ void proto_register_h248_3gpp(void) { { "Tandem Free Operation ", "h248.package_3GTFO", FT_BYTES, BASE_HEX, NULL, 0, "This package defines events and properties for Tandem Free Operation (TFO) control", HFILL }}, - { &hf_h248_package_3GTFO_parameters, - { "Tandem Free Operation", "h248.package_3GTFO", - FT_BYTES, BASE_DEC, NULL, 0, - "", HFILL }}, { &hf_h248_pkg_3GTFO_enable, { "TFO Activity Control", "h248.package_3GTFO.tfoenable", FT_UINT32, BASE_DEC, VALS(tfoenable_vals), 0, @@ -457,3 +520,4 @@ void proto_reg_handoff_h248_3gpp(void) { + diff --git a/epan/dissectors/packet-h248_annex_c.c b/epan/dissectors/packet-h248_annex_c.c index 908ec19180..496bb92fa1 100644 --- a/epan/dissectors/packet-h248_annex_c.c +++ b/epan/dissectors/packet-h248_annex_c.c @@ -32,7 +32,6 @@ /* H.248 Annex C */ static int proto_h248_pkg_annexc = -1; -static int hf_h248_pkg_annexc_parameters = -1; static int hf_h248_pkg_annexc_media = -1; static int hf_h248_pkg_annexc_ACodec = -1; @@ -952,8 +951,11 @@ static h248_pkg_param_t h248_annexc_package_properties[] = { static h248_package_t h248_annexc_package = { 0x0000, &proto_h248_pkg_annexc, - &hf_h248_pkg_annexc_parameters, &ett_annexc, + h248_annexc_package_properties_vals, + NULL, + NULL, + NULL, h248_annexc_package_properties, /* properties */ NULL, /* signals */ NULL, /* events */ @@ -963,8 +965,6 @@ static h248_package_t h248_annexc_package = { void proto_register_h248_annex_c(void) { static hf_register_info hf[] = { - { &hf_h248_pkg_annexc_parameters, - { "Parameter", "h248.pkg.annexc.parameter", FT_UINT16, BASE_HEX, VALS(h248_annexc_package_properties_vals), 0, "Annex-C Parameter ID", HFILL }}, { &hf_h248_pkg_annexc_media, { "Media", "h248.pkg.annexc.media", FT_UINT32, BASE_HEX, VALS(h248_annexc_media_vals), 0, "Media Type", HFILL }}, { &hf_h248_pkg_annexc_ACodec, diff --git a/epan/dissectors/packet-h248_annex_e.c b/epan/dissectors/packet-h248_annex_e.c index b16f56f5d8..5f1f470947 100644 --- a/epan/dissectors/packet-h248_annex_e.c +++ b/epan/dissectors/packet-h248_annex_e.c @@ -38,7 +38,6 @@ static gboolean implicit = TRUE; /* H.248.1 E.1 Generic Package */ static int hf_h248_pkg_generic = -1; -static int hf_h248_pkg_generic_params = -1; static int hf_h248_pkg_generic_cause_evt = -1; static int hf_h248_pkg_generic_cause_gencause = -1; static int hf_h248_pkg_generic_cause_failurecause = -1; @@ -47,6 +46,17 @@ static gint ett_h248_pkg_generic_cause_evt = -1; static gint ett_tdmc = -1; static gint ett_h248_pkg_generic = -1; +static const value_string h248_pkg_generic_cause_vals[] = { + {1, "gencause"}, + {2, "failurecause"}, + { 0, NULL } +}; + +static const value_string h248_pkg_generic_evt_vals[] = { + {1, "generic_cause"}, + { 0, NULL } +}; + static const value_string h248_pkg_generic_cause_gencause_vals[] = { { 1, "NR (Normal Release)"}, { 2, "UR (Unavailable Resources)"}, @@ -64,18 +74,21 @@ static h248_pkg_param_t h248_pkg_generic_cause_evt_params[] = { }; static h248_pkg_evt_t h248_pkg_generic_cause_evts[] = { - { 0x0001, &hf_h248_pkg_generic_cause_evt, &ett_h248_pkg_generic_cause_evt, h248_pkg_generic_cause_evt_params}, - { 0, NULL, NULL, NULL} + { 0x0001, &hf_h248_pkg_generic_cause_evt, &ett_h248_pkg_generic_cause_evt, h248_pkg_generic_cause_evt_params, h248_pkg_generic_cause_gencause_vals}, + { 0, NULL, NULL, NULL, NULL} }; static h248_package_t h248_pkg_generic = { 0x0001, &hf_h248_pkg_generic, - &hf_h248_pkg_generic_params, &ett_h248_pkg_generic, NULL, NULL, + h248_pkg_generic_evt_vals, + NULL, + NULL, + NULL, h248_pkg_generic_cause_evts, NULL }; @@ -151,7 +164,6 @@ static int hf_h248_pkg_tonedet_evt_ltd = -1; /* E.5 Basic DTMF Generator Package */ static int hf_h248_pkg_dg = -1; -static int hf_h248_pkg_dg_params = -1; static int hf_h248_pkg_dg_sig_d0 = -1; static int hf_h248_pkg_dg_sig_d1 = -1; static int hf_h248_pkg_dg_sig_d2 = -1; @@ -163,23 +175,34 @@ static gint ett_h248_pkg_dg_sig_d1 = -1; static gint ett_h248_pkg_dg_sig_d2 = -1; static gint ett_h248_pkg_dg_sig_d3 = -1; +static const value_string h248_pkg_dg_signals_vals[] = { + { 0x0010, "d0"}, + { 0x0011, "d1"}, + { 0x0012, "d2"}, + { 0x0013, "d3"}, + {0,NULL} +}; + /* Signals defenitions */ static h248_pkg_sig_t h248_pkg_dg_signals[] = { - { 0x0010, &hf_h248_pkg_dg_sig_d0, &ett_h248_pkg_dg_sig_d0, NULL }, - { 0x0011, &hf_h248_pkg_dg_sig_d1, &ett_h248_pkg_dg_sig_d1, NULL }, - { 0x0012, &hf_h248_pkg_dg_sig_d2, &ett_h248_pkg_dg_sig_d2, NULL }, - { 0x0013, &hf_h248_pkg_dg_sig_d3, &ett_h248_pkg_dg_sig_d3, NULL }, + { 0x0010, &hf_h248_pkg_dg_sig_d0, &ett_h248_pkg_dg_sig_d0, NULL, NULL }, + { 0x0011, &hf_h248_pkg_dg_sig_d1, &ett_h248_pkg_dg_sig_d1, NULL, NULL }, + { 0x0012, &hf_h248_pkg_dg_sig_d2, &ett_h248_pkg_dg_sig_d2, NULL, NULL }, + { 0x0013, &hf_h248_pkg_dg_sig_d3, &ett_h248_pkg_dg_sig_d3, NULL, NULL }, /* TODO add the rest of the signals */ - { 0, NULL, NULL, NULL} + { 0, NULL, NULL, NULL, NULL} }; /* Packet defenitions */ static h248_package_t h248_pkg_dg = { 0x0005, &hf_h248_pkg_dg, - &hf_h248_pkg_dg_params, &ett_h248_pkg_dg, + NULL, + h248_pkg_dg_signals_vals, + NULL, + NULL, NULL, /* Properties */ h248_pkg_dg_signals, /* signals */ NULL, /* events */ @@ -188,7 +211,6 @@ static h248_package_t h248_pkg_dg = { /* H.248.1 E.9 Analog Line Supervision Package */ static int hf_h248_pkg_al = -1; -static int hf_h248_pkg_al_param = -1; static int hf_h248_pkg_al_evt_onhook = -1; static int hf_h248_pkg_al_evt_offhook = -1; static int hf_h248_pkg_al_evt_flashhook = -1; @@ -203,6 +225,27 @@ static gint ett_h248_pkg_al_evt_onhook = -1; static gint ett_h248_pkg_al_evt_offhook = -1; static gint ett_h248_pkg_al_evt_flashhook = -1; + +static const value_string h248_pkg_al_evt_onhook_params_vals[] = { + { 0x0001, "strict"}, + { 0x0002, "init"}, + { 0, NULL} +}; + +static const value_string h248_pkg_al_evt_flashhook_params_vals[] = { + { 0x0001, "mindur"}, + { 0, NULL} +}; + +static const value_string h248_pkg_al_evts_vals[] = { + { 0x0004, "onhook"}, + { 0x0005, "offhook"}, + { 0x0006, "flashhook"}, + { 0, NULL} +}; + + + /* Events defenitions */ static const value_string h248_pkg_al_evt_onhook_strict_vals[] = { { 0, "exact"}, @@ -239,10 +282,9 @@ static h248_pkg_param_t h248_pkg_al_evt_flashhook_params[] = { }; static h248_pkg_evt_t h248_pkg_al_evts[] = { - { 0x0004, &hf_h248_pkg_al_evt_onhook, &ett_h248_pkg_al_evt_onhook, h248_pkg_al_evt_onhook_params }, - { 0x0005, &hf_h248_pkg_al_evt_offhook, &ett_h248_pkg_al_evt_offhook, h248_pkg_al_evt_offhook_params }, - - { 0x0006, &hf_h248_pkg_al_evt_flashhook, &ett_h248_pkg_al_evt_flashhook, h248_pkg_al_evt_flashhook_params }, + { 0x0004, &hf_h248_pkg_al_evt_onhook, &ett_h248_pkg_al_evt_onhook, h248_pkg_al_evt_onhook_params, h248_pkg_al_evt_onhook_params_vals}, + { 0x0005, &hf_h248_pkg_al_evt_offhook, &ett_h248_pkg_al_evt_offhook, h248_pkg_al_evt_offhook_params, h248_pkg_al_evt_onhook_params_vals }, + { 0x0006, &hf_h248_pkg_al_evt_flashhook, &ett_h248_pkg_al_evt_flashhook, h248_pkg_al_evt_flashhook_params, h248_pkg_al_evt_flashhook_params_vals }, { 0, NULL, NULL, NULL} }; @@ -262,8 +304,11 @@ static const value_string h248_pkg_al_parameters[] = { static h248_package_t h248_pkg_al = { 0x0009, &hf_h248_pkg_al, - &hf_h248_pkg_al_param, &ett_h248_pkg_al, + NULL, + NULL, + h248_pkg_al_evts_vals, + NULL, NULL, /* Properties */ NULL, /* signals */ h248_pkg_al_evts, /* events */ @@ -272,11 +317,15 @@ static h248_package_t h248_pkg_al = { /* H.248.1 E.12 RTP package */ static int hf_h248_pkg_rtp = -1; -static int hf_h248_pkg_rtp_param = -1; static int hf_h248_pkg_rtp_stat_ps = -1; static int ett_h248_pkg_rtp = -1; +static const value_string h248_pkg_rtp_stat_vals[] = { + { 0x0004, "ps"}, + { 0, NULL} +}; + static const value_string h248_pkg_rtp_parameters[] = { { 0x0001, "pltrans (Payload Transition)" }, { 0x0004, "ps (Packets Sent)" }, @@ -288,7 +337,7 @@ static const value_string h248_pkg_rtp_parameters[] = { }; static h248_pkg_stat_t h248_pkg_rtp_stat[] = { - { 0x0004, &hf_h248_pkg_rtp_stat_ps, &ett_h248_pkg_rtp, NULL }, + { 0x0004, &hf_h248_pkg_rtp_stat_ps, &ett_h248_pkg_rtp, NULL}, { 0, NULL, NULL, NULL} }; @@ -296,8 +345,11 @@ static h248_pkg_stat_t h248_pkg_rtp_stat[] = { static h248_package_t h248_pkg_rtp = { 0x000c, &hf_h248_pkg_rtp, - &hf_h248_pkg_rtp_param, &ett_h248_pkg_rtp, + h248_pkg_rtp_parameters, + NULL, + NULL, + NULL, NULL, /* Properties */ NULL, /* signals */ NULL, /* events */ @@ -306,7 +358,6 @@ static h248_package_t h248_pkg_rtp = { /* H.248.1 E.13 TDM Circuit Package */ static int hf_h248_pkg_tdmc = -1; -static int hf_h248_pkg_tdmc_param = -1; static int hf_h248_pkg_tdmc_ec = -1; static int hf_h248_pkg_tdmc_gain = -1; @@ -316,6 +367,12 @@ static const true_false_string h248_tdmc_ec_vals = { "On", "Off" }; +static const value_string h248_pkg_tdmc_props_vals[] = { + { 0x0008, "ec"}, + { 0x000a, "gain"}, + { 0, NULL} +}; + static h248_pkg_param_t h248_pkg_tdmc_props[] = { { 0x0008, &hf_h248_pkg_tdmc_ec, h248_param_ber_boolean, &implicit }, @@ -326,8 +383,11 @@ static h248_pkg_param_t h248_pkg_tdmc_props[] = { static h248_package_t h248_pkg_tdmc = { 0x000d, &hf_h248_pkg_tdmc, - &hf_h248_pkg_tdmc_param, &ett_h248_pkg_tdmc, + h248_pkg_tdmc_props_vals, + NULL, + NULL, + NULL, h248_pkg_tdmc_props, /* Properties */ NULL, /* signals */ NULL, /* events */ @@ -345,10 +405,6 @@ void proto_register_h248_annex_e(void) { { &hf_h248_pkg_generic_cause_failurecause, { "Generic Cause", "h248.pkg.generic.cause.failurecause", FT_STRING, BASE_HEX, NULL, 0, "", HFILL }}, /* H.248.1 E.9 Analog Line Supervision Package */ { &hf_h248_pkg_al, { "Analog Line Supervision Package", "h248.pkg.al", FT_BYTES, BASE_HEX, NULL, 0, "", HFILL }}, - { &hf_h248_pkg_al_param, - { "Parameter", "h248.pkg.al.parameter", - FT_UINT16, BASE_HEX, VALS(h248_pkg_al_parameters), 0, "Parameter", HFILL } - }, { &hf_h248_pkg_al_evt_onhook, { "onhook", "h248.pkg.al.onhook", FT_BYTES, BASE_HEX, NULL, 0, "", HFILL }}, { &hf_h248_pkg_al_evt_offhook, { "offhook", "h248.pkg.al.offhook", FT_BYTES, BASE_HEX, NULL, 0, "", HFILL }}, { &hf_h248_pkg_al_evt_flashhook, { "flashhook", "h248.pkg.al.flashhook", FT_BYTES, BASE_HEX, NULL, 0, "", HFILL }}, @@ -359,10 +415,6 @@ void proto_register_h248_annex_e(void) { { &hf_h248_pkg_al_evt_flashhook_par_mindur, { "Minimum duration in ms", "h248.pkg.al.ev.flashhook.mindur", FT_UINT32, BASE_DEC, NULL, 0, "", HFILL }}, /* H.248.1 E.12 RTP package */ { &hf_h248_pkg_rtp, { "RTP package", "h248.pkg.rtp", FT_BYTES, BASE_HEX, NULL, 0, "", HFILL }}, - { &hf_h248_pkg_rtp_param, - { "Parameter", "h248.pkg.rtp.parameter", - FT_UINT16, BASE_HEX, VALS(h248_pkg_rtp_parameters), 0, "Parameter", HFILL } - }, { &hf_h248_pkg_rtp_stat_ps, { "Packets Sent", "h248.pkg.rtp.stat.ps", FT_UINT64, BASE_DEC, NULL, 0, "Packets Sent", HFILL }}, /* H.248.1 E.13 TDM Circuit Package */ { &hf_h248_pkg_tdmc, { "TDM Circuit Package", "h248.pkg.tdmc", FT_BYTES, BASE_HEX, NULL, 0, "", HFILL }}, @@ -403,3 +455,4 @@ void proto_register_h248_annex_e(void) { void proto_reg_handoff_h248_annex_e(void) { } + diff --git a/epan/dissectors/packet-h248_q1950.c b/epan/dissectors/packet-h248_q1950.c index 8e5e4d737b..8852bf9c67 100644 --- a/epan/dissectors/packet-h248_q1950.c +++ b/epan/dissectors/packet-h248_q1950.c @@ -38,7 +38,6 @@ static int proto_q1950 = -1; /* A.3 Bearer characteristics package */ static int hf_h248_pkg_BCP = -1; -static int hf_h248_pkg_BCP_param = -1; static int hf_h248_pkg_BCP_BNCChar = -1; static int ett_h248_pkg_BCP = -1; @@ -50,6 +49,11 @@ static const value_string h248_pkg_BCP_parameters[] = { {0, NULL} }; +static const value_string h248_pkg_BCP_props_vals[] = { + {1,"BNCChar"}, + {0,NULL} +}; + /* Properties */ h248_pkg_param_t h248_pkg_BCP_props[] = { { 0x0001, &hf_h248_pkg_BCP_BNCChar, h248_param_ber_integer, &implicit }, @@ -60,13 +64,21 @@ h248_pkg_param_t h248_pkg_BCP_props[] = { static h248_package_t h248_pkg_BCP = { 0x001e, &hf_h248_pkg_BCP, - &hf_h248_pkg_BCP_param, &ett_h248_pkg_BCP, + h248_pkg_BCP_props_vals, + NULL, + NULL, + NULL, h248_pkg_BCP_props, /* Properties */ NULL, /* signals */ NULL, /* events */ NULL /* statistics */ }; + +/* A.4 Bearer Network connection cut-through package */ + +/* A.5 Bearer Reuse Idle Package */ + /* A.6 Generic bearer connection package Package Name: GB Package ID: 0x0021 @@ -76,7 +88,6 @@ static h248_package_t h248_pkg_BCP = { static dissector_handle_t sdp_dissector = NULL; static int hf_h248_pkg_bct = -1; -static int hf_h248_pkg_bct_param = -1; static int hf_h248_pkg_bct_tind = -1; static gint ett_h248_pkg_bct = -1; @@ -95,7 +106,7 @@ static void dissect_bct_tind_bit(proto_tree* tree, tvbuff_t* tvb, packet_info* p dissect_ber_octet_string(FALSE, pinfo, tree, tvb, 0, hfid, &sdp_tvb); if (sdp_tvb) { - /* XXX: is it realy sdp? */ + /* XXX: are we sure it is always sdp? */ call_dissector(sdp_dissector,sdp_tvb,pinfo,tree); } } else { @@ -120,8 +131,11 @@ static h248_pkg_evt_t h248_pkg_bct_events[] = { static h248_package_t h248_pkg_bct = { 0x0022, &hf_h248_pkg_bct, - &hf_h248_pkg_bct_param, &ett_h248_pkg_bct, + NULL, + NULL, + NULL, + NULL, NULL, /* Properties */ NULL, /* signals */ h248_pkg_bct_events, /* events */ @@ -130,7 +144,6 @@ static h248_package_t h248_pkg_bct = { /* A.8 Basic call progress tones generator with directionality */ static int hf_h248_pkg_bcg = -1; -static int hf_h248_pkg_bcg_param = -1; static int hf_h248_pkg_bcg_sig_bdt_par_btd = -1; static int hf_h248_pkg_bcg_sig_bdt = -1; static int hf_h248_pkg_bcg_sig_brt = -1; @@ -177,8 +190,11 @@ static h248_pkg_sig_t h248_pkg_bcg_signals[] = { static h248_package_t h248_pkg_bcg = { 0x0023, &hf_h248_pkg_bcg, - &hf_h248_pkg_bcg_param, &ett_h248_pkg_bcg, + NULL, + NULL, + NULL, + NULL, NULL, /* Properties */ h248_pkg_bcg_signals, /* signals */ NULL, /* events */ @@ -194,10 +210,6 @@ void proto_register_q1950(void) { { "BCP (Bearer characteristics package)", "h248.pkg.BCP", FT_BYTES, BASE_HEX, NULL, 0, "", HFILL } }, - { &hf_h248_pkg_BCP_param, - { "Parameter", "h248.package_bcp.parameter", - FT_UINT16, BASE_HEX, VALS(h248_pkg_BCP_parameters), 0, "Parameter", HFILL } - }, { &hf_h248_pkg_BCP_BNCChar, { "BNCChar (BNC Characteristics)", "h248.pkg.bcp.bncchar", FT_UINT32, BASE_HEX, VALS(bearer_network_connection_characteristics_vals), 0, "BNC Characteristics", HFILL } diff --git a/epan/dissectors/packet-sctp.c b/epan/dissectors/packet-sctp.c index e062ee3868..c7cc356dbc 100644 --- a/epan/dissectors/packet-sctp.c +++ b/epan/dissectors/packet-sctp.c @@ -189,6 +189,9 @@ static int hf_sctp_reassembled_in = -1; static int hf_sctp_duplicate = -1; static int hf_sctp_fragments = -1; static int hf_sctp_fragment = -1; +static int hf_sctp_rtt = -1; +static int hf_sctp_ack = -1; +static int hf_sctp_acked = -1; static dissector_table_t sctp_port_dissector_table; static dissector_table_t sctp_ppi_dissector_table; @@ -214,8 +217,14 @@ static gint ett_sctp_unrecognized_parameter_parameter = -1; static gint ett_sctp_fragments = -1; static gint ett_sctp_fragment = -1; +static gint ett_sctp_tsn = -1; +static gint ett_sctp_ack = -1; +static gint ett_sctp_acked = -1; + static dissector_handle_t data_handle; +static gboolean enable_tsn_analysis = FALSE; + #define SCTP_DATA_CHUNK_ID 0 #define SCTP_INIT_CHUNK_ID 1 #define SCTP_INIT_ACK_CHUNK_ID 2 @@ -507,6 +516,8 @@ sctp_crc32c(const unsigned char* buf, unsigned int len) * Routines for dissecting parameters */ +typedef struct _sctp_assoc_t sctp_assoc_t; + static void dissect_parameter(tvbuff_t *, packet_info *, proto_tree *, proto_item *, gboolean); @@ -520,12 +531,356 @@ static void dissect_error_causes(tvbuff_t *, packet_info *, proto_tree *); static gboolean -dissect_sctp_chunk(tvbuff_t *, packet_info *, proto_tree *, proto_tree *, gboolean); +dissect_data_chunk(tvbuff_t*, guint16, packet_info*, proto_tree*, proto_tree*, proto_item*, proto_item*, sctp_assoc_t*); static void dissect_sctp_packet(tvbuff_t *, packet_info *, proto_tree *, gboolean); +/* + * TSN Analysis + */ + +typedef struct _sctp_tsn_t { + guint32 tsn; + + struct { + guint32 framenum; + nstime_t ts; + } first_transmit; + + struct { + guint32 framenum; + nstime_t ts; + } ack; + + struct _sctp_tsn_t* next_same_ctsn; +} sctp_tsn_t; + +typedef struct { + guint32 ctsn_ack; + emem_tree_t* tsns; /* by tsn */ + emem_tree_t* ctsn_frames; /* by ctsn_frame */ + guint32* vtag; /* NULL means still unknown */ +} sctp_assoc_dir_t; + +struct _sctp_assoc_t { + guint32 port_label; /* SCTP_PORTLABEL(src,dst) */ + + sctp_assoc_dir_t up; + sctp_assoc_dir_t down; + + sctp_assoc_dir_t* current_dir; + sctp_assoc_dir_t* opposite_dir; + + struct _sctp_assoc_t* next_same_pl; +}; + +#define SCTP_PORTLABEL(a,b) ( (a>b) ? (a << 16) | b : (b << 16) | a ) + +static emem_tree_t* assocs_by_ptvtag; +static emem_tree_t* assocs_by_portlabel; + +static void new_tsn(packet_info* pinfo, proto_tree* tsn_tree, tvbuff_t* tvb, sctp_assoc_t* a, guint32 tsn) { + sctp_tsn_t* td; + nstime_t rtt; + + if (! enable_tsn_analysis) return; + + if (! (td = se_tree_lookup32(a->current_dir->tsns,tsn)) ) { + td = se_alloc0(sizeof(sctp_tsn_t)); + td->tsn = tsn; + td->first_transmit.framenum = pinfo->fd->num; + td->first_transmit.ts.secs = pinfo->fd->abs_ts.secs; + td->first_transmit.ts.nsecs = pinfo->fd->abs_ts.nsecs; + + se_tree_insert32(a->current_dir->tsns,tsn,td); + + if (! a->current_dir->ctsn_ack) { + a->current_dir->ctsn_ack = tsn - 1; + } + } + + if (td->first_transmit.framenum != pinfo->fd->num) { + proto_tree_add_uint(tsn_tree, hf_sctp_duplicate, tvb, 0 , 0, td->first_transmit.framenum); + } else { + if (td->ack.framenum) { + proto_item* ack_item = proto_tree_add_uint(tsn_tree, hf_sctp_acked, tvb, 0 , 0, td->ack.framenum); + proto_tree* ack_tree = proto_item_add_subtree(ack_item, ett_sctp_ack); + nstime_delta( &rtt, &(td->ack.ts), &(td->first_transmit.ts) ); + proto_tree_add_time(ack_tree, hf_sctp_rtt, tvb, 0, 0, &rtt); + } + } + +} + +static void ack_tsn(packet_info* pinfo, proto_tree* acks_tree, tvbuff_t* tvb, sctp_assoc_t* a, guint32 tsn) { + sctp_tsn_t* td; + + if (! enable_tsn_analysis) return; + + td = se_tree_lookup32(a->opposite_dir->tsns,tsn); + + if (td) { + proto_item* acked_item; + proto_tree* acked_tree; + nstime_t rtt; + + if (! td->ack.framenum) { + td->ack.framenum = pinfo->fd->num; + td->ack.ts.secs = pinfo->fd->abs_ts.secs; + td->ack.ts.nsecs = pinfo->fd->abs_ts.nsecs; + } + + nstime_delta( &rtt, &(td->ack.ts), &(td->first_transmit.ts) ); + + acked_item = proto_tree_add_uint(acks_tree, hf_sctp_ack, tvb, 0 , 0, td->first_transmit.framenum); + acked_tree = proto_item_add_subtree(acked_item, ett_sctp_acked); + + proto_tree_add_time(acked_tree, hf_sctp_rtt, tvb, 0, 0, &rtt); + + } +} + +static void ack_tsns_upto_ctsn(packet_info* pinfo, tvbuff_t* tvb, proto_tree* acks_tree, sctp_assoc_t* a, guint32 cum_tsn_ack) { + sctp_tsn_t *t, *first, *last; + guint32 save_cum_tsn_ack = cum_tsn_ack; + guint32 framenum = pinfo->fd->num; + + if (! enable_tsn_analysis) return; + + if(( t = se_tree_lookup32(a->opposite_dir->ctsn_frames, framenum) )) { + for ( ;t;t = t->next_same_ctsn) { + proto_item* acked_item = proto_tree_add_uint(acks_tree, hf_sctp_ack, tvb, 0 , 0, t->first_transmit.framenum); + proto_tree* acked_tree = proto_item_add_subtree(acked_item, ett_sctp_acked); + nstime_t rtt; + + nstime_delta( &rtt, &(t->ack.ts), &(t->first_transmit.ts) ); + proto_tree_add_time(acked_tree, hf_sctp_rtt, tvb, 0, 0, &rtt); + } + return; + } + + if (pinfo->fd->flags.visited) return; + + first = NULL; + last = NULL; + + do { + proto_item* acked_item; + proto_tree* acked_tree; + nstime_t rtt; + + if (cum_tsn_ack <= a->opposite_dir->ctsn_ack) break; + + t = se_tree_lookup32_le(a->opposite_dir->tsns,cum_tsn_ack--); + + if (!t) break; + + if (! t->ack.framenum) { + t->ack.framenum = framenum; + t->ack.ts.secs = pinfo->fd->abs_ts.secs; + t->ack.ts.nsecs = pinfo->fd->abs_ts.nsecs; + } + + nstime_delta( &rtt, &(t->ack.ts), &(t->first_transmit.ts) ); + + acked_item = proto_tree_add_uint(acks_tree, hf_sctp_ack, tvb, 0 , 0, t->first_transmit.framenum); + acked_tree = proto_item_add_subtree(acked_item, ett_sctp_acked); + + proto_tree_add_time(acked_tree, hf_sctp_rtt, tvb, 0, 0, &rtt); + + if (!first) { + first = t; + } + + if (last) { + last->next_same_ctsn = t; + } + + last = t; + } while (1); + + if (first) { + se_tree_insert32(a->opposite_dir->ctsn_frames,first->ack.framenum,first); + a->opposite_dir->ctsn_ack = save_cum_tsn_ack; + } +} + +static void ack_tsn_gap_block(packet_info* pinfo, proto_tree* acks_tree, tvbuff_t* tvb, sctp_assoc_t* a, guint32 tsn_start, guint32 tsn_end) { + if (! enable_tsn_analysis) return; + + do { + ack_tsn(pinfo, acks_tree, tvb, a, tsn_start++); + } while(tsn_start <= tsn_end); +} + +static sctp_assoc_t* new_assoc(sctp_assoc_t* prev, guint32 spt, guint32 dpt, guint32 svtag) { + sctp_assoc_t* a = se_alloc0(sizeof(sctp_assoc_t)); + guint32* vtagp = se_alloc0(sizeof(guint32)); + guint32 pl = SCTP_PORTLABEL(spt,dpt); + enum {DOWN,UP} direction = (spt<dpt) ? DOWN : UP; + emem_tree_key_t key[] = { + {1, &pl}, + {1, &svtag}, + {0, NULL} + }; + + a->port_label = pl; + + a->up.tsns = se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, + se_strdup_printf("sctp assoc %d-%d up tsns", + pl,svtag)); + + a->up.ctsn_frames = se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, + se_strdup_printf("sctp assoc %d-%d up ctsns", + pl,svtag)); + + a->down.tsns = se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, + se_strdup_printf("sctp assoc %d-%d down tsns", + pl,svtag)); + + a->down.ctsn_frames = se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, + se_strdup_printf("sctp assoc %d-%d down ctsns", + pl,svtag)); + + *vtagp = svtag; + + if (direction == DOWN) { + a->down.vtag = vtagp; + a->current_dir = &(a->down); + a->opposite_dir = &(a->up); + } else { + a->up.vtag = vtagp; + a->current_dir = &(a->up); + a->opposite_dir = &(a->down); + } + + if (prev) { + for (;prev->next_same_pl;prev = prev->next_same_pl); + prev->next_same_pl = a; + } else { + se_tree_insert32(assocs_by_portlabel,pl,a); + } + + se_tree_insert32_array(assocs_by_ptvtag,key,a); + + return a; +} + + +static sctp_assoc_t* get_assoc(guint32 spt, guint32 dpt, guint32 vtag) { + guint32 pl = SCTP_PORTLABEL(spt,dpt); + enum {DOWN,UP} direction = (spt<dpt) ? DOWN : UP; + emem_tree_key_t key[] = { + {1, &pl}, + {1, &vtag}, + {0, NULL} + }; + + sctp_assoc_t* a_pl = se_tree_lookup32(assocs_by_portlabel,pl); + sctp_assoc_t* a_vt = se_tree_lookup32_array(assocs_by_ptvtag,key); + sctp_assoc_t *a, *last; + + /* no assoc with this ports this is a new assoc */ + if (!a_pl) return new_assoc(NULL,spt,dpt,vtag); + + /* got vtag and portlabel */ + if (a_vt) { + if (spt==dpt) { + if (a_vt->down.vtag) { + direction = (*(a_vt->down.vtag) == vtag) ? DOWN : UP; + } else if (a_vt->up.vtag) { + direction = (*(a_vt->up.vtag) == vtag) ? UP : DOWN; + } else { + DISSECTOR_ASSERT_NOT_REACHED(); + } + } + + if (direction == DOWN) { + a_vt->current_dir = &(a_vt->down); + a_vt->opposite_dir = &(a_vt->up); + } else { + a_vt->current_dir = &(a_vt->up); + a_vt->opposite_dir = &(a_vt->down); + } + + return a_vt; + } + + for (a=a_pl; a; a = a->next_same_pl) { + last = a; + + /* + * this has both but is not the one we found + * skip it! + */ + if (a->up.vtag && a->down.vtag) continue; + + if (spt==dpt) { + if (a_pl->down.vtag) { + direction = (*(a_pl->down.vtag) == vtag) ? DOWN : UP; + } else if (a_pl->up.vtag) { + direction = (*(a_pl->up.vtag) == vtag) ? UP : DOWN; + } else { + DISSECTOR_ASSERT_NOT_REACHED(); + } + } + + if ( direction == DOWN ) { + /* + * we miss the high vtag and we have a low vtag, + * we assume this to be our other half + */ + a->down.vtag = se_alloc(sizeof(guint32)); + *(a->down.vtag) = vtag; + se_tree_insert32_array(assocs_by_ptvtag,key,a); + a->current_dir = &(a->down); + a->opposite_dir = &(a->up); + + return a; + } + + if (direction == UP) { + /* + * we miss the high vtag and we have a low vtag, + * we assume this to be our other half + */ + a->up.vtag = se_alloc(sizeof(guint32)); + *(a->up.vtag) = vtag; + se_tree_insert32_array(assocs_by_ptvtag,key,a); + a->current_dir = &(a->up); + a->opposite_dir = &(a->down); + + return a; + } + + /* this is the same half and this vtag is not the right one, keep looking */ + } + + /* + * if we get here it means we did not find our other half + * in the list of assocs with the same portlabel. + * This is a new association with the same portlabel + */ + + return new_assoc(last,spt,dpt,vtag); +} + +void sctp_dummy() { + void* k = ack_tsns_upto_ctsn; + void* l = ack_tsn; + void* m = new_tsn; + void* n = new_assoc; + void* o = get_assoc; + + (void)k; + (void)l; + (void)m; + (void)n; + (void)o; +} + #define HEARTBEAT_INFO_PARAMETER_INFO_OFFSET PARAMETER_VALUE_OFFSET @@ -1210,6 +1565,14 @@ dissect_unresolvable_address_cause(tvbuff_t *cause_tvb, packet_info *pinfo, prot proto_item_append_text(cause_item, ")"); } +static gboolean +dissect_sctp_chunk(tvbuff_t *chunk_tvb, + packet_info *pinfo, + proto_tree *tree, + proto_tree *sctp_tree, + sctp_assoc_t* assoc, + gboolean useinfo); + static void dissect_unrecognized_chunk_type_cause(tvbuff_t *cause_tvb, packet_info *pinfo, proto_tree *cause_tree, proto_item *cause_item) { @@ -1219,7 +1582,7 @@ dissect_unrecognized_chunk_type_cause(tvbuff_t *cause_tvb, packet_info *pinfo, chunk_length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET) - CAUSE_HEADER_LENGTH; unrecognized_chunk_tvb = tvb_new_subset(cause_tvb, CAUSE_INFO_OFFSET, chunk_length, chunk_length); - dissect_sctp_chunk(unrecognized_chunk_tvb, pinfo, cause_tree,cause_tree, FALSE); + dissect_sctp_chunk(unrecognized_chunk_tvb, pinfo, cause_tree,cause_tree, NULL, FALSE); unrecognized_type = tvb_get_guint8(unrecognized_chunk_tvb, CHUNK_TYPE_OFFSET); proto_item_append_text(cause_item, " (Type: %u (%s))", unrecognized_type, val_to_str(unrecognized_type, chunk_type_values, "unknown")); } @@ -2210,7 +2573,14 @@ static const true_false_string sctp_data_chunk_u_bit_value = { }; static gboolean -dissect_data_chunk(tvbuff_t *chunk_tvb, guint16 chunk_length, packet_info *pinfo, proto_tree *tree, proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item) +dissect_data_chunk(tvbuff_t *chunk_tvb, + guint16 chunk_length, + packet_info *pinfo, + proto_tree *tree, + proto_tree *chunk_tree, + proto_item *chunk_item, + proto_item *flags_item, + sctp_assoc_t* assoc) { guint number_of_ppid; guint32 payload_proto_id; @@ -2219,7 +2589,9 @@ dissect_data_chunk(tvbuff_t *chunk_tvb, guint16 chunk_length, packet_info *pinfo guint8 e_bit, b_bit, u_bit; guint16 stream_id, stream_seq_num = 0; guint32 tsn; - + proto_item* tsn_item = NULL; + proto_tree* tsn_tree = NULL; + if (chunk_length <= DATA_CHUNK_HEADER_LENGTH) { proto_item_append_text(chunk_item, ", bogus chunk length %u < %u)", chunk_length, DATA_CHUNK_HEADER_LENGTH); @@ -2249,11 +2621,11 @@ dissect_data_chunk(tvbuff_t *chunk_tvb, guint16 chunk_length, packet_info *pinfo proto_tree_add_item(flags_tree, hf_data_chunk_e_bit, chunk_tvb, CHUNK_FLAGS_OFFSET, CHUNK_FLAGS_LENGTH, NETWORK_BYTE_ORDER); proto_tree_add_item(flags_tree, hf_data_chunk_b_bit, chunk_tvb, CHUNK_FLAGS_OFFSET, CHUNK_FLAGS_LENGTH, NETWORK_BYTE_ORDER); proto_tree_add_item(flags_tree, hf_data_chunk_u_bit, chunk_tvb, CHUNK_FLAGS_OFFSET, CHUNK_FLAGS_LENGTH, NETWORK_BYTE_ORDER); - proto_tree_add_item(chunk_tree, hf_data_chunk_tsn, chunk_tvb, DATA_CHUNK_TSN_OFFSET, DATA_CHUNK_TSN_LENGTH, NETWORK_BYTE_ORDER); + tsn_item = proto_tree_add_item(chunk_tree, hf_data_chunk_tsn, chunk_tvb, DATA_CHUNK_TSN_OFFSET, DATA_CHUNK_TSN_LENGTH, NETWORK_BYTE_ORDER); proto_tree_add_item(chunk_tree, hf_data_chunk_stream_id, chunk_tvb, DATA_CHUNK_STREAM_ID_OFFSET, DATA_CHUNK_STREAM_ID_LENGTH, NETWORK_BYTE_ORDER); proto_tree_add_item(chunk_tree, hf_data_chunk_stream_seq_number, chunk_tvb, DATA_CHUNK_STREAM_SEQ_NUMBER_OFFSET, DATA_CHUNK_STREAM_SEQ_NUMBER_LENGTH, NETWORK_BYTE_ORDER); proto_tree_add_item(chunk_tree, hf_data_chunk_payload_proto_id, chunk_tvb, DATA_CHUNK_PAYLOAD_PROTOCOL_ID_OFFSET, DATA_CHUNK_PAYLOAD_PROTOCOL_ID_LENGTH, NETWORK_BYTE_ORDER); - + proto_item_append_text(chunk_item, "(%s, ", (u_bit) ? "unordered" : "ordered"); if (b_bit) { if (e_bit) @@ -2274,7 +2646,14 @@ dissect_data_chunk(tvbuff_t *chunk_tvb, guint16 chunk_length, packet_info *pinfo payload_proto_id, chunk_length - DATA_CHUNK_HEADER_LENGTH, plurality(chunk_length - DATA_CHUNK_HEADER_LENGTH, "", "s")); } - + + if (tsn_item) { + tsn_tree = proto_item_add_subtree(tsn_item,ett_sctp_tsn); + } + + new_tsn(pinfo, tsn_tree, chunk_tvb, assoc, tsn); + + payload_tvb = tvb_new_subset(chunk_tvb, DATA_CHUNK_PAYLOAD_OFFSET, chunk_length - DATA_CHUNK_HEADER_LENGTH, chunk_length - DATA_CHUNK_HEADER_LENGTH); /* Is this a fragment? */ @@ -2402,50 +2781,59 @@ dissect_init_ack_chunk(tvbuff_t *chunk_tvb, guint16 chunk_length, packet_info *p static void -dissect_sack_chunk(tvbuff_t *chunk_tvb, proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item) +dissect_sack_chunk(packet_info* pinfo, tvbuff_t *chunk_tvb, proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item, sctp_assoc_t* assoc) { guint16 number_of_gap_blocks, number_of_dup_tsns; guint16 gap_block_number, dup_tsn_number, start, end; gint gap_block_offset, dup_tsn_offset; guint32 cum_tsn_ack; proto_item *block_item; - proto_tree *block_tree, *flags_tree; - - if (chunk_tree) { - flags_tree = proto_item_add_subtree(flags_item, ett_sctp_sack_chunk_flags); - proto_tree_add_item(flags_tree, hf_sack_chunk_ns, chunk_tvb, CHUNK_FLAGS_OFFSET, CHUNK_FLAGS_LENGTH, NETWORK_BYTE_ORDER); - proto_tree_add_item(chunk_tree, hf_sack_chunk_cumulative_tsn_ack, chunk_tvb, SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET, SACK_CHUNK_CUMULATIVE_TSN_ACK_LENGTH, NETWORK_BYTE_ORDER); - proto_tree_add_item(chunk_tree, hf_sack_chunk_adv_rec_window_credit, chunk_tvb, SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET, SACK_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH, NETWORK_BYTE_ORDER); - proto_tree_add_item(chunk_tree, hf_sack_chunk_number_of_gap_blocks, chunk_tvb, SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_OFFSET, SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_LENGTH, NETWORK_BYTE_ORDER); - proto_tree_add_item(chunk_tree, hf_sack_chunk_number_of_dup_tsns, chunk_tvb, SACK_CHUNK_NUMBER_OF_DUP_TSNS_OFFSET, SACK_CHUNK_NUMBER_OF_DUP_TSNS_LENGTH, NETWORK_BYTE_ORDER); - - /* handle the gap acknowledgement blocks */ - number_of_gap_blocks = tvb_get_ntohs(chunk_tvb, SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_OFFSET); - gap_block_offset = SACK_CHUNK_GAP_BLOCK_OFFSET; - cum_tsn_ack = tvb_get_ntohl(chunk_tvb, SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET); - for(gap_block_number = 1; gap_block_number <= number_of_gap_blocks; gap_block_number++) { - start = tvb_get_ntohs(chunk_tvb, gap_block_offset); - end = tvb_get_ntohs(chunk_tvb, gap_block_offset + SACK_CHUNK_GAP_BLOCK_START_LENGTH); - block_item = proto_tree_add_text(chunk_tree, chunk_tvb, gap_block_offset, SACK_CHUNK_GAP_BLOCK_LENGTH, "Gap Acknowledgement for TSN %u to %u", cum_tsn_ack + start, cum_tsn_ack + end); - block_tree = proto_item_add_subtree(block_item, ett_sctp_sack_chunk_gap_block); - proto_tree_add_item(block_tree, hf_sack_chunk_gap_block_start, chunk_tvb, gap_block_offset, SACK_CHUNK_GAP_BLOCK_START_LENGTH, NETWORK_BYTE_ORDER); - proto_tree_add_item(block_tree, hf_sack_chunk_gap_block_end, chunk_tvb, gap_block_offset + SACK_CHUNK_GAP_BLOCK_START_LENGTH, SACK_CHUNK_GAP_BLOCK_END_LENGTH, NETWORK_BYTE_ORDER); - gap_block_offset += SACK_CHUNK_GAP_BLOCK_LENGTH; - } - - /* handle the duplicate TSNs */ - number_of_dup_tsns = tvb_get_ntohs(chunk_tvb, SACK_CHUNK_NUMBER_OF_DUP_TSNS_OFFSET); - dup_tsn_offset = SACK_CHUNK_GAP_BLOCK_OFFSET + number_of_gap_blocks * SACK_CHUNK_GAP_BLOCK_LENGTH; - for(dup_tsn_number = 1; dup_tsn_number <= number_of_dup_tsns; dup_tsn_number++) { - proto_tree_add_item(chunk_tree, hf_sack_chunk_duplicate_tsn, chunk_tvb, dup_tsn_offset, SACK_CHUNK_DUP_TSN_LENGTH, NETWORK_BYTE_ORDER); - dup_tsn_offset += SACK_CHUNK_DUP_TSN_LENGTH; - } - - proto_item_append_text(chunk_item, " (Cumulative TSN: %u, a_rwnd: %u, gaps: %u, duplicate TSNs: %u)", - tvb_get_ntohl(chunk_tvb, SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET), - tvb_get_ntohl(chunk_tvb, SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET), - number_of_gap_blocks, number_of_dup_tsns); - } + proto_tree *block_tree; + proto_tree *flags_tree; + proto_item* ctsa_item; + proto_tree *acks_tree; + + flags_tree = proto_item_add_subtree(flags_item, ett_sctp_sack_chunk_flags); + proto_tree_add_item(flags_tree, hf_sack_chunk_ns, chunk_tvb, CHUNK_FLAGS_OFFSET, CHUNK_FLAGS_LENGTH, NETWORK_BYTE_ORDER); + ctsa_item = proto_tree_add_item(chunk_tree, hf_sack_chunk_cumulative_tsn_ack, chunk_tvb, SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET, SACK_CHUNK_CUMULATIVE_TSN_ACK_LENGTH, NETWORK_BYTE_ORDER); + proto_tree_add_item(chunk_tree, hf_sack_chunk_adv_rec_window_credit, chunk_tvb, SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET, SACK_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH, NETWORK_BYTE_ORDER); + proto_tree_add_item(chunk_tree, hf_sack_chunk_number_of_gap_blocks, chunk_tvb, SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_OFFSET, SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_LENGTH, NETWORK_BYTE_ORDER); + proto_tree_add_item(chunk_tree, hf_sack_chunk_number_of_dup_tsns, chunk_tvb, SACK_CHUNK_NUMBER_OF_DUP_TSNS_OFFSET, SACK_CHUNK_NUMBER_OF_DUP_TSNS_LENGTH, NETWORK_BYTE_ORDER); + + /* handle the gap acknowledgement blocks */ + number_of_gap_blocks = tvb_get_ntohs(chunk_tvb, SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_OFFSET); + gap_block_offset = SACK_CHUNK_GAP_BLOCK_OFFSET; + cum_tsn_ack = tvb_get_ntohl(chunk_tvb, SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET); + + acks_tree = proto_item_add_subtree(ctsa_item,ett_sctp_ack); + ack_tsns_upto_ctsn(pinfo, chunk_tvb, acks_tree, assoc, cum_tsn_ack); + + + for(gap_block_number = 1; gap_block_number <= number_of_gap_blocks; gap_block_number++) { + start = tvb_get_ntohs(chunk_tvb, gap_block_offset); + end = tvb_get_ntohs(chunk_tvb, gap_block_offset + SACK_CHUNK_GAP_BLOCK_START_LENGTH); + block_item = proto_tree_add_text(chunk_tree, chunk_tvb, gap_block_offset, SACK_CHUNK_GAP_BLOCK_LENGTH, "Gap Acknowledgement for TSN %u to %u", cum_tsn_ack + start, cum_tsn_ack + end); + block_tree = proto_item_add_subtree(block_item, ett_sctp_sack_chunk_gap_block); + proto_tree_add_item(block_tree, hf_sack_chunk_gap_block_start, chunk_tvb, gap_block_offset, SACK_CHUNK_GAP_BLOCK_START_LENGTH, NETWORK_BYTE_ORDER); + proto_tree_add_item(block_tree, hf_sack_chunk_gap_block_end, chunk_tvb, gap_block_offset + SACK_CHUNK_GAP_BLOCK_START_LENGTH, SACK_CHUNK_GAP_BLOCK_END_LENGTH, NETWORK_BYTE_ORDER); + + ack_tsn_gap_block(pinfo, block_tree, chunk_tvb, assoc, cum_tsn_ack + start, cum_tsn_ack + end); + + gap_block_offset += SACK_CHUNK_GAP_BLOCK_LENGTH; + } + + /* handle the duplicate TSNs */ + number_of_dup_tsns = tvb_get_ntohs(chunk_tvb, SACK_CHUNK_NUMBER_OF_DUP_TSNS_OFFSET); + dup_tsn_offset = SACK_CHUNK_GAP_BLOCK_OFFSET + number_of_gap_blocks * SACK_CHUNK_GAP_BLOCK_LENGTH; + for(dup_tsn_number = 1; dup_tsn_number <= number_of_dup_tsns; dup_tsn_number++) { + proto_tree_add_item(chunk_tree, hf_sack_chunk_duplicate_tsn, chunk_tvb, dup_tsn_offset, SACK_CHUNK_DUP_TSN_LENGTH, NETWORK_BYTE_ORDER); + dup_tsn_offset += SACK_CHUNK_DUP_TSN_LENGTH; + } + + proto_item_append_text(chunk_item, " (Cumulative TSN: %u, a_rwnd: %u, gaps: %u, duplicate TSNs: %u)", + tvb_get_ntohl(chunk_tvb, SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET), + tvb_get_ntohl(chunk_tvb, SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET), + number_of_gap_blocks, number_of_dup_tsns); } #define HEARTBEAT_CHUNK_INFO_OFFSET CHUNK_VALUE_OFFSET @@ -2793,7 +3181,12 @@ static const true_false_string sctp_chunk_bit_2_value = { static gboolean -dissect_sctp_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree, proto_tree *sctp_tree, gboolean useinfo) +dissect_sctp_chunk(tvbuff_t *chunk_tvb, + packet_info *pinfo, + proto_tree *tree, + proto_tree *sctp_tree, + sctp_assoc_t* assoc, + gboolean useinfo) { guint8 type, flags; guint16 length, padding_length; @@ -2855,7 +3248,7 @@ dissect_sctp_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree, pr /* now dissect the chunk value */ switch(type) { case SCTP_DATA_CHUNK_ID: - result = dissect_data_chunk(chunk_tvb, length, pinfo, tree, chunk_tree, chunk_item, flags_item); + result = dissect_data_chunk(chunk_tvb, length, pinfo, tree, chunk_tree, chunk_item, flags_item, assoc); break; case SCTP_INIT_CHUNK_ID: dissect_init_chunk(chunk_tvb, length, pinfo, chunk_tree, chunk_item); @@ -2864,7 +3257,7 @@ dissect_sctp_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree, pr dissect_init_ack_chunk(chunk_tvb, length, pinfo, chunk_tree, chunk_item); break; case SCTP_SACK_CHUNK_ID: - dissect_sack_chunk(chunk_tvb, chunk_tree, chunk_item, flags_item); + dissect_sack_chunk(pinfo, chunk_tvb, chunk_tree, chunk_item, flags_item, assoc); break; case SCTP_HEARTBEAT_CHUNK_ID: dissect_heartbeat_chunk(chunk_tvb, length, pinfo, chunk_tree, chunk_item); @@ -2934,7 +3327,13 @@ dissect_sctp_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree, pr } static void -dissect_sctp_chunks(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *sctp_item, proto_tree *sctp_tree, gboolean encapsulated) +dissect_sctp_chunks(tvbuff_t *tvb, + packet_info *pinfo, + proto_tree *tree, + proto_item *sctp_item, + proto_tree *sctp_tree, + sctp_assoc_t* assoc, + gboolean encapsulated) { tvbuff_t *chunk_tvb; guint16 length, total_length, remaining_length; @@ -2964,7 +3363,7 @@ dissect_sctp_chunks(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_i } /* call dissect_sctp_chunk for the actual work */ - if (dissect_sctp_chunk(chunk_tvb, pinfo, tree, sctp_tree, !encapsulated) && (tree)) { + if (dissect_sctp_chunk(chunk_tvb, pinfo, tree, sctp_tree, assoc, !encapsulated) && (tree)) { proto_item_set_len(sctp_item, offset - last_offset + DATA_CHUNK_HEADER_LENGTH); sctp_item_length_set = TRUE; offset += total_length; @@ -2993,7 +3392,9 @@ dissect_sctp_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolea gboolean crc32c_correct = FALSE, adler32_correct = FALSE; proto_item *sctp_item; proto_tree *sctp_tree; - + guint32 vtag; + sctp_assoc_t* assoc = NULL; + length = tvb_length(tvb); checksum = tvb_get_ntohl(tvb, CHECKSUM_OFFSET); sctp_info.checksum_zero = (checksum == 0); @@ -3027,9 +3428,26 @@ dissect_sctp_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolea /* In the interest of speed, if "tree" is NULL, don't do any work not necessary to generate protocol tree items. */ + source_port = tvb_get_ntohs(tvb, SOURCE_PORT_OFFSET); + destination_port = tvb_get_ntohs(tvb, DESTINATION_PORT_OFFSET); + vtag = tvb_get_ntohl(tvb,VERIFICATION_TAG_OFFSET); + + assoc = get_assoc(source_port, destination_port, vtag); + + if (!assoc) { + proto_tree_add_text(tree,tvb,0,0,"No assoc: spt=%d dpt=%d vtag=%x",source_port, destination_port, vtag) ; + return; + } else { + char* dir = "down"; + + if (assoc->current_dir == &(assoc->up)) { + dir = "up"; + } + + proto_tree_add_text(tree,tvb,0,0,"assoc: pl=%d p=%p dir=%s",assoc->port_label,assoc,dir) ; + } + if (tree) { - source_port = tvb_get_ntohs(tvb, SOURCE_PORT_OFFSET); - destination_port = tvb_get_ntohs(tvb, DESTINATION_PORT_OFFSET); /* create the sctp protocol tree */ if (show_port_numbers) @@ -3047,7 +3465,7 @@ dissect_sctp_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolea proto_tree_add_item(sctp_tree, hf_verification_tag, tvb, VERIFICATION_TAG_OFFSET, VERIFICATION_TAG_LENGTH, NETWORK_BYTE_ORDER); proto_tree_add_item_hidden(sctp_tree, hf_port, tvb, SOURCE_PORT_OFFSET, SOURCE_PORT_LENGTH, NETWORK_BYTE_ORDER); proto_tree_add_item_hidden(sctp_tree, hf_port, tvb, DESTINATION_PORT_OFFSET, DESTINATION_PORT_LENGTH, NETWORK_BYTE_ORDER); - + length = tvb_length(tvb); checksum = tvb_get_ntohl(tvb, CHECKSUM_OFFSET); switch(sctp_checksum) { @@ -3094,7 +3512,7 @@ dissect_sctp_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolea sctp_item = NULL; }; /* add all chunks of the sctp datagram to the protocol tree */ - dissect_sctp_chunks(tvb, pinfo, tree, sctp_item, sctp_tree, encapsulated); + dissect_sctp_chunks(tvb, pinfo, tree, sctp_item, sctp_tree, assoc, encapsulated); } static void @@ -3246,6 +3664,11 @@ proto_register_sctp(void) { &hf_sctp_fragments, { "Reassembled SCTP Fragments", "sctp.fragments", FT_NONE, BASE_NONE, NULL, 0x0,NULL, HFILL }}, { &hf_sctp_reassembled_in, { "Reassembled Message in frame", "sctp.reassembled_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0, NULL, HFILL }}, { &hf_sctp_duplicate, { "Fragment already seen in frame", "sctp.duplicate", FT_FRAMENUM, BASE_NONE, NULL, 0x0, NULL, HFILL }}, + + { &hf_sctp_rtt, { "The RTT to ACK the chunk was", "sctp.rtt", FT_RELATIVE_TIME, BASE_DEC, NULL, 0x0, "", HFILL } }, + { &hf_sctp_acked, { "This chunk is acked in frame", "sctp.acked", FT_FRAMENUM, BASE_NONE, NULL, 0x0, NULL, HFILL } }, + { &hf_sctp_ack, { "Acknowledges the chunk in frame", "sctp.ack", FT_FRAMENUM, BASE_NONE, NULL, 0x0, NULL, HFILL } }, + }; /* Setup protocol subtree array */ @@ -3264,7 +3687,10 @@ proto_register_sctp(void) &ett_sctp_sack_chunk_gap_block, &ett_sctp_unrecognized_parameter_parameter, &ett_sctp_fragments, - &ett_sctp_fragment + &ett_sctp_fragment, + &ett_sctp_ack, + &ett_sctp_acked, + &ett_sctp_tsn }; static enum_val_t sctp_checksum_options[] = { @@ -3282,6 +3708,11 @@ proto_register_sctp(void) "Show port numbers in the protocol tree", "Show source and destination port numbers in the protocol tree", &show_port_numbers); + prefs_register_bool_preference(sctp_module, "tsn_analysis", + "Enable TSN analysis", + "Match TSNs and their SACKs", + &enable_tsn_analysis); + /* FIXME prefs_register_bool_preference(sctp_module, "show_chunk_types_in_tree", "Show chunk types in the protocol tree", @@ -3316,6 +3747,9 @@ proto_register_sctp(void) register_heur_dissector_list("sctp", &sctp_heur_subdissector_list); register_init_routine(frag_table_init); + + assocs_by_ptvtag = se_tree_create(EMEM_TREE_TYPE_RED_BLACK, "sctp_assocs_by_ptvtag"); + assocs_by_portlabel = se_tree_create(EMEM_TREE_TYPE_RED_BLACK, "sctp_assocs_by_portlabel"); } void |