From 0501699a4e338948e6dec36915274402a9553808 Mon Sep 17 00:00:00 2001 From: Jakub Zawadzki Date: Sun, 12 Mar 2017 09:23:17 +0100 Subject: [PATCH] sharkd: fix tap memleaks & support for links to frame, url & cleanup Change-Id: I08af04c7882802035344d0051055be05967fb089 Reviewed-on: https://code.wireshark.org/review/20502 Petri-Dish: Jakub Zawadzki Tested-by: Petri Dish Buildbot Reviewed-by: Michael Mann --- sharkd_session.c | 98 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 73 insertions(+), 25 deletions(-) diff --git a/sharkd_session.c b/sharkd_session.c index 3719f6337f..a56b542f95 100644 --- a/sharkd_session.c +++ b/sharkd_session.c @@ -67,12 +67,6 @@ #include "sharkd.h" -static struct register_ct * -_get_conversation_table_by_name(const char *name) -{ - return get_conversation_by_proto_id(proto_get_id_by_short_name(name)); -} - static void json_unescape_str(char *input) { @@ -684,7 +678,7 @@ sharkd_session_process_tap_stats_node_cb(const stat_node *n) static void sharkd_session_process_tap_stats_cb(void *psp) { - stats_tree *st = (stats_tree *)psp; + stats_tree *st = (stats_tree *) psp; printf("{\"tap\":\"stats:%s\",\"type\":\"stats\"", st->cfg->abbr); @@ -693,6 +687,14 @@ sharkd_session_process_tap_stats_cb(void *psp) printf("},"); } +static void +sharkd_session_free_tap_stats_cb(void *psp) +{ + stats_tree *st = (stats_tree *) psp; + + stats_tree_free(st); +} + struct sharkd_conv_tap_data { const char *type; @@ -819,8 +821,9 @@ sharkd_session_geoip_addr(address *addr, const char *suffix) } } } -#endif -#endif +#endif /* HAVE_GEOIP_V6 */ +#endif /* HAVE_GEOIP */ + return with_geoip; } @@ -977,6 +980,24 @@ sharkd_session_process_tap_conv_cb(void *arg) printf("],\"proto\":\"%s\",\"geoip\":%s},", proto, with_geoip ? "true" : "false"); } +static void +sharkd_session_free_tap_conv_cb(void *arg) +{ + conv_hash_t *hash = (conv_hash_t *) arg; + struct sharkd_conv_tap_data *iu = (struct sharkd_conv_tap_data *) hash->user_data; + + if (!strncmp(iu->type, "conv:", 5)) + { + reset_conversation_table_data(hash); + } + else if (!strncmp(iu->type, "endpt:", 6)) + { + reset_hostlist_table_data(hash); + } + + g_free(iu); +} + struct sharkd_export_object_list { struct sharkd_export_object_list *next; @@ -1177,6 +1198,7 @@ static void sharkd_session_process_tap(char *buf, const jsmntok_t *tokens, int count) { void *taps_data[16]; + GFreeFunc taps_free[16]; int taps_count = 0; int i; @@ -1188,13 +1210,11 @@ sharkd_session_process_tap(char *buf, const jsmntok_t *tokens, int count) char tapbuf[32]; const char *tok_tap; - tap_packet_cb tap_func = NULL; void *tap_data = NULL; + GFreeFunc tap_free = NULL; const char *tap_filter = ""; GString *tap_error = NULL; - taps_data[i] = NULL; - ws_snprintf(tapbuf, sizeof(tapbuf), "tap%d", i); tok_tap = json_find_attr(buf, tokens, count, tapbuf); if (!tok_tap) @@ -1215,20 +1235,22 @@ sharkd_session_process_tap(char *buf, const jsmntok_t *tokens, int count) tap_error = register_tap_listener(st->cfg->tapname, st, st->filter, st->cfg->flags, stats_tree_reset, stats_tree_packet, sharkd_session_process_tap_stats_cb); - tap_data = st; - if (!tap_error && cfg->init) cfg->init(st); + + tap_data = st; + tap_free = sharkd_session_free_tap_stats_cb; } else if (!strncmp(tok_tap, "conv:", 5) || !strncmp(tok_tap, "endpt:", 6)) { struct register_ct *ct = NULL; const char *ct_tapname; struct sharkd_conv_tap_data *ct_data; + tap_packet_cb tap_func = NULL; if (!strncmp(tok_tap, "conv:", 5)) { - ct = _get_conversation_table_by_name(tok_tap + 5); + ct = get_conversation_by_proto_id(proto_get_id_by_short_name(tok_tap + 5)); if (!ct || !(tap_func = get_conversation_packet_func(ct))) { @@ -1238,11 +1260,11 @@ sharkd_session_process_tap(char *buf, const jsmntok_t *tokens, int count) } else if (!strncmp(tok_tap, "endpt:", 6)) { - ct = _get_conversation_table_by_name(tok_tap + 6); + ct = get_conversation_by_proto_id(proto_get_id_by_short_name(tok_tap + 6)); if (!ct || !(tap_func = get_hostlist_packet_func(ct))) { - fprintf(stderr, "sharkd_session_process_tap() endpt %s not found\n", tok_tap + 5); + fprintf(stderr, "sharkd_session_process_tap() endpt %s not found\n", tok_tap + 6); continue; } } @@ -1265,6 +1287,7 @@ sharkd_session_process_tap(char *buf, const jsmntok_t *tokens, int count) tap_error = register_tap_listener(ct_tapname, &ct_data->hash, tap_filter, 0, NULL, tap_func, sharkd_session_process_tap_conv_cb); tap_data = &ct_data->hash; + tap_free = sharkd_session_free_tap_conv_cb; } else if (!strncmp(tok_tap, "eo:", 3)) { @@ -1306,12 +1329,14 @@ sharkd_session_process_tap(char *buf, const jsmntok_t *tokens, int count) tap_error = register_tap_listener(get_eo_tap_listener_name(eo), eo_object, NULL, 0, NULL, get_eo_packet_func(eo), sharkd_session_process_tap_eo_cb); tap_data = eo_object; + tap_free = g_free; /* need to free only eo_object, object_list need to be kept for potential download */ } else if (!strcmp(tok_tap, "rtp-streams")) { tap_error = register_tap_listener("rtp", &rtp_tapinfo, tap_filter, 0, rtpstream_reset_cb, rtpstream_packet, sharkd_session_process_tap_rtp_cb); tap_data = &rtp_tapinfo; + tap_free = rtpstream_reset_cb; } else { @@ -1321,13 +1346,15 @@ sharkd_session_process_tap(char *buf, const jsmntok_t *tokens, int count) if (tap_error) { - /* XXX, tap data memleaks */ fprintf(stderr, "sharkd_session_process_tap() name=%s error=%s", tok_tap, tap_error->str); g_string_free(tap_error, TRUE); + if (tap_free) + tap_free(tap_data); continue; } - taps_data[i] = tap_data; + taps_data[taps_count] = tap_data; + taps_free[taps_count] = tap_free; taps_count++; } @@ -1339,12 +1366,13 @@ sharkd_session_process_tap(char *buf, const jsmntok_t *tokens, int count) sharkd_retap(); printf("null],\"err\":0}\n"); - for (i = 0; i < 16; i++) + for (i = 0; i < taps_count; i++) { if (taps_data[i]) remove_tap_listener(taps_data[i]); - /* XXX, taps data memleaks */ + if (taps_free[i]) + taps_free[i](taps_data[i]); } } @@ -1526,8 +1554,26 @@ sharkd_session_process_frame_cb_tree(proto_tree *tree, tvbuff_t **tvbs) if (finfo->appendix_start >= 0 && finfo->appendix_length > 0) printf(",\"i\":[%u,%u]", finfo->appendix_start, finfo->appendix_length); - if (finfo->hfinfo && finfo->hfinfo->type == FT_PROTOCOL) - printf(",\"t\":\"proto\""); + + if (finfo->hfinfo) + { + if (finfo->hfinfo->type == FT_PROTOCOL) + { + printf(",\"t\":\"proto\""); + } + else if (finfo->hfinfo->type == FT_FRAMENUM) + { + printf(",\"t\":\"framenum\",\"fnum\":%u", finfo->value.value.uinteger); + } + else if (FI_GET_FLAG(finfo, FI_URL) && IS_FT_STRING(finfo->hfinfo->type)) + { + char *url = fvalue_to_string_repr(NULL, &finfo->value, FTREPR_DISPLAY, finfo->hfinfo->display); + + printf(",\"t\":\"url\",\"url\":"); + json_puts_string(url); + wmem_free(NULL, url); + } + } if (FI_GET_FLAG(finfo, PI_SEVERITY_MASK)) { @@ -1810,7 +1856,7 @@ sharkd_session_process_intervals(char *buf, const jsmntok_t *tokens, int count) if (filter_data && !(filter_data[framenum / 8] & (1 << (framenum % 8)))) continue; - msec_rel = (fdata->abs_ts.secs - start_ts->secs) * 1000 + (fdata->abs_ts.nsecs - start_ts->nsecs) / 1000000; + msec_rel = (fdata->abs_ts.secs - start_ts->secs) * (gint64) 1000 + (fdata->abs_ts.nsecs - start_ts->nsecs) / 1000000; new_idx = msec_rel / interval_ms; if (idx != new_idx) @@ -1860,7 +1906,7 @@ sharkd_session_process_intervals(char *buf, const jsmntok_t *tokens, int count) * (m) err - 0 if succeed * (o) tree - array of frame nodes with attributes: * l - label - * t: 'proto' + * t: 'proto', 'framenum', 'url' - type of node * s - severity * e - subtree ett index * n - array of subtree nodes @@ -1868,6 +1914,8 @@ sharkd_session_process_intervals(char *buf, const jsmntok_t *tokens, int count) * i - two item array: (appendix start, appendix length) * p - [RESERVED] two item array: (protocol start, protocol length) * ds- data src index + * url - only for t:'url', url + * fnum - only for t:'framenum', frame number * * (o) col - array of column data * (o) bytes - base64 of frame bytes