3 * Copyright (C) 2016 Jakub Zawadzki
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
22 #include <wsutil/wsjson.h>
23 #include <wsutil/ws_printf.h>
26 #include <epan/epan_dissect.h>
27 #include <epan/exceptions.h>
28 #include <epan/color_filters.h>
29 #include <epan/prefs.h>
30 #include <epan/prefs-int.h>
31 #include <epan/uat-int.h>
32 #include <wiretap/wtap.h>
34 #include <epan/column.h>
36 #include <ui/ssl_key_export.h>
38 #include <ui/io_graph_item.h>
39 #include <epan/stats_tree_priv.h>
40 #include <epan/stat_tap_ui.h>
41 #include <epan/conversation_table.h>
42 #include <epan/sequence_analysis.h>
43 #include <epan/expert.h>
44 #include <epan/export_object.h>
45 #include <epan/follow.h>
46 #include <epan/rtd_table.h>
47 #include <epan/srt_table.h>
49 #include <epan/dissectors/packet-h225.h>
50 #include <epan/rtp_pt.h>
51 #include <ui/voip_calls.h>
52 #include <ui/rtp_stream.h>
53 #include <ui/tap-rtp-common.h>
54 #include <ui/tap-rtp-analysis.h>
55 #include <epan/to_str.h>
57 #include <epan/addr_resolv.h>
58 #include <epan/dissectors/packet-rtp.h>
59 #include <ui/rtp_media.h>
61 # include <speex/speex_resampler.h>
63 # include <codecs/speex/speex_resampler.h>
64 #endif /* HAVE_SPEEXDSP */
66 #include <epan/maxmind_db.h>
68 #include <wsutil/pint.h>
69 #include <wsutil/strtoi.h>
75 struct sharkd_filter_item
77 guint8 *filtered; /* can be NULL if all frames are matching for given filter. */
80 static GHashTable *filter_table = NULL;
83 json_find_attr(const char *buf, const jsmntok_t *tokens, int count, const char *attr)
87 for (i = 0; i < count; i += 2)
89 const char *tok_attr = &buf[tokens[i + 0].start];
90 const char *tok_value = &buf[tokens[i + 1].start];
92 if (!strcmp(tok_attr, attr))
100 json_puts_string(const char *s)
102 static const char json_cntrl[0x20][6] =
104 "u0000", "u0001", "u0002", "u0003", "u0004", "u0005", "u0006", "u0007", "b", "t", "n", "u000b", "f", "r", "u000e", "u000f",
105 "u0010", "u0011", "u0012", "u0013", "u0014", "u0015", "u0016", "u0017", "u0018", "u0019", "u001a", "u001b", "u001c", "u001d", "u001e", "u001f"
108 const unsigned char *str = (const unsigned char *) s ? s : "";
112 for (i = 0; str[i]; i++)
117 fputs(json_cntrl[(guint)str[i]], stdout);
121 if (str[i] == '\\' || str[i] == '"')
131 json_print_base64_step(const guint8 *data, int *state1, int *state2)
133 gchar buf[(1 / 3 + 1) * 4 + 4 + 1];
137 wrote = g_base64_encode_step(data, 1, FALSE, buf, state1, state2);
139 wrote = g_base64_encode_close(FALSE, buf, state1, state2);
149 json_print_base64(const guint8 *data, size_t len)
152 int base64_state1 = 0;
153 int base64_state2 = 0;
157 for (i = 0; i < len; i++)
158 json_print_base64_step(&data[i], &base64_state1, &base64_state2);
160 json_print_base64_step(NULL, &base64_state1, &base64_state2);
165 static void G_GNUC_PRINTF(3, 4)
166 sharkd_json_value_anyf(gboolean sepa, const char *key, const char *valuef, ...)
179 if (valuef && *valuef)
183 va_start(ap, valuef);
190 sharkd_json_value_string(gboolean sepa, const char *key, const char *str)
192 sharkd_json_value_anyf(sepa, key, NULL);
193 json_puts_string(str);
197 sharkd_json_value_base64(gboolean sepa, const char *key, const guint8 *data, size_t len)
199 sharkd_json_value_anyf(sepa, key, NULL);
200 json_print_base64(data, len);
203 static void G_GNUC_PRINTF(3, 4)
204 sharkd_json_value_stringf(gboolean sepa, const char *key, const char *format, ...)
208 sharkd_json_value_anyf(sepa, key, NULL);
210 va_start(ap, format);
218 sharkd_json_array_open(gboolean sepa, const char *key)
220 sharkd_json_value_anyf(sepa, key, "[");
224 sharkd_json_array_close(void)
230 sharkd_json_object_open(gboolean sepa)
232 sharkd_json_value_anyf(sepa, NULL, "{");
236 sharkd_json_object_close(void)
242 sharkd_json_finish(void)
248 sharkd_json_simple_reply(int err, const char *errmsg)
250 sharkd_json_object_open(FALSE);
251 sharkd_json_value_anyf(FALSE, "err", "%d", err);
253 sharkd_json_value_string(TRUE, "errmsg", errmsg);
255 sharkd_json_object_close();
256 sharkd_json_finish();
260 sharkd_session_filter_free(gpointer data)
262 struct sharkd_filter_item *l = (struct sharkd_filter_item *) data;
268 static const struct sharkd_filter_item *
269 sharkd_session_filter_data(const char *filter)
271 struct sharkd_filter_item *l;
273 l = (struct sharkd_filter_item *) g_hash_table_lookup(filter_table, filter);
276 guint8 *filtered = NULL;
278 int ret = sharkd_filter(filter, &filtered);
283 l = (struct sharkd_filter_item *) g_malloc(sizeof(struct sharkd_filter_item));
284 l->filtered = filtered;
286 g_hash_table_insert(filter_table, g_strdup(filter), l);
293 sharkd_rtp_match_init(rtpstream_id_t *id, const char *init_str)
295 gboolean ret = FALSE;
297 guint32 tmp_addr_src, tmp_addr_dst;
298 address tmp_src_addr, tmp_dst_addr;
300 memset(id, 0, sizeof(*id));
302 arr = g_strsplit(init_str, "_", 7); /* pass larger value, so we'll catch incorrect input :) */
303 if (g_strv_length(arr) != 5)
306 /* TODO, for now only IPv4 */
307 if (!get_host_ipaddr(arr[0], &tmp_addr_src))
310 if (!ws_strtou16(arr[1], NULL, &id->src_port))
313 if (!get_host_ipaddr(arr[2], &tmp_addr_dst))
316 if (!ws_strtou16(arr[3], NULL, &id->dst_port))
319 if (!ws_hexstrtou32(arr[4], NULL, &id->ssrc))
322 set_address(&tmp_src_addr, AT_IPv4, 4, &tmp_addr_src);
323 copy_address(&id->src_addr, &tmp_src_addr);
324 set_address(&tmp_dst_addr, AT_IPv4, 4, &tmp_addr_dst);
325 copy_address(&id->dst_addr, &tmp_dst_addr);
335 sharkd_session_process_info_nstat_cb(const void *key, void *value, void *userdata)
337 stat_tap_table_ui *stat_tap = (stat_tap_table_ui *) value;
338 int *pi = (int *) userdata;
340 sharkd_json_object_open(*pi != 0);
341 sharkd_json_value_string(FALSE, "name", stat_tap->title);
342 sharkd_json_value_stringf(TRUE, "tap", "nstat:%s", (const char *) key);
343 sharkd_json_object_close();
350 sharkd_session_process_info_conv_cb(const void* key, void* value, void* userdata)
352 struct register_ct *table = (struct register_ct *) value;
353 int *pi = (int *) userdata;
355 const char *label = (const char *) key;
357 if (get_conversation_packet_func(table))
359 sharkd_json_object_open(*pi != 0);
360 sharkd_json_value_stringf(FALSE, "name", "Conversation List/%s", label);
361 sharkd_json_value_stringf(TRUE, "tap", "conv:%s", label);
362 sharkd_json_object_close();
367 if (get_hostlist_packet_func(table))
369 sharkd_json_object_open(*pi != 0);
370 sharkd_json_value_stringf(FALSE, "name", "Endpoint/%s", label);
371 sharkd_json_value_stringf(TRUE, "tap", "endpt:%s", label);
372 sharkd_json_object_close();
380 sharkd_session_seq_analysis_cb(const void *key, void *value, void *userdata)
382 register_analysis_t *analysis = (register_analysis_t *) value;
383 int *pi = (int *) userdata;
385 sharkd_json_object_open(*pi != 0);
386 sharkd_json_value_string(FALSE, "name", sequence_analysis_get_ui_name(analysis));
387 sharkd_json_value_stringf(TRUE, "tap", "seqa:%s", (const char *) key);
388 sharkd_json_object_close();
395 sharkd_export_object_visit_cb(const void *key _U_, void *value, void *user_data)
397 register_eo_t *eo = (register_eo_t *) value;
398 int *pi = (int *) user_data;
400 const int proto_id = get_eo_proto_id(eo);
401 const char *filter = proto_get_protocol_filter_name(proto_id);
402 const char *label = proto_get_protocol_short_name(find_protocol_by_id(proto_id));
404 sharkd_json_object_open(*pi != 0);
405 sharkd_json_value_stringf(FALSE, "name", "Export Object/%s", label);
406 sharkd_json_value_stringf(TRUE, "tap", "eo:%s", filter);
407 sharkd_json_object_close();
414 sharkd_srt_visit_cb(const void *key _U_, void *value, void *user_data)
416 register_srt_t *srt = (register_srt_t *) value;
417 int *pi = (int *) user_data;
419 const int proto_id = get_srt_proto_id(srt);
420 const char *filter = proto_get_protocol_filter_name(proto_id);
421 const char *label = proto_get_protocol_short_name(find_protocol_by_id(proto_id));
423 sharkd_json_object_open(*pi != 0);
424 sharkd_json_value_stringf(FALSE, "name", "Service Response Time/%s", label);
425 sharkd_json_value_stringf(TRUE, "tap", "srt:%s", filter);
426 sharkd_json_object_close();
433 sharkd_rtd_visit_cb(const void *key _U_, void *value, void *user_data)
435 register_rtd_t *rtd = (register_rtd_t *) value;
436 int *pi = (int *) user_data;
438 const int proto_id = get_rtd_proto_id(rtd);
439 const char *filter = proto_get_protocol_filter_name(proto_id);
440 const char *label = proto_get_protocol_short_name(find_protocol_by_id(proto_id));
442 sharkd_json_object_open(*pi != 0);
443 sharkd_json_value_stringf(FALSE, "name", "Response Time Delay/%s", label);
444 sharkd_json_value_stringf(TRUE, "tap", "rtd:%s", filter);
445 sharkd_json_object_close();
452 sharkd_follower_visit_cb(const void *key _U_, void *value, void *user_data)
454 register_follow_t *follower = (register_follow_t *) value;
455 int *pi = (int *) user_data;
457 const int proto_id = get_follow_proto_id(follower);
458 const char *label = proto_get_protocol_short_name(find_protocol_by_id(proto_id));
459 const char *filter = label; /* correct: get_follow_by_name() is registered by short name */
461 sharkd_json_object_open(*pi != 0);
462 sharkd_json_value_stringf(FALSE, "name", "Follow/%s", label);
463 sharkd_json_value_stringf(TRUE, "tap", "follow:%s", filter);
464 sharkd_json_object_close();
471 * sharkd_session_process_info()
473 * Process info request
475 * Output object with attributes:
476 * (m) version - version number
478 * (m) columns - available column formats, array of object with attributes:
479 * 'name' - column name
480 * 'format' - column format-name
482 * (m) stats - available statistics, array of object with attributes:
483 * 'name' - statistic name
484 * 'tap' - sharkd tap-name for statistic
486 * (m) convs - available conversation list, array of object with attributes:
487 * 'name' - conversation name
488 * 'tap' - sharkd tap-name for conversation
490 * (m) eo - available export object list, array of object with attributes:
491 * 'name' - export object name
492 * 'tap' - sharkd tap-name for eo
494 * (m) srt - available service response time list, array of object with attributes:
495 * 'name' - service response time name
496 * 'tap' - sharkd tap-name for srt
498 * (m) rtd - available response time delay list, array of object with attributes:
499 * 'name' - response time delay name
500 * 'tap' - sharkd tap-name for rtd
502 * (m) seqa - available sequence analysis (flow) list, array of object with attributes:
503 * 'name' - sequence analysis name
504 * 'tap' - sharkd tap-name
506 * (m) taps - available taps, array of object with attributes:
508 * 'tap' - sharkd tap-name
510 * (m) follow - available followers, array of object with attributes:
512 * 'tap' - sharkd tap-name
514 * (m) ftypes - conversation table for FT_ number to string, array of FT_xxx strings.
516 * (m) nstat - available table-based taps, array of object with attributes:
518 * 'tap' - sharkd tap-name
522 sharkd_session_process_info(void)
526 sharkd_json_object_open(FALSE);
528 sharkd_json_array_open(FALSE, "columns");
529 for (i = 0; i < NUM_COL_FMTS; i++)
531 const char *col_format = col_format_to_string(i);
532 const char *col_descr = col_format_desc(i);
534 sharkd_json_object_open(i != 0);
535 sharkd_json_value_string(FALSE, "name", col_descr);
536 sharkd_json_value_string(TRUE, "format", col_format);
537 sharkd_json_object_close();
539 sharkd_json_array_close();
541 sharkd_json_array_open(TRUE, "stats");
543 GList *cfg_list = stats_tree_get_cfg_list();
545 gboolean sepa = FALSE;
547 for (l = cfg_list; l; l = l->next)
549 stats_tree_cfg *cfg = (stats_tree_cfg *) l->data;
551 sharkd_json_object_open(sepa);
552 sharkd_json_value_string(FALSE, "name", cfg->name);
553 sharkd_json_value_stringf(TRUE, "tap", "stat:%s", cfg->abbr);
554 sharkd_json_object_close();
558 g_list_free(cfg_list);
560 sharkd_json_array_close();
562 sharkd_json_array_open(TRUE, "ftypes");
563 for (i = 0; i < FT_NUM_TYPES; i++)
564 sharkd_json_value_string(i != 0, NULL, ftype_name((ftenum_t) i));
565 sharkd_json_array_close();
567 sharkd_json_value_string(TRUE, "version", sharkd_version());
569 sharkd_json_array_open(TRUE, "nstat");
571 stat_tap_iterate_tables(sharkd_session_process_info_nstat_cb, &i);
572 sharkd_json_array_close();
574 sharkd_json_array_open(TRUE, "convs");
576 conversation_table_iterate_tables(sharkd_session_process_info_conv_cb, &i);
577 sharkd_json_array_close();
579 sharkd_json_array_open(TRUE, "seqa");
581 sequence_analysis_table_iterate_tables(sharkd_session_seq_analysis_cb, &i);
582 sharkd_json_array_close();
584 sharkd_json_array_open(TRUE, "taps");
586 sharkd_json_object_open(FALSE);
587 sharkd_json_value_string(FALSE, "name", "RTP streams");
588 sharkd_json_value_string(TRUE, "tap", "rtp-streams");
589 sharkd_json_object_close();
591 sharkd_json_object_open(TRUE);
592 sharkd_json_value_string(FALSE, "name", "Expert Information");
593 sharkd_json_value_string(TRUE, "tap", "expert");
594 sharkd_json_object_close();
596 sharkd_json_array_close();
598 sharkd_json_array_open(TRUE, "eo");
600 eo_iterate_tables(sharkd_export_object_visit_cb, &i);
601 sharkd_json_array_close();
603 sharkd_json_array_open(TRUE, "srt");
605 srt_table_iterate_tables(sharkd_srt_visit_cb, &i);
606 sharkd_json_array_close();
608 sharkd_json_array_open(TRUE, "rtd");
610 rtd_table_iterate_tables(sharkd_rtd_visit_cb, &i);
611 sharkd_json_array_close();
613 sharkd_json_array_open(TRUE, "follow");
615 follow_iterate_followers(sharkd_follower_visit_cb, &i);
616 sharkd_json_array_close();
618 sharkd_json_object_close();
619 sharkd_json_finish();
623 * sharkd_session_process_load()
625 * Process load request
628 * (m) file - file to be loaded
630 * Output object with attributes:
631 * (m) err - error code
634 sharkd_session_process_load(const char *buf, const jsmntok_t *tokens, int count)
636 const char *tok_file = json_find_attr(buf, tokens, count, "file");
639 fprintf(stderr, "load: filename=%s\n", tok_file);
644 if (sharkd_cf_open(tok_file, WTAP_TYPE_AUTO, FALSE, &err) != CF_OK)
646 sharkd_json_simple_reply(err, NULL);
652 err = sharkd_load_cap_file();
654 CATCH(OutOfMemoryError)
656 fprintf(stderr, "load: OutOfMemoryError\n");
661 sharkd_json_simple_reply(err, NULL);
665 * sharkd_session_process_status()
667 * Process status request
669 * Output object with attributes:
670 * (m) frames - count of currently loaded frames
671 * (m) duration - time difference between time of first frame, and last loaded frame
672 * (o) filename - capture filename
673 * (o) filesize - capture filesize
676 sharkd_session_process_status(void)
678 sharkd_json_object_open(FALSE);
680 sharkd_json_value_anyf(FALSE, "frames", "%u", cfile.count);
681 sharkd_json_value_anyf(TRUE, "duration", "%.9f", nstime_to_sec(&cfile.elapsed_time));
685 char *name = g_path_get_basename(cfile.filename);
687 sharkd_json_value_string(TRUE, "filename", name);
691 if (cfile.provider.wth)
693 gint64 file_size = wtap_file_size(cfile.provider.wth, NULL);
696 sharkd_json_value_anyf(TRUE, "filesize", "%" G_GINT64_FORMAT, file_size);
699 sharkd_json_object_close();
700 sharkd_json_finish();
703 struct sharkd_analyse_data
705 GHashTable *protocols_set;
706 nstime_t *first_time;
711 sharkd_session_process_analyse_cb(epan_dissect_t *edt, proto_tree *tree, struct epan_column_info *cinfo, const GSList *data_src, void *data)
713 struct sharkd_analyse_data *analyser = (struct sharkd_analyse_data *) data;
714 packet_info *pi = &edt->pi;
715 frame_data *fdata = pi->fd;
721 if (analyser->first_time == NULL || nstime_cmp(&fdata->abs_ts, analyser->first_time) < 0)
722 analyser->first_time = &fdata->abs_ts;
724 if (analyser->last_time == NULL || nstime_cmp(&fdata->abs_ts, analyser->last_time) > 0)
725 analyser->last_time = &fdata->abs_ts;
729 wmem_list_frame_t *frame;
731 for (frame = wmem_list_head(pi->layers); frame; frame = wmem_list_frame_next(frame))
733 int proto_id = GPOINTER_TO_UINT(wmem_list_frame_data(frame));
735 if (!g_hash_table_lookup_extended(analyser->protocols_set, GUINT_TO_POINTER(proto_id), NULL, NULL))
737 guint proto_count = g_hash_table_size(analyser->protocols_set);
739 g_hash_table_insert(analyser->protocols_set, GUINT_TO_POINTER(proto_id), GUINT_TO_POINTER(proto_id));
741 sharkd_json_value_string(proto_count != 0, NULL, proto_get_protocol_filter_name(proto_id));
749 * sharkd_session_process_status()
751 * Process analyse request
753 * Output object with attributes:
754 * (m) frames - count of currently loaded frames
755 * (m) protocols - protocol list
756 * (m) first - earliest frame time
757 * (m) last - latest frame time
760 sharkd_session_process_analyse(void)
762 unsigned int framenum;
763 struct sharkd_analyse_data analyser;
765 analyser.first_time = NULL;
766 analyser.last_time = NULL;
767 analyser.protocols_set = g_hash_table_new(NULL /* g_direct_hash() */, NULL /* g_direct_equal */);
769 sharkd_json_object_open(FALSE);
771 sharkd_json_value_anyf(FALSE, "frames", "%u", cfile.count);
773 sharkd_json_array_open(TRUE, "protocols");
774 for (framenum = 1; framenum <= cfile.count; framenum++)
775 sharkd_dissect_request(framenum, (framenum != 1) ? 1 : 0, framenum - 1, &sharkd_session_process_analyse_cb, SHARKD_DISSECT_FLAG_NULL, &analyser);
776 sharkd_json_array_close();
778 if (analyser.first_time)
779 sharkd_json_value_anyf(TRUE, "first", "%.9f", nstime_to_sec(analyser.first_time));
781 if (analyser.last_time)
782 sharkd_json_value_anyf(TRUE, "last", "%.9f", nstime_to_sec(analyser.last_time));
784 sharkd_json_object_close();
785 sharkd_json_finish();
787 g_hash_table_destroy(analyser.protocols_set);
791 sharkd_session_create_columns(column_info *cinfo, const char *buf, const jsmntok_t *tokens, int count)
793 const char *columns_custom[32];
794 guint16 columns_fmt[32];
795 gint16 columns_occur[32];
799 for (i = 0; i < 32; i++)
801 const char *tok_column;
802 char tok_column_name[64];
805 ws_snprintf(tok_column_name, sizeof(tok_column_name), "column%d", i);
806 tok_column = json_find_attr(buf, tokens, count, tok_column_name);
807 if (tok_column == NULL)
810 columns_custom[i] = NULL;
811 columns_occur[i] = 0;
813 if ((custom_sepa = strchr(tok_column, ':')))
815 *custom_sepa = '\0'; /* XXX, C abuse: discarding-const */
817 columns_fmt[i] = COL_CUSTOM;
818 columns_custom[i] = tok_column;
820 if (!ws_strtoi16(custom_sepa + 1, NULL, &columns_occur[i]))
825 if (!ws_strtou16(tok_column, NULL, &columns_fmt[i]))
828 if (columns_fmt[i] >= NUM_COL_FMTS)
831 /* if custom, that it shouldn't be just custom number -> error */
832 if (columns_fmt[i] == COL_CUSTOM)
839 col_setup(cinfo, cols);
841 for (i = 0; i < cols; i++)
843 col_item_t *col_item = &cinfo->columns[i];
845 col_item->col_fmt = columns_fmt[i];
846 col_item->col_title = NULL; /* no need for title */
848 if (col_item->col_fmt == COL_CUSTOM)
850 col_item->col_custom_fields = g_strdup(columns_custom[i]);
851 col_item->col_custom_occurrence = columns_occur[i];
854 col_item->col_fence = 0;
863 * sharkd_session_process_frames()
865 * Process frames request
868 * (o) column0...columnXX - requested columns either number in range [0..NUM_COL_FMTS), or custom (syntax <dfilter>:<occurence>).
869 * If column0 is not specified default column set will be used.
870 * (o) filter - filter to be used
871 * (o) skip=N - skip N frames
872 * (o) limit=N - show only N frames
873 * (o) refs - list (comma separated) with sorted time reference frame numbers.
875 * Output array of frames with attributes:
876 * (m) c - array of column data
877 * (m) num - frame number
878 * (o) i - if frame is ignored
879 * (o) m - if frame is marked
880 * (o) ct - if frame is commented
881 * (o) bg - color filter - background color in hex
882 * (o) fg - color filter - foreground color in hex
885 sharkd_session_process_frames(const char *buf, const jsmntok_t *tokens, int count)
887 const char *tok_filter = json_find_attr(buf, tokens, count, "filter");
888 const char *tok_column = json_find_attr(buf, tokens, count, "column0");
889 const char *tok_skip = json_find_attr(buf, tokens, count, "skip");
890 const char *tok_limit = json_find_attr(buf, tokens, count, "limit");
891 const char *tok_refs = json_find_attr(buf, tokens, count, "refs");
893 const guint8 *filter_data = NULL;
895 gboolean frame_sepa = FALSE;
898 guint32 framenum, prev_dis_num = 0;
899 guint32 current_ref_frame = 0, next_ref_frame = G_MAXUINT32;
903 column_info *cinfo = &cfile.cinfo;
904 column_info user_cinfo;
908 memset(&user_cinfo, 0, sizeof(user_cinfo));
909 cinfo = sharkd_session_create_columns(&user_cinfo, buf, tokens, count);
916 const struct sharkd_filter_item *filter_item;
918 filter_item = sharkd_session_filter_data(tok_filter);
921 filter_data = filter_item->filtered;
927 if (!ws_strtou32(tok_skip, NULL, &skip))
934 if (!ws_strtou32(tok_limit, NULL, &limit))
940 if (!ws_strtou32(tok_refs, &tok_refs, &next_ref_frame))
944 sharkd_json_array_open(FALSE, NULL);
945 for (framenum = 1; framenum <= cfile.count; framenum++)
948 guint32 ref_frame = (framenum != 1) ? 1 : 0;
950 if (filter_data && !(filter_data[framenum / 8] & (1 << (framenum % 8))))
956 prev_dis_num = framenum;
962 if (framenum >= next_ref_frame)
964 current_ref_frame = next_ref_frame;
966 if (*tok_refs != ',')
967 next_ref_frame = G_MAXUINT32;
969 while (*tok_refs == ',' && framenum >= next_ref_frame)
971 current_ref_frame = next_ref_frame;
973 if (!ws_strtou32(tok_refs + 1, &tok_refs, &next_ref_frame))
975 fprintf(stderr, "sharkd_session_process_frames() wrong format for refs: %s\n", tok_refs);
980 if (*tok_refs == '\0' && framenum >= next_ref_frame)
982 current_ref_frame = next_ref_frame;
983 next_ref_frame = G_MAXUINT32;
987 if (current_ref_frame)
988 ref_frame = current_ref_frame;
991 fdata = sharkd_get_frame(framenum);
992 sharkd_dissect_columns(fdata, ref_frame, prev_dis_num, cinfo, (fdata->color_filter == NULL));
994 sharkd_json_object_open(frame_sepa);
996 sharkd_json_array_open(FALSE, "c");
997 for (col = 0; col < cinfo->num_cols; ++col)
999 const col_item_t *col_item = &cinfo->columns[col];
1001 sharkd_json_value_string(col != 0, NULL, col_item->col_data);
1003 sharkd_json_array_close();
1005 sharkd_json_value_anyf(TRUE, "num", "%u", framenum);
1007 if (fdata->has_user_comment || fdata->has_phdr_comment)
1009 if (!fdata->has_user_comment || sharkd_get_user_comment(fdata) != NULL)
1010 sharkd_json_value_anyf(TRUE, "ct", "true");
1014 sharkd_json_value_anyf(TRUE, "i", "true");
1017 sharkd_json_value_anyf(TRUE, "m", "true");
1019 if (fdata->color_filter)
1021 sharkd_json_value_stringf(TRUE, "bg", "%x", color_t_to_rgb(&fdata->color_filter->bg_color));
1022 sharkd_json_value_stringf(TRUE, "fg", "%x", color_t_to_rgb(&fdata->color_filter->fg_color));
1025 sharkd_json_object_close();
1027 prev_dis_num = framenum;
1029 if (limit && --limit == 0)
1032 sharkd_json_array_close();
1033 sharkd_json_finish();
1035 if (cinfo != &cfile.cinfo)
1040 sharkd_session_process_tap_stats_node_cb(const stat_node *n)
1043 gboolean sepa = FALSE;
1045 sharkd_json_array_open(FALSE, NULL);
1046 for (node = n->children; node; node = node->next)
1048 sharkd_json_object_open(sepa);
1050 /* code based on stats_tree_get_values_from_node() */
1051 sharkd_json_value_string(FALSE, "name", node->name);
1052 sharkd_json_value_anyf(TRUE, "count", "%d", node->counter);
1053 if (node->counter && ((node->st_flags & ST_FLG_AVERAGE) || node->rng))
1055 sharkd_json_value_anyf(TRUE, "avg", "%.2f", ((float)node->total) / node->counter);
1056 sharkd_json_value_anyf(TRUE, "min", "%d", node->minvalue);
1057 sharkd_json_value_anyf(TRUE, "max", "%d", node->maxvalue);
1060 if (node->st->elapsed)
1061 sharkd_json_value_anyf(TRUE, "rate", "%.4f", ((float)node->counter) / node->st->elapsed);
1063 if (node->parent && node->parent->counter)
1064 sharkd_json_value_anyf(TRUE, "perc", "%.2f", (node->counter * 100.0) / node->parent->counter);
1065 else if (node->parent == &(node->st->root))
1066 sharkd_json_value_anyf(TRUE, "perc", "100");
1068 if (prefs.st_enable_burstinfo && node->max_burst)
1070 if (prefs.st_burst_showcount)
1071 sharkd_json_value_anyf(TRUE, "burstcount", "%d", node->max_burst);
1073 sharkd_json_value_anyf(TRUE, "burstrate", "%.4f", ((double)node->max_burst) / prefs.st_burst_windowlen);
1075 sharkd_json_value_anyf(TRUE, "bursttime", "%.3f", ((double)node->burst_time / 1000.0));
1080 sharkd_json_value_anyf(TRUE, "sub", NULL);
1081 sharkd_session_process_tap_stats_node_cb(node);
1083 sharkd_json_object_close();
1086 sharkd_json_array_close();
1090 * sharkd_session_process_tap_stats_cb()
1094 * (m) tap - tap name
1095 * (m) type:stats - tap output type
1096 * (m) name - stat name
1097 * (m) stats - array of object with attributes:
1098 * (m) name - stat item name
1099 * (m) count - stat item counter
1100 * (o) avg - stat item averange value
1101 * (o) min - stat item min value
1102 * (o) max - stat item max value
1103 * (o) rate - stat item rate value (ms)
1104 * (o) perc - stat item percentage
1105 * (o) burstrate - stat item burst rate
1106 * (o) burstcount - stat item burst count
1107 * (o) burstttme - stat item burst start
1108 * (o) sub - array of object with attributes like in stats node.
1111 sharkd_session_process_tap_stats_cb(void *psp)
1113 stats_tree *st = (stats_tree *) psp;
1115 sharkd_json_object_open(FALSE);
1117 sharkd_json_value_stringf(FALSE, "tap", "stats:%s", st->cfg->abbr);
1118 sharkd_json_value_string(TRUE, "type", "stats");
1119 sharkd_json_value_string(TRUE, "name", st->cfg->name);
1121 sharkd_json_value_anyf(TRUE, "stats", NULL);
1122 sharkd_session_process_tap_stats_node_cb(&st->root);
1124 sharkd_json_object_close();
1129 sharkd_session_free_tap_stats_cb(void *psp)
1131 stats_tree *st = (stats_tree *) psp;
1133 stats_tree_free(st);
1136 struct sharkd_expert_tap
1143 * sharkd_session_process_tap_expert_cb()
1145 * Output expert tap:
1147 * (m) tap - tap name
1148 * (m) type:expert - tap output type
1149 * (m) details - array of object with attributes:
1150 * (m) f - frame number, which generated expert information
1153 * (m) m - expert message
1157 sharkd_session_process_tap_expert_cb(void *tapdata)
1159 struct sharkd_expert_tap *etd = (struct sharkd_expert_tap *) tapdata;
1161 gboolean sepa = FALSE;
1163 sharkd_json_object_open(FALSE);
1165 sharkd_json_value_string(FALSE, "tap", "expert");
1166 sharkd_json_value_string(TRUE, "type", "expert");
1168 sharkd_json_array_open(TRUE, "details");
1169 for (list = etd->details; list; list = list->next)
1171 expert_info_t *ei = (expert_info_t *) list->data;
1174 sharkd_json_object_open(sepa);
1176 sharkd_json_value_anyf(FALSE, "f", "%u", ei->packet_num);
1178 tmp = try_val_to_str(ei->severity, expert_severity_vals);
1180 sharkd_json_value_string(TRUE, "s", tmp);
1182 tmp = try_val_to_str(ei->group, expert_group_vals);
1184 sharkd_json_value_string(TRUE, "g", tmp);
1186 sharkd_json_value_string(TRUE, "m", ei->summary);
1189 sharkd_json_value_string(TRUE, "p", ei->protocol);
1191 sharkd_json_object_close();
1194 sharkd_json_array_close();
1196 sharkd_json_object_close();
1201 sharkd_session_packet_tap_expert_cb(void *tapdata, packet_info *pinfo _U_, epan_dissect_t *edt _U_, const void *pointer)
1203 struct sharkd_expert_tap *etd = (struct sharkd_expert_tap *) tapdata;
1204 const expert_info_t *ei = (const expert_info_t *) pointer;
1205 expert_info_t *ei_copy;
1210 ei_copy = g_new(expert_info_t, 1);
1211 /* Note: this is a shallow copy */
1214 /* ei->protocol, ei->summary might be allocated in packet scope, make a copy. */
1215 ei_copy->protocol = g_string_chunk_insert_const(etd->text, ei_copy->protocol);
1216 ei_copy->summary = g_string_chunk_insert_const(etd->text, ei_copy->summary);
1218 etd->details = g_slist_prepend(etd->details, ei_copy);
1224 sharkd_session_free_tap_expert_cb(void *tapdata)
1226 struct sharkd_expert_tap *etd = (struct sharkd_expert_tap *) tapdata;
1228 g_slist_free_full(etd->details, g_free);
1229 g_string_chunk_free(etd->text);
1234 * sharkd_session_process_tap_flow_cb()
1237 * (m) tap - tap name
1238 * (m) type:flow - tap output type
1239 * (m) nodes - array of strings with node address
1240 * (m) flows - array of object with attributes:
1241 * (m) t - frame time string
1242 * (m) n - array of two numbers with source node index and destination node index
1243 * (m) pn - array of two numbers with source and destination port
1247 sharkd_session_process_tap_flow_cb(void *tapdata)
1249 seq_analysis_info_t *graph_analysis = (seq_analysis_info_t *) tapdata;
1253 gboolean sepa = FALSE;
1255 sequence_analysis_get_nodes(graph_analysis);
1257 sharkd_json_object_open(FALSE);
1258 sharkd_json_value_stringf(FALSE, "tap", "seqa:%s", graph_analysis->name);
1259 sharkd_json_value_string(TRUE, "type", "flow");
1261 sharkd_json_array_open(TRUE, "nodes");
1262 for (i = 0; i < graph_analysis->num_nodes; i++)
1266 addr_str = address_to_display(NULL, &(graph_analysis->nodes[i]));
1267 sharkd_json_value_string(i != 0, NULL, addr_str);
1268 wmem_free(NULL, addr_str);
1270 sharkd_json_array_close();
1272 sharkd_json_array_open(TRUE, "flows");
1273 flow_list = g_queue_peek_nth_link(graph_analysis->items, 0);
1276 seq_analysis_item_t *sai = (seq_analysis_item_t *) flow_list->data;
1278 flow_list = g_list_next(flow_list);
1283 sharkd_json_object_open(sepa);
1285 sharkd_json_value_string(FALSE, "t", sai->time_str);
1286 sharkd_json_value_anyf(TRUE, "n", "[%u,%u]", sai->src_node, sai->dst_node);
1287 sharkd_json_value_anyf(TRUE, "pn", "[%u,%u]", sai->port_src, sai->port_dst);
1290 sharkd_json_value_string(TRUE, "c", sai->comment);
1292 sharkd_json_object_close();
1295 sharkd_json_array_close();
1297 sharkd_json_object_close();
1302 sharkd_session_free_tap_flow_cb(void *tapdata)
1304 seq_analysis_info_t *graph_analysis = (seq_analysis_info_t *) tapdata;
1306 sequence_analysis_info_free(graph_analysis);
1309 struct sharkd_conv_tap_data
1313 gboolean resolve_name;
1314 gboolean resolve_port;
1318 sharkd_session_geoip_addr(address *addr, const char *suffix)
1320 const mmdb_lookup_t *lookup = NULL;
1321 gboolean with_geoip = FALSE;
1324 if (addr->type == AT_IPv4)
1328 memcpy(&ip, addr->data, 4);
1329 lookup = maxmind_db_lookup_ipv4(ip);
1331 else if (addr->type == AT_IPv6)
1333 const ws_in6_addr *ip6 = (const ws_in6_addr *) addr->data;
1335 lookup = maxmind_db_lookup_ipv6(ip6);
1338 if (!lookup || !lookup->found)
1341 if (lookup->country)
1343 snprintf(json_key, sizeof(json_key), "geoip_country%s", suffix);
1344 sharkd_json_value_string(TRUE, json_key, lookup->country);
1348 if (lookup->country_iso)
1350 snprintf(json_key, sizeof(json_key), "geoip_country_iso%s", suffix);
1351 sharkd_json_value_string(TRUE, json_key, lookup->country_iso);
1357 snprintf(json_key, sizeof(json_key), "geoip_city%s", suffix);
1358 sharkd_json_value_string(TRUE, json_key, lookup->city);
1364 snprintf(json_key, sizeof(json_key), "geoip_as_org%s", suffix);
1365 sharkd_json_value_string(TRUE, json_key, lookup->as_org);
1369 if (lookup->as_number > 0)
1371 snprintf(json_key, sizeof(json_key), "geoip_as%s", suffix);
1372 sharkd_json_value_anyf(TRUE, json_key, "%u", lookup->as_number);
1376 if (lookup->latitude >= -90.0 && lookup->latitude <= 90.0)
1378 snprintf(json_key, sizeof(json_key), "geoip_lat%s", suffix);
1379 sharkd_json_value_anyf(TRUE, json_key, "%f", lookup->latitude);
1383 if (lookup->longitude >= -180.0 && lookup->longitude <= 180.0)
1385 snprintf(json_key, sizeof(json_key), "geoip_lon%s", suffix);
1386 sharkd_json_value_anyf(TRUE, json_key, "%f", lookup->longitude);
1393 struct sharkd_analyse_rtp_items
1396 guint32 sequence_num;
1404 double arrive_offset;
1406 /* from tap_rtp_stat_t */
1411 struct sharkd_analyse_rtp
1413 const char *tap_name;
1418 tap_rtp_stat_t statinfo;
1422 sharkd_session_process_tap_rtp_free_cb(void *tapdata)
1424 struct sharkd_analyse_rtp *rtp_req = (struct sharkd_analyse_rtp *) tapdata;
1426 g_slist_free_full(rtp_req->packets, g_free);
1431 sharkd_session_packet_tap_rtp_analyse_cb(void *tapdata, packet_info *pinfo, epan_dissect_t *edt _U_, const void *pointer)
1433 struct sharkd_analyse_rtp *rtp_req = (struct sharkd_analyse_rtp *) tapdata;
1434 const struct _rtp_info *rtp_info = (const struct _rtp_info *) pointer;
1436 if (rtpstream_id_equal_pinfo_rtp_info(&rtp_req->id, pinfo, rtp_info))
1438 tap_rtp_stat_t *statinfo = &(rtp_req->statinfo);
1439 struct sharkd_analyse_rtp_items *item;
1441 rtppacket_analyse(statinfo, pinfo, rtp_info);
1443 item = (struct sharkd_analyse_rtp_items *) g_malloc(sizeof(struct sharkd_analyse_rtp_items));
1445 if (!rtp_req->packets)
1446 rtp_req->start_time = nstime_to_sec(&pinfo->abs_ts);
1448 item->frame_num = pinfo->num;
1449 item->sequence_num = rtp_info->info_seq_num;
1450 item->delta = (statinfo->flags & STAT_FLAG_FIRST) ? 0.0 : statinfo->delta;
1451 item->jitter = (statinfo->flags & STAT_FLAG_FIRST) ? 0.0 : statinfo->jitter;
1452 item->skew = (statinfo->flags & STAT_FLAG_FIRST) ? 0.0 : statinfo->skew;
1453 item->bandwidth = statinfo->bandwidth;
1454 item->marker = rtp_info->info_marker_set ? TRUE : FALSE;
1455 item->arrive_offset= nstime_to_sec(&pinfo->abs_ts) - rtp_req->start_time;
1457 item->flags = statinfo->flags;
1458 item->pt = statinfo->pt;
1460 /* XXX, O(n) optimize */
1461 rtp_req->packets = g_slist_append(rtp_req->packets, item);
1468 * sharkd_session_process_tap_rtp_analyse_cb()
1470 * Output rtp analyse tap:
1471 * (m) tap - tap name
1472 * (m) type - tap output type
1473 * (m) ssrc - RTP SSRC
1474 * (m) max_delta - Max delta (ms)
1475 * (m) max_delta_nr - Max delta packet #
1476 * (m) max_jitter - Max jitter (ms)
1477 * (m) mean_jitter - Mean jitter (ms)
1478 * (m) max_skew - Max skew (ms)
1479 * (m) total_nr - Total number of RTP packets
1480 * (m) seq_err - Number of sequence errors
1481 * (m) duration - Duration (ms)
1482 * (m) items - array of object with attributes:
1483 * (m) f - frame number
1484 * (m) o - arrive offset
1485 * (m) sn - sequence number
1489 * (m) bw - bandwidth
1490 * (o) s - status string
1491 * (o) t - status type
1492 * (o) mark - rtp mark
1495 sharkd_session_process_tap_rtp_analyse_cb(void *tapdata)
1497 const int RTP_TYPE_CN = 1;
1498 const int RTP_TYPE_ERROR = 2;
1499 const int RTP_TYPE_WARN = 3;
1500 const int RTP_TYPE_PT_EVENT = 4;
1502 const struct sharkd_analyse_rtp *rtp_req = (struct sharkd_analyse_rtp *) tapdata;
1503 const tap_rtp_stat_t *statinfo = &rtp_req->statinfo;
1505 gboolean sepa = FALSE;
1508 sharkd_json_object_open(FALSE);
1510 sharkd_json_value_string(FALSE, "tap", rtp_req->tap_name);
1511 sharkd_json_value_string(TRUE, "type", "rtp-analyse");
1512 sharkd_json_value_anyf(TRUE, "ssrc", "%u", rtp_req->id.ssrc);
1514 sharkd_json_value_anyf(TRUE, "max_delta", "%f", statinfo->max_delta);
1515 sharkd_json_value_anyf(TRUE, "max_delta_nr", "%u", statinfo->max_nr);
1516 sharkd_json_value_anyf(TRUE, "max_jitter", "%f", statinfo->max_jitter);
1517 sharkd_json_value_anyf(TRUE, "mean_jitter", "%f", statinfo->mean_jitter);
1518 sharkd_json_value_anyf(TRUE, "max_skew", "%f", statinfo->max_skew);
1519 sharkd_json_value_anyf(TRUE, "total_nr", "%u", statinfo->total_nr);
1520 sharkd_json_value_anyf(TRUE, "seq_err", "%u", statinfo->sequence);
1521 sharkd_json_value_anyf(TRUE, "duration", "%f", statinfo->time - statinfo->start_time);
1523 sharkd_json_array_open(TRUE, "items");
1524 for (l = rtp_req->packets; l; l = l->next)
1526 struct sharkd_analyse_rtp_items *item = (struct sharkd_analyse_rtp_items *) l->data;
1528 sharkd_json_object_open(sepa);
1530 sharkd_json_value_anyf(FALSE, "f", "%u", item->frame_num);
1531 sharkd_json_value_anyf(TRUE, "o", "%.9f", item->arrive_offset);
1532 sharkd_json_value_anyf(TRUE, "sn", "%u", item->sequence_num);
1533 sharkd_json_value_anyf(TRUE, "d", "%.2f", item->delta);
1534 sharkd_json_value_anyf(TRUE, "j", "%.2f", item->jitter);
1535 sharkd_json_value_anyf(TRUE, "sk", "%.2f", item->skew);
1536 sharkd_json_value_anyf(TRUE, "bw", "%.2f", item->bandwidth);
1538 if (item->pt == PT_CN)
1540 sharkd_json_value_string(TRUE, "s", "Comfort noise (PT=13, RFC 3389)");
1541 sharkd_json_value_anyf(TRUE, "t", "%d", RTP_TYPE_CN);
1543 else if (item->pt == PT_CN_OLD)
1545 sharkd_json_value_string(TRUE, "s", "Comfort noise (PT=19, reserved)");
1546 sharkd_json_value_anyf(TRUE, "t", "%d", RTP_TYPE_CN);
1548 else if (item->flags & STAT_FLAG_WRONG_SEQ)
1550 sharkd_json_value_string(TRUE, "s", "Wrong sequence number");
1551 sharkd_json_value_anyf(TRUE, "t", "%d", RTP_TYPE_ERROR);
1553 else if (item->flags & STAT_FLAG_DUP_PKT)
1555 sharkd_json_value_string(TRUE, "s", "Suspected duplicate (MAC address) only delta time calculated");
1556 sharkd_json_value_anyf(TRUE, "t", "%d", RTP_TYPE_WARN);
1558 else if (item->flags & STAT_FLAG_REG_PT_CHANGE)
1560 sharkd_json_value_stringf(TRUE, "s", "Payload changed to PT=%u%s",
1562 (item->flags & STAT_FLAG_PT_T_EVENT) ? " telephone/event" : "");
1563 sharkd_json_value_anyf(TRUE, "t", "%d", RTP_TYPE_WARN);
1565 else if (item->flags & STAT_FLAG_WRONG_TIMESTAMP)
1567 sharkd_json_value_string(TRUE, "s", "Incorrect timestamp");
1568 sharkd_json_value_anyf(TRUE, "t", "%d", RTP_TYPE_WARN);
1570 else if ((item->flags & STAT_FLAG_PT_CHANGE)
1571 && !(item->flags & STAT_FLAG_FIRST)
1572 && !(item->flags & STAT_FLAG_PT_CN)
1573 && (item->flags & STAT_FLAG_FOLLOW_PT_CN)
1574 && !(item->flags & STAT_FLAG_MARKER))
1576 sharkd_json_value_string(TRUE, "s", "Marker missing?");
1577 sharkd_json_value_anyf(TRUE, "t", "%d", RTP_TYPE_WARN);
1579 else if (item->flags & STAT_FLAG_PT_T_EVENT)
1581 sharkd_json_value_stringf(TRUE, "s", "PT=%u telephone/event", item->pt);
1582 sharkd_json_value_anyf(TRUE, "t", "%d", RTP_TYPE_PT_EVENT);
1584 else if (item->flags & STAT_FLAG_MARKER)
1586 sharkd_json_value_anyf(TRUE, "t", "%d", RTP_TYPE_WARN);
1590 sharkd_json_value_anyf(TRUE, "mark", "1");
1592 sharkd_json_object_close();
1595 sharkd_json_array_close();
1597 sharkd_json_object_close();
1602 * sharkd_session_process_tap_conv_cb()
1605 * (m) tap - tap name
1606 * (m) type - tap output type
1607 * (m) proto - protocol short name
1608 * (o) filter - filter string
1609 * (o) geoip - whether GeoIP information is available, boolean
1611 * (o) convs - array of object with attributes:
1612 * (m) saddr - source address
1613 * (m) daddr - destination address
1614 * (o) sport - source port
1615 * (o) dport - destination port
1616 * (m) txf - TX frame count
1617 * (m) txb - TX bytes
1618 * (m) rxf - RX frame count
1619 * (m) rxb - RX bytes
1620 * (m) start - (relative) first packet time
1621 * (m) stop - (relative) last packet time
1622 * (o) filter - conversation filter
1624 * (o) hosts - array of object with attributes:
1625 * (m) host - host address
1626 * (o) port - host port
1627 * (m) txf - TX frame count
1628 * (m) txb - TX bytes
1629 * (m) rxf - RX frame count
1630 * (m) rxb - RX bytes
1633 sharkd_session_process_tap_conv_cb(void *arg)
1635 conv_hash_t *hash = (conv_hash_t *) arg;
1636 const struct sharkd_conv_tap_data *iu = (struct sharkd_conv_tap_data *) hash->user_data;
1638 int proto_with_port;
1643 sharkd_json_object_open(FALSE);
1644 sharkd_json_value_string(FALSE, "tap", iu->type);
1646 if (!strncmp(iu->type, "conv:", 5))
1648 sharkd_json_value_string(TRUE, "type", "conv");
1649 sharkd_json_array_open(TRUE, "convs");
1650 proto = iu->type + 5;
1652 else if (!strncmp(iu->type, "endpt:", 6))
1654 sharkd_json_value_string(TRUE, "type", "host");
1655 sharkd_json_array_open(TRUE, "hosts");
1656 proto = iu->type + 6;
1660 sharkd_json_value_string(TRUE, "type", "err");
1664 proto_with_port = (!strcmp(proto, "TCP") || !strcmp(proto, "UDP") || !strcmp(proto, "SCTP"));
1666 if (iu->hash.conv_array != NULL && !strncmp(iu->type, "conv:", 5))
1668 for (i = 0; i < iu->hash.conv_array->len; i++)
1670 conv_item_t *iui = &g_array_index(iu->hash.conv_array, conv_item_t, i);
1671 char *src_addr, *dst_addr;
1672 char *src_port, *dst_port;
1675 sharkd_json_object_open(i != 0);
1677 sharkd_json_value_string(FALSE, "saddr", (src_addr = get_conversation_address(NULL, &iui->src_address, iu->resolve_name)));
1678 sharkd_json_value_string(TRUE, "daddr", (dst_addr = get_conversation_address(NULL, &iui->dst_address, iu->resolve_name)));
1680 if (proto_with_port)
1682 sharkd_json_value_string(TRUE, "sport", (src_port = get_conversation_port(NULL, iui->src_port, iui->etype, iu->resolve_port)));
1683 sharkd_json_value_string(TRUE, "dport", (dst_port = get_conversation_port(NULL, iui->dst_port, iui->etype, iu->resolve_port)));
1685 wmem_free(NULL, src_port);
1686 wmem_free(NULL, dst_port);
1689 sharkd_json_value_anyf(TRUE, "rxf", "%" G_GUINT64_FORMAT, iui->rx_frames);
1690 sharkd_json_value_anyf(TRUE, "rxb", "%" G_GUINT64_FORMAT, iui->rx_bytes);
1692 sharkd_json_value_anyf(TRUE, "txf", "%" G_GUINT64_FORMAT, iui->tx_frames);
1693 sharkd_json_value_anyf(TRUE, "txb", "%" G_GUINT64_FORMAT, iui->tx_bytes);
1695 sharkd_json_value_anyf(TRUE, "start", "%.9f", nstime_to_sec(&iui->start_time));
1696 sharkd_json_value_anyf(TRUE, "stop", "%.9f", nstime_to_sec(&iui->stop_time));
1698 filter_str = get_conversation_filter(iui, CONV_DIR_A_TO_FROM_B);
1701 sharkd_json_value_string(TRUE, "filter", filter_str);
1705 wmem_free(NULL, src_addr);
1706 wmem_free(NULL, dst_addr);
1708 if (sharkd_session_geoip_addr(&(iui->src_address), "1"))
1710 if (sharkd_session_geoip_addr(&(iui->dst_address), "2"))
1713 sharkd_json_object_close();
1716 else if (iu->hash.conv_array != NULL && !strncmp(iu->type, "endpt:", 6))
1718 for (i = 0; i < iu->hash.conv_array->len; i++)
1720 hostlist_talker_t *host = &g_array_index(iu->hash.conv_array, hostlist_talker_t, i);
1721 char *host_str, *port_str;
1724 sharkd_json_object_open(i != 0);
1726 sharkd_json_value_string(FALSE, "host", (host_str = get_conversation_address(NULL, &host->myaddress, iu->resolve_name)));
1728 if (proto_with_port)
1730 sharkd_json_value_string(TRUE, "port", (port_str = get_conversation_port(NULL, host->port, host->etype, iu->resolve_port)));
1732 wmem_free(NULL, port_str);
1735 sharkd_json_value_anyf(TRUE, "rxf", "%" G_GUINT64_FORMAT, host->rx_frames);
1736 sharkd_json_value_anyf(TRUE, "rxb", "%" G_GUINT64_FORMAT, host->rx_bytes);
1738 sharkd_json_value_anyf(TRUE, "txf", "%" G_GUINT64_FORMAT, host->tx_frames);
1739 sharkd_json_value_anyf(TRUE, "txb", "%" G_GUINT64_FORMAT, host->tx_bytes);
1741 filter_str = get_hostlist_filter(host);
1744 sharkd_json_value_string(TRUE, "filter", filter_str);
1748 wmem_free(NULL, host_str);
1750 if (sharkd_session_geoip_addr(&(host->myaddress), ""))
1752 sharkd_json_object_close();
1755 sharkd_json_array_close();
1757 sharkd_json_value_string(TRUE, "proto", proto);
1758 sharkd_json_value_anyf(TRUE, "geoip", with_geoip ? "true" : "false");
1760 sharkd_json_object_close();
1765 sharkd_session_free_tap_conv_cb(void *arg)
1767 conv_hash_t *hash = (conv_hash_t *) arg;
1768 struct sharkd_conv_tap_data *iu = (struct sharkd_conv_tap_data *) hash->user_data;
1770 if (!strncmp(iu->type, "conv:", 5))
1772 reset_conversation_table_data(hash);
1774 else if (!strncmp(iu->type, "endpt:", 6))
1776 reset_hostlist_table_data(hash);
1783 * sharkd_session_process_tap_nstat_cb()
1786 * (m) tap - tap name
1787 * (m) type - tap output type
1788 * (m) fields: array of objects with attributes:
1791 * (m) tables: array of object with attributes:
1792 * (m) t - table title
1793 * (m) i - array of items
1796 sharkd_session_process_tap_nstat_cb(void *arg)
1798 stat_data_t *stat_data = (stat_data_t *) arg;
1801 sharkd_json_object_open(FALSE);
1802 sharkd_json_value_stringf(FALSE, "tap", "nstat:%s", stat_data->stat_tap_data->cli_string);
1803 sharkd_json_value_string(TRUE, "type", "nstat");
1805 sharkd_json_array_open(TRUE, "fields");
1806 for (i = 0; i < stat_data->stat_tap_data->nfields; i++)
1808 stat_tap_table_item *field = &(stat_data->stat_tap_data->fields[i]);
1810 sharkd_json_object_open(i != 0);
1811 sharkd_json_value_string(FALSE, "c", field->column_name);
1812 sharkd_json_object_close();
1814 sharkd_json_array_close();
1816 sharkd_json_array_open(TRUE, "tables");
1817 for (i = 0; i < stat_data->stat_tap_data->tables->len; i++)
1819 stat_tap_table *table = g_array_index(stat_data->stat_tap_data->tables, stat_tap_table *, i);
1820 gboolean sepa = FALSE;
1822 sharkd_json_object_open(i != 0);
1824 sharkd_json_value_string(FALSE, "t", table->title);
1826 sharkd_json_array_open(TRUE, "i");
1827 for (j = 0; j < table->num_elements; j++)
1829 stat_tap_table_item_type *field_data;
1831 field_data = stat_tap_get_field_data(table, j, 0);
1832 if (field_data == NULL || field_data->type == TABLE_ITEM_NONE) /* Nothing for us here */
1835 sharkd_json_array_open(sepa, NULL);
1836 for (k = 0; k < table->num_fields; k++)
1838 field_data = stat_tap_get_field_data(table, j, k);
1840 switch (field_data->type)
1842 case TABLE_ITEM_UINT:
1843 sharkd_json_value_anyf(k != 0, NULL, "%u", field_data->value.uint_value);
1846 case TABLE_ITEM_INT:
1847 sharkd_json_value_anyf(k != 0, NULL, "%d", field_data->value.int_value);
1850 case TABLE_ITEM_STRING:
1851 sharkd_json_value_string(k != 0, NULL, field_data->value.string_value);
1854 case TABLE_ITEM_FLOAT:
1855 sharkd_json_value_anyf(k != 0, NULL, "%f", field_data->value.float_value);
1858 case TABLE_ITEM_ENUM:
1859 sharkd_json_value_anyf(k != 0, NULL, "%d", field_data->value.enum_value);
1862 case TABLE_ITEM_NONE:
1863 sharkd_json_value_anyf(k != 0, NULL, "null");
1868 sharkd_json_array_close();
1871 sharkd_json_array_close();
1872 sharkd_json_object_close();
1874 sharkd_json_array_close();
1876 sharkd_json_object_close();
1881 sharkd_session_free_tap_nstat_cb(void *arg)
1883 stat_data_t *stat_data = (stat_data_t *) arg;
1885 free_stat_tables(stat_data->stat_tap_data);
1889 * sharkd_session_process_tap_rtd_cb()
1892 * (m) tap - tap name
1893 * (m) type - tap output type
1894 * (m) stats - statistics rows - array object with attributes:
1895 * (m) type - statistic name
1896 * (m) num - number of messages
1897 * (m) min - minimum SRT time
1898 * (m) max - maximum SRT time
1899 * (m) tot - total SRT time
1900 * (m) min_frame - minimal SRT
1901 * (m) max_frame - maximum SRT
1902 * (o) open_req - Open Requests
1903 * (o) disc_rsp - Discarded Responses
1904 * (o) req_dup - Duplicated Requests
1905 * (o) rsp_dup - Duplicated Responses
1906 * (o) open_req - Open Requests
1907 * (o) disc_rsp - Discarded Responses
1908 * (o) req_dup - Duplicated Requests
1909 * (o) rsp_dup - Duplicated Responses
1912 sharkd_session_process_tap_rtd_cb(void *arg)
1914 rtd_data_t *rtd_data = (rtd_data_t *) arg;
1915 register_rtd_t *rtd = (register_rtd_t *) rtd_data->user_data;
1919 const char *filter = proto_get_protocol_filter_name(get_rtd_proto_id(rtd));
1921 /* XXX, some dissectors are having single table and multiple timestats (mgcp, megaco),
1922 * some multiple table and single timestat (radius, h225)
1923 * and it seems that value_string is used one for timestamp-ID, other one for table-ID
1924 * I wonder how it will gonna work with multiple timestats and multiple tables...
1925 * (for usage grep for: register_rtd_table)
1927 const value_string *vs = get_rtd_value_string(rtd);
1928 gboolean sepa = FALSE;
1930 sharkd_json_object_open(FALSE);
1931 sharkd_json_value_stringf(FALSE, "tap", "rtd:%s", filter);
1932 sharkd_json_value_string(TRUE, "type", "rtd");
1934 if (rtd_data->stat_table.num_rtds == 1)
1936 const rtd_timestat *ms = &rtd_data->stat_table.time_stats[0];
1938 sharkd_json_value_anyf(TRUE, "open_req", "%u", ms->open_req_num);
1939 sharkd_json_value_anyf(TRUE, "disc_rsp", "%u", ms->disc_rsp_num);
1940 sharkd_json_value_anyf(TRUE, "req_dup", "%u", ms->req_dup_num);
1941 sharkd_json_value_anyf(TRUE, "rsp_dup", "%u", ms->rsp_dup_num);
1944 sharkd_json_array_open(TRUE, "stats");
1945 for (i = 0; i < rtd_data->stat_table.num_rtds; i++)
1947 const rtd_timestat *ms = &rtd_data->stat_table.time_stats[i];
1949 for (j = 0; j < ms->num_timestat; j++)
1951 const char *type_str;
1953 if (ms->rtd[j].num == 0)
1956 sharkd_json_object_open(sepa);
1958 if (rtd_data->stat_table.num_rtds == 1)
1959 type_str = val_to_str_const(j, vs, "Other"); /* 1 table - description per row */
1961 type_str = val_to_str_const(i, vs, "Other"); /* multiple table - description per table */
1962 sharkd_json_value_string(FALSE, "type", type_str);
1964 sharkd_json_value_anyf(TRUE, "num", "%u", ms->rtd[j].num);
1965 sharkd_json_value_anyf(TRUE, "min", "%.9f", nstime_to_sec(&(ms->rtd[j].min)));
1966 sharkd_json_value_anyf(TRUE, "max", "%.9f", nstime_to_sec(&(ms->rtd[j].max)));
1967 sharkd_json_value_anyf(TRUE, "tot", "%.9f", nstime_to_sec(&(ms->rtd[j].tot)));
1968 sharkd_json_value_anyf(TRUE, "min_frame", "%u", ms->rtd[j].min_num);
1969 sharkd_json_value_anyf(TRUE, "max_frame", "%u", ms->rtd[j].max_num);
1971 if (rtd_data->stat_table.num_rtds != 1)
1973 /* like in tshark, display it on every row */
1974 sharkd_json_value_anyf(TRUE, "open_req", "%u", ms->open_req_num);
1975 sharkd_json_value_anyf(TRUE, "disc_rsp", "%u", ms->disc_rsp_num);
1976 sharkd_json_value_anyf(TRUE, "req_dup", "%u", ms->req_dup_num);
1977 sharkd_json_value_anyf(TRUE, "rsp_dup", "%u", ms->rsp_dup_num);
1980 sharkd_json_object_close();
1984 sharkd_json_array_close();
1986 sharkd_json_object_close();
1991 sharkd_session_free_tap_rtd_cb(void *arg)
1993 rtd_data_t *rtd_data = (rtd_data_t *) arg;
1995 free_rtd_table(&rtd_data->stat_table);
2000 * sharkd_session_process_tap_srt_cb()
2003 * (m) tap - tap name
2004 * (m) type - tap output type
2006 * (m) tables - array of object with attributes:
2007 * (m) n - table name
2008 * (m) f - table filter
2009 * (o) c - table column name
2010 * (m) r - table rows - array object with attributes:
2012 * (m) idx - procedure index
2013 * (m) num - number of events
2014 * (m) min - minimum SRT time
2015 * (m) max - maximum SRT time
2016 * (m) tot - total SRT time
2019 sharkd_session_process_tap_srt_cb(void *arg)
2021 srt_data_t *srt_data = (srt_data_t *) arg;
2022 register_srt_t *srt = (register_srt_t *) srt_data->user_data;
2024 const char *filter = proto_get_protocol_filter_name(get_srt_proto_id(srt));
2028 sharkd_json_object_open(FALSE);
2029 sharkd_json_value_stringf(FALSE, "tap", "srt:%s", filter);
2030 sharkd_json_value_string(TRUE, "type", "srt");
2032 sharkd_json_array_open(TRUE, "tables");
2033 for (i = 0; i < srt_data->srt_array->len; i++)
2036 srt_stat_table *rst = g_array_index(srt_data->srt_array, srt_stat_table *, i);
2037 gboolean sepa = FALSE;
2041 sharkd_json_object_open(i != 0);
2044 sharkd_json_value_string(FALSE, "n", rst->name);
2045 else if (rst->short_name)
2046 sharkd_json_value_string(FALSE, "n", rst->short_name);
2048 sharkd_json_value_stringf(FALSE, "n", "table%u", i);
2050 if (rst->filter_string)
2051 sharkd_json_value_string(TRUE, "f", rst->filter_string);
2053 if (rst->proc_column_name)
2054 sharkd_json_value_string(TRUE, "c", rst->proc_column_name);
2056 sharkd_json_array_open(TRUE, "r");
2057 for (j = 0; j < rst->num_procs; j++)
2060 srt_procedure_t *proc = &rst->procedures[j];
2062 if (proc->stats.num == 0)
2065 sharkd_json_object_open(sepa);
2067 sharkd_json_value_string(FALSE, "n", proc->procedure);
2069 if (rst->filter_string)
2070 sharkd_json_value_anyf(TRUE, "idx", "%d", proc->proc_index);
2072 sharkd_json_value_anyf(TRUE, "num", "%u", proc->stats.num);
2074 sharkd_json_value_anyf(TRUE, "min", "%.9f", nstime_to_sec(&proc->stats.min));
2075 sharkd_json_value_anyf(TRUE, "max", "%.9f", nstime_to_sec(&proc->stats.max));
2076 sharkd_json_value_anyf(TRUE, "tot", "%.9f", nstime_to_sec(&proc->stats.tot));
2078 sharkd_json_object_close();
2081 sharkd_json_array_close();
2083 sharkd_json_object_close();
2085 sharkd_json_array_close();
2087 sharkd_json_object_close();
2092 sharkd_session_free_tap_srt_cb(void *arg)
2094 srt_data_t *srt_data = (srt_data_t *) arg;
2095 register_srt_t *srt = (register_srt_t *) srt_data->user_data;
2097 free_srt_table(srt, srt_data->srt_array);
2098 g_array_free(srt_data->srt_array, TRUE);
2102 struct sharkd_export_object_list
2104 struct sharkd_export_object_list *next;
2111 static struct sharkd_export_object_list *sharkd_eo_list;
2114 * sharkd_session_process_tap_eo_cb()
2117 * (m) tap - tap name
2118 * (m) type - tap output type
2119 * (m) proto - protocol short name
2120 * (m) objects - array of object with attributes:
2121 * (m) pkt - packet number
2122 * (o) hostname - hostname
2123 * (o) type - content type
2124 * (o) filename - filename
2125 * (m) len - object length
2128 sharkd_session_process_tap_eo_cb(void *tapdata)
2130 export_object_list_t *tap_object = (export_object_list_t *) tapdata;
2131 struct sharkd_export_object_list *object_list = (struct sharkd_export_object_list *) tap_object->gui_data;
2135 sharkd_json_object_open(FALSE);
2136 sharkd_json_value_string(FALSE, "tap", object_list->type);
2137 sharkd_json_value_string(TRUE, "type", "eo");
2139 sharkd_json_value_string(TRUE, "proto", object_list->proto);
2141 sharkd_json_array_open(TRUE, "objects");
2142 for (slist = object_list->entries; slist; slist = slist->next)
2144 const export_object_entry_t *eo_entry = (export_object_entry_t *) slist->data;
2146 sharkd_json_object_open(i != 0);
2148 sharkd_json_value_anyf(FALSE, "pkt", "%u", eo_entry->pkt_num);
2150 if (eo_entry->hostname)
2151 sharkd_json_value_string(TRUE, "hostname", eo_entry->hostname);
2153 if (eo_entry->content_type)
2154 sharkd_json_value_string(TRUE, "type", eo_entry->content_type);
2156 if (eo_entry->filename)
2157 sharkd_json_value_string(TRUE, "filename", eo_entry->filename);
2159 sharkd_json_value_stringf(TRUE, "_download", "%s_%d", object_list->type, i);
2161 sharkd_json_value_anyf(TRUE, "len", "%" G_GINT64_FORMAT, eo_entry->payload_len);
2163 sharkd_json_object_close();
2167 sharkd_json_array_close();
2169 sharkd_json_object_close();
2174 sharkd_eo_object_list_add_entry(void *gui_data, export_object_entry_t *entry)
2176 struct sharkd_export_object_list *object_list = (struct sharkd_export_object_list *) gui_data;
2178 object_list->entries = g_slist_append(object_list->entries, entry);
2181 static export_object_entry_t *
2182 sharkd_eo_object_list_get_entry(void *gui_data, int row)
2184 struct sharkd_export_object_list *object_list = (struct sharkd_export_object_list *) gui_data;
2186 return (export_object_entry_t *) g_slist_nth_data(object_list->entries, row);
2190 * sharkd_session_process_tap_rtp_cb()
2192 * Output RTP streams tap:
2193 * (m) tap - tap name
2194 * (m) type - tap output type
2195 * (m) streams - array of object with attributes:
2196 * (m) ssrc - RTP synchronization source identifier
2197 * (m) payload - stream payload
2198 * (m) saddr - source address
2199 * (m) sport - source port
2200 * (m) daddr - destination address
2201 * (m) dport - destination port
2202 * (m) pkts - packets count
2203 * (m) max_delta - max delta (ms)
2204 * (m) max_jitter - max jitter (ms)
2205 * (m) mean_jitter - mean jitter (ms)
2208 * (m) problem - if analyser found the problem
2209 * (m) ipver - address IP version (4 or 6)
2212 sharkd_session_process_tap_rtp_cb(void *arg)
2214 rtpstream_tapinfo_t *rtp_tapinfo = (rtpstream_tapinfo_t *) arg;
2217 gboolean sepa = FALSE;
2219 sharkd_json_object_open(FALSE);
2220 sharkd_json_value_string(FALSE, "tap", "rtp-streams");
2221 sharkd_json_value_string(TRUE, "type", "rtp-streams");
2223 sharkd_json_array_open(TRUE, "streams");
2224 for (listx = g_list_first(rtp_tapinfo->strinfo_list); listx; listx = listx->next)
2226 rtpstream_info_t *streaminfo = (rtpstream_info_t *) listx->data;
2227 rtpstream_info_calc_t calc;
2229 rtpstream_info_calculate(streaminfo, &calc);
2231 sharkd_json_object_open(sepa);
2233 sharkd_json_value_anyf(FALSE, "ssrc", "%u", calc.ssrc);
2234 sharkd_json_value_string(TRUE, "payload", calc.all_payload_type_names);
2236 sharkd_json_value_string(TRUE, "saddr", calc.src_addr_str);
2237 sharkd_json_value_anyf(TRUE, "sport", "%u", calc.src_port);
2238 sharkd_json_value_string(TRUE, "daddr", calc.dst_addr_str);
2239 sharkd_json_value_anyf(TRUE, "dport", "%u", calc.dst_port);
2241 sharkd_json_value_anyf(TRUE, "pkts", "%u", calc.packet_count);
2243 sharkd_json_value_anyf(TRUE, "max_delta", "%f",calc.max_delta);
2244 sharkd_json_value_anyf(TRUE, "max_jitter", "%f", calc.max_jitter);
2245 sharkd_json_value_anyf(TRUE, "mean_jitter", "%f", calc.mean_jitter);
2247 sharkd_json_value_anyf(TRUE, "expectednr", "%u", calc.packet_expected);
2248 sharkd_json_value_anyf(TRUE, "totalnr", "%u", calc.total_nr);
2250 sharkd_json_value_anyf(TRUE, "problem", calc.problem ? "true" : "false");
2253 sharkd_json_value_anyf(TRUE, "ipver", "%d", (streaminfo->id.src_addr.type == AT_IPv6) ? 6 : 4);
2255 rtpstream_info_calc_free(&calc);
2257 sharkd_json_object_close();
2260 sharkd_json_array_close();
2262 sharkd_json_object_close();
2267 * sharkd_session_process_tap()
2269 * Process tap request
2272 * (m) tap0 - First tap request
2273 * (o) tap1...tap15 - Other tap requests
2275 * Output object with attributes:
2276 * (m) taps - array of object with attributes:
2277 * (m) tap - tap name
2278 * (m) type - tap output type
2280 * for type:stats see sharkd_session_process_tap_stats_cb()
2281 * for type:nstat see sharkd_session_process_tap_nstat_cb()
2282 * for type:conv see sharkd_session_process_tap_conv_cb()
2283 * for type:host see sharkd_session_process_tap_conv_cb()
2284 * for type:rtp-streams see sharkd_session_process_tap_rtp_cb()
2285 * for type:rtp-analyse see sharkd_session_process_tap_rtp_analyse_cb()
2286 * for type:eo see sharkd_session_process_tap_eo_cb()
2287 * for type:expert see sharkd_session_process_tap_expert_cb()
2288 * for type:rtd see sharkd_session_process_tap_rtd_cb()
2289 * for type:srt see sharkd_session_process_tap_srt_cb()
2290 * for type:flow see sharkd_session_process_tap_flow_cb()
2292 * (m) err - error code
2295 sharkd_session_process_tap(char *buf, const jsmntok_t *tokens, int count)
2297 void *taps_data[16];
2298 GFreeFunc taps_free[16];
2302 rtpstream_tapinfo_t rtp_tapinfo =
2303 { NULL, NULL, NULL, NULL, 0, NULL, 0, TAP_ANALYSE, NULL, NULL, NULL, FALSE };
2305 for (i = 0; i < 16; i++)
2308 const char *tok_tap;
2310 void *tap_data = NULL;
2311 GFreeFunc tap_free = NULL;
2312 const char *tap_filter = "";
2313 GString *tap_error = NULL;
2315 ws_snprintf(tapbuf, sizeof(tapbuf), "tap%d", i);
2316 tok_tap = json_find_attr(buf, tokens, count, tapbuf);
2320 if (!strncmp(tok_tap, "stat:", 5))
2322 stats_tree_cfg *cfg = stats_tree_get_cfg_by_abbr(tok_tap + 5);
2327 fprintf(stderr, "sharkd_session_process_tap() stat %s not found\n", tok_tap + 5);
2331 st = stats_tree_new(cfg, NULL, tap_filter);
2333 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, NULL);
2335 if (!tap_error && cfg->init)
2339 tap_free = sharkd_session_free_tap_stats_cb;
2341 else if (!strcmp(tok_tap, "expert"))
2343 struct sharkd_expert_tap *expert_tap;
2345 expert_tap = g_new0(struct sharkd_expert_tap, 1);
2346 expert_tap->text = g_string_chunk_new(100);
2348 tap_error = register_tap_listener("expert", expert_tap, NULL, 0, NULL, sharkd_session_packet_tap_expert_cb, sharkd_session_process_tap_expert_cb, NULL);
2350 tap_data = expert_tap;
2351 tap_free = sharkd_session_free_tap_expert_cb;
2353 else if (!strncmp(tok_tap, "seqa:", 5))
2355 seq_analysis_info_t *graph_analysis;
2356 register_analysis_t *analysis;
2357 const char *tap_name;
2358 tap_packet_cb tap_func;
2361 analysis = sequence_analysis_find_by_name(tok_tap + 5);
2364 fprintf(stderr, "sharkd_session_process_tap() seq analysis %s not found\n", tok_tap + 5);
2368 graph_analysis = sequence_analysis_info_new();
2369 graph_analysis->name = tok_tap + 5;
2370 /* TODO, make configurable */
2371 graph_analysis->any_addr = FALSE;
2373 tap_name = sequence_analysis_get_tap_listener_name(analysis);
2374 tap_flags = sequence_analysis_get_tap_flags(analysis);
2375 tap_func = sequence_analysis_get_packet_func(analysis);
2377 tap_error = register_tap_listener(tap_name, graph_analysis, NULL, tap_flags, NULL, tap_func, sharkd_session_process_tap_flow_cb, NULL);
2379 tap_data = graph_analysis;
2380 tap_free = sharkd_session_free_tap_flow_cb;
2382 else if (!strncmp(tok_tap, "conv:", 5) || !strncmp(tok_tap, "endpt:", 6))
2384 struct register_ct *ct = NULL;
2385 const char *ct_tapname;
2386 struct sharkd_conv_tap_data *ct_data;
2387 tap_packet_cb tap_func = NULL;
2389 if (!strncmp(tok_tap, "conv:", 5))
2391 ct = get_conversation_by_proto_id(proto_get_id_by_short_name(tok_tap + 5));
2393 if (!ct || !(tap_func = get_conversation_packet_func(ct)))
2395 fprintf(stderr, "sharkd_session_process_tap() conv %s not found\n", tok_tap + 5);
2399 else if (!strncmp(tok_tap, "endpt:", 6))
2401 ct = get_conversation_by_proto_id(proto_get_id_by_short_name(tok_tap + 6));
2403 if (!ct || !(tap_func = get_hostlist_packet_func(ct)))
2405 fprintf(stderr, "sharkd_session_process_tap() endpt %s not found\n", tok_tap + 6);
2411 fprintf(stderr, "sharkd_session_process_tap() conv/endpt(?): %s not found\n", tok_tap);
2415 ct_tapname = proto_get_protocol_filter_name(get_conversation_proto_id(ct));
2417 ct_data = (struct sharkd_conv_tap_data *) g_malloc0(sizeof(struct sharkd_conv_tap_data));
2418 ct_data->type = tok_tap;
2419 ct_data->hash.user_data = ct_data;
2421 /* XXX: make configurable */
2422 ct_data->resolve_name = TRUE;
2423 ct_data->resolve_port = TRUE;
2425 tap_error = register_tap_listener(ct_tapname, &ct_data->hash, tap_filter, 0, NULL, tap_func, sharkd_session_process_tap_conv_cb, NULL);
2427 tap_data = &ct_data->hash;
2428 tap_free = sharkd_session_free_tap_conv_cb;
2430 else if (!strncmp(tok_tap, "nstat:", 6))
2432 stat_tap_table_ui *stat_tap = stat_tap_by_name(tok_tap + 6);
2433 stat_data_t *stat_data;
2437 fprintf(stderr, "sharkd_session_process_tap() nstat=%s not found\n", tok_tap + 6);
2441 stat_tap->stat_tap_init_cb(stat_tap);
2443 stat_data = g_new0(stat_data_t, 1);
2444 stat_data->stat_tap_data = stat_tap;
2445 stat_data->user_data = NULL;
2447 tap_error = register_tap_listener(stat_tap->tap_name, stat_data, tap_filter, 0, NULL, stat_tap->packet_func, sharkd_session_process_tap_nstat_cb, NULL);
2449 tap_data = stat_data;
2450 tap_free = sharkd_session_free_tap_nstat_cb;
2452 else if (!strncmp(tok_tap, "rtd:", 4))
2454 register_rtd_t *rtd = get_rtd_table_by_name(tok_tap + 4);
2455 rtd_data_t *rtd_data;
2460 fprintf(stderr, "sharkd_session_process_tap() rtd=%s not found\n", tok_tap + 4);
2464 rtd_table_get_filter(rtd, "", &tap_filter, &err);
2467 fprintf(stderr, "sharkd_session_process_tap() rtd=%s err=%s\n", tok_tap + 4, err);
2472 rtd_data = g_new0(rtd_data_t, 1);
2473 rtd_data->user_data = rtd;
2474 rtd_table_dissector_init(rtd, &rtd_data->stat_table, NULL, NULL);
2476 tap_error = register_tap_listener(get_rtd_tap_listener_name(rtd), rtd_data, tap_filter, 0, NULL, get_rtd_packet_func(rtd), sharkd_session_process_tap_rtd_cb, NULL);
2478 tap_data = rtd_data;
2479 tap_free = sharkd_session_free_tap_rtd_cb;
2481 else if (!strncmp(tok_tap, "srt:", 4))
2483 register_srt_t *srt = get_srt_table_by_name(tok_tap + 4);
2484 srt_data_t *srt_data;
2489 fprintf(stderr, "sharkd_session_process_tap() srt=%s not found\n", tok_tap + 4);
2493 srt_table_get_filter(srt, "", &tap_filter, &err);
2496 fprintf(stderr, "sharkd_session_process_tap() srt=%s err=%s\n", tok_tap + 4, err);
2501 srt_data = g_new0(srt_data_t, 1);
2502 srt_data->srt_array = g_array_new(FALSE, TRUE, sizeof(srt_stat_table *));
2503 srt_data->user_data = srt;
2504 srt_table_dissector_init(srt, srt_data->srt_array);
2506 tap_error = register_tap_listener(get_srt_tap_listener_name(srt), srt_data, tap_filter, 0, NULL, get_srt_packet_func(srt), sharkd_session_process_tap_srt_cb, NULL);
2508 tap_data = srt_data;
2509 tap_free = sharkd_session_free_tap_srt_cb;
2511 else if (!strncmp(tok_tap, "eo:", 3))
2513 register_eo_t *eo = get_eo_by_name(tok_tap + 3);
2514 export_object_list_t *eo_object;
2515 struct sharkd_export_object_list *object_list;
2519 fprintf(stderr, "sharkd_session_process_tap() eo=%s not found\n", tok_tap + 3);
2523 for (object_list = sharkd_eo_list; object_list; object_list = object_list->next)
2525 if (!strcmp(object_list->type, tok_tap))
2527 g_slist_free_full(object_list->entries, (GDestroyNotify) eo_free_entry);
2528 object_list->entries = NULL;
2535 object_list = g_new(struct sharkd_export_object_list, 1);
2536 object_list->type = g_strdup(tok_tap);
2537 object_list->proto = proto_get_protocol_short_name(find_protocol_by_id(get_eo_proto_id(eo)));
2538 object_list->entries = NULL;
2539 object_list->next = sharkd_eo_list;
2540 sharkd_eo_list = object_list;
2543 eo_object = g_new0(export_object_list_t, 1);
2544 eo_object->add_entry = sharkd_eo_object_list_add_entry;
2545 eo_object->get_entry = sharkd_eo_object_list_get_entry;
2546 eo_object->gui_data = (void *) object_list;
2548 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, NULL);
2550 tap_data = eo_object;
2551 tap_free = g_free; /* need to free only eo_object, object_list need to be kept for potential download */
2553 else if (!strcmp(tok_tap, "rtp-streams"))
2555 tap_error = register_tap_listener("rtp", &rtp_tapinfo, tap_filter, 0, rtpstream_reset_cb, rtpstream_packet_cb, sharkd_session_process_tap_rtp_cb, NULL);
2557 tap_data = &rtp_tapinfo;
2558 tap_free = rtpstream_reset_cb;
2560 else if (!strncmp(tok_tap, "rtp-analyse:", 12))
2562 struct sharkd_analyse_rtp *rtp_req;
2564 rtp_req = (struct sharkd_analyse_rtp *) g_malloc0(sizeof(*rtp_req));
2565 if (!sharkd_rtp_match_init(&rtp_req->id, tok_tap + 12))
2567 rtpstream_id_free(&rtp_req->id);
2572 rtp_req->tap_name = tok_tap;
2573 rtp_req->statinfo.first_packet = TRUE;
2574 rtp_req->statinfo.reg_pt = PT_UNDEFINED;
2576 tap_error = register_tap_listener("rtp", rtp_req, tap_filter, 0, NULL, sharkd_session_packet_tap_rtp_analyse_cb, sharkd_session_process_tap_rtp_analyse_cb, NULL);
2579 tap_free = sharkd_session_process_tap_rtp_free_cb;
2583 fprintf(stderr, "sharkd_session_process_tap() %s not recognized\n", tok_tap);
2589 fprintf(stderr, "sharkd_session_process_tap() name=%s error=%s", tok_tap, tap_error->str);
2590 g_string_free(tap_error, TRUE);
2596 taps_data[taps_count] = tap_data;
2597 taps_free[taps_count] = tap_free;
2601 fprintf(stderr, "sharkd_session_process_tap() count=%d\n", taps_count);
2602 if (taps_count == 0)
2605 sharkd_json_object_open(FALSE);
2607 sharkd_json_array_open(FALSE, "taps");
2609 // This dummy value exists to permit unconditionally adding ',' in the taps callback.
2610 // XXX convert to json_dumper and remove this.
2611 sharkd_json_value_anyf(FALSE, NULL, "null");
2612 sharkd_json_array_close();
2614 sharkd_json_value_anyf(TRUE, "err", "0");
2616 sharkd_json_object_close();
2617 sharkd_json_finish();
2619 for (i = 0; i < taps_count; i++)
2622 remove_tap_listener(taps_data[i]);
2625 taps_free[i](taps_data[i]);
2630 * sharkd_session_process_follow()
2632 * Process follow request
2635 * (m) follow - follow protocol request (e.g. HTTP)
2636 * (m) filter - filter request (e.g. tcp.stream == 1)
2638 * Output object with attributes:
2640 * (m) err - error code
2641 * (m) shost - server host
2642 * (m) sport - server port
2643 * (m) sbytes - server send bytes count
2644 * (m) chost - client host
2645 * (m) cport - client port
2646 * (m) cbytes - client send bytes count
2647 * (o) payloads - array of object with attributes:
2648 * (o) s - set if server sent, else client
2649 * (m) n - packet number
2650 * (m) d - data base64 encoded
2653 sharkd_session_process_follow(char *buf, const jsmntok_t *tokens, int count)
2655 const char *tok_follow = json_find_attr(buf, tokens, count, "follow");
2656 const char *tok_filter = json_find_attr(buf, tokens, count, "filter");
2658 register_follow_t *follower;
2661 follow_info_t *follow_info;
2665 if (!tok_follow || !tok_filter)
2668 follower = get_follow_by_name(tok_follow);
2671 fprintf(stderr, "sharkd_session_process_follow() follower=%s not found\n", tok_follow);
2675 /* follow_reset_stream ? */
2676 follow_info = g_new0(follow_info_t, 1);
2677 /* gui_data, filter_out_filter not set, but not used by dissector */
2679 tap_error = register_tap_listener(get_follow_tap_string(follower), follow_info, tok_filter, 0, NULL, get_follow_tap_handler(follower), NULL, NULL);
2682 fprintf(stderr, "sharkd_session_process_follow() name=%s error=%s", tok_follow, tap_error->str);
2683 g_string_free(tap_error, TRUE);
2684 g_free(follow_info);
2690 sharkd_json_object_open(FALSE);
2692 sharkd_json_value_anyf(FALSE, "err", "0");
2694 /* Server information: hostname, port, bytes sent */
2695 host = address_to_name(&follow_info->server_ip);
2696 sharkd_json_value_string(TRUE, "shost", host);
2698 port = get_follow_port_to_display(follower)(NULL, follow_info->server_port);
2699 sharkd_json_value_string(TRUE, "sport", port);
2700 wmem_free(NULL, port);
2702 sharkd_json_value_anyf(TRUE, "sbytes", "%u", follow_info->bytes_written[0]);
2704 /* Client information: hostname, port, bytes sent */
2705 host = address_to_name(&follow_info->client_ip);
2706 sharkd_json_value_string(TRUE, "chost", host);
2708 port = get_follow_port_to_display(follower)(NULL, follow_info->client_port);
2709 sharkd_json_value_string(TRUE, "cport", port);
2710 wmem_free(NULL, port);
2712 sharkd_json_value_anyf(TRUE, "cbytes", "%u", follow_info->bytes_written[1]);
2714 if (follow_info->payload)
2716 follow_record_t *follow_record;
2718 gboolean sepa = FALSE;
2720 sharkd_json_array_open(TRUE, "payloads");
2721 for (cur = g_list_last(follow_info->payload); cur; cur = g_list_previous(cur))
2723 follow_record = (follow_record_t *) cur->data;
2725 sharkd_json_object_open(sepa);
2727 sharkd_json_value_anyf(FALSE, "n", "%u", follow_record->packet_num);
2728 sharkd_json_value_base64(TRUE, "d", follow_record->data->data, follow_record->data->len);
2730 if (follow_record->is_server)
2731 sharkd_json_value_anyf(TRUE, "s", "%d", 1);
2733 sharkd_json_object_close();
2736 sharkd_json_array_close();
2739 sharkd_json_object_close();
2740 sharkd_json_finish();
2742 remove_tap_listener(follow_info);
2743 follow_info_free(follow_info);
2747 sharkd_session_process_frame_cb_tree(epan_dissect_t *edt, proto_tree *tree, tvbuff_t **tvbs, gboolean display_hidden)
2750 gboolean sepa = FALSE;
2752 sharkd_json_array_open(FALSE, NULL);
2753 for (node = tree->first_child; node; node = node->next)
2755 field_info *finfo = PNODE_FINFO(node);
2760 if (!display_hidden && FI_GET_FLAG(finfo, FI_HIDDEN))
2763 sharkd_json_object_open(sepa);
2767 char label_str[ITEM_LABEL_LENGTH];
2769 label_str[0] = '\0';
2770 proto_item_fill_label(finfo, label_str);
2771 sharkd_json_value_string(FALSE, "l", label_str);
2775 sharkd_json_value_string(FALSE, "l", finfo->rep->representation);
2778 if (finfo->ds_tvb && tvbs && tvbs[0] != finfo->ds_tvb)
2782 for (idx = 1; tvbs[idx]; idx++)
2784 if (tvbs[idx] == finfo->ds_tvb)
2786 sharkd_json_value_anyf(TRUE, "ds", "%d", idx);
2792 if (finfo->start >= 0 && finfo->length > 0)
2793 sharkd_json_value_anyf(TRUE, "h", "[%d,%d]", finfo->start, finfo->length);
2795 if (finfo->appendix_start >= 0 && finfo->appendix_length > 0)
2796 sharkd_json_value_anyf(TRUE, "i", "[%d,%d]", finfo->appendix_start, finfo->appendix_length);
2803 if (finfo->hfinfo->type == FT_PROTOCOL)
2805 sharkd_json_value_string(TRUE, "t", "proto");
2807 else if (finfo->hfinfo->type == FT_FRAMENUM)
2809 sharkd_json_value_string(TRUE, "t", "framenum");
2810 sharkd_json_value_anyf(TRUE, "fnum", "%u", finfo->value.value.uinteger);
2812 else if (FI_GET_FLAG(finfo, FI_URL) && IS_FT_STRING(finfo->hfinfo->type))
2814 char *url = fvalue_to_string_repr(NULL, &finfo->value, FTREPR_DISPLAY, finfo->hfinfo->display);
2816 sharkd_json_value_string(TRUE, "t", "url");
2817 sharkd_json_value_string(TRUE, "url", url);
2818 wmem_free(NULL, url);
2821 filter = proto_construct_match_selected_string(finfo, edt);
2824 sharkd_json_value_string(TRUE, "f", filter);
2825 wmem_free(NULL, filter);
2829 if (FI_GET_FLAG(finfo, FI_GENERATED))
2830 sharkd_json_value_anyf(TRUE, "g", "true");
2832 if (FI_GET_FLAG(finfo, FI_HIDDEN))
2833 sharkd_json_value_anyf(TRUE, "v", "true");
2835 if (FI_GET_FLAG(finfo, PI_SEVERITY_MASK))
2837 const char *severity = try_val_to_str(FI_GET_FLAG(finfo, PI_SEVERITY_MASK), expert_severity_vals);
2839 g_assert(severity != NULL);
2841 sharkd_json_value_string(TRUE, "s", severity);
2844 if (((proto_tree *) node)->first_child)
2846 if (finfo->tree_type != -1)
2847 sharkd_json_value_anyf(TRUE, "e", "%d", finfo->tree_type);
2849 sharkd_json_value_anyf(TRUE, "n", NULL);
2850 sharkd_session_process_frame_cb_tree(edt, (proto_tree *) node, tvbs, display_hidden);
2853 sharkd_json_object_close();
2856 sharkd_json_array_close();
2860 sharkd_follower_visit_layers_cb(const void *key _U_, void *value, void *user_data)
2862 register_follow_t *follower = (register_follow_t *) value;
2863 packet_info *pi = (packet_info *) user_data;
2865 const int proto_id = get_follow_proto_id(follower);
2867 guint32 ignore_stream;
2869 if (proto_is_frame_protocol(pi->layers, proto_get_protocol_filter_name(proto_id)))
2871 const char *layer_proto = proto_get_protocol_short_name(find_protocol_by_id(proto_id));
2872 char *follow_filter;
2874 follow_filter = get_follow_conv_func(follower)(pi, &ignore_stream);
2876 sharkd_json_array_open(TRUE, NULL);
2877 sharkd_json_value_string(FALSE, NULL, layer_proto);
2878 sharkd_json_value_string(TRUE, NULL, follow_filter);
2879 sharkd_json_array_close();
2881 g_free(follow_filter);
2887 struct sharkd_frame_request_data
2889 gboolean display_hidden;
2893 sharkd_session_process_frame_cb(epan_dissect_t *edt, proto_tree *tree, struct epan_column_info *cinfo, const GSList *data_src, void *data)
2895 packet_info *pi = &edt->pi;
2896 frame_data *fdata = pi->fd;
2897 const char *pkt_comment = NULL;
2899 const struct sharkd_frame_request_data * const req_data = (const struct sharkd_frame_request_data * const) data;
2900 const gboolean display_hidden = (req_data) ? req_data->display_hidden : FALSE;
2902 sharkd_json_object_open(FALSE);
2904 sharkd_json_value_anyf(FALSE, "err", "0");
2906 if (fdata->has_user_comment)
2907 pkt_comment = sharkd_get_user_comment(fdata);
2908 else if (fdata->has_phdr_comment)
2909 pkt_comment = pi->rec->opt_comment;
2912 sharkd_json_value_string(TRUE, "comment", pkt_comment);
2916 tvbuff_t **tvbs = NULL;
2918 /* arrayize data src, to speedup searching for ds_tvb index */
2919 if (data_src && data_src->next /* only needed if there are more than one data source */)
2921 guint count = g_slist_length((GSList *) data_src);
2924 tvbs = (tvbuff_t **) g_malloc((count + 1) * sizeof(*tvbs));
2926 for (i = 0; i < count; i++)
2928 const struct data_source *src = (const struct data_source *) g_slist_nth_data((GSList *) data_src, i);
2930 tvbs[i] = get_data_source_tvb(src);
2936 sharkd_json_value_anyf(TRUE, "tree", NULL);
2937 sharkd_session_process_frame_cb_tree(edt, tree, tvbs, display_hidden);
2946 sharkd_json_array_open(TRUE, "col");
2947 for (col = 0; col < cinfo->num_cols; ++col)
2949 const col_item_t *col_item = &cinfo->columns[col];
2951 sharkd_json_value_string(col != 0, NULL, col_item->col_data);
2953 sharkd_json_array_close();
2957 sharkd_json_value_anyf(TRUE, "i", "true");
2960 sharkd_json_value_anyf(TRUE, "m", "true");
2962 if (fdata->color_filter)
2964 sharkd_json_value_stringf(TRUE, "bg", "%x", color_t_to_rgb(&fdata->color_filter->bg_color));
2965 sharkd_json_value_stringf(TRUE, "fg", "%x", color_t_to_rgb(&fdata->color_filter->fg_color));
2970 struct data_source *src = (struct data_source *) data_src->data;
2971 gboolean ds_sepa = FALSE;
2972 gboolean ds_open = FALSE;
2977 tvb = get_data_source_tvb(src);
2978 length = tvb_captured_length(tvb);
2982 const guchar *cp = tvb_get_ptr(tvb, 0, length);
2984 /* XXX pi.fd->encoding */
2985 sharkd_json_value_base64(TRUE, "bytes", cp, length);
2989 sharkd_json_value_base64(TRUE, "bytes", "", 0);
2992 data_src = data_src->next;
2995 sharkd_json_array_open(TRUE, "ds");
3001 src = (struct data_source *) data_src->data;
3003 sharkd_json_object_open(ds_sepa);
3006 char *src_name = get_data_source_name(src);
3008 sharkd_json_value_string(FALSE, "name", src_name);
3009 wmem_free(NULL, src_name);
3012 tvb = get_data_source_tvb(src);
3013 length = tvb_captured_length(tvb);
3017 const guchar *cp = tvb_get_ptr(tvb, 0, length);
3019 /* XXX pi.fd->encoding */
3020 sharkd_json_value_base64(TRUE, "bytes", cp, length);
3024 sharkd_json_value_base64(TRUE, "bytes", "", 0);
3027 sharkd_json_object_close();
3030 data_src = data_src->next;
3033 /* close ds, only if was opened */
3035 sharkd_json_array_close();
3038 sharkd_json_array_open(TRUE, "fol");
3039 // This dummy entry allows sharkd_follower_visit_layers_cb() to always insert ',' before dumping item.
3040 // XXX convert to json_dumper and remove the dummy entry.
3041 sharkd_json_value_anyf(FALSE, NULL, "0");
3042 follow_iterate_followers(sharkd_follower_visit_layers_cb, pi);
3043 sharkd_json_array_close();
3045 sharkd_json_object_close();
3046 sharkd_json_finish();
3049 #define SHARKD_IOGRAPH_MAX_ITEMS 250000 /* 250k limit of items is taken from wireshark-qt, on x86_64 sizeof(io_graph_item_t) is 152, so single graph can take max 36 MB */
3051 struct sharkd_iograph
3055 io_graph_item_unit_t calc_type;
3061 io_graph_item_t *items;
3066 sharkd_iograph_packet(void *g, packet_info *pinfo, epan_dissect_t *edt, const void *dummy _U_)
3068 struct sharkd_iograph *graph = (struct sharkd_iograph *) g;
3071 idx = get_io_graph_index(pinfo, graph->interval);
3072 if (idx < 0 || idx >= SHARKD_IOGRAPH_MAX_ITEMS)
3075 if (idx + 1 > graph->num_items)
3077 if (idx + 1 > graph->space_items)
3079 int new_size = idx + 1024;
3081 graph->items = (io_graph_item_t *) g_realloc(graph->items, sizeof(io_graph_item_t) * new_size);
3082 reset_io_graph_items(&graph->items[graph->space_items], new_size - graph->space_items);
3084 graph->space_items = new_size;
3086 else if (graph->items == NULL)
3088 graph->items = (io_graph_item_t *) g_malloc(sizeof(io_graph_item_t) * graph->space_items);
3089 reset_io_graph_items(graph->items, graph->space_items);
3092 graph->num_items = idx + 1;
3095 return update_io_graph_item(graph->items, idx, pinfo, edt, graph->hf_index, graph->calc_type, graph->interval);
3099 * sharkd_session_process_iograph()
3101 * Process iograph request
3104 * (o) interval - interval time in ms, if not specified: 1000ms
3105 * (m) graph0 - First graph request
3106 * (o) graph1...graph9 - Other graph requests
3107 * (o) filter0 - First graph filter
3108 * (o) filter1...filter9 - Other graph filters
3110 * Graph requests can be one of: "packets", "bytes", "bits", "sum:<field>", "frames:<field>", "max:<field>", "min:<field>", "avg:<field>", "load:<field>",
3111 * if you use variant with <field>, you need to pass field name in filter request.
3113 * Output object with attributes:
3114 * (m) iograph - array of graph results with attributes:
3115 * errmsg - graph cannot be constructed
3116 * items - graph values, zeros are skipped, if value is not a number it's next index encoded as hex string
3119 sharkd_session_process_iograph(char *buf, const jsmntok_t *tokens, int count)
3121 const char *tok_interval = json_find_attr(buf, tokens, count, "interval");
3122 struct sharkd_iograph graphs[10];
3123 gboolean is_any_ok = FALSE;
3126 guint32 interval_ms = 1000; /* default: one per second */
3131 if (!ws_strtou32(tok_interval, NULL, &interval_ms) || interval_ms == 0)
3133 fprintf(stderr, "Invalid interval parameter: %s.\n", tok_interval);
3138 for (i = graph_count = 0; i < (int) G_N_ELEMENTS(graphs); i++)
3140 struct sharkd_iograph *graph = &graphs[graph_count];
3142 const char *tok_graph;
3143 const char *tok_filter;
3144 char tok_format_buf[32];
3145 const char *field_name;
3147 snprintf(tok_format_buf, sizeof(tok_format_buf), "graph%d", i);
3148 tok_graph = json_find_attr(buf, tokens, count, tok_format_buf);
3152 snprintf(tok_format_buf, sizeof(tok_format_buf), "filter%d", i);
3153 tok_filter = json_find_attr(buf, tokens, count, tok_format_buf);
3155 if (!strcmp(tok_graph, "packets"))
3156 graph->calc_type = IOG_ITEM_UNIT_PACKETS;
3157 else if (!strcmp(tok_graph, "bytes"))
3158 graph->calc_type = IOG_ITEM_UNIT_BYTES;
3159 else if (!strcmp(tok_graph, "bits"))
3160 graph->calc_type = IOG_ITEM_UNIT_BITS;
3161 else if (g_str_has_prefix(tok_graph, "sum:"))
3162 graph->calc_type = IOG_ITEM_UNIT_CALC_SUM;
3163 else if (g_str_has_prefix(tok_graph, "frames:"))
3164 graph->calc_type = IOG_ITEM_UNIT_CALC_FRAMES;
3165 else if (g_str_has_prefix(tok_graph, "fields:"))
3166 graph->calc_type = IOG_ITEM_UNIT_CALC_FIELDS;
3167 else if (g_str_has_prefix(tok_graph, "max:"))
3168 graph->calc_type = IOG_ITEM_UNIT_CALC_MAX;
3169 else if (g_str_has_prefix(tok_graph, "min:"))
3170 graph->calc_type = IOG_ITEM_UNIT_CALC_MIN;
3171 else if (g_str_has_prefix(tok_graph, "avg:"))
3172 graph->calc_type = IOG_ITEM_UNIT_CALC_AVERAGE;
3173 else if (g_str_has_prefix(tok_graph, "load:"))
3174 graph->calc_type = IOG_ITEM_UNIT_CALC_LOAD;
3178 field_name = strchr(tok_graph, ':');
3180 field_name = field_name + 1;
3182 graph->interval = interval_ms;
3184 graph->hf_index = -1;
3185 graph->error = check_field_unit(field_name, &graph->hf_index, graph->calc_type);
3187 graph->space_items = 0; /* TODO, can avoid realloc()s in sharkd_iograph_packet() by calculating: capture_time / interval */
3188 graph->num_items = 0;
3189 graph->items = NULL;
3192 graph->error = register_tap_listener("frame", graph, tok_filter, TL_REQUIRES_PROTO_TREE, NULL, sharkd_iograph_packet, NULL, NULL);
3196 if (graph->error == NULL)
3200 /* retap only if we have at least one ok */
3204 sharkd_json_object_open(FALSE);
3206 sharkd_json_array_open(FALSE, "iograph");
3207 for (i = 0; i < graph_count; i++)
3209 struct sharkd_iograph *graph = &graphs[i];
3211 sharkd_json_object_open(i != 0);
3215 sharkd_json_value_string(FALSE, "errmsg", graph->error->str);
3216 g_string_free(graph->error, TRUE);
3223 sharkd_json_array_open(FALSE, "items");
3224 for (idx = 0; idx < graph->num_items; idx++)
3228 val = get_io_graph_item(graph->items, graph->calc_type, idx, graph->hf_index, &cfile, graph->interval, graph->num_items);
3230 /* if it's zero, don't display */
3234 /* cause zeros are not printed, need to output index */
3235 if (next_idx != idx)
3236 sharkd_json_value_stringf(next_idx != 0, NULL, "%x", idx);
3238 sharkd_json_value_anyf(idx != 0, NULL, "%f", val);
3241 sharkd_json_array_close();
3243 sharkd_json_object_close();
3245 remove_tap_listener(graph);
3246 g_free(graph->items);
3248 sharkd_json_array_close();
3250 sharkd_json_object_close();
3251 sharkd_json_finish();
3255 * sharkd_session_process_intervals()
3257 * Process intervals request - generate basic capture file statistics per requested interval.
3260 * (o) interval - interval time in ms, if not specified: 1000ms
3261 * (o) filter - filter for generating interval request
3263 * Output object with attributes:
3264 * (m) intervals - array of intervals, with indexes:
3265 * [0] - index of interval,
3266 * [1] - number of frames during interval,
3267 * [2] - number of bytes during interval.
3269 * (m) last - last interval number.
3270 * (m) frames - total number of frames
3271 * (m) bytes - total number of bytes
3273 * NOTE: If frames are not in order, there might be items with same interval index, or even negative one.
3276 sharkd_session_process_intervals(char *buf, const jsmntok_t *tokens, int count)
3278 const char *tok_interval = json_find_attr(buf, tokens, count, "interval");
3279 const char *tok_filter = json_find_attr(buf, tokens, count, "filter");
3281 const guint8 *filter_data = NULL;
3285 unsigned int frames;
3291 guint32 interval_ms = 1000; /* default: one per second */
3293 gboolean sepa = FALSE;
3294 unsigned int framenum;
3300 if (!ws_strtou32(tok_interval, NULL, &interval_ms) || interval_ms == 0)
3302 fprintf(stderr, "Invalid interval parameter: %s.\n", tok_interval);
3309 const struct sharkd_filter_item *filter_item;
3311 filter_item = sharkd_session_filter_data(tok_filter);
3314 filter_data = filter_item->filtered;
3317 st_total.frames = 0;
3325 sharkd_json_object_open(FALSE);
3326 sharkd_json_array_open(FALSE, "intervals");
3328 start_ts = (cfile.count >= 1) ? &(sharkd_get_frame(1)->abs_ts) : NULL;
3330 for (framenum = 1; framenum <= cfile.count; framenum++)
3336 if (filter_data && !(filter_data[framenum / 8] & (1 << (framenum % 8))))
3339 fdata = sharkd_get_frame(framenum);
3341 msec_rel = (fdata->abs_ts.secs - start_ts->secs) * (gint64) 1000 + (fdata->abs_ts.nsecs - start_ts->nsecs) / 1000000;
3342 new_idx = msec_rel / interval_ms;
3348 sharkd_json_value_anyf(sepa, NULL, "[%" G_GINT64_FORMAT ",%u,%" G_GUINT64_FORMAT "]", idx, st.frames, st.bytes);
3361 st.bytes += fdata->pkt_len;
3363 st_total.frames += 1;
3364 st_total.bytes += fdata->pkt_len;
3369 sharkd_json_value_anyf(sepa, NULL, "[%" G_GINT64_FORMAT ",%u,%" G_GUINT64_FORMAT "]", idx, st.frames, st.bytes);
3372 sharkd_json_array_close();
3374 sharkd_json_value_anyf(TRUE, "last", "%" G_GINT64_FORMAT, max_idx);
3375 sharkd_json_value_anyf(TRUE, "frames", "%u", st_total.frames);
3376 sharkd_json_value_anyf(TRUE, "bytes", "%" G_GUINT64_FORMAT, st_total.bytes);
3378 sharkd_json_object_close();
3379 sharkd_json_finish();
3383 * sharkd_session_process_frame()
3385 * Process frame request
3388 * (m) frame - requested frame number
3389 * (o) ref_frame - time reference frame number
3390 * (o) prev_frame - previously displayed frame number
3391 * (o) proto - set if output frame tree
3392 * (o) columns - set if output frame columns
3393 * (o) color - set if output color-filter bg/fg
3394 * (o) bytes - set if output frame bytes
3395 * (o) hidden - set if output hidden tree fields
3397 * Output object with attributes:
3398 * (m) err - 0 if succeed
3399 * (o) tree - array of frame nodes with attributes:
3401 * t: 'proto', 'framenum', 'url' - type of node
3404 * e - subtree ett index
3405 * n - array of subtree nodes
3406 * h - two item array: (item start, item length)
3407 * i - two item array: (appendix start, appendix length)
3408 * p - [RESERVED] two item array: (protocol start, protocol length)
3409 * ds- data src index
3410 * url - only for t:'url', url
3411 * fnum - only for t:'framenum', frame number
3412 * g - if field is generated by Wireshark
3413 * v - if field is hidden
3415 * (o) col - array of column data
3416 * (o) bytes - base64 of frame bytes
3417 * (o) ds - array of other data srcs
3418 * (o) comment - frame comment
3419 * (o) fol - array of follow filters:
3421 * [1] - filter string
3422 * (o) i - if frame is ignored
3423 * (o) m - if frame is marked
3424 * (o) bg - color filter - background color in hex
3425 * (o) fg - color filter - foreground color in hex
3428 sharkd_session_process_frame(char *buf, const jsmntok_t *tokens, int count)
3430 const char *tok_frame = json_find_attr(buf, tokens, count, "frame");
3431 const char *tok_ref_frame = json_find_attr(buf, tokens, count, "ref_frame");
3432 const char *tok_prev_frame = json_find_attr(buf, tokens, count, "prev_frame");
3434 guint32 framenum, ref_frame_num, prev_dis_num;
3435 guint32 dissect_flags = SHARKD_DISSECT_FLAG_NULL;
3436 struct sharkd_frame_request_data req_data;
3438 if (!tok_frame || !ws_strtou32(tok_frame, NULL, &framenum) || framenum == 0)
3441 ref_frame_num = (framenum != 1) ? 1 : 0;
3442 if (tok_ref_frame && (!ws_strtou32(tok_ref_frame, NULL, &ref_frame_num) || ref_frame_num > framenum))
3445 prev_dis_num = framenum - 1;
3446 if (tok_prev_frame && (!ws_strtou32(tok_prev_frame, NULL, &prev_dis_num) || prev_dis_num >= framenum))
3449 if (json_find_attr(buf, tokens, count, "proto") != NULL)
3450 dissect_flags |= SHARKD_DISSECT_FLAG_PROTO_TREE;
3451 if (json_find_attr(buf, tokens, count, "bytes") != NULL)
3452 dissect_flags |= SHARKD_DISSECT_FLAG_BYTES;
3453 if (json_find_attr(buf, tokens, count, "columns") != NULL)
3454 dissect_flags |= SHARKD_DISSECT_FLAG_COLUMNS;
3455 if (json_find_attr(buf, tokens, count, "color") != NULL)
3456 dissect_flags |= SHARKD_DISSECT_FLAG_COLOR;
3458 req_data.display_hidden = (json_find_attr(buf, tokens, count, "v") != NULL);
3460 sharkd_dissect_request(framenum, ref_frame_num, prev_dis_num, &sharkd_session_process_frame_cb, dissect_flags, &req_data);
3464 * sharkd_session_process_check()
3466 * Process check request.
3469 * (o) filter - filter to be checked
3470 * (o) field - field to be checked
3472 * Output object with attributes:
3473 * (m) err - always 0
3474 * (o) filter - 'ok', 'warn' or error message
3475 * (o) field - 'ok', or 'notfound'
3478 sharkd_session_process_check(char *buf, const jsmntok_t *tokens, int count)
3480 const char *tok_filter = json_find_attr(buf, tokens, count, "filter");
3481 const char *tok_field = json_find_attr(buf, tokens, count, "field");
3483 sharkd_json_object_open(FALSE);
3484 sharkd_json_value_anyf(FALSE, "err", "0");
3486 if (tok_filter != NULL)
3488 char *err_msg = NULL;
3491 if (dfilter_compile(tok_filter, &dfp, &err_msg))
3493 const char *s = "ok";
3495 if (dfp && dfilter_deprecated_tokens(dfp))
3498 sharkd_json_value_string(TRUE, "filter", s);
3503 sharkd_json_value_string(TRUE, "filter", err_msg);
3508 if (tok_field != NULL)
3510 header_field_info *hfi = proto_registrar_get_byname(tok_field);
3512 sharkd_json_value_string(TRUE, "field", (hfi) ? "ok" : "notfound");
3515 sharkd_json_object_close();
3516 sharkd_json_finish();
3521 struct sharkd_session_process_complete_pref_data
3529 sharkd_session_process_complete_pref_cb(module_t *module, gpointer d)
3531 struct sharkd_session_process_complete_pref_data *data = (struct sharkd_session_process_complete_pref_data *) d;
3533 if (strncmp(data->pref, module->name, strlen(data->pref)) != 0)
3536 sharkd_json_object_open(data->sepa);
3537 sharkd_json_value_string(FALSE, "f", module->name);
3538 sharkd_json_value_string(TRUE, "d", module->title);
3539 sharkd_json_object_close();
3547 sharkd_session_process_complete_pref_option_cb(pref_t *pref, gpointer d)
3549 struct sharkd_session_process_complete_pref_data *data = (struct sharkd_session_process_complete_pref_data *) d;
3550 const char *pref_name = prefs_get_name(pref);
3551 const char *pref_title = prefs_get_title(pref);
3553 if (strncmp(data->pref, pref_name, strlen(data->pref)) != 0)
3556 sharkd_json_object_open(data->sepa);
3557 sharkd_json_value_stringf(FALSE, "f", "%s.%s", data->module, pref_name);
3558 sharkd_json_value_string(TRUE, "d", pref_title);
3559 sharkd_json_object_close();
3563 return 0; /* continue */
3567 * sharkd_session_process_complete()
3569 * Process complete request
3572 * (o) field - field to be completed
3573 * (o) pref - preference to be completed
3575 * Output object with attributes:
3576 * (m) err - always 0
3577 * (o) field - array of object with attributes:
3578 * (m) f - field text
3579 * (o) t - field type (FT_ number)
3580 * (o) n - field name
3581 * (o) pref - array of object with attributes:
3583 * (o) d - pref description
3586 sharkd_session_process_complete(char *buf, const jsmntok_t *tokens, int count)
3588 const char *tok_field = json_find_attr(buf, tokens, count, "field");
3589 const char *tok_pref = json_find_attr(buf, tokens, count, "pref");
3591 sharkd_json_object_open(FALSE);
3592 sharkd_json_value_anyf(FALSE, "err", "0");
3594 if (tok_field != NULL && tok_field[0])
3596 const size_t filter_length = strlen(tok_field);
3597 const int filter_with_dot = !!strchr(tok_field, '.');
3602 gboolean sepa = FALSE;
3604 sharkd_json_array_open(TRUE, "field");
3606 for (proto_id = proto_get_first_protocol(&proto_cookie); proto_id != -1; proto_id = proto_get_next_protocol(&proto_cookie))
3608 protocol_t *protocol = find_protocol_by_id(proto_id);
3609 const char *protocol_filter;
3610 const char *protocol_name;
3611 header_field_info *hfinfo;
3613 if (!proto_is_protocol_enabled(protocol))
3616 protocol_name = proto_get_protocol_long_name(protocol);
3617 protocol_filter = proto_get_protocol_filter_name(proto_id);
3619 if (strlen(protocol_filter) >= filter_length && !g_ascii_strncasecmp(tok_field, protocol_filter, filter_length))
3621 sharkd_json_object_open(sepa);
3623 sharkd_json_value_string(FALSE, "f", protocol_filter);
3624 sharkd_json_value_anyf(TRUE, "t", "%d", FT_PROTOCOL);
3625 sharkd_json_value_string(TRUE, "n", protocol_name);
3627 sharkd_json_object_close();
3631 if (!filter_with_dot)
3634 for (hfinfo = proto_get_first_protocol_field(proto_id, &field_cookie); hfinfo != NULL; hfinfo = proto_get_next_protocol_field(proto_id, &field_cookie))
3636 if (hfinfo->same_name_prev_id != -1) /* ignore duplicate names */
3639 if (strlen(hfinfo->abbrev) >= filter_length && !g_ascii_strncasecmp(tok_field, hfinfo->abbrev, filter_length))
3641 sharkd_json_object_open(sepa);
3643 sharkd_json_value_string(FALSE, "f", hfinfo->abbrev);
3645 /* XXX, skip displaying name, if there are multiple (to not confuse user) */
3646 if (hfinfo->same_name_next == NULL)
3648 sharkd_json_value_anyf(TRUE, "t", "%d", hfinfo->type);
3649 sharkd_json_value_string(TRUE, "n", hfinfo->name);
3652 sharkd_json_object_close();
3658 sharkd_json_array_close();
3661 if (tok_pref != NULL && tok_pref[0])
3663 struct sharkd_session_process_complete_pref_data data;
3666 data.module = tok_pref;
3667 data.pref = tok_pref;
3670 sharkd_json_array_open(TRUE, "pref");
3671 if ((dot_sepa = strchr(tok_pref, '.')))
3675 *dot_sepa = '\0'; /* XXX, C abuse: discarding-const */
3676 data.pref = dot_sepa + 1;
3678 pref_mod = prefs_find_module(data.module);
3680 prefs_pref_foreach(pref_mod, sharkd_session_process_complete_pref_option_cb, &data);
3686 prefs_modules_foreach(sharkd_session_process_complete_pref_cb, &data);
3688 sharkd_json_array_close();
3691 sharkd_json_object_close();
3692 sharkd_json_finish();
3698 * sharkd_session_process_setcomment()
3700 * Process setcomment request
3703 * (m) frame - frame number
3704 * (o) comment - user comment
3706 * Output object with attributes:
3707 * (m) err - error code: 0 succeed
3710 sharkd_session_process_setcomment(char *buf, const jsmntok_t *tokens, int count)
3712 const char *tok_frame = json_find_attr(buf, tokens, count, "frame");
3713 const char *tok_comment = json_find_attr(buf, tokens, count, "comment");
3719 if (!tok_frame || !ws_strtou32(tok_frame, NULL, &framenum) || framenum == 0)
3722 fdata = sharkd_get_frame(framenum);
3726 ret = sharkd_set_user_comment(fdata, tok_comment);
3728 sharkd_json_simple_reply(ret, NULL);
3732 * sharkd_session_process_setconf()
3734 * Process setconf request
3737 * (m) name - preference name
3738 * (m) value - preference value
3740 * Output object with attributes:
3741 * (m) err - error code: 0 succeed
3744 sharkd_session_process_setconf(char *buf, const jsmntok_t *tokens, int count)
3746 const char *tok_name = json_find_attr(buf, tokens, count, "name");
3747 const char *tok_value = json_find_attr(buf, tokens, count, "value");
3749 char *errmsg = NULL;
3751 prefs_set_pref_e ret;
3753 if (!tok_name || tok_name[0] == '\0' || !tok_value)
3756 ws_snprintf(pref, sizeof(pref), "%s:%s", tok_name, tok_value);
3758 ret = prefs_set_pref(pref, &errmsg);
3760 sharkd_json_simple_reply(ret, errmsg);
3764 struct sharkd_session_process_dumpconf_data
3771 sharkd_session_process_dumpconf_cb(pref_t *pref, gpointer d)
3773 struct sharkd_session_process_dumpconf_data *data = (struct sharkd_session_process_dumpconf_data *) d;
3774 const char *pref_name = prefs_get_name(pref);
3776 char json_pref_key[512];
3778 snprintf(json_pref_key, sizeof(json_pref_key), "%s.%s", data->module->name, pref_name);
3779 sharkd_json_value_anyf(data->sepa, json_pref_key, "{");
3781 switch (prefs_get_type(pref))
3784 case PREF_DECODE_AS_UINT:
3785 sharkd_json_value_anyf(FALSE, "u", "%u", prefs_get_uint_value_real(pref, pref_current));
3786 if (prefs_get_uint_base(pref) != 10)
3787 sharkd_json_value_anyf(TRUE, "ub", "%u", prefs_get_uint_base(pref));
3791 sharkd_json_value_anyf(FALSE, "b", prefs_get_bool_value(pref, pref_current) ? "1" : "0");
3795 case PREF_SAVE_FILENAME:
3796 case PREF_OPEN_FILENAME:
3798 sharkd_json_value_string(FALSE, "s", prefs_get_string_value(pref, pref_current));
3803 const enum_val_t *enums;
3804 gboolean enum_sepa = FALSE;
3806 sharkd_json_array_open(FALSE, "e");
3807 for (enums = prefs_get_enumvals(pref); enums->name; enums++)
3809 sharkd_json_object_open(enum_sepa);
3811 sharkd_json_value_anyf(FALSE, "v", "%d", enums->value);
3813 if (enums->value == prefs_get_enum_value(pref, pref_current))
3814 sharkd_json_value_anyf(TRUE, "s", "1");
3816 sharkd_json_value_string(TRUE, "d", enums->description);
3818 sharkd_json_object_close();
3821 sharkd_json_array_close();
3826 case PREF_DECODE_AS_RANGE:
3828 char *range_str = range_convert_range(NULL, prefs_get_range_value_real(pref, pref_current));
3829 sharkd_json_value_string(FALSE, "r", range_str);
3830 wmem_free(NULL, range_str);
3836 uat_t *uat = prefs_get_uat_value(pref);
3839 sharkd_json_array_open(FALSE, "t");
3840 for (idx = 0; idx < uat->raw_data->len; idx++)
3842 void *rec = UAT_INDEX_PTR(uat, idx);
3845 sharkd_json_array_open(idx != 0, NULL);
3846 for (colnum = 0; colnum < uat->ncols; colnum++)
3848 char *str = uat_fld_tostr(rec, &(uat->fields[colnum]));
3850 sharkd_json_value_string(colnum != 0, NULL, str);
3854 sharkd_json_array_close();
3857 sharkd_json_array_close();
3863 case PREF_STATIC_TEXT:
3870 sharkd_json_value_string(TRUE, "t", prefs_get_title(pref));
3873 sharkd_json_object_close();
3876 return 0; /* continue */
3880 sharkd_session_process_dumpconf_mod_cb(module_t *module, gpointer d)
3882 struct sharkd_session_process_dumpconf_data *data = (struct sharkd_session_process_dumpconf_data *) d;
3884 data->module = module;
3885 prefs_pref_foreach(module, sharkd_session_process_dumpconf_cb, data);
3891 * sharkd_session_process_dumpconf()
3893 * Process dumpconf request
3896 * (o) pref - module, or preference, NULL for all
3898 * Output object with attributes:
3899 * (o) prefs - object with module preferences
3900 * (m) [KEY] - preference name
3901 * (o) u - preference value (for PREF_UINT, PREF_DECODE_AS_UINT)
3902 * (o) ub - preference value suggested base for display (for PREF_UINT, PREF_DECODE_AS_UINT) and if different than 10
3903 * (o) b - preference value (only for PREF_BOOL) (1 true, 0 false)
3904 * (o) s - preference value (for PREF_STRING, PREF_SAVE_FILENAME, PREF_OPEN_FILENAME, PREF_DIRNAME)
3905 * (o) e - preference possible values (only for PREF_ENUM)
3906 * (o) r - preference value (for PREF_RANGE, PREF_DECODE_AS_RANGE)
3907 * (o) t - preference value (only for PREF_UAT)
3910 sharkd_session_process_dumpconf(char *buf, const jsmntok_t *tokens, int count)
3912 const char *tok_pref = json_find_attr(buf, tokens, count, "pref");
3918 struct sharkd_session_process_dumpconf_data data;
3923 sharkd_json_object_open(FALSE);
3925 sharkd_json_value_anyf(FALSE, "prefs", NULL);
3926 sharkd_json_object_open(FALSE);
3927 prefs_modules_foreach(sharkd_session_process_dumpconf_mod_cb, &data);
3928 sharkd_json_object_close();
3930 sharkd_json_object_close();
3931 sharkd_json_finish();
3935 if ((dot_sepa = strchr(tok_pref, '.')))
3937 pref_t *pref = NULL;
3939 *dot_sepa = '\0'; /* XXX, C abuse: discarding-const */
3940 pref_mod = prefs_find_module(tok_pref);
3942 pref = prefs_find_preference(pref_mod, dot_sepa + 1);
3947 struct sharkd_session_process_dumpconf_data data;
3949 data.module = pref_mod;
3952 sharkd_json_object_open(FALSE);
3954 sharkd_json_value_anyf(FALSE, "prefs", NULL);
3955 sharkd_json_object_open(FALSE);
3956 sharkd_session_process_dumpconf_cb(pref, &data);
3957 sharkd_json_object_close();
3959 sharkd_json_object_close();
3960 sharkd_json_finish();
3966 pref_mod = prefs_find_module(tok_pref);
3969 struct sharkd_session_process_dumpconf_data data;
3971 data.module = pref_mod;
3974 sharkd_json_object_open(FALSE);
3976 sharkd_json_value_anyf(FALSE, "prefs", NULL);
3977 sharkd_json_object_open(FALSE);
3978 prefs_pref_foreach(pref_mod, sharkd_session_process_dumpconf_cb, &data);
3979 sharkd_json_object_close();
3981 sharkd_json_object_close();
3982 sharkd_json_finish();
3986 struct sharkd_download_rtp
3994 sharkd_rtp_download_free_items(void *ptr)
3996 rtp_packet_t *rtp_packet = (rtp_packet_t *) ptr;
3998 g_free(rtp_packet->info);
3999 g_free(rtp_packet->payload_data);
4004 sharkd_rtp_download_decode(struct sharkd_download_rtp *req)
4006 /* based on RtpAudioStream::decode() 6e29d874f8b5e6ebc59f661a0bb0dab8e56f122a */
4007 /* TODO, for now only without silence (timing_mode_ = Uninterrupted) */
4009 static const int sample_bytes_ = sizeof(SAMPLE) / sizeof(char);
4011 guint32 audio_out_rate_ = 0;
4012 struct _GHashTable *decoders_hash_ = rtp_decoder_hash_table_new();
4013 struct SpeexResamplerState_ *audio_resampler_ = NULL;
4015 gsize resample_buff_len = 0x1000;
4016 SAMPLE *resample_buff = (SAMPLE *) g_malloc(resample_buff_len);
4017 spx_uint32_t cur_in_rate = 0;
4018 char *write_buff = NULL;
4019 gint64 write_bytes = 0;
4020 unsigned channels = 0;
4021 unsigned sample_rate = 0;
4024 int base64_state1 = 0;
4025 int base64_state2 = 0;
4029 for (l = req->packets; l; l = l->next)
4031 rtp_packet_t *rtp_packet = (rtp_packet_t *) l->data;
4033 SAMPLE *decode_buff = NULL;
4034 size_t decoded_bytes;
4036 decoded_bytes = decode_rtp_packet(rtp_packet, &decode_buff, decoders_hash_, &channels, &sample_rate);
4037 if (decoded_bytes == 0 || sample_rate == 0)
4039 /* We didn't decode anything. Clean up and prep for the next packet. */
4040 g_free(decode_buff);
4044 if (audio_out_rate_ == 0)
4050 /* First non-zero wins */
4051 audio_out_rate_ = sample_rate;
4053 RTP_STREAM_DEBUG("Audio sample rate is %u", audio_out_rate_);
4055 /* write WAVE header */
4056 memset(&wav_hdr, 0, sizeof(wav_hdr));
4057 memcpy(&wav_hdr[0], "RIFF", 4);
4058 memcpy(&wav_hdr[4], "\xFF\xFF\xFF\xFF", 4); /* XXX, unknown */
4059 memcpy(&wav_hdr[8], "WAVE", 4);
4061 memcpy(&wav_hdr[12], "fmt ", 4);
4062 memcpy(&wav_hdr[16], "\x10\x00\x00\x00", 4); /* PCM */
4063 memcpy(&wav_hdr[20], "\x01\x00", 2); /* PCM */
4066 memcpy(&wav_hdr[22], &tmp16, 2);
4068 tmp32 = sample_rate;
4069 memcpy(&wav_hdr[24], &tmp32, 4);
4071 tmp32 = sample_rate * channels * sample_bytes_;
4072 memcpy(&wav_hdr[28], &tmp32, 4);
4074 tmp16 = channels * sample_bytes_;
4075 memcpy(&wav_hdr[32], &tmp16, 2);
4076 /* bits per sample */
4077 tmp16 = 8 * sample_bytes_;
4078 memcpy(&wav_hdr[34], &tmp16, 2);
4080 memcpy(&wav_hdr[36], "data", 4);
4081 memcpy(&wav_hdr[40], "\xFF\xFF\xFF\xFF", 4); /* XXX, unknown */
4083 for (i = 0; i < (int) sizeof(wav_hdr); i++)
4084 json_print_base64_step(&wav_hdr[i], &base64_state1, &base64_state2);
4087 // Write samples to our file.
4088 write_buff = (char *) decode_buff;
4089 write_bytes = decoded_bytes;
4091 if (audio_out_rate_ != sample_rate)
4093 spx_uint32_t in_len, out_len;
4095 /* Resample the audio to match our previous output rate. */
4096 if (!audio_resampler_)
4098 audio_resampler_ = speex_resampler_init(1, sample_rate, audio_out_rate_, 10, NULL);
4099 speex_resampler_skip_zeros(audio_resampler_);
4100 RTP_STREAM_DEBUG("Started resampling from %u to (out) %u Hz.", sample_rate, audio_out_rate_);
4104 spx_uint32_t audio_out_rate;
4105 speex_resampler_get_rate(audio_resampler_, &cur_in_rate, &audio_out_rate);
4107 if (sample_rate != cur_in_rate)
4109 speex_resampler_set_rate(audio_resampler_, sample_rate, audio_out_rate);
4110 RTP_STREAM_DEBUG("Changed input rate from %u to %u Hz. Out is %u.", cur_in_rate, sample_rate, audio_out_rate_);
4113 in_len = (spx_uint32_t)rtp_packet->info->info_payload_len;
4114 out_len = (audio_out_rate_ * (spx_uint32_t)rtp_packet->info->info_payload_len / sample_rate) + (audio_out_rate_ % sample_rate != 0);
4115 if (out_len * sample_bytes_ > resample_buff_len)
4117 while ((out_len * sample_bytes_ > resample_buff_len))
4118 resample_buff_len *= 2;
4119 resample_buff = (SAMPLE *) g_realloc(resample_buff, resample_buff_len);
4122 speex_resampler_process_int(audio_resampler_, 0, decode_buff, &in_len, resample_buff, &out_len);
4123 write_buff = (char *) resample_buff;
4124 write_bytes = out_len * sample_bytes_;
4127 /* Write the decoded, possibly-resampled audio */
4128 for (i = 0; i < write_bytes; i++)
4129 json_print_base64_step(&write_buff[i], &base64_state1, &base64_state2);
4131 g_free(decode_buff);
4134 json_print_base64_step(NULL, &base64_state1, &base64_state2);
4136 g_free(resample_buff);
4137 g_hash_table_destroy(decoders_hash_);
4141 sharkd_session_packet_download_tap_rtp_cb(void *tapdata, packet_info *pinfo, epan_dissect_t *edt _U_, const void *data)
4143 const struct _rtp_info *rtp_info = (const struct _rtp_info *) data;
4144 struct sharkd_download_rtp *req_rtp = (struct sharkd_download_rtp *) tapdata;
4146 /* do not consider RTP packets without a setup frame */
4147 if (rtp_info->info_setup_frame_num == 0)
4150 if (rtpstream_id_equal_pinfo_rtp_info(&req_rtp->id, pinfo, rtp_info))
4152 rtp_packet_t *rtp_packet;
4154 rtp_packet = g_new0(rtp_packet_t, 1);
4155 rtp_packet->info = (struct _rtp_info *) g_memdup(rtp_info, sizeof(struct _rtp_info));
4157 if (rtp_info->info_all_data_present && rtp_info->info_payload_len != 0)
4158 rtp_packet->payload_data = (guint8 *) g_memdup(&(rtp_info->info_data[rtp_info->info_payload_offset]), rtp_info->info_payload_len);
4160 if (!req_rtp->packets)
4161 req_rtp->start_time = nstime_to_sec(&pinfo->abs_ts);
4163 rtp_packet->frame_num = pinfo->num;
4164 rtp_packet->arrive_offset = nstime_to_sec(&pinfo->abs_ts) - req_rtp->start_time;
4166 /* XXX, O(n) optimize */
4167 req_rtp->packets = g_slist_append(req_rtp->packets, rtp_packet);
4174 * sharkd_session_process_download()
4176 * Process download request
4179 * (m) token - token to download
4181 * Output object with attributes:
4182 * (o) file - suggested name of file
4183 * (o) mime - suggested content type
4184 * (o) data - payload base64 encoded
4187 sharkd_session_process_download(char *buf, const jsmntok_t *tokens, int count)
4189 const char *tok_token = json_find_attr(buf, tokens, count, "token");
4194 if (!strncmp(tok_token, "eo:", 3))
4196 struct sharkd_export_object_list *object_list;
4197 const export_object_entry_t *eo_entry = NULL;
4199 for (object_list = sharkd_eo_list; object_list; object_list = object_list->next)
4201 size_t eo_type_len = strlen(object_list->type);
4203 if (!strncmp(tok_token, object_list->type, eo_type_len) && tok_token[eo_type_len] == '_')
4207 if (sscanf(&tok_token[eo_type_len + 1], "%d", &row) != 1)
4210 eo_entry = (export_object_entry_t *) g_slist_nth_data(object_list->entries, row);
4217 const char *mime = (eo_entry->content_type) ? eo_entry->content_type : "application/octet-stream";
4218 const char *filename = (eo_entry->filename) ? eo_entry->filename : tok_token;
4220 sharkd_json_object_open(FALSE);
4221 sharkd_json_value_string(FALSE, "file", filename);
4222 sharkd_json_value_string(TRUE, "mime", mime);
4223 sharkd_json_value_base64(TRUE, "data", eo_entry->payload_data, (size_t) eo_entry->payload_len);
4224 sharkd_json_object_close();
4225 sharkd_json_finish();
4228 else if (!strcmp(tok_token, "ssl-secrets"))
4230 char *str = ssl_export_sessions();
4234 const char *mime = "text/plain";
4235 const char *filename = "keylog.txt";
4237 sharkd_json_object_open(FALSE);
4238 sharkd_json_value_string(FALSE, "file", filename);
4239 sharkd_json_value_string(TRUE, "mime", mime);
4240 sharkd_json_value_base64(TRUE, "data", str, strlen(str));
4241 sharkd_json_object_close();
4242 sharkd_json_finish();
4246 else if (!strncmp(tok_token, "rtp:", 4))
4248 struct sharkd_download_rtp rtp_req;
4251 memset(&rtp_req, 0, sizeof(rtp_req));
4252 if (!sharkd_rtp_match_init(&rtp_req.id, tok_token + 4))
4254 fprintf(stderr, "sharkd_session_process_download() rtp tokenizing error %s\n", tok_token);
4258 tap_error = register_tap_listener("rtp", &rtp_req, NULL, 0, NULL, sharkd_session_packet_download_tap_rtp_cb, NULL, NULL);
4261 fprintf(stderr, "sharkd_session_process_download() rtp error=%s", tap_error->str);
4262 g_string_free(tap_error, TRUE);
4267 remove_tap_listener(&rtp_req);
4269 if (rtp_req.packets)
4271 const char *mime = "audio/x-wav";
4272 const char *filename = tok_token;
4274 sharkd_json_object_open(FALSE);
4275 sharkd_json_value_string(FALSE, "file", filename);
4276 sharkd_json_value_string(TRUE, "mime", mime);
4278 sharkd_json_value_anyf(TRUE, "data", NULL);
4280 sharkd_rtp_download_decode(&rtp_req);
4283 sharkd_json_object_close();
4284 sharkd_json_finish();
4286 g_slist_free_full(rtp_req.packets, sharkd_rtp_download_free_items);
4292 sharkd_session_process(char *buf, const jsmntok_t *tokens, int count)
4296 /* sanity check, and split strings */
4297 if (count < 1 || tokens[0].type != JSMN_OBJECT)
4299 fprintf(stderr, "sanity check(1): [0] not object\n");
4303 /* don't need [0] token */
4309 fprintf(stderr, "sanity check(2): %d not even\n", count);
4313 for (i = 0; i < count; i += 2)
4315 if (tokens[i].type != JSMN_STRING)
4317 fprintf(stderr, "sanity check(3): [%d] not string\n", i);
4321 if (tokens[i + 1].type != JSMN_STRING && tokens[i + 1].type != JSMN_PRIMITIVE)
4323 fprintf(stderr, "sanity check(3a): [%d] wrong type\n", i + 1);
4327 buf[tokens[i + 0].end] = '\0';
4328 buf[tokens[i + 1].end] = '\0';
4330 /* unescape only value, as keys are simple strings */
4331 if (tokens[i + 1].type == JSMN_STRING && !json_decode_string_inplace(&buf[tokens[i + 1].start]))
4333 fprintf(stderr, "sanity check(3b): [%d] cannot unescape string\n", i + 1);
4339 const char *tok_req = json_find_attr(buf, tokens, count, "req");
4343 fprintf(stderr, "sanity check(4): no \"req\".\n");
4347 if (!strcmp(tok_req, "load"))
4348 sharkd_session_process_load(buf, tokens, count);
4349 else if (!strcmp(tok_req, "status"))
4350 sharkd_session_process_status();
4351 else if (!strcmp(tok_req, "analyse"))
4352 sharkd_session_process_analyse();
4353 else if (!strcmp(tok_req, "info"))
4354 sharkd_session_process_info();
4355 else if (!strcmp(tok_req, "check"))
4356 sharkd_session_process_check(buf, tokens, count);
4357 else if (!strcmp(tok_req, "complete"))
4358 sharkd_session_process_complete(buf, tokens, count);
4359 else if (!strcmp(tok_req, "frames"))
4360 sharkd_session_process_frames(buf, tokens, count);
4361 else if (!strcmp(tok_req, "tap"))
4362 sharkd_session_process_tap(buf, tokens, count);
4363 else if (!strcmp(tok_req, "follow"))
4364 sharkd_session_process_follow(buf, tokens, count);
4365 else if (!strcmp(tok_req, "iograph"))
4366 sharkd_session_process_iograph(buf, tokens, count);
4367 else if (!strcmp(tok_req, "intervals"))
4368 sharkd_session_process_intervals(buf, tokens, count);
4369 else if (!strcmp(tok_req, "frame"))
4370 sharkd_session_process_frame(buf, tokens, count);
4371 else if (!strcmp(tok_req, "setcomment"))
4372 sharkd_session_process_setcomment(buf, tokens, count);
4373 else if (!strcmp(tok_req, "setconf"))
4374 sharkd_session_process_setconf(buf, tokens, count);
4375 else if (!strcmp(tok_req, "dumpconf"))
4376 sharkd_session_process_dumpconf(buf, tokens, count);
4377 else if (!strcmp(tok_req, "download"))
4378 sharkd_session_process_download(buf, tokens, count);
4379 else if (!strcmp(tok_req, "bye"))
4382 fprintf(stderr, "::: req = %s\n", tok_req);
4384 /* reply for every command are 0+ lines of JSON reply (outputed above), finished by empty new line */
4385 sharkd_json_finish();
4388 * We do an explicit fflush after every line, because
4389 * we want output to be written to the socket as soon
4390 * as the line is complete.
4392 * The stream is fully-buffered by default, so it's
4393 * only flushed when the buffer fills or the FILE *
4394 * is closed. On UN*X, we could set it to be line
4395 * buffered, but the MSVC standard I/O routines don't
4396 * support line buffering - they only support *byte*
4397 * buffering, doing a write for every byte written,
4398 * which is too inefficient, and full buffering,
4399 * which is what you get if you request line buffering.
4406 sharkd_session_main(void)
4409 jsmntok_t *tokens = NULL;
4410 int tokens_max = -1;
4412 fprintf(stderr, "Hello in child.\n");
4414 filter_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, sharkd_session_filter_free);
4416 #ifdef HAVE_MAXMINDDB
4417 /* mmdbresolve was stopped before fork(), force starting it */
4418 uat_get_table_by_name("MaxMind Database Paths")->post_update_cb();
4421 while (fgets(buf, sizeof(buf), stdin))
4423 /* every command is line seperated JSON */
4426 ret = json_parse(buf, NULL, 0);
4429 fprintf(stderr, "invalid JSON -> closing\n");
4433 /* fprintf(stderr, "JSON: %d tokens\n", ret); */
4436 if (tokens == NULL || tokens_max < ret)
4439 tokens = (jsmntok_t *) g_realloc(tokens, sizeof(jsmntok_t) * tokens_max);
4442 memset(tokens, 0, ret * sizeof(jsmntok_t));
4444 ret = json_parse(buf, tokens, ret);
4447 fprintf(stderr, "invalid JSON(2) -> closing\n");
4451 #if defined(HAVE_C_ARES) || defined(HAVE_MAXMINDDB)
4452 host_name_lookup_process();
4455 sharkd_session_process(buf, tokens, ret);
4458 g_hash_table_destroy(filter_table);
4465 * Editor modelines - http://www.wireshark.org/tools/modelines.html
4470 * indent-tabs-mode: t
4473 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
4474 * :indentSize=8:tabSize=8:noTabs=false: