From d09ffee44e0926d99318d52a775e4bcb3f9a73f4 Mon Sep 17 00:00:00 2001 From: Pascal Quantin Date: Tue, 18 Jun 2013 23:01:46 +0000 Subject: Add ability to export decrypted IPsec PDUs svn path=/trunk/; revision=50022 --- epan/dissectors/packet-exported_pdu.c | 5 +- epan/dissectors/packet-ipsec.c | 111 ++++++++++++++++++++++++---------- epan/exported_pdu.h | 4 +- 3 files changed, 83 insertions(+), 37 deletions(-) (limited to 'epan') diff --git a/epan/dissectors/packet-exported_pdu.c b/epan/dissectors/packet-exported_pdu.c index fd6a000147..6c73f6fa3a 100644 --- a/epan/dissectors/packet-exported_pdu.c +++ b/epan/dissectors/packet-exported_pdu.c @@ -33,8 +33,6 @@ void proto_reg_handoff_exported_pdu(void); -static gint exported_pdu_tap = -1; - static int proto_exported_pdu = -1; static int hf_exported_pdu_tag = -1; static int hf_exported_pdu_tag_len = -1; @@ -299,7 +297,8 @@ proto_register_exported_pdu(void) * The tap is registered here but it is to be used by dissectors that * want to export their PDU:s, see packet-sip.c */ - exported_pdu_tap = register_tap(EXPORT_PDU_TAP_NAME_LAYER_7); + register_tap(EXPORT_PDU_TAP_NAME_LAYER_3); + register_tap(EXPORT_PDU_TAP_NAME_LAYER_7); } diff --git a/epan/dissectors/packet-ipsec.c b/epan/dissectors/packet-ipsec.c index 37fc7393b4..7016f24299 100644 --- a/epan/dissectors/packet-ipsec.c +++ b/epan/dissectors/packet-ipsec.c @@ -82,6 +82,8 @@ ADD: Additional generic (non-checked) ICV length of 128, 192 and 256. #include #include #include +#include +#include #include @@ -113,6 +115,8 @@ static gint ett_esp = -1; static gint ett_esp_icv = -1; static gint ett_ipcomp = -1; +static gint exported_pdu_tap = -1; + static dissector_handle_t data_handle; static dissector_table_t ip_dissector_table; @@ -853,6 +857,23 @@ get_esp_sa(gint protocol_typ, gchar *src, gchar *dst, gint spi, } #endif +static void +export_ipsec_pdu(dissector_handle_t dissector_handle, packet_info *pinfo, tvbuff_t *tvb) +{ + if (have_tap_listener(exported_pdu_tap)) { + exp_pdu_data_t *exp_pdu_data; + + exp_pdu_data = load_export_pdu_tags(pinfo, dissector_handle_get_dissector_name(dissector_handle), -1, + (EXP_PDU_TAG_IP_SRC_BIT | EXP_PDU_TAG_IP_DST_BIT | EXP_PDU_TAG_SRC_PORT_BIT | + EXP_PDU_TAG_DST_PORT_BIT | EXP_PDU_TAG_ORIG_FNO_BIT)); + + exp_pdu_data->tvb_length = tvb_length(tvb); + exp_pdu_data->pdu_tvb = tvb; + + tap_queue_packet(exported_pdu_tap, pinfo, exp_pdu_data); + } +} + static void dissect_ah(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { @@ -860,6 +881,8 @@ dissect_ah(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) guint8 nxt; tvbuff_t *next_tvb; int advance; + dissector_handle_t dissector_handle; + guint32 saved_match_uint; advance = dissect_ah_header(tvb, pinfo, tree, &nxt, &next_tree); next_tvb = tvb_new_subset_remaining(tvb, advance); @@ -869,9 +892,16 @@ dissect_ah(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) } /* do lookup with the subdissector table */ - if (!dissector_try_uint(ip_dissector_table, nxt, next_tvb, pinfo, tree)) { - call_dissector(data_handle,next_tvb, pinfo, next_tree); + saved_match_uint = pinfo->match_uint; + dissector_handle = dissector_get_uint_handle(ip_dissector_table, nxt); + if (dissector_handle) { + pinfo->match_uint = nxt; + } else { + dissector_handle = data_handle; } + export_ipsec_pdu(dissector_handle, pinfo, next_tvb); + call_dissector(dissector_handle, next_tvb, pinfo, next_tree); + pinfo->match_uint = saved_match_uint; } int @@ -1029,6 +1059,9 @@ dissect_esp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) guint encapsulated_protocol = 0; gboolean decrypt_dissect_ok = FALSE; + tvbuff_t *next_tvb; + dissector_handle_t dissector_handle; + guint32 saved_match_uint; #ifdef HAVE_LIBGCRYPT gboolean get_address_ok = FALSE; @@ -1793,15 +1826,17 @@ dissect_esp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) /* Get the encapsulated protocol */ encapsulated_protocol = tvb_get_guint8(tvb_decrypted, decrypted_len - esp_iv_len - esp_auth_len - 1); - if(dissector_try_uint(ip_dissector_table, - encapsulated_protocol, - tvb_new_subset(tvb_decrypted, 0, - decrypted_len - esp_auth_len - esp_pad_len - esp_iv_len - 2, - decrypted_len - esp_auth_len - esp_pad_len - esp_iv_len - 2), - pinfo, - tree)) - { - decrypt_dissect_ok = TRUE; + dissector_handle = dissector_get_uint_handle(ip_dissector_table, encapsulated_protocol); + if (dissector_handle) { + saved_match_uint = pinfo->match_uint; + pinfo->match_uint = encapsulated_protocol; + next_tvb = tvb_new_subset(tvb_decrypted, 0, + decrypted_len - esp_auth_len - esp_pad_len - esp_iv_len - 2, + decrypted_len - esp_auth_len - esp_pad_len - esp_iv_len - 2); + export_ipsec_pdu(dissector_handle, pinfo, next_tvb); + call_dissector(dissector_handle, next_tvb, pinfo, tree); + pinfo->match_uint = saved_match_uint; + decrypt_dissect_ok = TRUE; } } } @@ -1838,11 +1873,11 @@ dissect_esp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) } else { - call_dissector(data_handle, - tvb_new_subset(tvb_decrypted, 0, + next_tvb = tvb_new_subset(tvb_decrypted, 0, decrypted_len - esp_iv_len - esp_auth_len, - decrypted_len - esp_iv_len - esp_auth_len), - pinfo, esp_tree); + decrypted_len - esp_iv_len - esp_auth_len); + export_ipsec_pdu(data_handle, pinfo, next_tvb); + call_dissector(data_handle, next_tvb, pinfo, esp_tree); if(esp_tree) dissect_esp_authentication(esp_tree, @@ -1872,9 +1907,9 @@ dissect_esp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) */ if(!g_esp_enable_encryption_decode && g_esp_enable_authentication_check && sad_is_present) { - call_dissector(data_handle, - tvb_new_subset(tvb, (int)sizeof(struct newesp), len - (int)sizeof(struct newesp) - esp_auth_len, -1), - pinfo, esp_tree); + next_tvb = tvb_new_subset(tvb, (int)sizeof(struct newesp), len - (int)sizeof(struct newesp) - esp_auth_len, -1); + export_ipsec_pdu(data_handle, pinfo, next_tvb); + call_dissector(data_handle, next_tvb, pinfo, esp_tree); if(esp_tree) dissect_esp_authentication(esp_tree, tvb, len , @@ -1898,16 +1933,16 @@ dissect_esp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { esp_pad_len = tvb_get_guint8(tvb, len - 14); encapsulated_protocol = tvb_get_guint8(tvb, len - 13); - if(dissector_try_uint(ip_dissector_table, - encapsulated_protocol, - tvb_new_subset(tvb, - (int)sizeof(struct newesp), - -1, - len - (int)sizeof(struct newesp) - 14 - esp_pad_len), - pinfo, - tree)) - { - decrypt_dissect_ok = TRUE; + dissector_handle = dissector_get_uint_handle(ip_dissector_table, encapsulated_protocol); + if (dissector_handle) { + saved_match_uint = pinfo->match_uint; + pinfo->match_uint = encapsulated_protocol; + next_tvb = tvb_new_subset(tvb, (int)sizeof(struct newesp), -1, + len - (int)sizeof(struct newesp) - 14 - esp_pad_len); + export_ipsec_pdu(dissector_handle, pinfo, next_tvb); + call_dissector(dissector_handle, next_tvb, pinfo, tree); + pinfo->match_uint = saved_match_uint; + decrypt_dissect_ok = TRUE; } } } @@ -1952,6 +1987,8 @@ dissect_ipcomp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) proto_item *ti; struct ipcomp ipcomp; const char *p; + dissector_handle_t dissector_handle; + guint32 saved_match_uint; /* * load the top pane info. This should be overwritten by @@ -1991,6 +2028,7 @@ dissect_ipcomp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) g_ntohs(ipcomp.comp_cpi)); data = tvb_new_subset_remaining(tvb, sizeof(struct ipcomp)); + export_ipsec_pdu(data_handle, pinfo, data); call_dissector(data_handle, data, pinfo, ipcomp_tree); /* @@ -2001,8 +2039,16 @@ dissect_ipcomp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) decomp = tvb_child_uncompress(data, data, 0, tvb_length(data)); if (decomp) { add_new_data_source(pinfo, decomp, "IPcomp inflated data"); - if (!dissector_try_uint(ip_dissector_table, ipcomp.comp_nxt, decomp, pinfo, tree)) - call_dissector(data_handle, decomp, pinfo, tree); + saved_match_uint = pinfo->match_uint; + dissector_handle = dissector_get_uint_handle(ip_dissector_table, ipcomp.comp_nxt); + if (dissector_handle) { + pinfo->match_uint = ipcomp.comp_nxt; + } else { + dissector_handle = data_handle; + } + export_ipsec_pdu(dissector_handle, pinfo, decomp); + call_dissector(dissector_handle, decomp, pinfo, tree); + pinfo->match_uint = saved_match_uint; } } } @@ -2199,7 +2245,6 @@ proto_reg_handoff_ipsec(void) dissector_add_uint("ip.proto", IP_PROTO_IPCOMP, ipcomp_handle); ip_dissector_table = find_dissector_table("ip.proto"); -} - - + exported_pdu_tap = find_tap_id(EXPORT_PDU_TAP_NAME_LAYER_3); +} diff --git a/epan/exported_pdu.h b/epan/exported_pdu.h index 2d5465419c..c6399da35e 100644 --- a/epan/exported_pdu.h +++ b/epan/exported_pdu.h @@ -34,7 +34,9 @@ * NOTE if a new tap is added here it needs to be added to export_pdu_dlg.c and packet-exported_pdu.c * TODO: Use an enum_val_t instead? */ -#define EXPORT_PDU_TAP_NAME_LAYER_7 "export_pdu_layer_7_tap" +#define EXPORT_PDU_TAP_NAME_LAYER_3 "OSI layer 3" +#define EXPORT_PDU_TAP_NAME_LAYER_7 "OSI layer 7" + /** * This struct is used as the data part of tap_queue_packet() and contains a * buffer with metadata of the protocol PDU included in the tvb in the struct. -- cgit v1.2.3