aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-l2tp.c
diff options
context:
space:
mode:
authorMichael Mann <mmann78@netscape.net>2015-04-02 23:11:51 -0400
committerAnders Broman <a.broman58@gmail.com>2015-06-25 16:42:28 +0000
commit74e526f1965d8bfd573105e06986e41e97c1d781 (patch)
tree8e77b744f290ee1eabb56ce7fed1e8e826c22b31 /epan/dissectors/packet-l2tp.c
parentacc581081e84c93e878a678fbb3655aba253607a (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.c143
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);
}
/*