diff options
author | Michael Mann <mmann78@netscape.net> | 2015-04-02 23:11:51 -0400 |
---|---|---|
committer | Anders Broman <a.broman58@gmail.com> | 2015-06-25 16:42:28 +0000 |
commit | 74e526f1965d8bfd573105e06986e41e97c1d781 (patch) | |
tree | 8e77b744f290ee1eabb56ce7fed1e8e826c22b31 /epan/dissectors/packet-l2tp.c | |
parent | acc581081e84c93e878a678fbb3655aba253607a (diff) |
Add proper "Decode As" mechanism for L2TPv3 subdissectors instead of preference.
Change-Id: I87f6f9f40e1c33148de43b53a8881d51416f5d2c
Reviewed-on: https://code.wireshark.org/review/7898
Reviewed-by: Michael Mann <mmann78@netscape.net>
Petri-Dish: Michael Mann <mmann78@netscape.net>
Reviewed-by: Anders Broman <a.broman58@gmail.com>
Diffstat (limited to 'epan/dissectors/packet-l2tp.c')
-rw-r--r-- | epan/dissectors/packet-l2tp.c | 143 |
1 files changed, 46 insertions, 97 deletions
diff --git a/epan/dissectors/packet-l2tp.c b/epan/dissectors/packet-l2tp.c index e506809315..3ec831de67 100644 --- a/epan/dissectors/packet-l2tp.c +++ b/epan/dissectors/packet-l2tp.c @@ -60,6 +60,7 @@ #include <epan/prefs.h> #include <epan/conversation.h> #include <epan/expert.h> +#include <epan/decode_as.h> #include <wsutil/md5.h> #include <wsutil/sha1.h> @@ -207,6 +208,7 @@ static int hf_l2tp_zero_length_bit_message = -1; static int hf_l2tp_offset_padding = -1; static dissector_table_t l2tp_vendor_avp_dissector_table; +static dissector_table_t pw_type_table; #define UDP_PORT_L2TP 1701 @@ -251,36 +253,8 @@ static const enum_val_t l2tpv3_cookies[] = { }; #define L2TPv3_COOKIE_DEFAULT 0 - -#define L2TPv3_PROTOCOL_ETH 0 -#define L2TPv3_PROTOCOL_CHDLC 1 -#define L2TPv3_PROTOCOL_FR 2 -#define L2TPv3_PROTOCOL_PPP 3 -#define L2TPv3_PROTOCOL_IP 4 -#define L2TPv3_PROTOCOL_MPLS 5 -#define L2TPv3_PROTOCOL_AAL5 6 -#define L2TPv3_PROTOCOL_LAPD 7 -#define L2TPv3_PROTOCOL_DOCSIS_DMPT 8 -#define L2TPv3_PROTOCOL_ERICSSON 9 -#define L2TPv3_PROTOCOL_MAX (L2TPv3_PROTOCOL_ERICSSON + 1) - #define L2TPv3_PROTOCOL_DEFAULT L2TPv3_PROTOCOL_CHDLC -static const enum_val_t l2tpv3_protocols[] = { - {"detect", "Detect", -1}, - {"eth", "Ethernet", L2TPv3_PROTOCOL_ETH}, - {"chdlc", "Cisco HDLC", L2TPv3_PROTOCOL_CHDLC}, - {"fr", "Frame Relay", L2TPv3_PROTOCOL_FR}, - {"ppp", "PPP", L2TPv3_PROTOCOL_PPP}, - {"ip", "IP", L2TPv3_PROTOCOL_IP}, - {"mpls", "MPLS", L2TPv3_PROTOCOL_MPLS}, - {"aal5", "AAL5", L2TPv3_PROTOCOL_AAL5}, - {"lapd", "LAPD", L2TPv3_PROTOCOL_LAPD}, - {"docsis-dmpt", "DOCSIS-DMPT", L2TPv3_PROTOCOL_DOCSIS_DMPT}, - {"ehdlc", "Ericsson HDLC", L2TPv3_PROTOCOL_ERICSSON}, - {NULL, NULL, 0} -}; - #define L2TPv3_L2_SPECIFIC_NONE 0 #define L2TPv3_L2_SPECIFIC_DEFAULT 1 #define L2TPv3_L2_SPECIFIC_ATM 2 @@ -299,7 +273,6 @@ static const enum_val_t l2tpv3_l2_specifics[] = { }; static gint l2tpv3_cookie = -1; -static gint l2tpv3_protocol = -1; static gint l2tpv3_l2_specific = -1; #define MESSAGE_TYPE_SCCRQ 1 @@ -770,16 +743,8 @@ static const true_false_string tfs_new_existing = { "New", "Existing" }; static dissector_handle_t ppp_hdlc_handle; static dissector_handle_t ppp_lcp_options_handle; -static dissector_handle_t eth_withoutfcs_handle; -static dissector_handle_t chdlc_handle; -static dissector_handle_t fr_handle; -static dissector_handle_t ip_handle; -static dissector_handle_t mpls_handle; static dissector_handle_t atm_oam_handle; static dissector_handle_t llc_handle; -static dissector_handle_t lapd_handle; -static dissector_handle_t mp2t_handle; -static dissector_handle_t ehdlc_handle; static dissector_handle_t data_handle; static dissector_handle_t l2tp_udp_handle; @@ -1159,7 +1124,7 @@ static l2tpv3_session_t *store_pw_type(l2tpv3_session_t *_session, int msg_type) { l2tpv3_session_t *session = _session; - gint result = l2tpv3_protocol; + gint result = -1; guint16 pw_type; switch (msg_type) { @@ -1292,6 +1257,16 @@ static void update_session(l2tpv3_tunnel_t *tunnel, l2tpv3_session_t *session) } } +static void l2tp_prompt(packet_info *pinfo _U_, gchar* result) +{ + g_snprintf(result, MAX_DECODE_AS_PROMPT_LEN, "Decode L2TPv3 packet type 0x%04x as", + GPOINTER_TO_UINT(p_get_proto_data(pinfo->pool, pinfo, proto_l2tp, 0))); +} + +static gpointer l2tp_value(packet_info *pinfo _U_) +{ + return p_get_proto_data(pinfo->pool, pinfo, proto_l2tp, 0); +} /* * Dissect CISCO AVP:s @@ -2030,13 +2005,13 @@ process_l2tpv3_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, { int idx = *pIdx; int sid; - guint8 oam_cell = 0; + guint32 oam_cell = 0; proto_tree *l2_specific = NULL; proto_item *ti = NULL; tvbuff_t *next_tvb; gint cookie_len = l2tpv3_cookie; gint l2_spec = l2tpv3_l2_specific; - gint pw_type = l2tpv3_protocol; + gint pw_type = -1; lcce_settings_t *lcce = NULL; l2tpv3_session_t *session = NULL; @@ -2162,49 +2137,11 @@ process_l2tpv3_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, break; } - switch(pw_type){ - case L2TPv3_PROTOCOL_ETH: - call_dissector(eth_withoutfcs_handle, next_tvb, pinfo, tree); - break; - case L2TPv3_PROTOCOL_CHDLC: - call_dissector(chdlc_handle, next_tvb, pinfo, tree); - break; - case L2TPv3_PROTOCOL_FR: - call_dissector(fr_handle, next_tvb, pinfo, tree); - break; - case L2TPv3_PROTOCOL_PPP: - /* - * PPP is transported without Address and Control - * fields, ppp_hdlc_handle can handle that as if if - * was ACFC (NULL Address and Control) - */ - call_dissector(ppp_hdlc_handle, next_tvb, pinfo, tree); - break; - case L2TPv3_PROTOCOL_IP: - call_dissector(ip_handle, next_tvb, pinfo, tree); - break; - case L2TPv3_PROTOCOL_MPLS: - call_dissector(mpls_handle, next_tvb, pinfo, tree); - break; - case L2TPv3_PROTOCOL_DOCSIS_DMPT: - call_dissector(mp2t_handle, next_tvb, pinfo, tree); - break; - case L2TPv3_PROTOCOL_AAL5: - if (oam_cell) { - call_dissector(atm_oam_handle, next_tvb, pinfo, tree); - } else { - call_dissector(llc_handle, next_tvb, pinfo, tree); - } - break; - case L2TPv3_PROTOCOL_LAPD: - call_dissector(lapd_handle, next_tvb, pinfo, tree); - break; - case L2TPv3_PROTOCOL_ERICSSON: - call_dissector(ehdlc_handle, next_tvb, pinfo, tree); - break; - default: + p_add_proto_data(pinfo->pool, pinfo, proto_l2tp, 0, GUINT_TO_POINTER((guint)pw_type)); + + if (!dissector_try_uint_new(pw_type_table, pw_type, next_tvb, pinfo, tree, FALSE, GUINT_TO_POINTER(oam_cell))) + { call_dissector(data_handle, next_tvb, pinfo, tree); - break; } } @@ -2709,6 +2646,19 @@ dissect_l2tp_ip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) return; } +static int dissect_atm_oam_llc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data) +{ + guint32 oam_cell = GPOINTER_TO_UINT(data); + + if (oam_cell) { + call_dissector(atm_oam_handle, tvb, pinfo, tree); + } else { + call_dissector(llc_handle, tvb, pinfo, tree); + } + + return tvb_captured_length(tvb); +} + static void init_l2tp_dissection(void) { GSList *iterator = list_heads; @@ -3039,6 +2989,12 @@ proto_register_l2tp(void) module_t *l2tp_module; expert_module_t* expert_l2tp; + /* Decode As handling */ + static build_valid_func l2tp_da_build_value[1] = {l2tp_value}; + static decode_as_value_t l2tp_da_values = {l2tp_prompt, 1, l2tp_da_build_value}; + static decode_as_t l2tp_da = {"l2tp", "L2TPv3 payload", "l2tp.pw_type", 1, 0, &l2tp_da_values, NULL, NULL, + decode_as_default_populate_list, decode_as_default_reset, decode_as_default_change, NULL}; + proto_l2tp = proto_register_protocol( "Layer 2 Tunneling Protocol", "L2TP", "l2tp"); proto_register_field_array(proto_l2tp, hf, array_length(hf)); @@ -3047,6 +3003,7 @@ proto_register_l2tp(void) expert_register_field_array(expert_l2tp, ei, array_length(ei)); l2tp_vendor_avp_dissector_table = register_dissector_table("l2tp.vendor_avp", "L2TP vendor AVP dissector table", FT_UINT32, BASE_DEC); + pw_type_table = register_dissector_table("l2tp.pw_type", "L2TPv3 payload type", FT_UINT32, BASE_DEC); l2tp_module = prefs_register_protocol(proto_l2tp, NULL); @@ -3066,24 +3023,21 @@ proto_register_l2tp(void) l2tpv3_l2_specifics, FALSE); - prefs_register_enum_preference(l2tp_module, - "protocol", - "Decode L2TPv3 packet contents as this protocol", - "Decode L2TPv3 packet contents as this protocol", - &l2tpv3_protocol, - l2tpv3_protocols, - FALSE); + prefs_register_obsolete_preference(l2tp_module, "protocol"); prefs_register_string_preference(l2tp_module,"shared_secret","Shared Secret", "Shared secret used for control message digest authentication", &shared_secret); register_init_routine(init_l2tp_dissection); + register_decode_as(&l2tp_da); } void proto_reg_handoff_l2tp(void) { + dissector_handle_t atm_oam_llc_handle; + l2tp_udp_handle = new_create_dissector_handle(dissect_l2tp_udp, proto_l2tp); dissector_add_uint("udp.port", UDP_PORT_L2TP, l2tp_udp_handle); @@ -3103,17 +3057,12 @@ proto_reg_handoff_l2tp(void) /* * Get a handle for the dissectors used in v3. */ - eth_withoutfcs_handle = find_dissector("eth_withoutfcs"); - chdlc_handle = find_dissector("chdlc"); - fr_handle = find_dissector("fr"); - ip_handle = find_dissector("ip"); - mpls_handle = find_dissector("mpls"); atm_oam_handle = find_dissector("atm_oam_cell"); llc_handle = find_dissector("llc"); - lapd_handle = find_dissector("lapd"); - mp2t_handle = find_dissector("mp2t"); - ehdlc_handle = find_dissector("ehdlc"); data_handle = find_dissector("data"); + + atm_oam_llc_handle = new_create_dissector_handle( dissect_atm_oam_llc, proto_l2tp ); + dissector_add_uint("l2tp.pw_type", L2TPv3_PROTOCOL_AAL5, atm_oam_llc_handle); } /* |