diff options
author | Guy Harris <guy@alum.mit.edu> | 2009-01-13 06:54:06 +0000 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2009-01-13 06:54:06 +0000 |
commit | a2f9627d095350be7bb94d7bad7b84fc85c01ada (patch) | |
tree | 696137ebd44ff9a5607601fdcdb813f8e14a0a99 | |
parent | 144f4d7c0a511cceb58cf0471b9d392182ac097b (diff) |
Fix the URL for the RLM stuff at Cisco.
Add some heuristics to the RLM LAPD-over-UDP dissector, so as not to
misdissect as many packets.
Fetch the LAPD dissector handle only once.
Change some Boolean arguments to gboolean from int.
svn path=/trunk/; revision=27217
-rw-r--r-- | epan/libwireshark.def | 1 | ||||
-rw-r--r-- | epan/xdlc.c | 70 | ||||
-rw-r--r-- | epan/xdlc.h | 14 | ||||
-rw-r--r-- | plugins/rlm/packet-rlm.c | 24 |
4 files changed, 98 insertions, 11 deletions
diff --git a/epan/libwireshark.def b/epan/libwireshark.def index d7142a863d..d25f71a3d3 100644 --- a/epan/libwireshark.def +++ b/epan/libwireshark.def @@ -65,6 +65,7 @@ capture_sll capture_tr capture_wlancap check_col +check_xdlc_control circuit_add_proto_data circuit_get_proto_data circuit_new diff --git a/epan/xdlc.c b/epan/xdlc.c index 362ad16a98..7f54f0083b 100644 --- a/epan/xdlc.c +++ b/epan/xdlc.c @@ -136,7 +136,7 @@ const value_string modifier_vals_resp[] = { }; int -get_xdlc_control(const guchar *pd, int offset, int is_extended) +get_xdlc_control(const guchar *pd, int offset, gboolean is_extended) { guint16 control; @@ -170,13 +170,71 @@ get_xdlc_control(const guchar *pd, int offset, int is_extended) return control; } +/* + * Check whether the control field of the packet looks valid. + */ +gboolean +check_xdlc_control(tvbuff_t *tvb, int offset, + const value_string *u_modifier_short_vals_cmd, + const value_string *u_modifier_short_vals_resp, gboolean is_response, + gboolean is_extended _U_) +{ + guint16 control; + + if (!tvb_bytes_exist(tvb, offset, 1)) + return FALSE; /* not enough data to check */ + switch (tvb_get_guint8(tvb, offset) & 0x03) { + + case XDLC_S: + /* + * Supervisory frame. + * No fields to check for validity here. + */ + return TRUE; + + case XDLC_U: + /* + * Unnumbered frame. + * + * XXX - is this two octets, with a P/F bit, in HDLC extended + * operation? It's one octet in LLC, even though the control + * field of I and S frames is a 2-byte extended-operation field + * in LLC. Given that there are no sequence numbers in the + * control field of a U frame, there doesn't appear to be any + * need for it to be 2 bytes in extended operation. + */ + if (u_modifier_short_vals_cmd == NULL) + u_modifier_short_vals_cmd = modifier_short_vals_cmd; + if (u_modifier_short_vals_resp == NULL) + u_modifier_short_vals_resp = modifier_short_vals_resp; + control = tvb_get_guint8(tvb, offset); + if (is_response) { + if (match_strval(control & XDLC_U_MODIFIER_MASK, + u_modifier_short_vals_resp) == NULL) + return FALSE; /* unknown modifier */ + } else { + if (match_strval(control & XDLC_U_MODIFIER_MASK, + u_modifier_short_vals_cmd) == NULL) + return FALSE; /* unknown modifier */ + } + return TRUE; + + default: + /* + * Information frame. + * No fields to check for validity here. + */ + return TRUE; + } +} + int dissect_xdlc_control(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *xdlc_tree, int hf_xdlc_control, gint ett_xdlc_control, const xdlc_cf_items *cf_items_nonext, const xdlc_cf_items *cf_items_ext, const value_string *u_modifier_short_vals_cmd, - const value_string *u_modifier_short_vals_resp, int is_response, - int is_extended, int append_info) + const value_string *u_modifier_short_vals_resp, gboolean is_response, + gboolean is_extended, gboolean append_info) { guint16 control; int control_len; @@ -192,6 +250,9 @@ dissect_xdlc_control(tvbuff_t *tvb, int offset, packet_info *pinfo, switch (tvb_get_guint8(tvb, offset) & 0x03) { case XDLC_S: + /* + * Supervisory frame. + */ if (is_extended) { control = tvb_get_letohs(tvb, offset); control_len = 2; @@ -203,9 +264,6 @@ dissect_xdlc_control(tvbuff_t *tvb, int offset, packet_info *pinfo, cf_items = cf_items_nonext; control_format = "Control field: %s (0x%02X)"; } - /* - * Supervisory frame. - */ switch (control & XDLC_S_FTYPE_MASK) { case XDLC_RR: frame_type = "RR"; diff --git a/epan/xdlc.h b/epan/xdlc.h index 0f1612cc69..d081537b1e 100644 --- a/epan/xdlc.h +++ b/epan/xdlc.h @@ -128,13 +128,21 @@ extern const value_string stype_vals[]; extern const value_string modifier_vals_cmd[]; extern const value_string modifier_vals_resp[]; -extern int get_xdlc_control(const guchar *pd, int offset, int extended); +extern int get_xdlc_control(const guchar *pd, int offset, gboolean is_extended); + +/* + * Check whether the control field of the packet looks valid. + */ +extern gboolean check_xdlc_control(tvbuff_t *tvb, int offset, + const value_string *u_modifier_short_vals_cmd, + const value_string *u_modifier_short_vals_resp, gboolean is_response, + gboolean is_extended _U_); extern int dissect_xdlc_control(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *xdlc_tree, int hf_xdlc_control, gint ett_xdlc_control, const xdlc_cf_items *cf_items_nonext, const xdlc_cf_items *cf_items_ext, const value_string *u_modifier_short_vals_cmd, - const value_string *u_modifier_short_vals_resp, int is_response, - int is_extended, int append_info); + const value_string *u_modifier_short_vals_resp, gboolean is_response, + gboolean is_extended, gboolean append_info); #endif diff --git a/plugins/rlm/packet-rlm.c b/plugins/rlm/packet-rlm.c index ce98977efa..db05bab821 100644 --- a/plugins/rlm/packet-rlm.c +++ b/plugins/rlm/packet-rlm.c @@ -28,7 +28,7 @@ * many redundant NASes. I don't know much about the format, but you * can read about the feature here: * - * http://www.cisco.com/univercd/cc/td/doc/product/software/ios120/120newft/120t/120t3/rlm_123.htm + * http://www.cisco.com/en/US/docs/ios/12_0t/12_0t3/feature/guide/rlm_123.html * * RLM runs on a UDP port (default 3000) between the MGC and the NAS. * On port N+1 (default 3001), a Q.931/LAPD/UDP connection is maintained. @@ -57,6 +57,7 @@ #include <glib.h> #include <epan/packet.h> +#include <epan/xdlc.h> /* Initialize the protocol and registered fields */ static int proto_rlm = -1; @@ -86,6 +87,7 @@ static gint ett_rlm = -1; Maybe this isn't the best place for it, but RLM goes hand in hand with Q.931 traffic on a higher port. */ +static dissector_handle_t lapd_handle; static gboolean dissect_udp_lapd(tvbuff_t *tvb, packet_info *pinfo _U_ , proto_tree *tree) { @@ -95,7 +97,20 @@ dissect_udp_lapd(tvbuff_t *tvb, packet_info *pinfo _U_ , proto_tree *tree) { || pinfo->destport != pinfo->srcport) return FALSE; - call_dissector(find_dissector("lapd"), tvb, pinfo, tree); + /* + * XXX - check for a valid LAPD address field. + */ + + /* + * OK, check whether the control field looks valid. + */ + if (!check_xdlc_control(tvb, 2, NULL, NULL, FALSE, FALSE)) + return FALSE; + + /* + * Loooks OK - call the LAPD dissector. + */ + call_dissector(lapd_handle, tvb, pinfo, tree); return TRUE; } @@ -175,6 +190,11 @@ dissect_rlm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) void proto_reg_handoff_rlm(void) { + /* + * Find a handle for the LAPD dissector. + */ + lapd_handle = find_dissector("lapd"); + heur_dissector_add("udp", dissect_rlm, proto_rlm); heur_dissector_add("udp", dissect_udp_lapd, proto_get_id_by_filter_name("lapd")); } |