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_unescape_str(char *input)
85 return wsjson_unescape_json_string(input, input);
89 json_find_attr(const char *buf, const jsmntok_t *tokens, int count, const char *attr)
93 for (i = 0; i < count; i += 2)
95 const char *tok_attr = &buf[tokens[i + 0].start];
96 const char *tok_value = &buf[tokens[i + 1].start];
98 if (!strcmp(tok_attr, attr))
106 json_puts_string(const char *s)
108 static const char json_cntrl[0x20][6] =
110 "u0000", "u0001", "u0002", "u0003", "u0004", "u0005", "u0006", "u0007", "b", "t", "n", "u000b", "f", "r", "u000e", "u000f",
111 "u0010", "u0011", "u0012", "u0013", "u0014", "u0015", "u0016", "u0017", "u0018", "u0019", "u001a", "u001b", "u001c", "u001d", "u001e", "u001f"
114 const unsigned char *str = (const unsigned char *) s ? s : "";
118 for (i = 0; str[i]; i++)
123 fputs(json_cntrl[(guint)str[i]], stdout);
127 if (str[i] == '\\' || str[i] == '"')
137 json_print_base64_step(const guint8 *data, int *state1, int *state2)
139 gchar buf[(1 / 3 + 1) * 4 + 4 + 1];
143 wrote = g_base64_encode_step(data, 1, FALSE, buf, state1, state2);
145 wrote = g_base64_encode_close(FALSE, buf, state1, state2);
155 json_print_base64(const guint8 *data, size_t len)
158 int base64_state1 = 0;
159 int base64_state2 = 0;
163 for (i = 0; i < len; i++)
164 json_print_base64_step(&data[i], &base64_state1, &base64_state2);
166 json_print_base64_step(NULL, &base64_state1, &base64_state2);
171 static void G_GNUC_PRINTF(3, 4)
172 sharkd_json_value_anyf(gboolean sepa, const char *key, const char *valuef, ...)
185 if (valuef && *valuef)
189 va_start(ap, valuef);
196 sharkd_json_value_string(gboolean sepa, const char *key, const char *str)
198 sharkd_json_value_anyf(sepa, key, NULL);
199 json_puts_string(str);
203 sharkd_json_value_base64(gboolean sepa, const char *key, const guint8 *data, size_t len)
205 sharkd_json_value_anyf(sepa, key, NULL);
206 json_print_base64(data, len);
209 static void G_GNUC_PRINTF(3, 4)
210 sharkd_json_value_stringf(gboolean sepa, const char *key, const char *format, ...)
214 sharkd_json_value_anyf(sepa, key, NULL);
216 va_start(ap, format);
224 sharkd_json_array_open(gboolean sepa, const char *key)
226 sharkd_json_value_anyf(sepa, key, "[");
230 sharkd_json_array_close(void)
236 sharkd_json_object_open(gboolean sepa)
238 sharkd_json_value_anyf(sepa, NULL, "{");
242 sharkd_json_object_close(void)
248 sharkd_json_finish(void)
254 sharkd_json_simple_reply(int err, const char *errmsg)
256 sharkd_json_object_open(FALSE);
257 sharkd_json_value_anyf(FALSE, "err", "%d", err);
259 sharkd_json_value_string(TRUE, "errmsg", errmsg);
261 sharkd_json_object_close();
262 sharkd_json_finish();
266 sharkd_session_filter_free(gpointer data)
268 struct sharkd_filter_item *l = (struct sharkd_filter_item *) data;
274 static const struct sharkd_filter_item *
275 sharkd_session_filter_data(const char *filter)
277 struct sharkd_filter_item *l;
279 l = (struct sharkd_filter_item *) g_hash_table_lookup(filter_table, filter);
282 guint8 *filtered = NULL;
284 int ret = sharkd_filter(filter, &filtered);
289 l = (struct sharkd_filter_item *) g_malloc(sizeof(struct sharkd_filter_item));
290 l->filtered = filtered;
292 g_hash_table_insert(filter_table, g_strdup(filter), l);
299 sharkd_rtp_match_init(rtpstream_id_t *id, const char *init_str)
301 gboolean ret = FALSE;
303 guint32 tmp_addr_src, tmp_addr_dst;
304 address tmp_src_addr, tmp_dst_addr;
306 memset(id, 0, sizeof(*id));
308 arr = g_strsplit(init_str, "_", 7); /* pass larger value, so we'll catch incorrect input :) */
309 if (g_strv_length(arr) != 5)
312 /* TODO, for now only IPv4 */
313 if (!get_host_ipaddr(arr[0], &tmp_addr_src))
316 if (!ws_strtou16(arr[1], NULL, &id->src_port))
319 if (!get_host_ipaddr(arr[2], &tmp_addr_dst))
322 if (!ws_strtou16(arr[3], NULL, &id->dst_port))
325 if (!ws_hexstrtou32(arr[4], NULL, &id->ssrc))
328 set_address(&tmp_src_addr, AT_IPv4, 4, &tmp_addr_src);
329 copy_address(&id->src_addr, &tmp_src_addr);
330 set_address(&tmp_dst_addr, AT_IPv4, 4, &tmp_addr_dst);
331 copy_address(&id->dst_addr, &tmp_dst_addr);
341 sharkd_session_process_info_nstat_cb(const void *key, void *value, void *userdata)
343 stat_tap_table_ui *stat_tap = (stat_tap_table_ui *) value;
344 int *pi = (int *) userdata;
346 sharkd_json_object_open(*pi != 0);
347 sharkd_json_value_stringf(FALSE, "name", "%s", stat_tap->title);
348 sharkd_json_value_stringf(TRUE, "tap", "nstat:%s", (const char *) key);
349 sharkd_json_object_close();
356 sharkd_session_process_info_conv_cb(const void* key, void* value, void* userdata)
358 struct register_ct *table = (struct register_ct *) value;
359 int *pi = (int *) userdata;
361 const char *label = (const char *) key;
363 if (get_conversation_packet_func(table))
365 sharkd_json_object_open(*pi != 0);
366 sharkd_json_value_stringf(FALSE, "name", "Conversation List/%s", label);
367 sharkd_json_value_stringf(TRUE, "tap", "conv:%s", label);
368 sharkd_json_object_close();
373 if (get_hostlist_packet_func(table))
375 sharkd_json_object_open(*pi != 0);
376 sharkd_json_value_stringf(FALSE, "name", "Endpoint/%s", label);
377 sharkd_json_value_stringf(TRUE, "tap", "endpt:%s", label);
378 sharkd_json_object_close();
386 sharkd_session_seq_analysis_cb(const void *key, void *value, void *userdata)
388 register_analysis_t *analysis = (register_analysis_t *) value;
389 int *pi = (int *) userdata;
391 sharkd_json_object_open(*pi != 0);
392 sharkd_json_value_stringf(FALSE, "name", "%s", sequence_analysis_get_ui_name(analysis));
393 sharkd_json_value_stringf(TRUE, "tap", "seqa:%s", (const char *) key);
394 sharkd_json_object_close();
401 sharkd_export_object_visit_cb(const void *key _U_, void *value, void *user_data)
403 register_eo_t *eo = (register_eo_t *) value;
404 int *pi = (int *) user_data;
406 const int proto_id = get_eo_proto_id(eo);
407 const char *filter = proto_get_protocol_filter_name(proto_id);
408 const char *label = proto_get_protocol_short_name(find_protocol_by_id(proto_id));
410 sharkd_json_object_open(*pi != 0);
411 sharkd_json_value_stringf(FALSE, "name", "Export Object/%s", label);
412 sharkd_json_value_stringf(TRUE, "tap", "eo:%s", filter);
413 sharkd_json_object_close();
420 sharkd_srt_visit_cb(const void *key _U_, void *value, void *user_data)
422 register_srt_t *srt = (register_srt_t *) value;
423 int *pi = (int *) user_data;
425 const int proto_id = get_srt_proto_id(srt);
426 const char *filter = proto_get_protocol_filter_name(proto_id);
427 const char *label = proto_get_protocol_short_name(find_protocol_by_id(proto_id));
429 sharkd_json_object_open(*pi != 0);
430 sharkd_json_value_stringf(FALSE, "name", "Service Response Time/%s", label);
431 sharkd_json_value_stringf(TRUE, "tap", "srt:%s", filter);
432 sharkd_json_object_close();
439 sharkd_rtd_visit_cb(const void *key _U_, void *value, void *user_data)
441 register_rtd_t *rtd = (register_rtd_t *) value;
442 int *pi = (int *) user_data;
444 const int proto_id = get_rtd_proto_id(rtd);
445 const char *filter = proto_get_protocol_filter_name(proto_id);
446 const char *label = proto_get_protocol_short_name(find_protocol_by_id(proto_id));
448 sharkd_json_object_open(*pi != 0);
449 sharkd_json_value_stringf(FALSE, "name", "Response Time Delay/%s", label);
450 sharkd_json_value_stringf(TRUE, "tap", "rtd:%s", filter);
451 sharkd_json_object_close();
458 sharkd_follower_visit_cb(const void *key _U_, void *value, void *user_data)
460 register_follow_t *follower = (register_follow_t *) value;
461 int *pi = (int *) user_data;
463 const int proto_id = get_follow_proto_id(follower);
464 const char *label = proto_get_protocol_short_name(find_protocol_by_id(proto_id));
465 const char *filter = label; /* correct: get_follow_by_name() is registered by short name */
467 sharkd_json_object_open(*pi != 0);
468 sharkd_json_value_stringf(FALSE, "name", "Follow/%s", label);
469 sharkd_json_value_stringf(TRUE, "tap", "follow:%s", filter);
470 sharkd_json_object_close();
477 * sharkd_session_process_info()
479 * Process info request
481 * Output object with attributes:
482 * (m) columns - available column formats, array of object with attributes:
483 * 'name' - column name
484 * 'format' - column format-name
486 * (m) stats - available statistics, array of object with attributes:
487 * 'name' - statistic name
488 * 'tap' - sharkd tap-name for statistic
490 * (m) convs - available conversation list, array of object with attributes:
491 * 'name' - conversation name
492 * 'tap' - sharkd tap-name for conversation
494 * (m) eo - available export object list, array of object with attributes:
495 * 'name' - export object name
496 * 'tap' - sharkd tap-name for eo
498 * (m) srt - available service response time list, array of object with attributes:
499 * 'name' - service response time name
500 * 'tap' - sharkd tap-name for srt
502 * (m) rtd - available response time delay list, array of object with attributes:
503 * 'name' - response time delay name
504 * 'tap' - sharkd tap-name for rtd
506 * (m) seqa - available sequence analysis (flow) list, array of object with attributes:
507 * 'name' - sequence analysis name
508 * 'tap' - sharkd tap-name
510 * (m) taps - available taps, array of object with attributes:
512 * 'tap' - sharkd tap-name
514 * (m) follow - available followers, array of object with attributes:
516 * 'tap' - sharkd tap-name
518 * (m) ftypes - conversation table for FT_ number to string
521 sharkd_session_process_info(void)
525 sharkd_json_object_open(FALSE);
527 sharkd_json_array_open(FALSE, "columns");
528 for (i = 0; i < NUM_COL_FMTS; i++)
530 const char *col_format = col_format_to_string(i);
531 const char *col_descr = col_format_desc(i);
533 sharkd_json_object_open(i != 0);
534 sharkd_json_value_stringf(FALSE, "name", "%s", col_descr);
535 sharkd_json_value_stringf(TRUE, "format", "%s", col_format);
536 sharkd_json_object_close();
538 sharkd_json_array_close();
540 sharkd_json_array_open(TRUE, "stats");
542 GList *cfg_list = stats_tree_get_cfg_list();
544 gboolean sepa = FALSE;
546 for (l = cfg_list; l; l = l->next)
548 stats_tree_cfg *cfg = (stats_tree_cfg *) l->data;
550 sharkd_json_object_open(sepa);
551 sharkd_json_value_stringf(FALSE, "name", "%s", cfg->name);
552 sharkd_json_value_stringf(TRUE, "tap", "stat:%s", cfg->abbr);
553 sharkd_json_object_close();
557 g_list_free(cfg_list);
559 sharkd_json_array_close();
561 sharkd_json_array_open(TRUE, "ftypes");
562 for (i = 0; i < FT_NUM_TYPES; i++)
563 sharkd_json_value_string(i != 0, NULL, ftype_name((ftenum_t) i));
564 sharkd_json_array_close();
566 sharkd_json_value_string(TRUE, "version", sharkd_version());
568 sharkd_json_array_open(TRUE, "nstat");
570 stat_tap_iterate_tables(sharkd_session_process_info_nstat_cb, &i);
571 sharkd_json_array_close();
573 sharkd_json_array_open(TRUE, "convs");
575 conversation_table_iterate_tables(sharkd_session_process_info_conv_cb, &i);
576 sharkd_json_array_close();
578 sharkd_json_array_open(TRUE, "seqa");
580 sequence_analysis_table_iterate_tables(sharkd_session_seq_analysis_cb, &i);
581 sharkd_json_array_close();
583 sharkd_json_array_open(TRUE, "taps");
585 sharkd_json_object_open(FALSE);
586 sharkd_json_value_string(FALSE, "name", "RTP streams");
587 sharkd_json_value_string(TRUE, "tap", "rtp-streams");
588 sharkd_json_object_close();
590 sharkd_json_object_open(TRUE);
591 sharkd_json_value_string(FALSE, "name", "Expert Information");
592 sharkd_json_value_string(TRUE, "tap", "expert");
593 sharkd_json_object_close();
595 sharkd_json_array_close();
597 sharkd_json_array_open(TRUE, "eo");
599 eo_iterate_tables(sharkd_export_object_visit_cb, &i);
600 sharkd_json_array_close();
602 sharkd_json_array_open(TRUE, "srt");
604 srt_table_iterate_tables(sharkd_srt_visit_cb, &i);
605 sharkd_json_array_close();
607 sharkd_json_array_open(TRUE, "rtd");
609 rtd_table_iterate_tables(sharkd_rtd_visit_cb, &i);
610 sharkd_json_array_close();
612 sharkd_json_array_open(TRUE, "follow");
614 follow_iterate_followers(sharkd_follower_visit_cb, &i);
615 sharkd_json_array_close();
617 sharkd_json_object_close();
618 sharkd_json_finish();
622 * sharkd_session_process_load()
624 * Process load request
627 * (m) file - file to be loaded
629 * Output object with attributes:
630 * (m) err - error code
633 sharkd_session_process_load(const char *buf, const jsmntok_t *tokens, int count)
635 const char *tok_file = json_find_attr(buf, tokens, count, "file");
638 fprintf(stderr, "load: filename=%s\n", tok_file);
643 if (sharkd_cf_open(tok_file, WTAP_TYPE_AUTO, FALSE, &err) != CF_OK)
645 sharkd_json_simple_reply(err, NULL);
651 err = sharkd_load_cap_file();
653 CATCH(OutOfMemoryError)
655 fprintf(stderr, "load: OutOfMemoryError\n");
660 sharkd_json_simple_reply(err, NULL);
664 * sharkd_session_process_status()
666 * Process status request
668 * Output object with attributes:
669 * (m) frames - count of currently loaded frames
670 * (m) duration - time difference between time of first frame, and last loaded frame
671 * (o) filename - capture filename
672 * (o) filesize - capture filesize
675 sharkd_session_process_status(void)
677 sharkd_json_object_open(FALSE);
679 sharkd_json_value_anyf(FALSE, "frames", "%u", cfile.count);
680 sharkd_json_value_anyf(TRUE, "duration", "%.9f", nstime_to_sec(&cfile.elapsed_time));
684 char *name = g_path_get_basename(cfile.filename);
686 sharkd_json_value_string(TRUE, "filename", name);
690 if (cfile.provider.wth)
692 gint64 file_size = wtap_file_size(cfile.provider.wth, NULL);
695 sharkd_json_value_anyf(TRUE, "filesize", "%" G_GINT64_FORMAT, file_size);
698 sharkd_json_object_close();
699 sharkd_json_finish();
702 struct sharkd_analyse_data
704 GHashTable *protocols_set;
705 nstime_t *first_time;
710 sharkd_session_process_analyse_cb(epan_dissect_t *edt, proto_tree *tree, struct epan_column_info *cinfo, const GSList *data_src, void *data)
712 struct sharkd_analyse_data *analyser = (struct sharkd_analyse_data *) data;
713 packet_info *pi = &edt->pi;
714 frame_data *fdata = pi->fd;
720 if (analyser->first_time == NULL || nstime_cmp(&fdata->abs_ts, analyser->first_time) < 0)
721 analyser->first_time = &fdata->abs_ts;
723 if (analyser->last_time == NULL || nstime_cmp(&fdata->abs_ts, analyser->last_time) > 0)
724 analyser->last_time = &fdata->abs_ts;
728 wmem_list_frame_t *frame;
730 for (frame = wmem_list_head(pi->layers); frame; frame = wmem_list_frame_next(frame))
732 int proto_id = GPOINTER_TO_UINT(wmem_list_frame_data(frame));
734 if (!g_hash_table_lookup_extended(analyser->protocols_set, GUINT_TO_POINTER(proto_id), NULL, NULL))
736 guint proto_count = g_hash_table_size(analyser->protocols_set);
738 g_hash_table_insert(analyser->protocols_set, GUINT_TO_POINTER(proto_id), GUINT_TO_POINTER(proto_id));
740 sharkd_json_value_string(proto_count != 0, NULL, proto_get_protocol_filter_name(proto_id));
748 * sharkd_session_process_status()
750 * Process analyse request
752 * Output object with attributes:
753 * (m) frames - count of currently loaded frames
754 * (m) protocols - protocol list
755 * (m) first - earliest frame time
756 * (m) last - latest frame time
759 sharkd_session_process_analyse(void)
761 unsigned int framenum;
762 struct sharkd_analyse_data analyser;
764 analyser.first_time = NULL;
765 analyser.last_time = NULL;
766 analyser.protocols_set = g_hash_table_new(NULL /* g_direct_hash() */, NULL /* g_direct_equal */);
768 sharkd_json_object_open(FALSE);
770 sharkd_json_value_anyf(FALSE, "frames", "%u", cfile.count);
772 sharkd_json_array_open(TRUE, "protocols");
773 for (framenum = 1; framenum <= cfile.count; framenum++)
774 sharkd_dissect_request(framenum, (framenum != 1) ? 1 : 0, framenum - 1, &sharkd_session_process_analyse_cb, SHARKD_DISSECT_FLAG_NULL, &analyser);
775 sharkd_json_array_close();
777 if (analyser.first_time)
778 sharkd_json_value_anyf(TRUE, "first", "%.9f", nstime_to_sec(analyser.first_time));
780 if (analyser.last_time)
781 sharkd_json_value_anyf(TRUE, "last", "%.9f", nstime_to_sec(analyser.last_time));
783 sharkd_json_object_close();
784 sharkd_json_finish();
786 g_hash_table_destroy(analyser.protocols_set);
790 sharkd_session_create_columns(column_info *cinfo, const char *buf, const jsmntok_t *tokens, int count)
792 const char *columns_custom[32];
793 guint16 columns_fmt[32];
794 gint16 columns_occur[32];
798 for (i = 0; i < 32; i++)
800 const char *tok_column;
801 char tok_column_name[64];
804 ws_snprintf(tok_column_name, sizeof(tok_column_name), "column%d", i);
805 tok_column = json_find_attr(buf, tokens, count, tok_column_name);
806 if (tok_column == NULL)
809 columns_custom[i] = NULL;
810 columns_occur[i] = 0;
812 if ((custom_sepa = strchr(tok_column, ':')))
814 *custom_sepa = '\0'; /* XXX, C abuse: discarding-const */
816 columns_fmt[i] = COL_CUSTOM;
817 columns_custom[i] = tok_column;
819 if (!ws_strtoi16(custom_sepa + 1, NULL, &columns_occur[i]))
824 if (!ws_strtou16(tok_column, NULL, &columns_fmt[i]))
827 if (columns_fmt[i] >= NUM_COL_FMTS)
830 /* if custom, that it shouldn't be just custom number -> error */
831 if (columns_fmt[i] == COL_CUSTOM)
838 col_setup(cinfo, cols);
840 for (i = 0; i < cols; i++)
842 col_item_t *col_item = &cinfo->columns[i];
844 col_item->col_fmt = columns_fmt[i];
845 col_item->col_title = NULL; /* no need for title */
847 if (col_item->col_fmt == COL_CUSTOM)
849 col_item->col_custom_fields = g_strdup(columns_custom[i]);
850 col_item->col_custom_occurrence = columns_occur[i];
853 col_item->col_fence = 0;
862 * sharkd_session_process_frames()
864 * Process frames request
867 * (o) column0...columnXX - requested columns either number in range [0..NUM_COL_FMTS), or custom (syntax <dfilter>:<occurence>).
868 * If column0 is not specified default column set will be used.
869 * (o) filter - filter to be used
870 * (o) skip=N - skip N frames
871 * (o) limit=N - show only N frames
872 * (o) refs - list (comma separated) with sorted time reference frame numbers.
874 * Output array of frames with attributes:
875 * (m) c - array of column data
876 * (m) num - frame number
877 * (o) i - if frame is ignored
878 * (o) m - if frame is marked
879 * (o) ct - if frame is commented
880 * (o) bg - color filter - background color in hex
881 * (o) fg - color filter - foreground color in hex
884 sharkd_session_process_frames(const char *buf, const jsmntok_t *tokens, int count)
886 const char *tok_filter = json_find_attr(buf, tokens, count, "filter");
887 const char *tok_column = json_find_attr(buf, tokens, count, "column0");
888 const char *tok_skip = json_find_attr(buf, tokens, count, "skip");
889 const char *tok_limit = json_find_attr(buf, tokens, count, "limit");
890 const char *tok_refs = json_find_attr(buf, tokens, count, "refs");
892 const guint8 *filter_data = NULL;
894 gboolean frame_sepa = FALSE;
897 guint32 framenum, prev_dis_num = 0;
898 guint32 current_ref_frame = 0, next_ref_frame = G_MAXUINT32;
902 column_info *cinfo = &cfile.cinfo;
903 column_info user_cinfo;
907 memset(&user_cinfo, 0, sizeof(user_cinfo));
908 cinfo = sharkd_session_create_columns(&user_cinfo, buf, tokens, count);
915 const struct sharkd_filter_item *filter_item;
917 filter_item = sharkd_session_filter_data(tok_filter);
920 filter_data = filter_item->filtered;
926 if (!ws_strtou32(tok_skip, NULL, &skip))
933 if (!ws_strtou32(tok_limit, NULL, &limit))
939 if (!ws_strtou32(tok_refs, &tok_refs, &next_ref_frame))
943 sharkd_json_array_open(FALSE, NULL);
944 for (framenum = 1; framenum <= cfile.count; framenum++)
947 guint32 ref_frame = (framenum != 1) ? 1 : 0;
949 if (filter_data && !(filter_data[framenum / 8] & (1 << (framenum % 8))))
955 prev_dis_num = framenum;
961 if (framenum >= next_ref_frame)
963 current_ref_frame = next_ref_frame;
965 if (*tok_refs != ',')
966 next_ref_frame = G_MAXUINT32;
968 while (*tok_refs == ',' && framenum >= next_ref_frame)
970 current_ref_frame = next_ref_frame;
972 if (!ws_strtou32(tok_refs + 1, &tok_refs, &next_ref_frame))
974 fprintf(stderr, "sharkd_session_process_frames() wrong format for refs: %s\n", tok_refs);
979 if (*tok_refs == '\0' && framenum >= next_ref_frame)
981 current_ref_frame = next_ref_frame;
982 next_ref_frame = G_MAXUINT32;
986 if (current_ref_frame)
987 ref_frame = current_ref_frame;
990 fdata = sharkd_get_frame(framenum);
991 sharkd_dissect_columns(fdata, ref_frame, prev_dis_num, cinfo, (fdata->color_filter == NULL));
993 sharkd_json_object_open(frame_sepa);
995 sharkd_json_array_open(FALSE, "c");
996 for (col = 0; col < cinfo->num_cols; ++col)
998 const col_item_t *col_item = &cinfo->columns[col];
1000 sharkd_json_value_string(col != 0, NULL, col_item->col_data);
1002 sharkd_json_array_close();
1004 sharkd_json_value_anyf(TRUE, "num", "%u", framenum);
1006 if (fdata->flags.has_user_comment || fdata->flags.has_phdr_comment)
1008 if (!fdata->flags.has_user_comment || sharkd_get_user_comment(fdata) != NULL)
1009 sharkd_json_value_anyf(TRUE, "ct", "true");
1012 if (fdata->flags.ignored)
1013 sharkd_json_value_anyf(TRUE, "i", "true");
1015 if (fdata->flags.marked)
1016 sharkd_json_value_anyf(TRUE, "m", "true");
1018 if (fdata->color_filter)
1020 sharkd_json_value_stringf(TRUE, "bg", "%x", color_t_to_rgb(&fdata->color_filter->bg_color));
1021 sharkd_json_value_stringf(TRUE, "fg", "%x", color_t_to_rgb(&fdata->color_filter->fg_color));
1024 sharkd_json_object_close();
1026 prev_dis_num = framenum;
1028 if (limit && --limit == 0)
1031 sharkd_json_array_close();
1032 sharkd_json_finish();
1034 if (cinfo != &cfile.cinfo)
1039 sharkd_session_process_tap_stats_node_cb(const stat_node *n)
1042 gboolean sepa = FALSE;
1044 sharkd_json_array_open(FALSE, NULL);
1045 for (node = n->children; node; node = node->next)
1047 sharkd_json_object_open(sepa);
1049 /* code based on stats_tree_get_values_from_node() */
1050 sharkd_json_value_stringf(FALSE, "name", "%s", node->name);
1051 sharkd_json_value_anyf(TRUE, "count", "%d", node->counter);
1052 if (node->counter && ((node->st_flags & ST_FLG_AVERAGE) || node->rng))
1054 sharkd_json_value_anyf(TRUE, "avg", "%.2f", ((float)node->total) / node->counter);
1055 sharkd_json_value_anyf(TRUE, "min", "%d", node->minvalue);
1056 sharkd_json_value_anyf(TRUE, "max", "%d", node->maxvalue);
1059 if (node->st->elapsed)
1060 sharkd_json_value_anyf(TRUE, "rate", "%.4f", ((float)node->counter) / node->st->elapsed);
1062 if (node->parent && node->parent->counter)
1063 sharkd_json_value_anyf(TRUE, "perc", "%.2f", (node->counter * 100.0) / node->parent->counter);
1064 else if (node->parent == &(node->st->root))
1065 sharkd_json_value_anyf(TRUE, "perc", "100");
1067 if (prefs.st_enable_burstinfo && node->max_burst)
1069 if (prefs.st_burst_showcount)
1070 sharkd_json_value_anyf(TRUE, "burstcount", "%d", node->max_burst);
1072 sharkd_json_value_anyf(TRUE, "burstrate", "%.4f", ((double)node->max_burst) / prefs.st_burst_windowlen);
1074 sharkd_json_value_anyf(TRUE, "bursttime", "%.3f", ((double)node->burst_time / 1000.0));
1079 sharkd_json_value_anyf(TRUE, "sub", NULL);
1080 sharkd_session_process_tap_stats_node_cb(node);
1082 sharkd_json_object_close();
1085 sharkd_json_array_close();
1089 * sharkd_session_process_tap_stats_cb()
1093 * (m) tap - tap name
1094 * (m) type:stats - tap output type
1095 * (m) name - stat name
1096 * (m) stats - array of object with attributes:
1097 * (m) name - stat item name
1098 * (m) count - stat item counter
1099 * (o) avg - stat item averange value
1100 * (o) min - stat item min value
1101 * (o) max - stat item max value
1102 * (o) rate - stat item rate value (ms)
1103 * (o) perc - stat item percentage
1104 * (o) burstrate - stat item burst rate
1105 * (o) burstcount - stat item burst count
1106 * (o) burstttme - stat item burst start
1107 * (o) sub - array of object with attributes like in stats node.
1110 sharkd_session_process_tap_stats_cb(void *psp)
1112 stats_tree *st = (stats_tree *) psp;
1114 sharkd_json_object_open(FALSE);
1116 sharkd_json_value_stringf(FALSE, "tap", "stats:%s", st->cfg->abbr);
1117 sharkd_json_value_string(TRUE, "type", "stats");
1118 sharkd_json_value_stringf(TRUE, "name", "%s", st->cfg->name);
1120 sharkd_json_value_anyf(TRUE, "stats", NULL);
1121 sharkd_session_process_tap_stats_node_cb(&st->root);
1123 sharkd_json_object_close();
1128 sharkd_session_free_tap_stats_cb(void *psp)
1130 stats_tree *st = (stats_tree *) psp;
1132 stats_tree_free(st);
1135 struct sharkd_expert_tap
1142 * sharkd_session_process_tap_expert_cb()
1144 * Output expert tap:
1146 * (m) tap - tap name
1147 * (m) type:expert - tap output type
1148 * (m) details - array of object with attributes:
1149 * (m) f - frame number, which generated expert information
1152 * (m) m - expert message
1156 sharkd_session_process_tap_expert_cb(void *tapdata)
1158 struct sharkd_expert_tap *etd = (struct sharkd_expert_tap *) tapdata;
1160 gboolean sepa = FALSE;
1162 sharkd_json_object_open(FALSE);
1164 sharkd_json_value_string(FALSE, "tap", "expert");
1165 sharkd_json_value_string(TRUE, "type", "expert");
1167 sharkd_json_array_open(TRUE, "details");
1168 for (list = etd->details; list; list = list->next)
1170 expert_info_t *ei = (expert_info_t *) list->data;
1173 sharkd_json_object_open(sepa);
1175 sharkd_json_value_anyf(FALSE, "f", "%u", ei->packet_num);
1177 tmp = try_val_to_str(ei->severity, expert_severity_vals);
1179 sharkd_json_value_string(TRUE, "s", tmp);
1181 tmp = try_val_to_str(ei->group, expert_group_vals);
1183 sharkd_json_value_string(TRUE, "g", tmp);
1185 sharkd_json_value_string(TRUE, "m", ei->summary);
1188 sharkd_json_value_string(TRUE, "p", ei->protocol);
1190 sharkd_json_object_close();
1193 sharkd_json_array_close();
1195 sharkd_json_object_close();
1200 sharkd_session_packet_tap_expert_cb(void *tapdata, packet_info *pinfo _U_, epan_dissect_t *edt _U_, const void *pointer)
1202 struct sharkd_expert_tap *etd = (struct sharkd_expert_tap *) tapdata;
1203 const expert_info_t *ei = (const expert_info_t *) pointer;
1204 expert_info_t *ei_copy;
1209 ei_copy = g_new(expert_info_t, 1);
1210 /* Note: this is a shallow copy */
1213 /* ei->protocol, ei->summary might be allocated in packet scope, make a copy. */
1214 ei_copy->protocol = g_string_chunk_insert_const(etd->text, ei_copy->protocol);
1215 ei_copy->summary = g_string_chunk_insert_const(etd->text, ei_copy->summary);
1217 etd->details = g_slist_prepend(etd->details, ei_copy);
1223 sharkd_session_free_tap_expert_cb(void *tapdata)
1225 struct sharkd_expert_tap *etd = (struct sharkd_expert_tap *) tapdata;
1227 g_slist_free_full(etd->details, g_free);
1228 g_string_chunk_free(etd->text);
1233 * sharkd_session_process_tap_flow_cb()
1236 * (m) tap - tap name
1237 * (m) type:flow - tap output type
1238 * (m) nodes - array of strings with node address
1239 * (m) flows - array of object with attributes:
1240 * (m) t - frame time string
1241 * (m) n - array of two numbers with source node index and destination node index
1242 * (m) pn - array of two numbers with source and destination port
1246 sharkd_session_process_tap_flow_cb(void *tapdata)
1248 seq_analysis_info_t *graph_analysis = (seq_analysis_info_t *) tapdata;
1252 gboolean sepa = FALSE;
1254 sequence_analysis_get_nodes(graph_analysis);
1256 sharkd_json_object_open(FALSE);
1257 sharkd_json_value_stringf(FALSE, "tap", "seqa:%s", graph_analysis->name);
1258 sharkd_json_value_string(TRUE, "type", "flow");
1260 sharkd_json_array_open(TRUE, "nodes");
1261 for (i = 0; i < graph_analysis->num_nodes; i++)
1265 addr_str = address_to_display(NULL, &(graph_analysis->nodes[i]));
1266 sharkd_json_value_string(i != 0, NULL, addr_str);
1267 wmem_free(NULL, addr_str);
1269 sharkd_json_array_close();
1271 sharkd_json_array_open(TRUE, "flows");
1272 flow_list = g_queue_peek_nth_link(graph_analysis->items, 0);
1275 seq_analysis_item_t *sai = (seq_analysis_item_t *) flow_list->data;
1277 flow_list = g_list_next(flow_list);
1282 sharkd_json_object_open(sepa);
1284 sharkd_json_value_stringf(FALSE, "t", "%s", sai->time_str);
1285 sharkd_json_value_anyf(TRUE, "n", "[%u,%u]", sai->src_node, sai->dst_node);
1286 sharkd_json_value_anyf(TRUE, "pn", "[%u,%u]", sai->port_src, sai->port_dst);
1289 sharkd_json_value_string(TRUE, "c", sai->comment);
1291 sharkd_json_object_close();
1294 sharkd_json_array_close();
1296 sharkd_json_object_close();
1301 sharkd_session_free_tap_flow_cb(void *tapdata)
1303 seq_analysis_info_t *graph_analysis = (seq_analysis_info_t *) tapdata;
1305 sequence_analysis_info_free(graph_analysis);
1308 struct sharkd_conv_tap_data
1312 gboolean resolve_name;
1313 gboolean resolve_port;
1317 sharkd_session_geoip_addr(address *addr, const char *suffix)
1319 const mmdb_lookup_t *lookup = NULL;
1320 gboolean with_geoip = FALSE;
1323 if (addr->type == AT_IPv4)
1327 memcpy(&ip, addr->data, 4);
1328 lookup = maxmind_db_lookup_ipv4(ip);
1330 else if (addr->type == AT_IPv6)
1332 const ws_in6_addr *ip6 = (const ws_in6_addr *) addr->data;
1334 lookup = maxmind_db_lookup_ipv6(ip6);
1337 if (!lookup || !lookup->found)
1340 if (lookup->country)
1342 snprintf(json_key, sizeof(json_key), "geoip_country%s", suffix);
1343 sharkd_json_value_string(TRUE, json_key, lookup->country);
1347 if (lookup->country_iso)
1349 snprintf(json_key, sizeof(json_key), "geoip_country_iso%s", suffix);
1350 sharkd_json_value_string(TRUE, json_key, lookup->country_iso);
1356 snprintf(json_key, sizeof(json_key), "geoip_city%s", suffix);
1357 sharkd_json_value_string(TRUE, json_key, lookup->city);
1363 snprintf(json_key, sizeof(json_key), "geoip_as_org%s", suffix);
1364 sharkd_json_value_string(TRUE, json_key, lookup->as_org);
1368 if (lookup->as_number > 0)
1370 snprintf(json_key, sizeof(json_key), "geoip_as%s", suffix);
1371 sharkd_json_value_anyf(TRUE, json_key, "%u", lookup->as_number);
1375 if (lookup->latitude >= -90.0 && lookup->latitude <= 90.0)
1377 snprintf(json_key, sizeof(json_key), "geoip_lat%s", suffix);
1378 sharkd_json_value_anyf(TRUE, json_key, "%f", lookup->latitude);
1382 if (lookup->longitude >= -180.0 && lookup->longitude <= 180.0)
1384 snprintf(json_key, sizeof(json_key), "geoip_lon%s", suffix);
1385 sharkd_json_value_anyf(TRUE, json_key, "%f", lookup->longitude);
1392 struct sharkd_analyse_rtp_items
1395 guint32 sequence_num;
1403 double arrive_offset;
1405 /* from tap_rtp_stat_t */
1410 struct sharkd_analyse_rtp
1412 const char *tap_name;
1417 tap_rtp_stat_t statinfo;
1421 sharkd_session_process_tap_rtp_free_cb(void *tapdata)
1423 struct sharkd_analyse_rtp *rtp_req = (struct sharkd_analyse_rtp *) tapdata;
1425 g_slist_free_full(rtp_req->packets, g_free);
1430 sharkd_session_packet_tap_rtp_analyse_cb(void *tapdata, packet_info *pinfo, epan_dissect_t *edt _U_, const void *pointer)
1432 struct sharkd_analyse_rtp *rtp_req = (struct sharkd_analyse_rtp *) tapdata;
1433 const struct _rtp_info *rtp_info = (const struct _rtp_info *) pointer;
1435 if (rtpstream_id_equal_pinfo_rtp_info(&rtp_req->id, pinfo, rtp_info))
1437 tap_rtp_stat_t *statinfo = &(rtp_req->statinfo);
1438 struct sharkd_analyse_rtp_items *item;
1440 rtppacket_analyse(statinfo, pinfo, rtp_info);
1442 item = (struct sharkd_analyse_rtp_items *) g_malloc(sizeof(struct sharkd_analyse_rtp_items));
1444 if (!rtp_req->packets)
1445 rtp_req->start_time = nstime_to_sec(&pinfo->abs_ts);
1447 item->frame_num = pinfo->num;
1448 item->sequence_num = rtp_info->info_seq_num;
1449 item->delta = (statinfo->flags & STAT_FLAG_FIRST) ? 0.0 : statinfo->delta;
1450 item->jitter = (statinfo->flags & STAT_FLAG_FIRST) ? 0.0 : statinfo->jitter;
1451 item->skew = (statinfo->flags & STAT_FLAG_FIRST) ? 0.0 : statinfo->skew;
1452 item->bandwidth = statinfo->bandwidth;
1453 item->marker = rtp_info->info_marker_set ? TRUE : FALSE;
1454 item->arrive_offset= nstime_to_sec(&pinfo->abs_ts) - rtp_req->start_time;
1456 item->flags = statinfo->flags;
1457 item->pt = statinfo->pt;
1459 /* XXX, O(n) optimize */
1460 rtp_req->packets = g_slist_append(rtp_req->packets, item);
1467 * sharkd_session_process_tap_rtp_analyse_cb()
1469 * Output rtp analyse tap:
1470 * (m) tap - tap name
1471 * (m) type - tap output type
1472 * (m) ssrc - RTP SSRC
1473 * (m) max_delta - Max delta (ms)
1474 * (m) max_delta_nr - Max delta packet #
1475 * (m) max_jitter - Max jitter (ms)
1476 * (m) mean_jitter - Mean jitter (ms)
1477 * (m) max_skew - Max skew (ms)
1478 * (m) total_nr - Total number of RTP packets
1479 * (m) seq_err - Number of sequence errors
1480 * (m) duration - Duration (ms)
1481 * (m) items - array of object with attributes:
1482 * (m) f - frame number
1483 * (m) o - arrive offset
1484 * (m) sn - sequence number
1488 * (m) bw - bandwidth
1489 * (o) s - status string
1490 * (o) t - status type
1491 * (o) mark - rtp mark
1494 sharkd_session_process_tap_rtp_analyse_cb(void *tapdata)
1496 const int RTP_TYPE_CN = 1;
1497 const int RTP_TYPE_ERROR = 2;
1498 const int RTP_TYPE_WARN = 3;
1499 const int RTP_TYPE_PT_EVENT = 4;
1501 const struct sharkd_analyse_rtp *rtp_req = (struct sharkd_analyse_rtp *) tapdata;
1502 const tap_rtp_stat_t *statinfo = &rtp_req->statinfo;
1504 gboolean sepa = FALSE;
1507 sharkd_json_object_open(FALSE);
1509 sharkd_json_value_string(FALSE, "tap", rtp_req->tap_name);
1510 sharkd_json_value_string(TRUE, "type", "rtp-analyse");
1511 sharkd_json_value_anyf(TRUE, "ssrc", "%u", rtp_req->id.ssrc);
1513 sharkd_json_value_anyf(TRUE, "max_delta", "%f", statinfo->max_delta);
1514 sharkd_json_value_anyf(TRUE, "max_delta_nr", "%u", statinfo->max_nr);
1515 sharkd_json_value_anyf(TRUE, "max_jitter", "%f", statinfo->max_jitter);
1516 sharkd_json_value_anyf(TRUE, "mean_jitter", "%f", statinfo->mean_jitter);
1517 sharkd_json_value_anyf(TRUE, "max_skew", "%f", statinfo->max_skew);
1518 sharkd_json_value_anyf(TRUE, "total_nr", "%u", statinfo->total_nr);
1519 sharkd_json_value_anyf(TRUE, "seq_err", "%u", statinfo->sequence);
1520 sharkd_json_value_anyf(TRUE, "duration", "%f", statinfo->time - statinfo->start_time);
1522 sharkd_json_array_open(TRUE, "items");
1523 for (l = rtp_req->packets; l; l = l->next)
1525 struct sharkd_analyse_rtp_items *item = (struct sharkd_analyse_rtp_items *) l->data;
1527 sharkd_json_object_open(sepa);
1529 sharkd_json_value_anyf(FALSE, "f", "%u", item->frame_num);
1530 sharkd_json_value_anyf(TRUE, "o", "%.9f", item->arrive_offset);
1531 sharkd_json_value_anyf(TRUE, "sn", "%u", item->sequence_num);
1532 sharkd_json_value_anyf(TRUE, "d", "%.2f", item->delta);
1533 sharkd_json_value_anyf(TRUE, "j", "%.2f", item->jitter);
1534 sharkd_json_value_anyf(TRUE, "sk", "%.2f", item->skew);
1535 sharkd_json_value_anyf(TRUE, "bw", "%.2f", item->bandwidth);
1537 if (item->pt == PT_CN)
1539 sharkd_json_value_string(TRUE, "s", "Comfort noise (PT=13, RFC 3389)");
1540 sharkd_json_value_anyf(TRUE, "t", "%d", RTP_TYPE_CN);
1542 else if (item->pt == PT_CN_OLD)
1544 sharkd_json_value_string(TRUE, "s", "Comfort noise (PT=19, reserved)");
1545 sharkd_json_value_anyf(TRUE, "t", "%d", RTP_TYPE_CN);
1547 else if (item->flags & STAT_FLAG_WRONG_SEQ)
1549 sharkd_json_value_string(TRUE, "s", "Wrong sequence number");
1550 sharkd_json_value_anyf(TRUE, "t", "%d", RTP_TYPE_ERROR);
1552 else if (item->flags & STAT_FLAG_DUP_PKT)
1554 sharkd_json_value_string(TRUE, "s", "Suspected duplicate (MAC address) only delta time calculated");
1555 sharkd_json_value_anyf(TRUE, "t", "%d", RTP_TYPE_WARN);
1557 else if (item->flags & STAT_FLAG_REG_PT_CHANGE)
1559 sharkd_json_value_stringf(TRUE, "s", "Payload changed to PT=%u%s",
1561 (item->flags & STAT_FLAG_PT_T_EVENT) ? " telephone/event" : "");
1562 sharkd_json_value_anyf(TRUE, "t", "%d", RTP_TYPE_WARN);
1564 else if (item->flags & STAT_FLAG_WRONG_TIMESTAMP)
1566 sharkd_json_value_string(TRUE, "s", "Incorrect timestamp");
1567 sharkd_json_value_anyf(TRUE, "t", "%d", RTP_TYPE_WARN);
1569 else if ((item->flags & STAT_FLAG_PT_CHANGE)
1570 && !(item->flags & STAT_FLAG_FIRST)
1571 && !(item->flags & STAT_FLAG_PT_CN)
1572 && (item->flags & STAT_FLAG_FOLLOW_PT_CN)
1573 && !(item->flags & STAT_FLAG_MARKER))
1575 sharkd_json_value_string(TRUE, "s", "Marker missing?");
1576 sharkd_json_value_anyf(TRUE, "t", "%d", RTP_TYPE_WARN);
1578 else if (item->flags & STAT_FLAG_PT_T_EVENT)
1580 sharkd_json_value_stringf(TRUE, "s", "PT=%u telephone/event", item->pt);
1581 sharkd_json_value_anyf(TRUE, "t", "%d", RTP_TYPE_PT_EVENT);
1583 else if (item->flags & STAT_FLAG_MARKER)
1585 sharkd_json_value_anyf(TRUE, "t", "%d", RTP_TYPE_WARN);
1589 sharkd_json_value_anyf(TRUE, "mark", "1");
1591 sharkd_json_object_close();
1594 sharkd_json_array_close();
1596 sharkd_json_object_close();
1601 * sharkd_session_process_tap_conv_cb()
1604 * (m) tap - tap name
1605 * (m) type - tap output type
1606 * (m) proto - protocol short name
1607 * (o) filter - filter string
1609 * (o) convs - array of object with attributes:
1610 * (m) saddr - source address
1611 * (m) daddr - destination address
1612 * (o) sport - source port
1613 * (o) dport - destination port
1614 * (m) txf - TX frame count
1615 * (m) txb - TX bytes
1616 * (m) rxf - RX frame count
1617 * (m) rxb - RX bytes
1618 * (m) start - (relative) first packet time
1619 * (m) stop - (relative) last packet time
1621 * (o) hosts - array of object with attributes:
1622 * (m) host - host address
1623 * (o) port - host port
1624 * (m) txf - TX frame count
1625 * (m) txb - TX bytes
1626 * (m) rxf - RX frame count
1627 * (m) rxb - RX bytes
1630 sharkd_session_process_tap_conv_cb(void *arg)
1632 conv_hash_t *hash = (conv_hash_t *) arg;
1633 const struct sharkd_conv_tap_data *iu = (struct sharkd_conv_tap_data *) hash->user_data;
1635 int proto_with_port;
1640 sharkd_json_object_open(FALSE);
1641 sharkd_json_value_string(FALSE, "tap", iu->type);
1643 if (!strncmp(iu->type, "conv:", 5))
1645 sharkd_json_value_string(TRUE, "type", "conv");
1646 sharkd_json_array_open(TRUE, "convs");
1647 proto = iu->type + 5;
1649 else if (!strncmp(iu->type, "endpt:", 6))
1651 sharkd_json_value_string(TRUE, "type", "host");
1652 sharkd_json_array_open(TRUE, "hosts");
1653 proto = iu->type + 6;
1657 sharkd_json_value_string(TRUE, "type", "err");
1661 proto_with_port = (!strcmp(proto, "TCP") || !strcmp(proto, "UDP") || !strcmp(proto, "SCTP"));
1663 if (iu->hash.conv_array != NULL && !strncmp(iu->type, "conv:", 5))
1665 for (i = 0; i < iu->hash.conv_array->len; i++)
1667 conv_item_t *iui = &g_array_index(iu->hash.conv_array, conv_item_t, i);
1668 char *src_addr, *dst_addr;
1669 char *src_port, *dst_port;
1672 sharkd_json_object_open(i != 0);
1674 sharkd_json_value_stringf(FALSE, "saddr", "%s", (src_addr = get_conversation_address(NULL, &iui->src_address, iu->resolve_name)));
1675 sharkd_json_value_stringf(TRUE, "daddr", "%s", (dst_addr = get_conversation_address(NULL, &iui->dst_address, iu->resolve_name)));
1677 if (proto_with_port)
1679 sharkd_json_value_stringf(TRUE, "sport", "%s", (src_port = get_conversation_port(NULL, iui->src_port, iui->etype, iu->resolve_port)));
1680 sharkd_json_value_stringf(TRUE, "dport", "%s", (dst_port = get_conversation_port(NULL, iui->dst_port, iui->etype, iu->resolve_port)));
1682 wmem_free(NULL, src_port);
1683 wmem_free(NULL, dst_port);
1686 sharkd_json_value_anyf(TRUE, "rxf", "%" G_GUINT64_FORMAT, iui->rx_frames);
1687 sharkd_json_value_anyf(TRUE, "rxb", "%" G_GUINT64_FORMAT, iui->rx_bytes);
1689 sharkd_json_value_anyf(TRUE, "txf", "%" G_GUINT64_FORMAT, iui->tx_frames);
1690 sharkd_json_value_anyf(TRUE, "txb", "%" G_GUINT64_FORMAT, iui->tx_bytes);
1692 sharkd_json_value_anyf(TRUE, "start", "%.9f", nstime_to_sec(&iui->start_time));
1693 sharkd_json_value_anyf(TRUE, "stop", "%.9f", nstime_to_sec(&iui->stop_time));
1695 filter_str = get_conversation_filter(iui, CONV_DIR_A_TO_FROM_B);
1698 sharkd_json_value_stringf(TRUE, "filter", "%s", filter_str);
1702 wmem_free(NULL, src_addr);
1703 wmem_free(NULL, dst_addr);
1705 if (sharkd_session_geoip_addr(&(iui->src_address), "1"))
1707 if (sharkd_session_geoip_addr(&(iui->dst_address), "2"))
1710 sharkd_json_object_close();
1713 else if (iu->hash.conv_array != NULL && !strncmp(iu->type, "endpt:", 6))
1715 for (i = 0; i < iu->hash.conv_array->len; i++)
1717 hostlist_talker_t *host = &g_array_index(iu->hash.conv_array, hostlist_talker_t, i);
1718 char *host_str, *port_str;
1721 sharkd_json_object_open(i != 0);
1723 sharkd_json_value_stringf(FALSE, "host", "%s", (host_str = get_conversation_address(NULL, &host->myaddress, iu->resolve_name)));
1725 if (proto_with_port)
1727 sharkd_json_value_stringf(TRUE, "port", "%s", (port_str = get_conversation_port(NULL, host->port, host->etype, iu->resolve_port)));
1729 wmem_free(NULL, port_str);
1732 sharkd_json_value_anyf(TRUE, "rxf", "%" G_GUINT64_FORMAT, host->rx_frames);
1733 sharkd_json_value_anyf(TRUE, "rxb", "%" G_GUINT64_FORMAT, host->rx_bytes);
1735 sharkd_json_value_anyf(TRUE, "txf", "%" G_GUINT64_FORMAT, host->tx_frames);
1736 sharkd_json_value_anyf(TRUE, "txb", "%" G_GUINT64_FORMAT, host->tx_bytes);
1738 filter_str = get_hostlist_filter(host);
1741 sharkd_json_value_stringf(TRUE, "filter", "%s", filter_str);
1745 wmem_free(NULL, host_str);
1747 if (sharkd_session_geoip_addr(&(host->myaddress), ""))
1749 sharkd_json_object_close();
1752 sharkd_json_array_close();
1754 sharkd_json_value_string(TRUE, "proto", proto);
1755 sharkd_json_value_anyf(TRUE, "geoip", with_geoip ? "true" : "false");
1757 sharkd_json_object_close();
1762 sharkd_session_free_tap_conv_cb(void *arg)
1764 conv_hash_t *hash = (conv_hash_t *) arg;
1765 struct sharkd_conv_tap_data *iu = (struct sharkd_conv_tap_data *) hash->user_data;
1767 if (!strncmp(iu->type, "conv:", 5))
1769 reset_conversation_table_data(hash);
1771 else if (!strncmp(iu->type, "endpt:", 6))
1773 reset_hostlist_table_data(hash);
1780 * sharkd_session_process_tap_nstat_cb()
1783 * (m) tap - tap name
1784 * (m) type - tap output type
1785 * (m) fields: array of objects with attributes:
1788 * (m) tables: array of object with attributes:
1789 * (m) t - table title
1790 * (m) i - array of items
1793 sharkd_session_process_tap_nstat_cb(void *arg)
1795 stat_data_t *stat_data = (stat_data_t *) arg;
1798 sharkd_json_object_open(FALSE);
1799 sharkd_json_value_stringf(FALSE, "tap", "nstat:%s", stat_data->stat_tap_data->cli_string);
1800 sharkd_json_value_string(TRUE, "type", "nstat");
1802 sharkd_json_array_open(TRUE, "fields");
1803 for (i = 0; i < stat_data->stat_tap_data->nfields; i++)
1805 stat_tap_table_item *field = &(stat_data->stat_tap_data->fields[i]);
1807 sharkd_json_object_open(i != 0);
1808 sharkd_json_value_string(FALSE, "c", field->column_name);
1809 sharkd_json_object_close();
1811 sharkd_json_array_close();
1813 sharkd_json_array_open(TRUE, "tables");
1814 for (i = 0; i < stat_data->stat_tap_data->tables->len; i++)
1816 stat_tap_table *table = g_array_index(stat_data->stat_tap_data->tables, stat_tap_table *, i);
1817 gboolean sepa = FALSE;
1819 sharkd_json_object_open(i != 0);
1821 sharkd_json_value_stringf(FALSE, "t", "%s", table->title);
1823 sharkd_json_array_open(TRUE, "i");
1824 for (j = 0; j < table->num_elements; j++)
1826 stat_tap_table_item_type *field_data;
1828 field_data = stat_tap_get_field_data(table, j, 0);
1829 if (field_data == NULL || field_data->type == TABLE_ITEM_NONE) /* Nothing for us here */
1832 sharkd_json_array_open(sepa, NULL);
1833 for (k = 0; k < table->num_fields; k++)
1835 field_data = stat_tap_get_field_data(table, j, k);
1837 switch (field_data->type)
1839 case TABLE_ITEM_UINT:
1840 sharkd_json_value_anyf(k != 0, NULL, "%u", field_data->value.uint_value);
1843 case TABLE_ITEM_INT:
1844 sharkd_json_value_anyf(k != 0, NULL, "%d", field_data->value.int_value);
1847 case TABLE_ITEM_STRING:
1848 sharkd_json_value_string(k != 0, NULL, field_data->value.string_value);
1851 case TABLE_ITEM_FLOAT:
1852 sharkd_json_value_anyf(k != 0, NULL, "%f", field_data->value.float_value);
1855 case TABLE_ITEM_ENUM:
1856 sharkd_json_value_anyf(k != 0, NULL, "%d", field_data->value.enum_value);
1859 case TABLE_ITEM_NONE:
1860 sharkd_json_value_anyf(k != 0, NULL, "null");
1865 sharkd_json_array_close();
1868 sharkd_json_array_close();
1869 sharkd_json_object_close();
1871 sharkd_json_array_close();
1873 sharkd_json_object_close();
1878 sharkd_session_free_tap_nstat_cb(void *arg)
1880 stat_data_t *stat_data = (stat_data_t *) arg;
1882 free_stat_tables(stat_data->stat_tap_data);
1886 * sharkd_session_process_tap_rtd_cb()
1889 * (m) tap - tap name
1890 * (m) type - tap output type
1891 * (m) stats - statistics rows - array object with attributes:
1892 * (m) type - statistic name
1893 * (m) num - number of messages
1894 * (m) min - minimum SRT time
1895 * (m) max - maximum SRT time
1896 * (m) tot - total SRT time
1897 * (m) min_frame - minimal SRT
1898 * (m) max_frame - maximum SRT
1899 * (o) open_req - Open Requests
1900 * (o) disc_rsp - Discarded Responses
1901 * (o) req_dup - Duplicated Requests
1902 * (o) rsp_dup - Duplicated Responses
1903 * (o) open_req - Open Requests
1904 * (o) disc_rsp - Discarded Responses
1905 * (o) req_dup - Duplicated Requests
1906 * (o) rsp_dup - Duplicated Responses
1909 sharkd_session_process_tap_rtd_cb(void *arg)
1911 rtd_data_t *rtd_data = (rtd_data_t *) arg;
1912 register_rtd_t *rtd = (register_rtd_t *) rtd_data->user_data;
1916 const char *filter = proto_get_protocol_filter_name(get_rtd_proto_id(rtd));
1918 /* XXX, some dissectors are having single table and multiple timestats (mgcp, megaco),
1919 * some multiple table and single timestat (radius, h225)
1920 * and it seems that value_string is used one for timestamp-ID, other one for table-ID
1921 * I wonder how it will gonna work with multiple timestats and multiple tables...
1922 * (for usage grep for: register_rtd_table)
1924 const value_string *vs = get_rtd_value_string(rtd);
1925 gboolean sepa = FALSE;
1927 sharkd_json_object_open(FALSE);
1928 sharkd_json_value_stringf(FALSE, "tap", "rtd:%s", filter);
1929 sharkd_json_value_string(TRUE, "type", "rtd");
1931 if (rtd_data->stat_table.num_rtds == 1)
1933 const rtd_timestat *ms = &rtd_data->stat_table.time_stats[0];
1935 sharkd_json_value_anyf(TRUE, "open_req", "%u", ms->open_req_num);
1936 sharkd_json_value_anyf(TRUE, "disc_rsp", "%u", ms->disc_rsp_num);
1937 sharkd_json_value_anyf(TRUE, "req_dup", "%u", ms->req_dup_num);
1938 sharkd_json_value_anyf(TRUE, "rsp_dup", "%u", ms->rsp_dup_num);
1941 sharkd_json_array_open(TRUE, "stats");
1942 for (i = 0; i < rtd_data->stat_table.num_rtds; i++)
1944 const rtd_timestat *ms = &rtd_data->stat_table.time_stats[i];
1946 for (j = 0; j < ms->num_timestat; j++)
1948 const char *type_str;
1950 if (ms->rtd[j].num == 0)
1953 sharkd_json_object_open(sepa);
1955 if (rtd_data->stat_table.num_rtds == 1)
1956 type_str = val_to_str_const(j, vs, "Other"); /* 1 table - description per row */
1958 type_str = val_to_str_const(i, vs, "Other"); /* multiple table - description per table */
1959 sharkd_json_value_string(FALSE, "type", type_str);
1961 sharkd_json_value_anyf(TRUE, "num", "%u", ms->rtd[j].num);
1962 sharkd_json_value_anyf(TRUE, "min", "%.9f", nstime_to_sec(&(ms->rtd[j].min)));
1963 sharkd_json_value_anyf(TRUE, "max", "%.9f", nstime_to_sec(&(ms->rtd[j].max)));
1964 sharkd_json_value_anyf(TRUE, "tot", "%.9f", nstime_to_sec(&(ms->rtd[j].tot)));
1965 sharkd_json_value_anyf(TRUE, "min_frame", "%u", ms->rtd[j].min_num);
1966 sharkd_json_value_anyf(TRUE, "max_frame", "%u", ms->rtd[j].max_num);
1968 if (rtd_data->stat_table.num_rtds != 1)
1970 /* like in tshark, display it on every row */
1971 sharkd_json_value_anyf(TRUE, "open_req", "%u", ms->open_req_num);
1972 sharkd_json_value_anyf(TRUE, "disc_rsp", "%u", ms->disc_rsp_num);
1973 sharkd_json_value_anyf(TRUE, "req_dup", "%u", ms->req_dup_num);
1974 sharkd_json_value_anyf(TRUE, "rsp_dup", "%u", ms->rsp_dup_num);
1977 sharkd_json_object_close();
1981 sharkd_json_array_close();
1983 sharkd_json_object_close();
1988 sharkd_session_free_tap_rtd_cb(void *arg)
1990 rtd_data_t *rtd_data = (rtd_data_t *) arg;
1992 free_rtd_table(&rtd_data->stat_table);
1997 * sharkd_session_process_tap_srt_cb()
2000 * (m) tap - tap name
2001 * (m) type - tap output type
2003 * (m) tables - array of object with attributes:
2004 * (m) n - table name
2005 * (m) f - table filter
2006 * (o) c - table column name
2007 * (m) r - table rows - array object with attributes:
2009 * (m) idx - procedure index
2010 * (m) num - number of events
2011 * (m) min - minimum SRT time
2012 * (m) max - maximum SRT time
2013 * (m) tot - total SRT time
2016 sharkd_session_process_tap_srt_cb(void *arg)
2018 srt_data_t *srt_data = (srt_data_t *) arg;
2019 register_srt_t *srt = (register_srt_t *) srt_data->user_data;
2021 const char *filter = proto_get_protocol_filter_name(get_srt_proto_id(srt));
2025 sharkd_json_object_open(FALSE);
2026 sharkd_json_value_stringf(FALSE, "tap", "srt:%s", filter);
2027 sharkd_json_value_string(TRUE, "type", "srt");
2029 sharkd_json_array_open(TRUE, "tables");
2030 for (i = 0; i < srt_data->srt_array->len; i++)
2033 srt_stat_table *rst = g_array_index(srt_data->srt_array, srt_stat_table *, i);
2034 gboolean sepa = FALSE;
2038 sharkd_json_object_open(i != 0);
2041 sharkd_json_value_string(FALSE, "n", rst->name);
2042 else if (rst->short_name)
2043 sharkd_json_value_string(FALSE, "n", rst->short_name);
2045 sharkd_json_value_stringf(FALSE, "n", "table%u", i);
2047 if (rst->filter_string)
2048 sharkd_json_value_string(TRUE, "f", rst->filter_string);
2050 if (rst->proc_column_name)
2051 sharkd_json_value_string(TRUE, "c", rst->proc_column_name);
2053 sharkd_json_array_open(TRUE, "r");
2054 for (j = 0; j < rst->num_procs; j++)
2057 srt_procedure_t *proc = &rst->procedures[j];
2059 if (proc->stats.num == 0)
2062 sharkd_json_object_open(sepa);
2064 sharkd_json_value_string(FALSE, "n", proc->procedure);
2066 if (rst->filter_string)
2067 sharkd_json_value_anyf(TRUE, "idx", "%d", proc->proc_index);
2069 sharkd_json_value_anyf(TRUE, "num", "%u", proc->stats.num);
2071 sharkd_json_value_anyf(TRUE, "min", "%.9f", nstime_to_sec(&proc->stats.min));
2072 sharkd_json_value_anyf(TRUE, "max", "%.9f", nstime_to_sec(&proc->stats.max));
2073 sharkd_json_value_anyf(TRUE, "tot", "%.9f", nstime_to_sec(&proc->stats.tot));
2075 sharkd_json_object_close();
2078 sharkd_json_array_close();
2080 sharkd_json_object_close();
2082 sharkd_json_array_close();
2084 sharkd_json_object_close();
2089 sharkd_session_free_tap_srt_cb(void *arg)
2091 srt_data_t *srt_data = (srt_data_t *) arg;
2092 register_srt_t *srt = (register_srt_t *) srt_data->user_data;
2094 free_srt_table(srt, srt_data->srt_array);
2095 g_array_free(srt_data->srt_array, TRUE);
2099 struct sharkd_export_object_list
2101 struct sharkd_export_object_list *next;
2108 static struct sharkd_export_object_list *sharkd_eo_list;
2111 * sharkd_session_process_tap_eo_cb()
2114 * (m) tap - tap name
2115 * (m) type - tap output type
2116 * (m) proto - protocol short name
2117 * (m) objects - array of object with attributes:
2118 * (m) pkt - packet number
2119 * (o) hostname - hostname
2120 * (o) type - content type
2121 * (o) filename - filename
2122 * (m) len - object length
2125 sharkd_session_process_tap_eo_cb(void *tapdata)
2127 export_object_list_t *tap_object = (export_object_list_t *) tapdata;
2128 struct sharkd_export_object_list *object_list = (struct sharkd_export_object_list *) tap_object->gui_data;
2132 sharkd_json_object_open(FALSE);
2133 sharkd_json_value_string(FALSE, "tap", object_list->type);
2134 sharkd_json_value_string(TRUE, "type", "eo");
2136 sharkd_json_value_stringf(TRUE, "proto", "%s", object_list->proto);
2138 sharkd_json_array_open(TRUE, "objects");
2139 for (slist = object_list->entries; slist; slist = slist->next)
2141 const export_object_entry_t *eo_entry = (export_object_entry_t *) slist->data;
2143 sharkd_json_object_open(i != 0);
2145 sharkd_json_value_anyf(FALSE, "pkt", "%u", eo_entry->pkt_num);
2147 if (eo_entry->hostname)
2148 sharkd_json_value_string(TRUE, "hostname", eo_entry->hostname);
2150 if (eo_entry->content_type)
2151 sharkd_json_value_string(TRUE, "type", eo_entry->content_type);
2153 if (eo_entry->filename)
2154 sharkd_json_value_string(TRUE, "filename", eo_entry->filename);
2156 sharkd_json_value_stringf(TRUE, "_download", "%s_%d", object_list->type, i);
2158 sharkd_json_value_anyf(TRUE, "len", "%" G_GINT64_FORMAT, eo_entry->payload_len);
2160 sharkd_json_object_close();
2164 sharkd_json_array_close();
2166 sharkd_json_object_close();
2171 sharkd_eo_object_list_add_entry(void *gui_data, export_object_entry_t *entry)
2173 struct sharkd_export_object_list *object_list = (struct sharkd_export_object_list *) gui_data;
2175 object_list->entries = g_slist_append(object_list->entries, entry);
2178 static export_object_entry_t *
2179 sharkd_eo_object_list_get_entry(void *gui_data, int row)
2181 struct sharkd_export_object_list *object_list = (struct sharkd_export_object_list *) gui_data;
2183 return (export_object_entry_t *) g_slist_nth_data(object_list->entries, row);
2187 * sharkd_session_process_tap_rtp_cb()
2189 * Output RTP streams tap:
2190 * (m) tap - tap name
2191 * (m) type - tap output type
2192 * (m) streams - array of object with attributes:
2193 * (m) ssrc - RTP synchronization source identifier
2194 * (m) payload - stream payload
2195 * (m) saddr - source address
2196 * (m) sport - source port
2197 * (m) daddr - destination address
2198 * (m) dport - destination port
2199 * (m) pkts - packets count
2200 * (m) max_delta - max delta (ms)
2201 * (m) max_jitter - max jitter (ms)
2202 * (m) mean_jitter - mean jitter (ms)
2205 * (m) problem - if analyser found the problem
2206 * (m) ipver - address IP version (4 or 6)
2209 sharkd_session_process_tap_rtp_cb(void *arg)
2211 rtpstream_tapinfo_t *rtp_tapinfo = (rtpstream_tapinfo_t *) arg;
2214 gboolean sepa = FALSE;
2216 sharkd_json_object_open(FALSE);
2217 sharkd_json_value_stringf(FALSE, "tap", "rtp-streams");
2218 sharkd_json_value_string(TRUE, "type", "rtp-streams");
2220 sharkd_json_array_open(TRUE, "streams");
2221 for (listx = g_list_first(rtp_tapinfo->strinfo_list); listx; listx = listx->next)
2223 rtpstream_info_t *streaminfo = (rtpstream_info_t *) listx->data;
2224 rtpstream_info_calc_t calc;
2226 rtpstream_info_calculate(streaminfo, &calc);
2228 sharkd_json_object_open(sepa);
2230 sharkd_json_value_anyf(FALSE, "ssrc", "%u", calc.ssrc);
2231 sharkd_json_value_stringf(TRUE, "payload", "%s", calc.all_payload_type_names);
2233 sharkd_json_value_stringf(TRUE, "saddr", "%s", calc.src_addr_str);
2234 sharkd_json_value_anyf(TRUE, "sport", "%u", calc.src_port);
2235 sharkd_json_value_stringf(TRUE, "daddr", "%s", calc.dst_addr_str);
2236 sharkd_json_value_anyf(TRUE, "dport", "%u", calc.dst_port);
2238 sharkd_json_value_anyf(TRUE, "pkts", "%u", calc.packet_count);
2240 sharkd_json_value_anyf(TRUE, "max_delta", "%f",calc.max_delta);
2241 sharkd_json_value_anyf(TRUE, "max_jitter", "%f", calc.max_jitter);
2242 sharkd_json_value_anyf(TRUE, "mean_jitter", "%f", calc.mean_jitter);
2244 sharkd_json_value_anyf(TRUE, "expectednr", "%u", calc.packet_expected);
2245 sharkd_json_value_anyf(TRUE, "totalnr", "%u", calc.total_nr);
2247 sharkd_json_value_anyf(TRUE, "problem", calc.problem ? "true" : "false");
2250 sharkd_json_value_anyf(TRUE, "ipver", "%d", (streaminfo->id.src_addr.type == AT_IPv6) ? 6 : 4);
2252 rtpstream_info_calc_free(&calc);
2254 sharkd_json_object_close();
2257 sharkd_json_array_close();
2259 sharkd_json_object_close();
2264 * sharkd_session_process_tap()
2266 * Process tap request
2269 * (m) tap0 - First tap request
2270 * (o) tap1...tap15 - Other tap requests
2272 * Output object with attributes:
2273 * (m) taps - array of object with attributes:
2274 * (m) tap - tap name
2275 * (m) type - tap output type
2277 * for type:stats see sharkd_session_process_tap_stats_cb()
2278 * for type:nstat see sharkd_session_process_tap_nstat_cb()
2279 * for type:conv see sharkd_session_process_tap_conv_cb()
2280 * for type:host see sharkd_session_process_tap_conv_cb()
2281 * for type:rtp-streams see sharkd_session_process_tap_rtp_cb()
2282 * for type:rtp-analyse see sharkd_session_process_tap_rtp_analyse_cb()
2283 * for type:eo see sharkd_session_process_tap_eo_cb()
2284 * for type:expert see sharkd_session_process_tap_expert_cb()
2285 * for type:rtd see sharkd_session_process_tap_rtd_cb()
2286 * for type:srt see sharkd_session_process_tap_srt_cb()
2287 * for type:flow see sharkd_session_process_tap_flow_cb()
2289 * (m) err - error code
2292 sharkd_session_process_tap(char *buf, const jsmntok_t *tokens, int count)
2294 void *taps_data[16];
2295 GFreeFunc taps_free[16];
2299 rtpstream_tapinfo_t rtp_tapinfo =
2300 { NULL, NULL, NULL, NULL, 0, NULL, 0, TAP_ANALYSE, NULL, NULL, NULL, FALSE };
2302 for (i = 0; i < 16; i++)
2305 const char *tok_tap;
2307 void *tap_data = NULL;
2308 GFreeFunc tap_free = NULL;
2309 const char *tap_filter = "";
2310 GString *tap_error = NULL;
2312 ws_snprintf(tapbuf, sizeof(tapbuf), "tap%d", i);
2313 tok_tap = json_find_attr(buf, tokens, count, tapbuf);
2317 if (!strncmp(tok_tap, "stat:", 5))
2319 stats_tree_cfg *cfg = stats_tree_get_cfg_by_abbr(tok_tap + 5);
2324 fprintf(stderr, "sharkd_session_process_tap() stat %s not found\n", tok_tap + 5);
2328 st = stats_tree_new(cfg, NULL, tap_filter);
2330 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);
2332 if (!tap_error && cfg->init)
2336 tap_free = sharkd_session_free_tap_stats_cb;
2338 else if (!strcmp(tok_tap, "expert"))
2340 struct sharkd_expert_tap *expert_tap;
2342 expert_tap = g_new0(struct sharkd_expert_tap, 1);
2343 expert_tap->text = g_string_chunk_new(100);
2345 tap_error = register_tap_listener("expert", expert_tap, NULL, 0, NULL, sharkd_session_packet_tap_expert_cb, sharkd_session_process_tap_expert_cb, NULL);
2347 tap_data = expert_tap;
2348 tap_free = sharkd_session_free_tap_expert_cb;
2350 else if (!strncmp(tok_tap, "seqa:", 5))
2352 seq_analysis_info_t *graph_analysis;
2353 register_analysis_t *analysis;
2354 const char *tap_name;
2355 tap_packet_cb tap_func;
2358 analysis = sequence_analysis_find_by_name(tok_tap + 5);
2361 fprintf(stderr, "sharkd_session_process_tap() seq analysis %s not found\n", tok_tap + 5);
2365 graph_analysis = sequence_analysis_info_new();
2366 graph_analysis->name = tok_tap + 5;
2367 /* TODO, make configurable */
2368 graph_analysis->any_addr = FALSE;
2370 tap_name = sequence_analysis_get_tap_listener_name(analysis);
2371 tap_flags = sequence_analysis_get_tap_flags(analysis);
2372 tap_func = sequence_analysis_get_packet_func(analysis);
2374 tap_error = register_tap_listener(tap_name, graph_analysis, NULL, tap_flags, NULL, tap_func, sharkd_session_process_tap_flow_cb, NULL);
2376 tap_data = graph_analysis;
2377 tap_free = sharkd_session_free_tap_flow_cb;
2379 else if (!strncmp(tok_tap, "conv:", 5) || !strncmp(tok_tap, "endpt:", 6))
2381 struct register_ct *ct = NULL;
2382 const char *ct_tapname;
2383 struct sharkd_conv_tap_data *ct_data;
2384 tap_packet_cb tap_func = NULL;
2386 if (!strncmp(tok_tap, "conv:", 5))
2388 ct = get_conversation_by_proto_id(proto_get_id_by_short_name(tok_tap + 5));
2390 if (!ct || !(tap_func = get_conversation_packet_func(ct)))
2392 fprintf(stderr, "sharkd_session_process_tap() conv %s not found\n", tok_tap + 5);
2396 else if (!strncmp(tok_tap, "endpt:", 6))
2398 ct = get_conversation_by_proto_id(proto_get_id_by_short_name(tok_tap + 6));
2400 if (!ct || !(tap_func = get_hostlist_packet_func(ct)))
2402 fprintf(stderr, "sharkd_session_process_tap() endpt %s not found\n", tok_tap + 6);
2408 fprintf(stderr, "sharkd_session_process_tap() conv/endpt(?): %s not found\n", tok_tap);
2412 ct_tapname = proto_get_protocol_filter_name(get_conversation_proto_id(ct));
2414 ct_data = (struct sharkd_conv_tap_data *) g_malloc0(sizeof(struct sharkd_conv_tap_data));
2415 ct_data->type = tok_tap;
2416 ct_data->hash.user_data = ct_data;
2418 /* XXX: make configurable */
2419 ct_data->resolve_name = TRUE;
2420 ct_data->resolve_port = TRUE;
2422 tap_error = register_tap_listener(ct_tapname, &ct_data->hash, tap_filter, 0, NULL, tap_func, sharkd_session_process_tap_conv_cb, NULL);
2424 tap_data = &ct_data->hash;
2425 tap_free = sharkd_session_free_tap_conv_cb;
2427 else if (!strncmp(tok_tap, "nstat:", 6))
2429 stat_tap_table_ui *stat_tap = stat_tap_by_name(tok_tap + 6);
2430 stat_data_t *stat_data;
2434 fprintf(stderr, "sharkd_session_process_tap() nstat=%s not found\n", tok_tap + 6);
2438 stat_tap->stat_tap_init_cb(stat_tap);
2440 stat_data = g_new0(stat_data_t, 1);
2441 stat_data->stat_tap_data = stat_tap;
2442 stat_data->user_data = NULL;
2444 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);
2446 tap_data = stat_data;
2447 tap_free = sharkd_session_free_tap_nstat_cb;
2449 else if (!strncmp(tok_tap, "rtd:", 4))
2451 register_rtd_t *rtd = get_rtd_table_by_name(tok_tap + 4);
2452 rtd_data_t *rtd_data;
2457 fprintf(stderr, "sharkd_session_process_tap() rtd=%s not found\n", tok_tap + 4);
2461 rtd_table_get_filter(rtd, "", &tap_filter, &err);
2464 fprintf(stderr, "sharkd_session_process_tap() rtd=%s err=%s\n", tok_tap + 4, err);
2469 rtd_data = g_new0(rtd_data_t, 1);
2470 rtd_data->user_data = rtd;
2471 rtd_table_dissector_init(rtd, &rtd_data->stat_table, NULL, NULL);
2473 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);
2475 tap_data = rtd_data;
2476 tap_free = sharkd_session_free_tap_rtd_cb;
2478 else if (!strncmp(tok_tap, "srt:", 4))
2480 register_srt_t *srt = get_srt_table_by_name(tok_tap + 4);
2481 srt_data_t *srt_data;
2486 fprintf(stderr, "sharkd_session_process_tap() srt=%s not found\n", tok_tap + 4);
2490 srt_table_get_filter(srt, "", &tap_filter, &err);
2493 fprintf(stderr, "sharkd_session_process_tap() srt=%s err=%s\n", tok_tap + 4, err);
2498 srt_data = g_new0(srt_data_t, 1);
2499 srt_data->srt_array = g_array_new(FALSE, TRUE, sizeof(srt_stat_table *));
2500 srt_data->user_data = srt;
2501 srt_table_dissector_init(srt, srt_data->srt_array);
2503 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);
2505 tap_data = srt_data;
2506 tap_free = sharkd_session_free_tap_srt_cb;
2508 else if (!strncmp(tok_tap, "eo:", 3))
2510 register_eo_t *eo = get_eo_by_name(tok_tap + 3);
2511 export_object_list_t *eo_object;
2512 struct sharkd_export_object_list *object_list;
2516 fprintf(stderr, "sharkd_session_process_tap() eo=%s not found\n", tok_tap + 3);
2520 for (object_list = sharkd_eo_list; object_list; object_list = object_list->next)
2522 if (!strcmp(object_list->type, tok_tap))
2524 g_slist_free_full(object_list->entries, (GDestroyNotify) eo_free_entry);
2525 object_list->entries = NULL;
2532 object_list = g_new(struct sharkd_export_object_list, 1);
2533 object_list->type = g_strdup(tok_tap);
2534 object_list->proto = proto_get_protocol_short_name(find_protocol_by_id(get_eo_proto_id(eo)));
2535 object_list->entries = NULL;
2536 object_list->next = sharkd_eo_list;
2537 sharkd_eo_list = object_list;
2540 eo_object = g_new0(export_object_list_t, 1);
2541 eo_object->add_entry = sharkd_eo_object_list_add_entry;
2542 eo_object->get_entry = sharkd_eo_object_list_get_entry;
2543 eo_object->gui_data = (void *) object_list;
2545 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);
2547 tap_data = eo_object;
2548 tap_free = g_free; /* need to free only eo_object, object_list need to be kept for potential download */
2550 else if (!strcmp(tok_tap, "rtp-streams"))
2552 tap_error = register_tap_listener("rtp", &rtp_tapinfo, tap_filter, 0, rtpstream_reset_cb, rtpstream_packet_cb, sharkd_session_process_tap_rtp_cb, NULL);
2554 tap_data = &rtp_tapinfo;
2555 tap_free = rtpstream_reset_cb;
2557 else if (!strncmp(tok_tap, "rtp-analyse:", 12))
2559 struct sharkd_analyse_rtp *rtp_req;
2561 rtp_req = (struct sharkd_analyse_rtp *) g_malloc0(sizeof(*rtp_req));
2562 if (!sharkd_rtp_match_init(&rtp_req->id, tok_tap + 12))
2564 rtpstream_id_free(&rtp_req->id);
2569 rtp_req->tap_name = tok_tap;
2570 rtp_req->statinfo.first_packet = TRUE;
2571 rtp_req->statinfo.reg_pt = PT_UNDEFINED;
2573 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);
2576 tap_free = sharkd_session_process_tap_rtp_free_cb;
2580 fprintf(stderr, "sharkd_session_process_tap() %s not recognized\n", tok_tap);
2586 fprintf(stderr, "sharkd_session_process_tap() name=%s error=%s", tok_tap, tap_error->str);
2587 g_string_free(tap_error, TRUE);
2593 taps_data[taps_count] = tap_data;
2594 taps_free[taps_count] = tap_free;
2598 fprintf(stderr, "sharkd_session_process_tap() count=%d\n", taps_count);
2599 if (taps_count == 0)
2602 sharkd_json_object_open(FALSE);
2604 sharkd_json_array_open(FALSE, "taps");
2606 sharkd_json_value_anyf(FALSE, NULL, "null");
2607 sharkd_json_array_close();
2609 sharkd_json_value_anyf(TRUE, "err", "0");
2611 sharkd_json_object_close();
2612 sharkd_json_finish();
2614 for (i = 0; i < taps_count; i++)
2617 remove_tap_listener(taps_data[i]);
2620 taps_free[i](taps_data[i]);
2625 * sharkd_session_process_follow()
2627 * Process follow request
2630 * (m) follow - follow protocol request (e.g. HTTP)
2631 * (m) filter - filter request (e.g. tcp.stream == 1)
2633 * Output object with attributes:
2635 * (m) err - error code
2636 * (m) shost - server host
2637 * (m) sport - server port
2638 * (m) sbytes - server send bytes count
2639 * (m) chost - client host
2640 * (m) cport - client port
2641 * (m) cbytes - client send bytes count
2642 * (o) payloads - array of object with attributes:
2643 * (o) s - set if server sent, else client
2644 * (m) n - packet number
2645 * (m) d - data base64 encoded
2648 sharkd_session_process_follow(char *buf, const jsmntok_t *tokens, int count)
2650 const char *tok_follow = json_find_attr(buf, tokens, count, "follow");
2651 const char *tok_filter = json_find_attr(buf, tokens, count, "filter");
2653 register_follow_t *follower;
2656 follow_info_t *follow_info;
2660 if (!tok_follow || !tok_filter)
2663 follower = get_follow_by_name(tok_follow);
2666 fprintf(stderr, "sharkd_session_process_follow() follower=%s not found\n", tok_follow);
2670 /* follow_reset_stream ? */
2671 follow_info = g_new0(follow_info_t, 1);
2672 /* gui_data, filter_out_filter not set, but not used by dissector */
2674 tap_error = register_tap_listener(get_follow_tap_string(follower), follow_info, tok_filter, 0, NULL, get_follow_tap_handler(follower), NULL, NULL);
2677 fprintf(stderr, "sharkd_session_process_follow() name=%s error=%s", tok_follow, tap_error->str);
2678 g_string_free(tap_error, TRUE);
2679 g_free(follow_info);
2685 sharkd_json_object_open(FALSE);
2687 sharkd_json_value_anyf(FALSE, "err", "0");
2689 /* Server information: hostname, port, bytes sent */
2690 host = address_to_name(&follow_info->server_ip);
2691 sharkd_json_value_string(TRUE, "shost", host);
2693 port = get_follow_port_to_display(follower)(NULL, follow_info->server_port);
2694 sharkd_json_value_string(TRUE, "sport", port);
2695 wmem_free(NULL, port);
2697 sharkd_json_value_anyf(TRUE, "sbytes", "%u", follow_info->bytes_written[0]);
2699 /* Client information: hostname, port, bytes sent */
2700 host = address_to_name(&follow_info->client_ip);
2701 sharkd_json_value_string(TRUE, "chost", host);
2703 port = get_follow_port_to_display(follower)(NULL, follow_info->client_port);
2704 sharkd_json_value_string(TRUE, "cport", port);
2705 wmem_free(NULL, port);
2707 sharkd_json_value_anyf(TRUE, "cbytes", "%u", follow_info->bytes_written[1]);
2709 if (follow_info->payload)
2711 follow_record_t *follow_record;
2713 gboolean sepa = FALSE;
2715 sharkd_json_array_open(TRUE, "payloads");
2716 for (cur = g_list_last(follow_info->payload); cur; cur = g_list_previous(cur))
2718 follow_record = (follow_record_t *) cur->data;
2720 sharkd_json_object_open(sepa);
2722 sharkd_json_value_anyf(FALSE, "n", "%u", follow_record->packet_num);
2723 sharkd_json_value_base64(TRUE, "d", follow_record->data->data, follow_record->data->len);
2725 if (follow_record->is_server)
2726 sharkd_json_value_anyf(TRUE, "s", "%d", 1);
2728 sharkd_json_object_close();
2731 sharkd_json_array_close();
2734 sharkd_json_object_close();
2735 sharkd_json_finish();
2737 remove_tap_listener(follow_info);
2738 follow_info_free(follow_info);
2742 sharkd_session_process_frame_cb_tree(epan_dissect_t *edt, proto_tree *tree, tvbuff_t **tvbs, gboolean display_hidden)
2745 gboolean sepa = FALSE;
2747 sharkd_json_array_open(FALSE, NULL);
2748 for (node = tree->first_child; node; node = node->next)
2750 field_info *finfo = PNODE_FINFO(node);
2755 if (!display_hidden && FI_GET_FLAG(finfo, FI_HIDDEN))
2758 sharkd_json_object_open(sepa);
2762 char label_str[ITEM_LABEL_LENGTH];
2764 label_str[0] = '\0';
2765 proto_item_fill_label(finfo, label_str);
2766 sharkd_json_value_string(FALSE, "l", label_str);
2770 sharkd_json_value_string(FALSE, "l", finfo->rep->representation);
2773 if (finfo->ds_tvb && tvbs && tvbs[0] != finfo->ds_tvb)
2777 for (idx = 1; tvbs[idx]; idx++)
2779 if (tvbs[idx] == finfo->ds_tvb)
2781 sharkd_json_value_anyf(TRUE, "ds", "%d", idx);
2787 if (finfo->start >= 0 && finfo->length > 0)
2788 sharkd_json_value_anyf(TRUE, "h", "[%d,%d]", finfo->start, finfo->length);
2790 if (finfo->appendix_start >= 0 && finfo->appendix_length > 0)
2791 sharkd_json_value_anyf(TRUE, "i", "[%d,%d]", finfo->appendix_start, finfo->appendix_length);
2798 if (finfo->hfinfo->type == FT_PROTOCOL)
2800 sharkd_json_value_stringf(TRUE, "t", "proto");
2802 else if (finfo->hfinfo->type == FT_FRAMENUM)
2804 sharkd_json_value_string(TRUE, "t", "framenum");
2805 sharkd_json_value_anyf(TRUE, "fnum", "%u", finfo->value.value.uinteger);
2807 else if (FI_GET_FLAG(finfo, FI_URL) && IS_FT_STRING(finfo->hfinfo->type))
2809 char *url = fvalue_to_string_repr(NULL, &finfo->value, FTREPR_DISPLAY, finfo->hfinfo->display);
2811 sharkd_json_value_string(TRUE, "t", "url");
2812 sharkd_json_value_string(TRUE, "url", url);
2813 wmem_free(NULL, url);
2816 filter = proto_construct_match_selected_string(finfo, edt);
2819 sharkd_json_value_string(TRUE, "f", filter);
2820 wmem_free(NULL, filter);
2824 if (FI_GET_FLAG(finfo, FI_GENERATED))
2825 sharkd_json_value_anyf(TRUE, "g", "true");
2827 if (FI_GET_FLAG(finfo, FI_HIDDEN))
2828 sharkd_json_value_anyf(TRUE, "v", "true");
2830 if (FI_GET_FLAG(finfo, PI_SEVERITY_MASK))
2832 const char *severity = try_val_to_str(FI_GET_FLAG(finfo, PI_SEVERITY_MASK), expert_severity_vals);
2834 g_assert(severity != NULL);
2836 sharkd_json_value_stringf(TRUE, "s", "%s", severity);
2839 if (((proto_tree *) node)->first_child)
2841 if (finfo->tree_type != -1)
2842 sharkd_json_value_anyf(TRUE, "e", "%d", finfo->tree_type);
2844 sharkd_json_value_anyf(TRUE, "n", NULL);
2845 sharkd_session_process_frame_cb_tree(edt, (proto_tree *) node, tvbs, display_hidden);
2848 sharkd_json_object_close();
2851 sharkd_json_array_close();
2855 sharkd_follower_visit_layers_cb(const void *key _U_, void *value, void *user_data)
2857 register_follow_t *follower = (register_follow_t *) value;
2858 packet_info *pi = (packet_info *) user_data;
2860 const int proto_id = get_follow_proto_id(follower);
2862 guint32 ignore_stream;
2864 if (proto_is_frame_protocol(pi->layers, proto_get_protocol_filter_name(proto_id)))
2866 const char *layer_proto = proto_get_protocol_short_name(find_protocol_by_id(proto_id));
2867 char *follow_filter;
2869 follow_filter = get_follow_conv_func(follower)(pi, &ignore_stream);
2871 sharkd_json_array_open(TRUE, NULL);
2872 sharkd_json_value_string(FALSE, NULL, layer_proto);
2873 sharkd_json_value_string(TRUE, NULL, follow_filter);
2874 sharkd_json_array_close();
2876 g_free(follow_filter);
2882 struct sharkd_frame_request_data
2884 gboolean display_hidden;
2888 sharkd_session_process_frame_cb(epan_dissect_t *edt, proto_tree *tree, struct epan_column_info *cinfo, const GSList *data_src, void *data)
2890 packet_info *pi = &edt->pi;
2891 frame_data *fdata = pi->fd;
2892 const char *pkt_comment = NULL;
2894 const struct sharkd_frame_request_data * const req_data = (const struct sharkd_frame_request_data * const) data;
2895 const gboolean display_hidden = (req_data) ? req_data->display_hidden : FALSE;
2897 sharkd_json_object_open(FALSE);
2899 sharkd_json_value_anyf(FALSE, "err", "0");
2901 if (fdata->flags.has_user_comment)
2902 pkt_comment = sharkd_get_user_comment(fdata);
2903 else if (fdata->flags.has_phdr_comment)
2904 pkt_comment = pi->rec->opt_comment;
2907 sharkd_json_value_string(TRUE, "comment", pkt_comment);
2911 tvbuff_t **tvbs = NULL;
2913 /* arrayize data src, to speedup searching for ds_tvb index */
2914 if (data_src && data_src->next /* only needed if there are more than one data source */)
2916 guint count = g_slist_length((GSList *) data_src);
2919 tvbs = (tvbuff_t **) g_malloc((count + 1) * sizeof(*tvbs));
2921 for (i = 0; i < count; i++)
2923 const struct data_source *src = (const struct data_source *) g_slist_nth_data((GSList *) data_src, i);
2925 tvbs[i] = get_data_source_tvb(src);
2931 sharkd_json_value_anyf(TRUE, "tree", NULL);
2932 sharkd_session_process_frame_cb_tree(edt, tree, tvbs, display_hidden);
2941 sharkd_json_array_open(TRUE, "col");
2942 for (col = 0; col < cinfo->num_cols; ++col)
2944 const col_item_t *col_item = &cinfo->columns[col];
2946 sharkd_json_value_string(col != 0, NULL, col_item->col_data);
2948 sharkd_json_array_close();
2951 if (fdata->flags.ignored)
2952 sharkd_json_value_anyf(TRUE, "i", "true");
2954 if (fdata->flags.marked)
2955 sharkd_json_value_anyf(TRUE, "m", "true");
2957 if (fdata->color_filter)
2959 sharkd_json_value_stringf(TRUE, "bg", "%x", color_t_to_rgb(&fdata->color_filter->bg_color));
2960 sharkd_json_value_stringf(TRUE, "fg", "%x", color_t_to_rgb(&fdata->color_filter->fg_color));
2965 struct data_source *src = (struct data_source *) data_src->data;
2966 gboolean ds_sepa = FALSE;
2967 gboolean ds_open = FALSE;
2972 tvb = get_data_source_tvb(src);
2973 length = tvb_captured_length(tvb);
2977 const guchar *cp = tvb_get_ptr(tvb, 0, length);
2979 /* XXX pi.fd->flags.encoding */
2980 sharkd_json_value_base64(TRUE, "bytes", cp, length);
2984 sharkd_json_value_base64(TRUE, "bytes", "", 0);
2987 data_src = data_src->next;
2990 sharkd_json_array_open(TRUE, "ds");
2996 src = (struct data_source *) data_src->data;
2998 sharkd_json_object_open(ds_sepa);
3001 char *src_name = get_data_source_name(src);
3003 sharkd_json_value_string(FALSE, "name", src_name);
3004 wmem_free(NULL, src_name);
3007 tvb = get_data_source_tvb(src);
3008 length = tvb_captured_length(tvb);
3012 const guchar *cp = tvb_get_ptr(tvb, 0, length);
3014 /* XXX pi.fd->flags.encoding */
3015 sharkd_json_value_base64(TRUE, "bytes", cp, length);
3019 sharkd_json_value_base64(TRUE, "bytes", "", 0);
3022 sharkd_json_object_close();
3025 data_src = data_src->next;
3028 /* close ds, only if was opened */
3030 sharkd_json_array_close();
3033 sharkd_json_array_open(TRUE, "fol");
3034 sharkd_json_value_anyf(FALSE, NULL, "0");
3035 follow_iterate_followers(sharkd_follower_visit_layers_cb, pi);
3036 sharkd_json_array_close();
3038 sharkd_json_object_close();
3039 sharkd_json_finish();
3042 #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 */
3044 struct sharkd_iograph
3048 io_graph_item_unit_t calc_type;
3054 io_graph_item_t *items;
3059 sharkd_iograph_packet(void *g, packet_info *pinfo, epan_dissect_t *edt, const void *dummy _U_)
3061 struct sharkd_iograph *graph = (struct sharkd_iograph *) g;
3064 idx = get_io_graph_index(pinfo, graph->interval);
3065 if (idx < 0 || idx >= SHARKD_IOGRAPH_MAX_ITEMS)
3068 if (idx + 1 > graph->num_items)
3070 if (idx + 1 > graph->space_items)
3072 int new_size = idx + 1024;
3074 graph->items = (io_graph_item_t *) g_realloc(graph->items, sizeof(io_graph_item_t) * new_size);
3075 reset_io_graph_items(&graph->items[graph->space_items], new_size - graph->space_items);
3077 graph->space_items = new_size;
3079 else if (graph->items == NULL)
3081 graph->items = (io_graph_item_t *) g_malloc(sizeof(io_graph_item_t) * graph->space_items);
3082 reset_io_graph_items(graph->items, graph->space_items);
3085 graph->num_items = idx + 1;
3088 return update_io_graph_item(graph->items, idx, pinfo, edt, graph->hf_index, graph->calc_type, graph->interval);
3092 * sharkd_session_process_iograph()
3094 * Process iograph request
3097 * (o) interval - interval time in ms, if not specified: 1000ms
3098 * (m) graph0 - First graph request
3099 * (o) graph1...graph9 - Other graph requests
3100 * (o) filter0 - First graph filter
3101 * (o) filter1...filter9 - Other graph filters
3103 * Graph requests can be one of: "packets", "bytes", "bits", "sum:<field>", "frames:<field>", "max:<field>", "min:<field>", "avg:<field>", "load:<field>",
3104 * if you use variant with <field>, you need to pass field name in filter request.
3106 * Output object with attributes:
3107 * (m) iograph - array of graph results with attributes:
3108 * errmsg - graph cannot be constructed
3109 * items - graph values, zeros are skipped, if value is not a number it's next index encoded as hex string
3112 sharkd_session_process_iograph(char *buf, const jsmntok_t *tokens, int count)
3114 const char *tok_interval = json_find_attr(buf, tokens, count, "interval");
3115 struct sharkd_iograph graphs[10];
3116 gboolean is_any_ok = FALSE;
3119 guint32 interval_ms = 1000; /* default: one per second */
3124 if (!ws_strtou32(tok_interval, NULL, &interval_ms) || interval_ms == 0)
3126 fprintf(stderr, "Invalid interval parameter: %s.\n", tok_interval);
3131 for (i = graph_count = 0; i < (int) G_N_ELEMENTS(graphs); i++)
3133 struct sharkd_iograph *graph = &graphs[graph_count];
3135 const char *tok_graph;
3136 const char *tok_filter;
3137 char tok_format_buf[32];
3138 const char *field_name;
3140 snprintf(tok_format_buf, sizeof(tok_format_buf), "graph%d", i);
3141 tok_graph = json_find_attr(buf, tokens, count, tok_format_buf);
3145 snprintf(tok_format_buf, sizeof(tok_format_buf), "filter%d", i);
3146 tok_filter = json_find_attr(buf, tokens, count, tok_format_buf);
3148 if (!strcmp(tok_graph, "packets"))
3149 graph->calc_type = IOG_ITEM_UNIT_PACKETS;
3150 else if (!strcmp(tok_graph, "bytes"))
3151 graph->calc_type = IOG_ITEM_UNIT_BYTES;
3152 else if (!strcmp(tok_graph, "bits"))
3153 graph->calc_type = IOG_ITEM_UNIT_BITS;
3154 else if (g_str_has_prefix(tok_graph, "sum:"))
3155 graph->calc_type = IOG_ITEM_UNIT_CALC_SUM;
3156 else if (g_str_has_prefix(tok_graph, "frames:"))
3157 graph->calc_type = IOG_ITEM_UNIT_CALC_FRAMES;
3158 else if (g_str_has_prefix(tok_graph, "fields:"))
3159 graph->calc_type = IOG_ITEM_UNIT_CALC_FIELDS;
3160 else if (g_str_has_prefix(tok_graph, "max:"))
3161 graph->calc_type = IOG_ITEM_UNIT_CALC_MAX;
3162 else if (g_str_has_prefix(tok_graph, "min:"))
3163 graph->calc_type = IOG_ITEM_UNIT_CALC_MIN;
3164 else if (g_str_has_prefix(tok_graph, "avg:"))
3165 graph->calc_type = IOG_ITEM_UNIT_CALC_AVERAGE;
3166 else if (g_str_has_prefix(tok_graph, "load:"))
3167 graph->calc_type = IOG_ITEM_UNIT_CALC_LOAD;
3171 field_name = strchr(tok_graph, ':');
3173 field_name = field_name + 1;
3175 graph->interval = interval_ms;
3177 graph->hf_index = -1;
3178 graph->error = check_field_unit(field_name, &graph->hf_index, graph->calc_type);
3180 graph->space_items = 0; /* TODO, can avoid realloc()s in sharkd_iograph_packet() by calculating: capture_time / interval */
3181 graph->num_items = 0;
3182 graph->items = NULL;
3185 graph->error = register_tap_listener("frame", graph, tok_filter, TL_REQUIRES_PROTO_TREE, NULL, sharkd_iograph_packet, NULL, NULL);
3189 if (graph->error == NULL)
3193 /* retap only if we have at least one ok */
3197 sharkd_json_object_open(FALSE);
3199 sharkd_json_array_open(FALSE, "iograph");
3200 for (i = 0; i < graph_count; i++)
3202 struct sharkd_iograph *graph = &graphs[i];
3204 sharkd_json_object_open(i != 0);
3208 sharkd_json_value_string(FALSE, "errmsg", graph->error->str);
3209 g_string_free(graph->error, TRUE);
3216 sharkd_json_array_open(FALSE, "items");
3217 for (idx = 0; idx < graph->num_items; idx++)
3221 val = get_io_graph_item(graph->items, graph->calc_type, idx, graph->hf_index, &cfile, graph->interval, graph->num_items);
3223 /* if it's zero, don't display */
3227 /* cause zeros are not printed, need to output index */
3228 if (next_idx != idx)
3229 sharkd_json_value_stringf(next_idx != 0, NULL, "%x", idx);
3231 sharkd_json_value_anyf(idx != 0, NULL, "%f", val);
3234 sharkd_json_array_close();
3236 sharkd_json_object_close();
3238 remove_tap_listener(graph);
3239 g_free(graph->items);
3241 sharkd_json_array_close();
3243 sharkd_json_object_close();
3244 sharkd_json_finish();
3248 * sharkd_session_process_intervals()
3250 * Process intervals request - generate basic capture file statistics per requested interval.
3253 * (o) interval - interval time in ms, if not specified: 1000ms
3254 * (o) filter - filter for generating interval request
3256 * Output object with attributes:
3257 * (m) intervals - array of intervals, with indexes:
3258 * [0] - index of interval,
3259 * [1] - number of frames during interval,
3260 * [2] - number of bytes during interval.
3262 * (m) last - last interval number.
3263 * (m) frames - total number of frames
3264 * (m) bytes - total number of bytes
3266 * NOTE: If frames are not in order, there might be items with same interval index, or even negative one.
3269 sharkd_session_process_intervals(char *buf, const jsmntok_t *tokens, int count)
3271 const char *tok_interval = json_find_attr(buf, tokens, count, "interval");
3272 const char *tok_filter = json_find_attr(buf, tokens, count, "filter");
3274 const guint8 *filter_data = NULL;
3278 unsigned int frames;
3284 guint32 interval_ms = 1000; /* default: one per second */
3286 gboolean sepa = FALSE;
3287 unsigned int framenum;
3293 if (!ws_strtou32(tok_interval, NULL, &interval_ms) || interval_ms == 0)
3295 fprintf(stderr, "Invalid interval parameter: %s.\n", tok_interval);
3302 const struct sharkd_filter_item *filter_item;
3304 filter_item = sharkd_session_filter_data(tok_filter);
3307 filter_data = filter_item->filtered;
3310 st_total.frames = 0;
3318 sharkd_json_object_open(FALSE);
3319 sharkd_json_array_open(FALSE, "intervals");
3321 start_ts = (cfile.count >= 1) ? &(sharkd_get_frame(1)->abs_ts) : NULL;
3323 for (framenum = 1; framenum <= cfile.count; framenum++)
3329 if (filter_data && !(filter_data[framenum / 8] & (1 << (framenum % 8))))
3332 fdata = sharkd_get_frame(framenum);
3334 msec_rel = (fdata->abs_ts.secs - start_ts->secs) * (gint64) 1000 + (fdata->abs_ts.nsecs - start_ts->nsecs) / 1000000;
3335 new_idx = msec_rel / interval_ms;
3341 sharkd_json_value_anyf(sepa, NULL, "[%" G_GINT64_FORMAT ",%u,%" G_GUINT64_FORMAT "]", idx, st.frames, st.bytes);
3354 st.bytes += fdata->pkt_len;
3356 st_total.frames += 1;
3357 st_total.bytes += fdata->pkt_len;
3362 sharkd_json_value_anyf(sepa, NULL, "[%" G_GINT64_FORMAT ",%u,%" G_GUINT64_FORMAT "]", idx, st.frames, st.bytes);
3365 sharkd_json_array_close();
3367 sharkd_json_value_anyf(TRUE, "last", "%" G_GINT64_FORMAT, max_idx);
3368 sharkd_json_value_anyf(TRUE, "frames", "%u", st_total.frames);
3369 sharkd_json_value_anyf(TRUE, "bytes", "%" G_GUINT64_FORMAT, st_total.bytes);
3371 sharkd_json_object_close();
3372 sharkd_json_finish();
3376 * sharkd_session_process_frame()
3378 * Process frame request
3381 * (m) frame - requested frame number
3382 * (o) ref_frame - time reference frame number
3383 * (o) prev_frame - previously displayed frame number
3384 * (o) proto - set if output frame tree
3385 * (o) columns - set if output frame columns
3386 * (o) color - set if output color-filter bg/fg
3387 * (o) bytes - set if output frame bytes
3388 * (o) hidden - set if output hidden tree fields
3390 * Output object with attributes:
3391 * (m) err - 0 if succeed
3392 * (o) tree - array of frame nodes with attributes:
3394 * t: 'proto', 'framenum', 'url' - type of node
3397 * e - subtree ett index
3398 * n - array of subtree nodes
3399 * h - two item array: (item start, item length)
3400 * i - two item array: (appendix start, appendix length)
3401 * p - [RESERVED] two item array: (protocol start, protocol length)
3402 * ds- data src index
3403 * url - only for t:'url', url
3404 * fnum - only for t:'framenum', frame number
3405 * g - if field is generated by Wireshark
3406 * v - if field is hidden
3408 * (o) col - array of column data
3409 * (o) bytes - base64 of frame bytes
3410 * (o) ds - array of other data srcs
3411 * (o) comment - frame comment
3412 * (o) fol - array of follow filters:
3414 * [1] - filter string
3415 * (o) i - if frame is ignored
3416 * (o) m - if frame is marked
3417 * (o) bg - color filter - background color in hex
3418 * (o) fg - color filter - foreground color in hex
3421 sharkd_session_process_frame(char *buf, const jsmntok_t *tokens, int count)
3423 const char *tok_frame = json_find_attr(buf, tokens, count, "frame");
3424 const char *tok_ref_frame = json_find_attr(buf, tokens, count, "ref_frame");
3425 const char *tok_prev_frame = json_find_attr(buf, tokens, count, "prev_frame");
3427 guint32 framenum, ref_frame_num, prev_dis_num;
3428 guint32 dissect_flags = SHARKD_DISSECT_FLAG_NULL;
3429 struct sharkd_frame_request_data req_data;
3431 if (!tok_frame || !ws_strtou32(tok_frame, NULL, &framenum) || framenum == 0)
3434 ref_frame_num = (framenum != 1) ? 1 : 0;
3435 if (tok_ref_frame && (!ws_strtou32(tok_ref_frame, NULL, &ref_frame_num) || ref_frame_num > framenum))
3438 prev_dis_num = framenum - 1;
3439 if (tok_prev_frame && (!ws_strtou32(tok_prev_frame, NULL, &prev_dis_num) || prev_dis_num >= framenum))
3442 if (json_find_attr(buf, tokens, count, "proto") != NULL)
3443 dissect_flags |= SHARKD_DISSECT_FLAG_PROTO_TREE;
3444 if (json_find_attr(buf, tokens, count, "bytes") != NULL)
3445 dissect_flags |= SHARKD_DISSECT_FLAG_BYTES;
3446 if (json_find_attr(buf, tokens, count, "columns") != NULL)
3447 dissect_flags |= SHARKD_DISSECT_FLAG_COLUMNS;
3448 if (json_find_attr(buf, tokens, count, "color") != NULL)
3449 dissect_flags |= SHARKD_DISSECT_FLAG_COLOR;
3451 req_data.display_hidden = (json_find_attr(buf, tokens, count, "v") != NULL);
3453 sharkd_dissect_request(framenum, ref_frame_num, prev_dis_num, &sharkd_session_process_frame_cb, dissect_flags, &req_data);
3457 * sharkd_session_process_check()
3459 * Process check request.
3462 * (o) filter - filter to be checked
3463 * (o) field - field to be checked
3465 * Output object with attributes:
3466 * (m) err - always 0
3467 * (o) filter - 'ok', 'warn' or error message
3468 * (o) field - 'ok', or 'notfound'
3471 sharkd_session_process_check(char *buf, const jsmntok_t *tokens, int count)
3473 const char *tok_filter = json_find_attr(buf, tokens, count, "filter");
3474 const char *tok_field = json_find_attr(buf, tokens, count, "field");
3476 sharkd_json_object_open(FALSE);
3477 sharkd_json_value_anyf(FALSE, "err", "0");
3479 if (tok_filter != NULL)
3481 char *err_msg = NULL;
3484 if (dfilter_compile(tok_filter, &dfp, &err_msg))
3486 const char *s = "ok";
3488 if (dfp && dfilter_deprecated_tokens(dfp))
3491 sharkd_json_value_stringf(TRUE, "filter", "%s", s);
3496 sharkd_json_value_string(TRUE, "filter", err_msg);
3501 if (tok_field != NULL)
3503 header_field_info *hfi = proto_registrar_get_byname(tok_field);
3505 sharkd_json_value_stringf(TRUE, "field", (hfi) ? "ok" : "notfound");
3508 sharkd_json_object_close();
3509 sharkd_json_finish();
3514 struct sharkd_session_process_complete_pref_data
3522 sharkd_session_process_complete_pref_cb(module_t *module, gpointer d)
3524 struct sharkd_session_process_complete_pref_data *data = (struct sharkd_session_process_complete_pref_data *) d;
3526 if (strncmp(data->pref, module->name, strlen(data->pref)) != 0)
3529 sharkd_json_object_open(data->sepa);
3530 sharkd_json_value_stringf(FALSE, "f", "%s", module->name);
3531 sharkd_json_value_stringf(TRUE, "d", "%s", module->title);
3532 sharkd_json_object_close();
3540 sharkd_session_process_complete_pref_option_cb(pref_t *pref, gpointer d)
3542 struct sharkd_session_process_complete_pref_data *data = (struct sharkd_session_process_complete_pref_data *) d;
3543 const char *pref_name = prefs_get_name(pref);
3544 const char *pref_title = prefs_get_title(pref);
3546 if (strncmp(data->pref, pref_name, strlen(data->pref)) != 0)
3549 sharkd_json_object_open(data->sepa);
3550 sharkd_json_value_stringf(FALSE, "f", "%s.%s", data->module, pref_name);
3551 sharkd_json_value_stringf(TRUE, "d", "%s", pref_title);
3552 sharkd_json_object_close();
3556 return 0; /* continue */
3560 * sharkd_session_process_complete()
3562 * Process complete request
3565 * (o) field - field to be completed
3566 * (o) pref - preference to be completed
3568 * Output object with attributes:
3569 * (m) err - always 0
3570 * (o) field - array of object with attributes:
3571 * (m) f - field text
3572 * (o) t - field type (FT_ number)
3573 * (o) n - field name
3574 * (o) pref - array of object with attributes:
3576 * (o) d - pref description
3579 sharkd_session_process_complete(char *buf, const jsmntok_t *tokens, int count)
3581 const char *tok_field = json_find_attr(buf, tokens, count, "field");
3582 const char *tok_pref = json_find_attr(buf, tokens, count, "pref");
3584 sharkd_json_object_open(FALSE);
3585 sharkd_json_value_anyf(FALSE, "err", "0");
3587 if (tok_field != NULL && tok_field[0])
3589 const size_t filter_length = strlen(tok_field);
3590 const int filter_with_dot = !!strchr(tok_field, '.');
3595 gboolean sepa = FALSE;
3597 sharkd_json_array_open(TRUE, "field");
3599 for (proto_id = proto_get_first_protocol(&proto_cookie); proto_id != -1; proto_id = proto_get_next_protocol(&proto_cookie))
3601 protocol_t *protocol = find_protocol_by_id(proto_id);
3602 const char *protocol_filter;
3603 const char *protocol_name;
3604 header_field_info *hfinfo;
3606 if (!proto_is_protocol_enabled(protocol))
3609 protocol_name = proto_get_protocol_long_name(protocol);
3610 protocol_filter = proto_get_protocol_filter_name(proto_id);
3612 if (strlen(protocol_filter) >= filter_length && !g_ascii_strncasecmp(tok_field, protocol_filter, filter_length))
3614 sharkd_json_object_open(sepa);
3616 sharkd_json_value_string(FALSE, "f", protocol_filter);
3617 sharkd_json_value_anyf(TRUE, "t", "%d", FT_PROTOCOL);
3618 sharkd_json_value_string(TRUE, "n", protocol_name);
3620 sharkd_json_object_close();
3624 if (!filter_with_dot)
3627 for (hfinfo = proto_get_first_protocol_field(proto_id, &field_cookie); hfinfo != NULL; hfinfo = proto_get_next_protocol_field(proto_id, &field_cookie))
3629 if (hfinfo->same_name_prev_id != -1) /* ignore duplicate names */
3632 if (strlen(hfinfo->abbrev) >= filter_length && !g_ascii_strncasecmp(tok_field, hfinfo->abbrev, filter_length))
3634 sharkd_json_object_open(sepa);
3636 sharkd_json_value_string(FALSE, "f", hfinfo->abbrev);
3638 /* XXX, skip displaying name, if there are multiple (to not confuse user) */
3639 if (hfinfo->same_name_next == NULL)
3641 sharkd_json_value_anyf(TRUE, "t", "%d", hfinfo->type);
3642 sharkd_json_value_string(TRUE, "n", hfinfo->name);
3645 sharkd_json_object_close();
3651 sharkd_json_array_close();
3654 if (tok_pref != NULL && tok_pref[0])
3656 struct sharkd_session_process_complete_pref_data data;
3659 data.module = tok_pref;
3660 data.pref = tok_pref;
3663 sharkd_json_array_open(TRUE, "pref");
3664 if ((dot_sepa = strchr(tok_pref, '.')))
3668 *dot_sepa = '\0'; /* XXX, C abuse: discarding-const */
3669 data.pref = dot_sepa + 1;
3671 pref_mod = prefs_find_module(data.module);
3673 prefs_pref_foreach(pref_mod, sharkd_session_process_complete_pref_option_cb, &data);
3679 prefs_modules_foreach(sharkd_session_process_complete_pref_cb, &data);
3681 sharkd_json_array_close();
3684 sharkd_json_object_close();
3685 sharkd_json_finish();
3691 * sharkd_session_process_setcomment()
3693 * Process setcomment request
3696 * (m) frame - frame number
3697 * (o) comment - user comment
3699 * Output object with attributes:
3700 * (m) err - error code: 0 succeed
3703 sharkd_session_process_setcomment(char *buf, const jsmntok_t *tokens, int count)
3705 const char *tok_frame = json_find_attr(buf, tokens, count, "frame");
3706 const char *tok_comment = json_find_attr(buf, tokens, count, "comment");
3712 if (!tok_frame || !ws_strtou32(tok_frame, NULL, &framenum) || framenum == 0)
3715 fdata = sharkd_get_frame(framenum);
3719 ret = sharkd_set_user_comment(fdata, tok_comment);
3721 sharkd_json_simple_reply(ret, NULL);
3725 * sharkd_session_process_setconf()
3727 * Process setconf request
3730 * (m) name - preference name
3731 * (m) value - preference value
3733 * Output object with attributes:
3734 * (m) err - error code: 0 succeed
3737 sharkd_session_process_setconf(char *buf, const jsmntok_t *tokens, int count)
3739 const char *tok_name = json_find_attr(buf, tokens, count, "name");
3740 const char *tok_value = json_find_attr(buf, tokens, count, "value");
3742 char *errmsg = NULL;
3744 prefs_set_pref_e ret;
3746 if (!tok_name || tok_name[0] == '\0' || !tok_value)
3749 ws_snprintf(pref, sizeof(pref), "%s:%s", tok_name, tok_value);
3751 ret = prefs_set_pref(pref, &errmsg);
3753 sharkd_json_simple_reply(ret, errmsg);
3757 struct sharkd_session_process_dumpconf_data
3764 sharkd_session_process_dumpconf_cb(pref_t *pref, gpointer d)
3766 struct sharkd_session_process_dumpconf_data *data = (struct sharkd_session_process_dumpconf_data *) d;
3767 const char *pref_name = prefs_get_name(pref);
3769 char json_pref_key[512];
3771 snprintf(json_pref_key, sizeof(json_pref_key), "%s.%s", data->module->name, pref_name);
3772 sharkd_json_value_anyf(data->sepa, json_pref_key, "{");
3774 switch (prefs_get_type(pref))
3777 case PREF_DECODE_AS_UINT:
3778 sharkd_json_value_anyf(FALSE, "u", "%u", prefs_get_uint_value_real(pref, pref_current));
3779 if (prefs_get_uint_base(pref) != 10)
3780 sharkd_json_value_anyf(TRUE, "ub", "%u", prefs_get_uint_base(pref));
3784 sharkd_json_value_anyf(FALSE, "b", prefs_get_bool_value(pref, pref_current) ? "1" : "0");
3788 case PREF_SAVE_FILENAME:
3789 case PREF_OPEN_FILENAME:
3791 sharkd_json_value_string(FALSE, "s", prefs_get_string_value(pref, pref_current));
3796 const enum_val_t *enums;
3797 gboolean enum_sepa = FALSE;
3799 sharkd_json_array_open(FALSE, "e");
3800 for (enums = prefs_get_enumvals(pref); enums->name; enums++)
3802 sharkd_json_object_open(enum_sepa);
3804 sharkd_json_value_anyf(FALSE, "v", "%d", enums->value);
3806 if (enums->value == prefs_get_enum_value(pref, pref_current))
3807 sharkd_json_value_anyf(TRUE, "s", "1");
3809 sharkd_json_value_string(TRUE, "d", enums->description);
3811 sharkd_json_object_close();
3814 sharkd_json_array_close();
3819 case PREF_DECODE_AS_RANGE:
3821 char *range_str = range_convert_range(NULL, prefs_get_range_value_real(pref, pref_current));
3822 sharkd_json_value_stringf(FALSE, "r", "%s", range_str);
3823 wmem_free(NULL, range_str);
3829 uat_t *uat = prefs_get_uat_value(pref);
3832 sharkd_json_array_open(FALSE, "t");
3833 for (idx = 0; idx < uat->raw_data->len; idx++)
3835 void *rec = UAT_INDEX_PTR(uat, idx);
3838 sharkd_json_array_open(idx != 0, NULL);
3839 for (colnum = 0; colnum < uat->ncols; colnum++)
3841 char *str = uat_fld_tostr(rec, &(uat->fields[colnum]));
3843 sharkd_json_value_string(colnum != 0, NULL, str);
3847 sharkd_json_array_close();
3850 sharkd_json_array_close();
3856 case PREF_STATIC_TEXT:
3863 sharkd_json_value_string(TRUE, "t", prefs_get_title(pref));
3866 sharkd_json_object_close();
3869 return 0; /* continue */
3873 sharkd_session_process_dumpconf_mod_cb(module_t *module, gpointer d)
3875 struct sharkd_session_process_dumpconf_data *data = (struct sharkd_session_process_dumpconf_data *) d;
3877 data->module = module;
3878 prefs_pref_foreach(module, sharkd_session_process_dumpconf_cb, data);
3884 * sharkd_session_process_dumpconf()
3886 * Process dumpconf request
3889 * (o) pref - module, or preference, NULL for all
3891 * Output object with attributes:
3892 * (o) prefs - object with module preferences
3893 * (m) [KEY] - preference name
3894 * (o) u - preference value (for PREF_UINT, PREF_DECODE_AS_UINT)
3895 * (o) ub - preference value suggested base for display (for PREF_UINT, PREF_DECODE_AS_UINT) and if different than 10
3896 * (o) b - preference value (only for PREF_BOOL) (1 true, 0 false)
3897 * (o) s - preference value (for PREF_STRING, PREF_SAVE_FILENAME, PREF_OPEN_FILENAME, PREF_DIRNAME)
3898 * (o) e - preference possible values (only for PREF_ENUM)
3899 * (o) r - preference value (for PREF_RANGE, PREF_DECODE_AS_RANGE)
3900 * (o) t - preference value (only for PREF_UAT)
3903 sharkd_session_process_dumpconf(char *buf, const jsmntok_t *tokens, int count)
3905 const char *tok_pref = json_find_attr(buf, tokens, count, "pref");
3911 struct sharkd_session_process_dumpconf_data data;
3916 sharkd_json_object_open(FALSE);
3918 sharkd_json_value_anyf(FALSE, "prefs", NULL);
3919 sharkd_json_object_open(FALSE);
3920 prefs_modules_foreach(sharkd_session_process_dumpconf_mod_cb, &data);
3921 sharkd_json_object_close();
3923 sharkd_json_object_close();
3924 sharkd_json_finish();
3928 if ((dot_sepa = strchr(tok_pref, '.')))
3930 pref_t *pref = NULL;
3932 *dot_sepa = '\0'; /* XXX, C abuse: discarding-const */
3933 pref_mod = prefs_find_module(tok_pref);
3935 pref = prefs_find_preference(pref_mod, dot_sepa + 1);
3940 struct sharkd_session_process_dumpconf_data data;
3942 data.module = pref_mod;
3945 sharkd_json_object_open(FALSE);
3947 sharkd_json_value_anyf(FALSE, "prefs", NULL);
3948 sharkd_json_object_open(FALSE);
3949 sharkd_session_process_dumpconf_cb(pref, &data);
3950 sharkd_json_object_close();
3952 sharkd_json_object_close();
3953 sharkd_json_finish();
3959 pref_mod = prefs_find_module(tok_pref);
3962 struct sharkd_session_process_dumpconf_data data;
3964 data.module = pref_mod;
3967 sharkd_json_object_open(FALSE);
3969 sharkd_json_value_anyf(FALSE, "prefs", NULL);
3970 sharkd_json_object_open(FALSE);
3971 prefs_pref_foreach(pref_mod, sharkd_session_process_dumpconf_cb, &data);
3972 sharkd_json_object_close();
3974 sharkd_json_object_close();
3975 sharkd_json_finish();
3979 struct sharkd_download_rtp
3987 sharkd_rtp_download_free_items(void *ptr)
3989 rtp_packet_t *rtp_packet = (rtp_packet_t *) ptr;
3991 g_free(rtp_packet->info);
3992 g_free(rtp_packet->payload_data);
3997 sharkd_rtp_download_decode(struct sharkd_download_rtp *req)
3999 /* based on RtpAudioStream::decode() 6e29d874f8b5e6ebc59f661a0bb0dab8e56f122a */
4000 /* TODO, for now only without silence (timing_mode_ = Uninterrupted) */
4002 static const int sample_bytes_ = sizeof(SAMPLE) / sizeof(char);
4004 guint32 audio_out_rate_ = 0;
4005 struct _GHashTable *decoders_hash_ = rtp_decoder_hash_table_new();
4006 struct SpeexResamplerState_ *audio_resampler_ = NULL;
4008 gsize resample_buff_len = 0x1000;
4009 SAMPLE *resample_buff = (SAMPLE *) g_malloc(resample_buff_len);
4010 spx_uint32_t cur_in_rate = 0;
4011 char *write_buff = NULL;
4012 gint64 write_bytes = 0;
4013 unsigned channels = 0;
4014 unsigned sample_rate = 0;
4017 int base64_state1 = 0;
4018 int base64_state2 = 0;
4022 for (l = req->packets; l; l = l->next)
4024 rtp_packet_t *rtp_packet = (rtp_packet_t *) l->data;
4026 SAMPLE *decode_buff = NULL;
4027 size_t decoded_bytes;
4029 decoded_bytes = decode_rtp_packet(rtp_packet, &decode_buff, decoders_hash_, &channels, &sample_rate);
4030 if (decoded_bytes == 0 || sample_rate == 0)
4032 /* We didn't decode anything. Clean up and prep for the next packet. */
4033 g_free(decode_buff);
4037 if (audio_out_rate_ == 0)
4043 /* First non-zero wins */
4044 audio_out_rate_ = sample_rate;
4046 RTP_STREAM_DEBUG("Audio sample rate is %u", audio_out_rate_);
4048 /* write WAVE header */
4049 memset(&wav_hdr, 0, sizeof(wav_hdr));
4050 memcpy(&wav_hdr[0], "RIFF", 4);
4051 memcpy(&wav_hdr[4], "\xFF\xFF\xFF\xFF", 4); /* XXX, unknown */
4052 memcpy(&wav_hdr[8], "WAVE", 4);
4054 memcpy(&wav_hdr[12], "fmt ", 4);
4055 memcpy(&wav_hdr[16], "\x10\x00\x00\x00", 4); /* PCM */
4056 memcpy(&wav_hdr[20], "\x01\x00", 2); /* PCM */
4059 memcpy(&wav_hdr[22], &tmp16, 2);
4061 tmp32 = sample_rate;
4062 memcpy(&wav_hdr[24], &tmp32, 4);
4064 tmp32 = sample_rate * channels * sample_bytes_;
4065 memcpy(&wav_hdr[28], &tmp32, 4);
4067 tmp16 = channels * sample_bytes_;
4068 memcpy(&wav_hdr[32], &tmp16, 2);
4069 /* bits per sample */
4070 tmp16 = 8 * sample_bytes_;
4071 memcpy(&wav_hdr[34], &tmp16, 2);
4073 memcpy(&wav_hdr[36], "data", 4);
4074 memcpy(&wav_hdr[40], "\xFF\xFF\xFF\xFF", 4); /* XXX, unknown */
4076 for (i = 0; i < (int) sizeof(wav_hdr); i++)
4077 json_print_base64_step(&wav_hdr[i], &base64_state1, &base64_state2);
4080 // Write samples to our file.
4081 write_buff = (char *) decode_buff;
4082 write_bytes = decoded_bytes;
4084 if (audio_out_rate_ != sample_rate)
4086 spx_uint32_t in_len, out_len;
4088 /* Resample the audio to match our previous output rate. */
4089 if (!audio_resampler_)
4091 audio_resampler_ = speex_resampler_init(1, sample_rate, audio_out_rate_, 10, NULL);
4092 speex_resampler_skip_zeros(audio_resampler_);
4093 RTP_STREAM_DEBUG("Started resampling from %u to (out) %u Hz.", sample_rate, audio_out_rate_);
4097 spx_uint32_t audio_out_rate;
4098 speex_resampler_get_rate(audio_resampler_, &cur_in_rate, &audio_out_rate);
4100 if (sample_rate != cur_in_rate)
4102 speex_resampler_set_rate(audio_resampler_, sample_rate, audio_out_rate);
4103 RTP_STREAM_DEBUG("Changed input rate from %u to %u Hz. Out is %u.", cur_in_rate, sample_rate, audio_out_rate_);
4106 in_len = (spx_uint32_t)rtp_packet->info->info_payload_len;
4107 out_len = (audio_out_rate_ * (spx_uint32_t)rtp_packet->info->info_payload_len / sample_rate) + (audio_out_rate_ % sample_rate != 0);
4108 if (out_len * sample_bytes_ > resample_buff_len)
4110 while ((out_len * sample_bytes_ > resample_buff_len))
4111 resample_buff_len *= 2;
4112 resample_buff = (SAMPLE *) g_realloc(resample_buff, resample_buff_len);
4115 speex_resampler_process_int(audio_resampler_, 0, decode_buff, &in_len, resample_buff, &out_len);
4116 write_buff = (char *) resample_buff;
4117 write_bytes = out_len * sample_bytes_;
4120 /* Write the decoded, possibly-resampled audio */
4121 for (i = 0; i < write_bytes; i++)
4122 json_print_base64_step(&write_buff[i], &base64_state1, &base64_state2);
4124 g_free(decode_buff);
4127 json_print_base64_step(NULL, &base64_state1, &base64_state2);
4129 g_free(resample_buff);
4130 g_hash_table_destroy(decoders_hash_);
4134 sharkd_session_packet_download_tap_rtp_cb(void *tapdata, packet_info *pinfo, epan_dissect_t *edt _U_, const void *data)
4136 const struct _rtp_info *rtp_info = (const struct _rtp_info *) data;
4137 struct sharkd_download_rtp *req_rtp = (struct sharkd_download_rtp *) tapdata;
4139 /* do not consider RTP packets without a setup frame */
4140 if (rtp_info->info_setup_frame_num == 0)
4143 if (rtpstream_id_equal_pinfo_rtp_info(&req_rtp->id, pinfo, rtp_info))
4145 rtp_packet_t *rtp_packet;
4147 rtp_packet = g_new0(rtp_packet_t, 1);
4148 rtp_packet->info = (struct _rtp_info *) g_memdup(rtp_info, sizeof(struct _rtp_info));
4150 if (rtp_info->info_all_data_present && rtp_info->info_payload_len != 0)
4151 rtp_packet->payload_data = (guint8 *) g_memdup(&(rtp_info->info_data[rtp_info->info_payload_offset]), rtp_info->info_payload_len);
4153 if (!req_rtp->packets)
4154 req_rtp->start_time = nstime_to_sec(&pinfo->abs_ts);
4156 rtp_packet->frame_num = pinfo->num;
4157 rtp_packet->arrive_offset = nstime_to_sec(&pinfo->abs_ts) - req_rtp->start_time;
4159 /* XXX, O(n) optimize */
4160 req_rtp->packets = g_slist_append(req_rtp->packets, rtp_packet);
4167 * sharkd_session_process_download()
4169 * Process download request
4172 * (m) token - token to download
4174 * Output object with attributes:
4175 * (o) file - suggested name of file
4176 * (o) mime - suggested content type
4177 * (o) data - payload base64 encoded
4180 sharkd_session_process_download(char *buf, const jsmntok_t *tokens, int count)
4182 const char *tok_token = json_find_attr(buf, tokens, count, "token");
4187 if (!strncmp(tok_token, "eo:", 3))
4189 struct sharkd_export_object_list *object_list;
4190 const export_object_entry_t *eo_entry = NULL;
4192 for (object_list = sharkd_eo_list; object_list; object_list = object_list->next)
4194 size_t eo_type_len = strlen(object_list->type);
4196 if (!strncmp(tok_token, object_list->type, eo_type_len) && tok_token[eo_type_len] == '_')
4200 if (sscanf(&tok_token[eo_type_len + 1], "%d", &row) != 1)
4203 eo_entry = (export_object_entry_t *) g_slist_nth_data(object_list->entries, row);
4210 const char *mime = (eo_entry->content_type) ? eo_entry->content_type : "application/octet-stream";
4211 const char *filename = (eo_entry->filename) ? eo_entry->filename : tok_token;
4213 sharkd_json_object_open(FALSE);
4214 sharkd_json_value_string(FALSE, "file", filename);
4215 sharkd_json_value_string(TRUE, "mime", mime);
4216 sharkd_json_value_base64(TRUE, "data", eo_entry->payload_data, (size_t) eo_entry->payload_len);
4217 sharkd_json_object_close();
4218 sharkd_json_finish();
4221 else if (!strcmp(tok_token, "ssl-secrets"))
4223 char *str = ssl_export_sessions();
4227 const char *mime = "text/plain";
4228 const char *filename = "keylog.txt";
4230 sharkd_json_object_open(FALSE);
4231 sharkd_json_value_string(FALSE, "file", filename);
4232 sharkd_json_value_string(TRUE, "mime", mime);
4233 sharkd_json_value_base64(TRUE, "data", str, strlen(str));
4234 sharkd_json_object_close();
4235 sharkd_json_finish();
4239 else if (!strncmp(tok_token, "rtp:", 4))
4241 struct sharkd_download_rtp rtp_req;
4244 memset(&rtp_req, 0, sizeof(rtp_req));
4245 if (!sharkd_rtp_match_init(&rtp_req.id, tok_token + 4))
4247 fprintf(stderr, "sharkd_session_process_download() rtp tokenizing error %s\n", tok_token);
4251 tap_error = register_tap_listener("rtp", &rtp_req, NULL, 0, NULL, sharkd_session_packet_download_tap_rtp_cb, NULL, NULL);
4254 fprintf(stderr, "sharkd_session_process_download() rtp error=%s", tap_error->str);
4255 g_string_free(tap_error, TRUE);
4260 remove_tap_listener(&rtp_req);
4262 if (rtp_req.packets)
4264 const char *mime = "audio/x-wav";
4265 const char *filename = tok_token;
4267 sharkd_json_object_open(FALSE);
4268 sharkd_json_value_string(FALSE, "file", filename);
4269 sharkd_json_value_string(TRUE, "mime", mime);
4271 sharkd_json_value_anyf(TRUE, "data", NULL);
4273 sharkd_rtp_download_decode(&rtp_req);
4276 sharkd_json_object_close();
4277 sharkd_json_finish();
4279 g_slist_free_full(rtp_req.packets, sharkd_rtp_download_free_items);
4285 sharkd_session_process(char *buf, const jsmntok_t *tokens, int count)
4289 /* sanity check, and split strings */
4290 if (count < 1 || tokens[0].type != JSMN_OBJECT)
4292 fprintf(stderr, "sanity check(1): [0] not object\n");
4296 /* don't need [0] token */
4302 fprintf(stderr, "sanity check(2): %d not even\n", count);
4306 for (i = 0; i < count; i += 2)
4308 if (tokens[i].type != JSMN_STRING)
4310 fprintf(stderr, "sanity check(3): [%d] not string\n", i);
4314 if (tokens[i + 1].type != JSMN_STRING && tokens[i + 1].type != JSMN_PRIMITIVE)
4316 fprintf(stderr, "sanity check(3a): [%d] wrong type\n", i + 1);
4320 buf[tokens[i + 0].end] = '\0';
4321 buf[tokens[i + 1].end] = '\0';
4323 /* unescape only value, as keys are simple strings */
4324 if (tokens[i + 1].type == JSMN_STRING && !json_unescape_str(&buf[tokens[i + 1].start]))
4326 fprintf(stderr, "sanity check(3b): [%d] cannot unescape string\n", i + 1);
4332 const char *tok_req = json_find_attr(buf, tokens, count, "req");
4336 fprintf(stderr, "sanity check(4): no \"req\".\n");
4340 if (!strcmp(tok_req, "load"))
4341 sharkd_session_process_load(buf, tokens, count);
4342 else if (!strcmp(tok_req, "status"))
4343 sharkd_session_process_status();
4344 else if (!strcmp(tok_req, "analyse"))
4345 sharkd_session_process_analyse();
4346 else if (!strcmp(tok_req, "info"))
4347 sharkd_session_process_info();
4348 else if (!strcmp(tok_req, "check"))
4349 sharkd_session_process_check(buf, tokens, count);
4350 else if (!strcmp(tok_req, "complete"))
4351 sharkd_session_process_complete(buf, tokens, count);
4352 else if (!strcmp(tok_req, "frames"))
4353 sharkd_session_process_frames(buf, tokens, count);
4354 else if (!strcmp(tok_req, "tap"))
4355 sharkd_session_process_tap(buf, tokens, count);
4356 else if (!strcmp(tok_req, "follow"))
4357 sharkd_session_process_follow(buf, tokens, count);
4358 else if (!strcmp(tok_req, "iograph"))
4359 sharkd_session_process_iograph(buf, tokens, count);
4360 else if (!strcmp(tok_req, "intervals"))
4361 sharkd_session_process_intervals(buf, tokens, count);
4362 else if (!strcmp(tok_req, "frame"))
4363 sharkd_session_process_frame(buf, tokens, count);
4364 else if (!strcmp(tok_req, "setcomment"))
4365 sharkd_session_process_setcomment(buf, tokens, count);
4366 else if (!strcmp(tok_req, "setconf"))
4367 sharkd_session_process_setconf(buf, tokens, count);
4368 else if (!strcmp(tok_req, "dumpconf"))
4369 sharkd_session_process_dumpconf(buf, tokens, count);
4370 else if (!strcmp(tok_req, "download"))
4371 sharkd_session_process_download(buf, tokens, count);
4372 else if (!strcmp(tok_req, "bye"))
4375 fprintf(stderr, "::: req = %s\n", tok_req);
4377 /* reply for every command are 0+ lines of JSON reply (outputed above), finished by empty new line */
4378 sharkd_json_finish();
4381 * We do an explicit fflush after every line, because
4382 * we want output to be written to the socket as soon
4383 * as the line is complete.
4385 * The stream is fully-buffered by default, so it's
4386 * only flushed when the buffer fills or the FILE *
4387 * is closed. On UN*X, we could set it to be line
4388 * buffered, but the MSVC standard I/O routines don't
4389 * support line buffering - they only support *byte*
4390 * buffering, doing a write for every byte written,
4391 * which is too inefficient, and full buffering,
4392 * which is what you get if you request line buffering.
4399 sharkd_session_main(void)
4402 jsmntok_t *tokens = NULL;
4403 int tokens_max = -1;
4405 fprintf(stderr, "Hello in child.\n");
4407 filter_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, sharkd_session_filter_free);
4409 #ifdef HAVE_MAXMINDDB
4410 /* mmdbresolve was stopped before fork(), force starting it */
4411 uat_get_table_by_name("MaxMind Database Paths")->post_update_cb();
4414 while (fgets(buf, sizeof(buf), stdin))
4416 /* every command is line seperated JSON */
4419 ret = wsjson_parse(buf, NULL, 0);
4422 fprintf(stderr, "invalid JSON -> closing\n");
4426 /* fprintf(stderr, "JSON: %d tokens\n", ret); */
4429 if (tokens == NULL || tokens_max < ret)
4432 tokens = (jsmntok_t *) g_realloc(tokens, sizeof(jsmntok_t) * tokens_max);
4435 memset(tokens, 0, ret * sizeof(jsmntok_t));
4437 ret = wsjson_parse(buf, tokens, ret);
4440 fprintf(stderr, "invalid JSON(2) -> closing\n");
4444 #if defined(HAVE_C_ARES) || defined(HAVE_MAXMINDDB)
4445 host_name_lookup_process();
4448 sharkd_session_process(buf, tokens, ret);
4451 g_hash_table_destroy(filter_table);
4458 * Editor modelines - http://www.wireshark.org/tools/modelines.html
4463 * indent-tabs-mode: t
4466 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
4467 * :indentSize=8:tabSize=8:noTabs=false: