/builds/wireshark/wireshark/ui/io_graph_item.h (2024)

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name sharkd_session.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -ffloat16-excess-precision=fast -fbfloat16-excess-precision=fast -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/builds/wireshark/wireshark/build -fcoverage-compilation-dir=/builds/wireshark/wireshark/build -resource-dir /usr/lib/llvm-18/lib/clang/18 -isystem /usr/include/glib-2.0 -isystem /usr/lib/x86_64-linux-gnu/glib-2.0/include -D G_DISABLE_DEPRECATED -D G_DISABLE_SINGLE_INCLUDES -D WS_DEBUG -D WS_DEBUG_UTF_8 -I /builds/wireshark/wireshark/build -I /builds/wireshark/wireshark -I /builds/wireshark/wireshark/include -I /builds/wireshark/wireshark/wiretap -internal-isystem /usr/lib/llvm-18/lib/clang/18/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/13/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/builds/wireshark/wireshark/= -fmacro-prefix-map=/builds/wireshark/wireshark/build/= -fmacro-prefix-map=../= -Wno-error=stringop-overflow= -Wno-error=deprecated-declarations -Wno-format-truncation -Wno-pointer-sign -std=gnu11 -ferror-limit 19 -fvisibility=hidden -fwrapv -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fcolor-diagnostics -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /builds/wireshark/wireshark/sbout/2024-07-15-100248-3329-1 -x c /builds/wireshark/wireshark/sharkd_session.c

1/* sharkd_session.c2 *3 * Copyright (C) 2016 Jakub Zawadzki4 *5 * Wireshark - Network traffic analyzer6 * By Gerald Combs <[emailprotected]>7 * Copyright 1998 Gerald Combs8 *9 * SPDX-License-Identifier: GPL-2.0-or-later10 */11 12#include "wtap_opttypes.h"13#include <config.h>14 15#include <stdio.h>16#include <stdlib.h>17#include <stdarg.h>18#include <string.h>19#include <errno(*__errno_location ()).h>20#include <inttypes.h>21 22#include <glib.h>23 24#include <wsutil/wsjson.h>25#include <wsutil/json_dumper.h>26#include <wsutil/ws_assert.h>27#include <wsutil/wsgcrypt.h>28 29#include <file.h>30#include <epan/epan_dissect.h>31#include <epan/exceptions.h>32#include <epan/color_filters.h>33#include <epan/prefs.h>34#include <epan/prefs-int.h>35#include <epan/uat-int.h>36#include <wiretap/wtap.h>37 38#include <epan/column.h>39#include <epan/column-info.h>40 41#include <ui/ssl_key_export.h>42 43#include <ui/io_graph_item.h>44#include <epan/stats_tree_priv.h>45#include <epan/stat_tap_ui.h>46#include <epan/conversation_table.h>47#include <epan/sequence_analysis.h>48#include <epan/expert.h>49#include <epan/export_object.h>50#include <epan/follow.h>51#include <epan/rtd_table.h>52#include <epan/srt_table.h>53#include <epan/to_str.h>54 55#include <epan/dissectors/packet-h225.h>56#include <epan/rtp_pt.h>57#include <ui/voip_calls.h>58#include <ui/rtp_stream.h>59#include <ui/tap-rtp-common.h>60#include <ui/tap-rtp-analysis.h>61#include <ui/cli/tap-protohierstat.h>62#include <ui/cli/tap-voip.h>63#include <wsutil/version_info.h>64#include <epan/to_str.h>65 66#include <epan/addr_resolv.h>67#include <epan/dissectors/packet-rtp.h>68#include <ui/rtp_media.h>69#include <ui/mcast_stream.h>70#include <speex/speex_resampler.h>71 72#include <epan/maxmind_db.h>73 74#include <wsutil/pint.h>75#include <wsutil/strnatcmp.h>76#include <wsutil/strtoi.h>77 78#include "globals.h"79 80#include "sharkd.h"81 82struct sharkd_filter_item83{84 uint8_t *filtered; /* can be NULL if all frames are matching for given filter. */85};86 87static GHashTable *filter_table;88 89static int mode;90static uint32_t rpcid;91 92static json_dumper dumper;93 94 95static const char *96json_find_attr(const char *buf, const jsmntok_t *tokens, int count, const char *attr)97{98 int i;99 100 for (i = 0; i < count; i += 2)101 {102 const char *tok_attr = &buf[tokens[i + 0].start];103 const char *tok_value = &buf[tokens[i + 1].start];104 105 if (!strcmp(tok_attr, attr))106 return tok_value;107 }108 109 return NULL((void*)0);110}111 112static void113json_print_base64(const uint8_t *data, size_t len)114{115 json_dumper_begin_base64(&dumper);116 json_dumper_write_base64(&dumper, data, len);117 json_dumper_end_base64(&dumper);118}119 120static void G_GNUC_PRINTF(2, 3)__attribute__((__format__ (__printf__, 2, 3)))121sharkd_json_value_anyf(const char *key, const char *format, ...)122{123 if (key)124 json_dumper_set_member_name(&dumper, key);125 126 va_list ap;127 va_start(ap, format)__builtin_va_start(ap, format);128 json_dumper_value_va_list(&dumper, format, ap);129 va_end(ap)__builtin_va_end(ap);130}131 132static void133sharkd_json_value_string(const char *key, const char *str)134{135 if (key)136 json_dumper_set_member_name(&dumper, key);137 json_dumper_value_string(&dumper, str);138}139 140static void141sharkd_json_value_base64(const char *key, const uint8_t *data, size_t len)142{143 if (key)144 json_dumper_set_member_name(&dumper, key);145 json_print_base64(data, len);146}147 148static void G_GNUC_PRINTF(2, 3)__attribute__((__format__ (__printf__, 2, 3)))149sharkd_json_value_stringf(const char *key, const char *format, ...)150{151 if (key)152 json_dumper_set_member_name(&dumper, key);153 154 va_list ap;155 va_start(ap, format)__builtin_va_start(ap, format);156 char* sformat = ws_strdup_printf("\"%s\"", format)wmem_strdup_printf(((void*)0), "\"%s\"", format);157 json_dumper_value_va_list(&dumper, sformat, ap);158 g_free(sformat);159 va_end(ap)__builtin_va_end(ap);160}161 162static void163sharkd_json_array_open(const char *key)164{165 if (key)166 json_dumper_set_member_name(&dumper, key);167 json_dumper_begin_array(&dumper);168}169 170static void171sharkd_json_array_close(void)172{173 json_dumper_end_array(&dumper);174}175 176static void177sharkd_json_object_open(const char *key)178{179 if (key)180 json_dumper_set_member_name(&dumper, key);181 json_dumper_begin_object(&dumper);182}183 184static void185sharkd_json_object_close(void)186{187 json_dumper_end_object(&dumper);188}189 190static void191sharkd_json_response_open(uint32_t id)192{193 json_dumper_begin_object(&dumper); // start the message194 sharkd_json_value_string("jsonrpc", "2.0");195 sharkd_json_value_anyf("id", "%d", id);196}197 198static void199sharkd_json_response_close(void)200{201 json_dumper_end_object(&dumper); // end the message202 203 json_dumper_finish(&dumper);204 205 /*206 * We do an explicit fflush after every line, because207 * we want output to be written to the socket as soon208 * as the line is complete.209 *210 * The stream is fully-buffered by default, so it's211 * only flushed when the buffer fills or the FILE *212 * is closed. On UN*X, we could set it to be line213 * buffered, but the MSVC standard I/O routines don't214 * support line buffering - they only support *byte*215 * buffering, doing a write for every byte written,216 * which is too inefficient, and full buffering,217 * which is what you get if you request line buffering.218 */219 fflush(stdoutstdout);220}221 222static void223sharkd_json_result_prologue(uint32_t id)224{225 sharkd_json_response_open(id);226 sharkd_json_object_open("result"); // start the result object227}228 229static void230sharkd_json_result_epilogue(void)231{232 json_dumper_end_object(&dumper); // end the result object233 sharkd_json_response_close();234}235 236static void237sharkd_json_result_array_prologue(uint32_t id)238{239 sharkd_json_response_open(id);240 sharkd_json_array_open("result"); // start the result array241}242 243static void244sharkd_json_result_array_epilogue(void)245{246 sharkd_json_array_close(); // end of result array247 sharkd_json_response_close();248}249 250static void251sharkd_json_simple_ok(uint32_t id)252{253 sharkd_json_result_prologue(id);254 sharkd_json_value_string("status", "OK");255 sharkd_json_result_epilogue();256}257 258static void259sharkd_json_warning(uint32_t id, char *warning)260{261 sharkd_json_result_prologue(id);262 sharkd_json_value_string("status", "Warning");263 sharkd_json_value_string("warning", warning);264 sharkd_json_result_epilogue();265}266 267static void G_GNUC_PRINTF(4, 5)__attribute__((__format__ (__printf__, 4, 5)))268sharkd_json_error(uint32_t id, int code, char* data, char* format, ...)269{270 sharkd_json_response_open(id);271 sharkd_json_object_open("error");272 sharkd_json_value_anyf("code", "%d", code);273 274 if (format)275 {276 // format the text message277 va_list args;278 279 va_start(args, format)__builtin_va_start(args, format);280 char *error_msg = ws_strdup_vprintf(format, args)wmem_strdup_vprintf(((void*)0), format, args);281 va_end(args)__builtin_va_end(args);282 283 sharkd_json_value_string("message", error_msg);284 285 g_free(error_msg);286 }287 288 sharkd_json_object_close();289 290 if (data)291 sharkd_json_value_string("data", data);292 293 sharkd_json_response_close();294}295 296static bool_Bool297is_param_match(const char *param_in, const char *valid_param)298{299 char* ptr;300 301 if ((ptr = g_strrstr(valid_param, "*")))302 {303 size_t prefix_len = ptr - valid_param;304 return !strncmp(param_in, valid_param, prefix_len);305 }306 else307 return !strcmp(param_in, valid_param);308}309 310/*311 * json_prep does four things:312 *313 * 1. check the syntax of the root and parameter members314 * 2. tokenize the names and values by zero terminating them315 * 3. unescape the names and values316 * 4. extracts and saves the rpcid317 * - we have to do it here as it's needed for the error messages318 *319 * The objective is to minimise the validation work in the functions320 * that process each called method.321 *322 * This gets a little messy as the JSON parser creates a flat list323 * of all members rather than create a tree.324 */325static bool_Bool326json_prep(char* buf, const jsmntok_t* tokens, int count)327{328 int i;329 const char* method = NULL((void*)0);330 char* attr_name = NULL((void*)0);331 char* attr_value = NULL((void*)0);332 333#define SHARKD_JSON_ANY0 0334#define SHARKD_JSON_STRING1 1335#define SHARKD_JSON_INTEGER2 2336#define SHARKD_JSON_UINTEGER3 3337#define SHARKD_JSON_FLOAT4 4338#define SHARKD_JSON_OBJECT5 5339#define SHARKD_JSON_ARRAY6 6340#define SHARKD_JSON_BOOLEAN7 7341#define SHARKD_ARRAY_END99 99342 343 struct member_attribute {344 const char* parent_ctx;345 const char* name;346 int level;347 jsmntype_t type;348 int value_type;349 bool_Bool is_mandatory;350 };351 352#define SHARKD_MANDATORY1 true1353#define SHARKD_OPTIONAL0 false0354 355 /*356 * The member attribute structure is key to the syntax checking. The357 * array contains all of the root level (1) member names, the data358 * types permissible for the value and a boolean that indicates whether359 * or not the member is mandatory.360 *361 * Once we get into the next layer (2) of the json tree, we need to check362 * params member names and data types dependent in the context of the method363 * (parent_ctx).364 */365 366 struct member_attribute name_array[] = {367 // Root members368 {NULL((void*)0), "jsonrpc", 1, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_MANDATORY1},369 {NULL((void*)0), "userid", 1, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},370 {NULL((void*)0), "id", 1, JSMN_PRIMITIVE, SHARKD_JSON_UINTEGER3, SHARKD_MANDATORY1},371 {NULL((void*)0), "method", 1, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_MANDATORY1},372 {NULL((void*)0), "params", 1, JSMN_OBJECT, SHARKD_JSON_OBJECT5, SHARKD_OPTIONAL0},373 374 // Valid methods375 {"method", "analyse", 1, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},376 {"method", "bye", 1, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},377 {"method", "check", 1, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},378 {"method", "complete", 1, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},379 {"method", "download", 1, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},380 {"method", "dumpconf", 1, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},381 {"method", "follow", 1, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},382 {"method", "frame", 1, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},383 {"method", "frames", 1, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},384 {"method", "info", 1, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},385 {"method", "intervals", 1, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},386 {"method", "iograph", 1, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},387 {"method", "load", 1, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},388 {"method", "setcomment", 1, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},389 {"method", "setconf", 1, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},390 {"method", "status", 1, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},391 {"method", "tap", 1, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},392 393 // Parameters and their method context394 {"check", "field", 2, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},395 {"check", "filter", 2, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},396 {"complete", "field", 2, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},397 {"complete", "pref", 2, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},398 {"download", "token", 2, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},399 {"dumpconf", "pref", 2, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},400 {"follow", "follow", 2, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_MANDATORY1},401 {"follow", "filter", 2, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_MANDATORY1},402 {"follow", "sub_stream", 2, JSMN_PRIMITIVE, SHARKD_JSON_UINTEGER3, SHARKD_OPTIONAL0},403 {"frame", "frame", 2, JSMN_PRIMITIVE, SHARKD_JSON_UINTEGER3, SHARKD_MANDATORY1},404 {"frame", "proto", 2, JSMN_PRIMITIVE, SHARKD_JSON_BOOLEAN7, SHARKD_OPTIONAL0},405 {"frame", "ref_frame", 2, JSMN_PRIMITIVE, SHARKD_JSON_UINTEGER3, SHARKD_OPTIONAL0},406 {"frame", "prev_frame", 2, JSMN_PRIMITIVE, SHARKD_JSON_UINTEGER3, SHARKD_OPTIONAL0},407 {"frame", "columns", 2, JSMN_PRIMITIVE, SHARKD_JSON_BOOLEAN7, SHARKD_OPTIONAL0},408 {"frame", "color", 2, JSMN_PRIMITIVE, SHARKD_JSON_BOOLEAN7, SHARKD_OPTIONAL0},409 {"frame", "bytes", 2, JSMN_PRIMITIVE, SHARKD_JSON_BOOLEAN7, SHARKD_OPTIONAL0},410 {"frame", "hidden", 2, JSMN_PRIMITIVE, SHARKD_JSON_BOOLEAN7, SHARKD_OPTIONAL0},411 {"frames", "column*", 2, JSMN_UNDEFINED, SHARKD_JSON_ANY0, SHARKD_OPTIONAL0},412 {"frames", "filter", 2, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},413 {"frames", "skip", 2, JSMN_PRIMITIVE, SHARKD_JSON_UINTEGER3, SHARKD_OPTIONAL0},414 {"frames", "limit", 2, JSMN_PRIMITIVE, SHARKD_JSON_UINTEGER3, SHARKD_OPTIONAL0},415 {"frames", "refs", 2, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},416 {"intervals", "interval", 2, JSMN_PRIMITIVE, SHARKD_JSON_UINTEGER3, SHARKD_OPTIONAL0},417 {"intervals", "filter", 2, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},418 {"iograph", "interval", 2, JSMN_PRIMITIVE, SHARKD_JSON_UINTEGER3, SHARKD_OPTIONAL0},419 {"iograph", "interval_units", 2, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},420 {"iograph", "filter", 2, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},421 {"iograph", "graph0", 2, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_MANDATORY1},422 {"iograph", "graph1", 2, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},423 {"iograph", "graph2", 2, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},424 {"iograph", "graph3", 2, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},425 {"iograph", "graph4", 2, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},426 {"iograph", "graph5", 2, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},427 {"iograph", "graph6", 2, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},428 {"iograph", "graph7", 2, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},429 {"iograph", "graph8", 2, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},430 {"iograph", "graph9", 2, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},431 {"iograph", "filter0", 2, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},432 {"iograph", "filter1", 2, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},433 {"iograph", "filter2", 2, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},434 {"iograph", "filter3", 2, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},435 {"iograph", "filter4", 2, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},436 {"iograph", "filter5", 2, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},437 {"iograph", "filter6", 2, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},438 {"iograph", "filter7", 2, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},439 {"iograph", "filter8", 2, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},440 {"iograph", "filter9", 2, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},441 {"load", "file", 2, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_MANDATORY1},442 {"setcomment", "frame", 2, JSMN_PRIMITIVE, SHARKD_JSON_UINTEGER3, SHARKD_MANDATORY1},443 {"setcomment", "comment", 2, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},444 {"setconf", "name", 2, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_MANDATORY1},445 {"setconf", "value", 2, JSMN_UNDEFINED, SHARKD_JSON_ANY0, SHARKD_MANDATORY1},446 {"tap", "tap0", 2, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_MANDATORY1},447 {"tap", "tap1", 2, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},448 {"tap", "tap2", 2, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},449 {"tap", "tap3", 2, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},450 {"tap", "tap4", 2, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},451 {"tap", "tap5", 2, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},452 {"tap", "tap6", 2, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},453 {"tap", "tap7", 2, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},454 {"tap", "tap8", 2, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},455 {"tap", "tap9", 2, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},456 {"tap", "tap10", 2, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},457 {"tap", "tap11", 2, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},458 {"tap", "tap12", 2, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},459 {"tap", "tap13", 2, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},460 {"tap", "tap14", 2, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},461 {"tap", "tap15", 2, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},462 {"tap", "filter", 2, JSMN_STRING, SHARKD_JSON_STRING1, SHARKD_OPTIONAL0},463 464 // End of the name_array465 {NULL((void*)0), NULL((void*)0), 0, JSMN_STRING, SHARKD_ARRAY_END99, SHARKD_OPTIONAL0},466 };467 468 rpcid = 0;469 470 /* sanity check, and split strings */471 if (count < 1 || tokens[0].type != JSMN_OBJECT)472 {473 sharkd_json_error(474 rpcid, -32600, NULL((void*)0),475 "The request must an object"476 );477 return false0;478 }479 480 /* don't need [0] token */481 tokens++;482 count--;483 484 if (count & 1)485 {486 sharkd_json_error(487 rpcid, -32600, NULL((void*)0),488 "The request must contain name/value pairs"489 );490 return false0;491 }492 493 for (i = 0; i < count; i += 2)494 {495 buf[tokens[i + 0].end] = '\0';496 buf[tokens[i + 1].end] = '\0';497 }498 499 // we must get the id as soon as possible so that it's available in all future error messages500 attr_value = (char*)json_find_attr(buf, tokens, count, "id");501 if (attr_value)502 {503 if (!ws_strtou32(attr_value, NULL((void*)0), &rpcid))504 {505 sharkd_json_error(506 rpcid, -32600, NULL((void*)0),507 "The id value must be a positive integer"508 );509 return false0;510 }511 }512 513 method = json_find_attr(buf, tokens, count, "method");514 515 if (method)516 {517 bool_Bool is_supported = false0;518 i = 0; // name array index519 520 // check that the request method is good521 while (name_array[i].value_type != SHARKD_ARRAY_END99)522 {523 if (name_array[i].parent_ctx)524 {525 if (!strcmp(method, name_array[i].name) && !strcmp(name_array[i].parent_ctx, "method"))526 is_supported = true1; // the method is valid527 }528 529 i++;530 }531 532 if (!is_supported)533 {534 sharkd_json_error(535 rpcid, -32601, NULL((void*)0),536 "The method %s is not supported", method537 );538 return false0;539 }540 }541 542 for (i = 0; i < count; i += 2)543 {544 if (tokens[i].type != JSMN_STRING)545 {546 sharkd_json_error(547 rpcid, -32600, NULL((void*)0),548 "Member names must be a string - member %d is not string", (i / 2) + 1549 );550 return false0;551 }552 553 attr_name = &buf[tokens[i + 0].start];554 attr_value = &buf[tokens[i + 1].start];555 556 if (!strcmp(attr_name, "jsonrpc"))557 {558 if (strcmp(&buf[tokens[i + 1].start], "2.0"))559 {560 sharkd_json_error(561 rpcid, -32600, NULL((void*)0),562 "Only JSON %s is supported", "2.0"563 );564 return false0;565 }566 }567 568 /* unescape only value, as keys are simple strings */569 if (tokens[i + 1].type == JSMN_STRING && !json_decode_string_inplace(attr_value))570 {571 sharkd_json_error(572 rpcid, -32600, NULL((void*)0),573 "Cannot unescape the value string of member %d", (i / 2) + 1574 );575 return false0;576 }577 578 /* Confirm that the member is valid */579 bool_Bool match = false0;580 581 // We need to check root members (level 1) and parameters (level 2), hence the for loop.582 583 for (int level = 1; level < 3; level++)584 {585 size_t j = 0;586 587 while (name_array[j].value_type != SHARKD_ARRAY_END99) // iterate through the array until we hit the end588 {589 if (is_param_match(attr_name, name_array[j].name) && name_array[j].level == level)590 {591 // We need to be sure the match is in the correct context592 // i.e. is this a match for a root member (level 1) or for a parameter (level 2).593 594 if (level == 1)595 {596 // need to guard against a parameter name matching a method name597 if (method)598 {599 if (name_array[j].parent_ctx)600 {601 j++;602 continue;603 }604 605 if (!strcmp(method, &buf[tokens[i + 0].start]))606 {607 j++;608 continue;609 }610 }611 612 match = true1;613 }614 else if (method)615 {616 if (level == 2 && !strcmp(name_array[j].parent_ctx, method))617 match = true1;618 else619 {620 j++;621 continue;622 }623 }624 else625 {626 j++;627 continue;628 }629 630 // The match looks good, let's now check the data types631 632 if (tokens[i + 1].type != name_array[j].type && name_array[j].type != SHARKD_JSON_ANY0)633 {634 sharkd_json_error(635 rpcid, -32600, NULL((void*)0),636 "The data type for member %s is not valid", attr_name637 );638 return false0;639 }640 else if (name_array[j].type == JSMN_PRIMITIVE && name_array[j].value_type == SHARKD_JSON_UINTEGER3)641 {642 uint32_t temp;643 if (!ws_strtou32(attr_value, NULL((void*)0), &temp) || temp <= 0)644 {645 sharkd_json_error(646 rpcid, -32600, NULL((void*)0),647 "The value for %s must be a positive integer", name_array[j].name648 );649 return false0;650 }651 }652 else if (name_array[j].type == JSMN_PRIMITIVE && name_array[j].value_type == SHARKD_JSON_BOOLEAN7)653 {654 if (strcmp(attr_value, "true") && strcmp(attr_value, "false"))655 {656 sharkd_json_error(657 rpcid, -32600, NULL((void*)0),658 "The value for %s must be a boolean (true or false)", name_array[j].name659 );660 return false0;661 }662 663 }664 break; // looks like a valid match665 }666 j++;667 }668 }669 670 if (!match)671 {672 sharkd_json_error(673 rpcid, -32600, NULL((void*)0),674 "%s is not a valid member name", attr_name675 );676 return false0;677 }678 }679 680 /* check for mandatory members */681 size_t j = 0;682 683 while (name_array[j].value_type != SHARKD_ARRAY_END99)684 {685 if (name_array[j].is_mandatory && name_array[j].level == 1)686 {687 if (!json_find_attr(buf, tokens, count, name_array[j].name))688 {689 sharkd_json_error(690 rpcid, -32600, NULL((void*)0),691 "Mandatory member %s is missing", name_array[j].name692 );693 return false0;694 }695 }696 j++;697 }698 699 // check that the current request contains the mandatory parameters700 j = 0;701 702 while (name_array[j].value_type != SHARKD_ARRAY_END99)703 {704 if (name_array[j].is_mandatory && name_array[j].level == 2 && !strcmp(method, name_array[j].parent_ctx))705 {706 if (!json_find_attr(buf, tokens, count, name_array[j].name))707 {708 sharkd_json_error(709 rpcid, -32600, NULL((void*)0),710 "Mandatory parameter %s is missing", name_array[j].name711 );712 return false0;713 }714 }715 j++;716 }717 718 719 // check that the parameters for the current request are valid for the method and that the data type for the value is valid720 721 return true1;722}723 724static void725sharkd_session_filter_free(void *data)726{727 struct sharkd_filter_item *l = (struct sharkd_filter_item *) data;728 729 g_free(l->filtered);730 g_free(l);731}732 733static const struct sharkd_filter_item *734sharkd_session_filter_data(const char *filter)735{736 struct sharkd_filter_item *l;737 738 l = (struct sharkd_filter_item *) g_hash_table_lookup(filter_table, filter);739 if (!l)740 {741 uint8_t *filtered = NULL((void*)0);742 743 int ret = sharkd_filter(filter, &filtered);744 745 if (ret == -1)746 return NULL((void*)0);747 748 l = g_new(struct sharkd_filter_item, 1)((struct sharkd_filter_item *) g_malloc_n ((1), sizeof (struct
sharkd_filter_item)))
;749 l->filtered = filtered;750 751 g_hash_table_insert(filter_table, g_strdup(filter)g_strdup_inline (filter), l);752 }753 754 return l;755}756 757static bool_Bool758sharkd_rtp_match_init(rtpstream_id_t *id, const char *init_str)759{760 bool_Bool ret = false0;761 char **arr;762 uint32_t tmp_addr_src, tmp_addr_dst;763 address tmp_src_addr, tmp_dst_addr;764 765 memset(id, 0, sizeof(*id));766 767 arr = g_strsplit(init_str, "_", 7); /* pass larger value, so we'll catch incorrect input :) */768 if (g_strv_length(arr) != 5)769 goto fail;770 771 /* TODO, for now only IPv4 */772 if (!get_host_ipaddr(arr[0], &tmp_addr_src))773 goto fail;774 775 if (!ws_strtou16(arr[1], NULL((void*)0), &id->src_port))776 goto fail;777 778 if (!get_host_ipaddr(arr[2], &tmp_addr_dst))779 goto fail;780 781 if (!ws_strtou16(arr[3], NULL((void*)0), &id->dst_port))782 goto fail;783 784 if (!ws_hexstrtou32(arr[4], NULL((void*)0), &id->ssrc))785 goto fail;786 787 set_address(&tmp_src_addr, AT_IPv4, 4, &tmp_addr_src);788 copy_address(&id->src_addr, &tmp_src_addr);789 set_address(&tmp_dst_addr, AT_IPv4, 4, &tmp_addr_dst);790 copy_address(&id->dst_addr, &tmp_dst_addr);791 792 ret = true1;793 794fail:795 g_strfreev(arr);796 return ret;797}798 799static bool_Bool800sharkd_session_process_info_nstat_cb(const void *key, void *value, void *userdata _U___attribute__((unused)))801{802 stat_tap_table_ui *stat_tap = (stat_tap_table_ui *) value;803 804 json_dumper_begin_object(&dumper);805 sharkd_json_value_string("name", stat_tap->title);806 sharkd_json_value_stringf("tap", "nstat:%s", (const char *) key);807 json_dumper_end_object(&dumper);808 809 return false0;810}811 812static bool_Bool813sharkd_session_process_info_conv_cb(const void* key, void* value, void* userdata _U___attribute__((unused)))814{815 struct register_ct *table = (struct register_ct *) value;816 817 const char *label = (const char *) key;818 819 if (get_conversation_packet_func(table))820 {821 json_dumper_begin_object(&dumper);822 sharkd_json_value_stringf("name", "Conversation List/%s", label);823 sharkd_json_value_stringf("tap", "conv:%s", label);824 json_dumper_end_object(&dumper);825 }826 827 if (get_endpoint_packet_func(table))828 {829 json_dumper_begin_object(&dumper);830 sharkd_json_value_stringf("name", "Endpoint/%s", label);831 sharkd_json_value_stringf("tap", "endpt:%s", label);832 json_dumper_end_object(&dumper);833 }834 return false0;835}836 837static bool_Bool838sharkd_session_seq_analysis_cb(const void *key, void *value, void *userdata _U___attribute__((unused)))839{840 register_analysis_t *analysis = (register_analysis_t *) value;841 842 json_dumper_begin_object(&dumper);843 sharkd_json_value_string("name", sequence_analysis_get_ui_name(analysis));844 sharkd_json_value_stringf("tap", "seqa:%s", (const char *) key);845 json_dumper_end_object(&dumper);846 847 return false0;848}849 850static bool_Bool851sharkd_export_object_visit_cb(const void *key _U___attribute__((unused)), void *value, void *user_data _U___attribute__((unused)))852{853 register_eo_t *eo = (register_eo_t *) value;854 855 const int proto_id = get_eo_proto_id(eo);856 const char *filter = proto_get_protocol_filter_name(proto_id);857 const char *label = proto_get_protocol_short_name(find_protocol_by_id(proto_id));858 859 json_dumper_begin_object(&dumper);860 sharkd_json_value_stringf("name", "Export Object/%s", label);861 sharkd_json_value_stringf("tap", "eo:%s", filter);862 json_dumper_end_object(&dumper);863 864 return false0;865}866 867static bool_Bool868sharkd_srt_visit_cb(const void *key _U___attribute__((unused)), void *value, void *user_data _U___attribute__((unused)))869{870 register_srt_t *srt = (register_srt_t *) value;871 872 const int proto_id = get_srt_proto_id(srt);873 const char *filter = proto_get_protocol_filter_name(proto_id);874 const char *label = proto_get_protocol_short_name(find_protocol_by_id(proto_id));875 876 json_dumper_begin_object(&dumper);877 sharkd_json_value_stringf("name", "Service Response Time/%s", label);878 sharkd_json_value_stringf("tap", "srt:%s", filter);879 json_dumper_end_object(&dumper);880 881 return false0;882}883 884static bool_Bool885sharkd_rtd_visit_cb(const void *key _U___attribute__((unused)), void *value, void *user_data _U___attribute__((unused)))886{887 register_rtd_t *rtd = (register_rtd_t *) value;888 889 const int proto_id = get_rtd_proto_id(rtd);890 const char *filter = proto_get_protocol_filter_name(proto_id);891 const char *label = proto_get_protocol_short_name(find_protocol_by_id(proto_id));892 893 json_dumper_begin_object(&dumper);894 sharkd_json_value_stringf("name", "Response Time Delay/%s", label);895 sharkd_json_value_stringf("tap", "rtd:%s", filter);896 json_dumper_end_object(&dumper);897 898 return false0;899}900 901static bool_Bool902sharkd_follower_visit_cb(const void *key _U___attribute__((unused)), void *value, void *user_data _U___attribute__((unused)))903{904 register_follow_t *follower = (register_follow_t *) value;905 906 const int proto_id = get_follow_proto_id(follower);907 const char *label = proto_get_protocol_short_name(find_protocol_by_id(proto_id));908 const char *filter = label; /* correct: get_follow_by_name() is registered by short name */909 910 json_dumper_begin_object(&dumper);911 sharkd_json_value_stringf("name", "Follow/%s", label);912 sharkd_json_value_stringf("tap", "follow:%s", filter);913 json_dumper_end_object(&dumper);914 915 return false0;916}917 918static void919sharkd_session_print_capture_types(void)920{921 unsigned i;922 GArray *writable_type_subtypes;923 writable_type_subtypes = wtap_get_writable_file_types_subtypes(FT_SORT_BY_NAME);924 for (i = 0; i < writable_type_subtypes->len; i++) {925 int ft = g_array_index(writable_type_subtypes, int, i)(((int*) (void *) (writable_type_subtypes)->data) [(i)]);926 sharkd_json_object_open(NULL((void*)0));927 sharkd_json_value_string("name", wtap_file_type_subtype_name(ft));928 sharkd_json_value_string("description", wtap_file_type_subtype_description(ft));929 sharkd_json_object_close();930 }931 g_array_free(writable_type_subtypes, TRUE(!(0)));932}933 934struct encap_type_info935{936 const char *name;937 const char *description;938};939 940static int941encap_type_info_nat_compare(const void *a, const void *b)942{943 return ws_ascii_strnatcmp(((const struct encap_type_info *)a)->name,944 ((const struct encap_type_info *)b)->name);945}946 947static void948encap_type_info_visit(void *data, void *user_data _U___attribute__((unused)))949{950 sharkd_json_object_open(NULL((void*)0));951 sharkd_json_value_string("name", ((struct encap_type_info *)data)->name);952 sharkd_json_value_string("description", ((struct encap_type_info *)data)->description);953 sharkd_json_object_close();954}955 956static void957sharkd_session_print_encap_types(void)958{959 int i;960 struct encap_type_info *encaps;961 GSList *list = NULL((void*)0);962 encaps = g_new(struct encap_type_info, WTAP_NUM_ENCAP_TYPES)((struct encap_type_info *) g_malloc_n ((wtap_get_num_encap_types
()), sizeof (struct encap_type_info)))
;963 for (i = 0; i < WTAP_NUM_ENCAP_TYPESwtap_get_num_encap_types(); i++) {964 encaps[i].name = wtap_encap_name(i);965 if (encaps[i].name != NULL((void*)0)) {966 encaps[i].description = wtap_encap_description(i);967 list = g_slist_insert_sorted(list, &encaps[i], encap_type_info_nat_compare);968 }969 }970 g_slist_foreach(list, encap_type_info_visit, NULL((void*)0));971 g_slist_free(list);972 g_free(encaps);973}974 975/**976 * sharkd_session_process_info()977 *978 * Process info request979 *980 * Output object with attributes:981 * (m) version - version number982 *983 * (m) columns - available column formats, array of object with attributes:984 * 'name' - column name985 * 'format' - column format-name986 *987 * (m) stats - available statistics, array of object with attributes:988 * 'name' - statistic name989 * 'tap' - sharkd tap-name for statistic990 *991 * (m) convs - available conversation list, array of object with attributes:992 * 'name' - conversation name993 * 'tap' - sharkd tap-name for conversation994 *995 * (m) eo - available export object list, array of object with attributes:996 * 'name' - export object name997 * 'tap' - sharkd tap-name for eo998 *999 * (m) srt - available service response time list, array of object with attributes:1000 * 'name' - service response time name1001 * 'tap' - sharkd tap-name for srt1002 *1003 * (m) rtd - available response time delay list, array of object with attributes:1004 * 'name' - response time delay name1005 * 'tap' - sharkd tap-name for rtd1006 *1007 * (m) seqa - available sequence analysis (flow) list, array of object with attributes:1008 * 'name' - sequence analysis name1009 * 'tap' - sharkd tap-name1010 *1011 * (m) taps - available taps, array of object with attributes:1012 * 'name' - tap name1013 * 'tap' - sharkd tap-name1014 *1015 * (m) follow - available followers, array of object with attributes:1016 * 'name' - tap name1017 * 'tap' - sharkd tap-name1018 *1019 * (m) ftypes - conversation table for FT_ number to string, array of FT_xxx strings.1020 *1021 * (m) nstat - available table-based taps, array of object with attributes:1022 * 'name' - tap name1023 * 'tap' - sharkd tap-name1024 *1025 * (m) capture_types - available capture types, array of object with attributes:1026 * 'name' - capture type name1027 * 'description' - capture type description1028 *1029 * (m) encap_types - available encapsulation types, array of object with attributes:1030 * 'name' - encapsulation type name1031 * 'description' - encapsulation type description1032 */1033static void1034sharkd_session_process_info(void)1035{1036 int i;1037 1038 sharkd_json_result_prologue(rpcid);1039 1040 sharkd_json_array_open("columns");1041 for (i = 0; i < NUM_COL_FMTS; i++)1042 {1043 const char *col_format = col_format_to_string(i);1044 const char *col_descr = col_format_desc(i);1045 1046 json_dumper_begin_object(&dumper);1047 sharkd_json_value_string("name", col_descr);1048 sharkd_json_value_string("format", col_format);1049 json_dumper_end_object(&dumper);1050 }1051 sharkd_json_array_close();1052 1053 sharkd_json_array_open("stats");1054 {1055 GList *cfg_list = stats_tree_get_cfg_list();1056 GList *l;1057 1058 for (l = cfg_list; l; l = l->next)1059 {1060 stats_tree_cfg *cfg = (stats_tree_cfg *) l->data;1061 1062 json_dumper_begin_object(&dumper);1063 sharkd_json_value_string("name", cfg->title);1064 sharkd_json_value_stringf("tap", "stat:%s", cfg->abbr);1065 json_dumper_end_object(&dumper);1066 }1067 1068 g_list_free(cfg_list);1069 }1070 sharkd_json_array_close();1071 1072 sharkd_json_array_open("ftypes");1073 for (i = 0; i < FT_NUM_TYPES; i++)1074 sharkd_json_value_string(NULL((void*)0), ftype_name((ftenum_t) i));1075 sharkd_json_array_close();1076 1077 sharkd_json_array_open("capture_types");1078 sharkd_session_print_capture_types();1079 sharkd_json_array_close();1080 1081 sharkd_json_array_open("encap_types");1082 sharkd_session_print_encap_types();1083 sharkd_json_array_close();1084 1085 sharkd_json_value_string("version", get_ws_vcs_version_info_short());1086 1087 sharkd_json_array_open("nstat");1088 i = 0;1089 stat_tap_iterate_tables(sharkd_session_process_info_nstat_cb, &i);1090 sharkd_json_array_close();1091 1092 sharkd_json_array_open("convs");1093 i = 0;1094 conversation_table_iterate_tables(sharkd_session_process_info_conv_cb, &i);1095 sharkd_json_array_close();1096 1097 sharkd_json_array_open("seqa");1098 i = 0;1099 sequence_analysis_table_iterate_tables(sharkd_session_seq_analysis_cb, &i);1100 sharkd_json_array_close();1101 1102 sharkd_json_array_open("taps");1103 {1104 json_dumper_begin_object(&dumper);1105 sharkd_json_value_string("name", "UDP Multicast Streams");1106 sharkd_json_value_string("tap", "multicast");1107 json_dumper_end_object(&dumper);1108 1109 json_dumper_begin_object(&dumper);1110 sharkd_json_value_string("name", "RTP streams");1111 sharkd_json_value_string("tap", "rtp-streams");1112 json_dumper_end_object(&dumper);1113 1114 json_dumper_begin_object(&dumper);1115 sharkd_json_value_string("name", "Protocol Hierarchy Statistics");1116 sharkd_json_value_string("tap", "phs");1117 json_dumper_end_object(&dumper);1118 1119 json_dumper_begin_object(&dumper);1120 sharkd_json_value_string("name", "VoIP Calls");1121 sharkd_json_value_string("tap", "voip-calls");1122 json_dumper_end_object(&dumper);1123 1124 json_dumper_begin_object(&dumper);1125 sharkd_json_value_string("name", "VoIP Conversations");1126 sharkd_json_value_string("tap", "voip-convs");1127 json_dumper_end_object(&dumper);1128 1129 json_dumper_begin_object(&dumper);1130 sharkd_json_value_string("name", "Expert Information");1131 sharkd_json_value_string("tap", "expert");1132 json_dumper_end_object(&dumper);1133 }1134 sharkd_json_array_close();1135 1136 sharkd_json_array_open("eo");1137 i = 0;1138 eo_iterate_tables(sharkd_export_object_visit_cb, &i);1139 sharkd_json_array_close();1140 1141 sharkd_json_array_open("srt");1142 i = 0;1143 srt_table_iterate_tables(sharkd_srt_visit_cb, &i);1144 sharkd_json_array_close();1145 1146 sharkd_json_array_open("rtd");1147 i = 0;1148 rtd_table_iterate_tables(sharkd_rtd_visit_cb, &i);1149 sharkd_json_array_close();1150 1151 sharkd_json_array_open("follow");1152 i = 0;1153 follow_iterate_followers(sharkd_follower_visit_cb, &i);1154 sharkd_json_array_close();1155 1156 sharkd_json_result_epilogue();1157}1158 1159/**1160 * sharkd_session_process_load()1161 *1162 * Process load request1163 *1164 * Input:1165 * (m) file - file to be loaded1166 *1167 * Output object with attributes:1168 * (m) err - error code1169 */1170static void1171sharkd_session_process_load(const char *buf, const jsmntok_t *tokens, int count)1172{1173 const char *tok_file = json_find_attr(buf, tokens, count, "file");1174 int err = 0;1175 1176 if (!tok_file)1177 return;1178 1179 fprintf(stderrstderr, "load: filename=%s\n", tok_file);1180 1181 if (sharkd_cf_open(tok_file, WTAP_TYPE_AUTO0, false0, &err) != CF_OK)1182 {1183 sharkd_json_error(1184 rpcid, -2001, NULL((void*)0),1185 "Unable to open the file"1186 );1187 return;1188 }1189 1190 TRY{ except_t *volatile exc; volatile int except_state = 0; static
const except_id_t catch_spec[] = { { 1, 0 } }; { struct except_stacknode
except_sn; struct except_catch except_ch; except_setup_try(&
except_sn, &except_ch, catch_spec, 1); if (_setjmp (except_ch
.except_jmp)) *(&exc) = &except_ch.except_obj; else *
(&exc) = 0; if(except_state & 1) except_state |= 2; except_state
&= ~1; if (except_state == 0 && exc == 0)
1191 {1192 err = sharkd_load_cap_file();1193 }1194 CATCH(OutOfMemoryError)if (except_state == 0 && exc != 0 && exc->
except_id.except_code == (8) && (except_state |= 1))
1195 {1196 sharkd_json_error(1197 rpcid, -32603, NULL((void*)0),1198 "Load failed, out of memory"1199 );1200 fprintf(stderrstderr, "load: OutOfMemoryError\n");1201 err = ENOMEM12;1202 }1203 ENDTRYif(!(except_state&1) && exc != 0) except_rethrow(
exc); except_free(except_ch.except_obj.except_dyndata); except_pop
(); };}
;1204 1205 if (err == 0)1206 {1207 sharkd_json_simple_ok(rpcid);1208 }1209 else1210 {1211 sharkd_json_result_prologue(rpcid);1212 sharkd_json_value_string("status", wtap_strerror(err));1213 sharkd_json_value_anyf("err", "%d", err);1214 sharkd_json_result_epilogue();1215 }1216 1217}1218 1219/**1220 * sharkd_session_process_status()1221 *1222 * Process status request1223 *1224 * Output object with attributes:1225 * (m) frames - count of currently loaded frames1226 * (m) duration - time difference between time of first frame, and last loaded frame1227 * (o) filename - capture filename1228 * (o) filesize - capture filesize1229 * (o) columns - array of column titles1230 * (o) column_info - array of column infos, array of object with attributes:1231 * 'title' - column title1232 * 'format' - column format (%x or %Cus:<expr>:<occurrence> if COL_CUSTOM)1233 * 'visible' - true if column is visible1234 * 'resolved' - true if column is resolved1235 */1236static void1237sharkd_session_process_status(void)1238{1239 sharkd_json_result_prologue(rpcid);1240 1241 sharkd_json_value_anyf("frames", "%u", cfile.count);1242 sharkd_json_value_anyf("duration", "%.9f", nstime_to_sec(&cfile.elapsed_time));1243 1244 if (cfile.filename)1245 {1246 char *name = g_path_get_basename(cfile.filename);1247 1248 sharkd_json_value_string("filename", name);1249 g_free(name);1250 }1251 1252 if (cfile.provider.wth)1253 {1254 int64_t file_size = wtap_file_size(cfile.provider.wth, NULL((void*)0));1255 1256 if (file_size > 0)1257 sharkd_json_value_anyf("filesize", "%" PRId64"l" "d", file_size);1258 }1259 1260 if (cfile.cinfo.num_cols > 0)1261 {1262 sharkd_json_array_open("columns");1263 for (int i = 0; i < cfile.cinfo.num_cols; ++i)1264 {1265 sharkd_json_value_string(NULL((void*)0), get_column_title(i));1266 }1267 sharkd_json_array_close();1268 1269 sharkd_json_array_open("column_info");1270 for (int i = 0; i < cfile.cinfo.num_cols; ++i)1271 {1272 int fmt = get_column_format(i);1273 sharkd_json_object_open(NULL((void*)0));1274 sharkd_json_value_string("title", get_column_title(i));1275 if (fmt != COL_CUSTOM)1276 {1277 sharkd_json_value_string("format", col_format_to_string(fmt));1278 } else {1279 sharkd_json_value_stringf("format", "%s:%s:%d", col_format_to_string(fmt), get_column_custom_fields(i), get_column_custom_occurrence(i));1280 }1281 sharkd_json_value_anyf("visible", get_column_visible(i) ? "true" : "false");1282 sharkd_json_value_anyf("resolved", get_column_resolved(i) ? "true" : "false");1283 sharkd_json_object_close();1284 }1285 sharkd_json_array_close();1286 }1287 1288 sharkd_json_result_epilogue();1289}1290 1291struct sharkd_analyse_data1292{1293 GHashTable *protocols_set;1294 nstime_t *first_time;1295 nstime_t *last_time;1296};1297 1298static void1299sharkd_session_process_analyse_cb(epan_dissect_t *edt, proto_tree *tree _U___attribute__((unused)),1300 struct epan_column_info *cinfo _U___attribute__((unused)), const GSList *data_src _U___attribute__((unused)), void *data)1301{1302 struct sharkd_analyse_data *analyser = (struct sharkd_analyse_data *) data;1303 packet_info *pi = &edt->pi;1304 frame_data *fdata = pi->fd;1305 1306 if (analyser->first_time == NULL((void*)0) || nstime_cmp(&fdata->abs_ts, analyser->first_time) < 0)1307 analyser->first_time = &fdata->abs_ts;1308 1309 if (analyser->last_time == NULL((void*)0) || nstime_cmp(&fdata->abs_ts, analyser->last_time) > 0)1310 analyser->last_time = &fdata->abs_ts;1311 1312 if (pi->layers)1313 {1314 wmem_list_frame_t *frame;1315 1316 for (frame = wmem_list_head(pi->layers); frame; frame = wmem_list_frame_next(frame))1317 {1318 int proto_id = GPOINTER_TO_UINT(wmem_list_frame_data(frame))((guint) (gulong) (wmem_list_frame_data(frame)));1319 1320 if (!g_hash_table_lookup_extended(analyser->protocols_set, GUINT_TO_POINTER(proto_id)((gpointer) (gulong) (proto_id)), NULL((void*)0), NULL((void*)0)))1321 {1322 g_hash_table_insert(analyser->protocols_set, GUINT_TO_POINTER(proto_id)((gpointer) (gulong) (proto_id)), GUINT_TO_POINTER(proto_id)((gpointer) (gulong) (proto_id)));1323 sharkd_json_value_string(NULL((void*)0), proto_get_protocol_filter_name(proto_id));1324 }1325 }1326 }1327 1328}1329 1330/**1331 * sharkd_session_process_status()1332 *1333 * Process analyse request1334 *1335 * Output object with attributes:1336 * (m) frames - count of currently loaded frames1337 * (m) protocols - protocol list1338 * (m) first - earliest frame time1339 * (m) last - latest frame time1340 */1341static void1342sharkd_session_process_analyse(void)1343{1344 struct sharkd_analyse_data analyser;1345 wtap_rec rec; /* Record metadata */1346 Buffer rec_buf; /* Record data */1347 1348 analyser.first_time = NULL((void*)0);1349 analyser.last_time = NULL((void*)0);1350 analyser.protocols_set = g_hash_table_new(NULL((void*)0) /* g_direct_hash() */, NULL((void*)0) /* g_direct_equal */);1351 1352 sharkd_json_result_prologue(rpcid);1353 1354 sharkd_json_value_anyf("frames", "%u", cfile.count);1355 1356 sharkd_json_array_open("protocols");1357 1358 wtap_rec_init(&rec);1359 ws_buffer_init(&rec_buf, 1514);1360 1361 for (uint32_t framenum = 1; framenum <= cfile.count; framenum++)1362 {1363 enum dissect_request_status status;1364 int err;1365 char *err_info;1366 1367 status = sharkd_dissect_request(framenum,1368 (framenum != 1) ? 1 : 0, framenum - 1,1369 &rec, &rec_buf, NULL((void*)0), SHARKD_DISSECT_FLAG_NULL0x00u,1370 &sharkd_session_process_analyse_cb, &analyser,1371 &err, &err_info);1372 switch (status) {1373 1374 case DISSECT_REQUEST_SUCCESS:1375 break;1376 1377 case DISSECT_REQUEST_NO_SUCH_FRAME:1378 /* XXX - report the error. */1379 break;1380 1381 case DISSECT_REQUEST_READ_ERROR:1382 /*1383 * Free up the error string.1384 * XXX - report the error.1385 */1386 g_free(err_info);1387 break;1388 }1389 }1390 1391 sharkd_json_array_close();1392 1393 if (analyser.first_time)1394 sharkd_json_value_anyf("first", "%.9f", nstime_to_sec(analyser.first_time));1395 1396 if (analyser.last_time)1397 sharkd_json_value_anyf("last", "%.9f", nstime_to_sec(analyser.last_time));1398 1399 sharkd_json_result_epilogue();1400 1401 wtap_rec_cleanup(&rec);1402 ws_buffer_free(&rec_buf);1403 1404 g_hash_table_destroy(analyser.protocols_set);1405}1406 1407static column_info *1408sharkd_session_create_columns(column_info *cinfo, const char *buf, const jsmntok_t *tokens, int count)1409{1410 const char *columns_custom[32];1411 uint16_t columns_fmt[32];1412 int16_t columns_occur[32];1413 1414 int i, cols;1415 1416 for (i = 0; i < 32; i++)1417 {1418 const char *tok_column;1419 char tok_column_name[64];1420 char *custom_sepa;1421 1422 snprintf(tok_column_name, sizeof(tok_column_name), "column%d", i);1423 tok_column = json_find_attr(buf, tokens, count, tok_column_name);1424 if (tok_column == NULL((void*)0))1425 break;1426 1427 columns_custom[i] = NULL((void*)0);1428 columns_occur[i] = 0;1429 1430 if ((custom_sepa = strchr(tok_column, ':')))1431 {1432 *custom_sepa = '\0'; /* XXX, C abuse: discarding-const */1433 1434 columns_fmt[i] = COL_CUSTOM;1435 columns_custom[i] = tok_column;1436 1437 if (!ws_strtoi16(custom_sepa + 1, NULL((void*)0), &columns_occur[i]))1438 return NULL((void*)0);1439 }1440 else1441 {1442 if (!ws_strtou16(tok_column, NULL((void*)0), &columns_fmt[i]))1443 return NULL((void*)0);1444 1445 if (columns_fmt[i] >= NUM_COL_FMTS)1446 return NULL((void*)0);1447 1448 /* if custom, that it shouldn't be just custom number -> error */1449 if (columns_fmt[i] == COL_CUSTOM)1450 return NULL((void*)0);1451 }1452 }1453 1454 cols = i;1455 1456 col_setup(cinfo, cols);1457 1458 for (i = 0; i < cols; i++)1459 {1460 col_item_t *col_item = &cinfo->columns[i];1461 1462 col_item->col_fmt = columns_fmt[i];1463 col_item->col_title = NULL((void*)0); /* no need for title */1464 1465 if (col_item->col_fmt == COL_CUSTOM)1466 {1467 col_item->col_custom_fields = g_strdup(columns_custom[i])g_strdup_inline (columns_custom[i]);1468 col_item->col_custom_occurrence = columns_occur[i];1469 }1470 1471 col_item->col_fence = 0;1472 }1473 1474 col_finalize(cinfo);1475 1476 return cinfo;1477}1478 1479static void1480sharkd_session_process_frames_cb(epan_dissect_t *edt, proto_tree *tree _U___attribute__((unused)),1481 struct epan_column_info *cinfo, const GSList *data_src _U___attribute__((unused)), void *data _U___attribute__((unused)))1482{1483 packet_info *pi = &edt->pi;1484 frame_data *fdata = pi->fd;1485 wtap_block_t pkt_block = NULL((void*)0);1486 unsigned int i;1487 char *comment = NULL((void*)0);1488 1489 json_dumper_begin_object(&dumper);1490 1491 sharkd_json_array_open("c");1492 for (int col = 0; col < cinfo->num_cols; ++col)1493 {1494 sharkd_json_value_string(NULL((void*)0), get_column_text(cinfo, col));1495 }1496 sharkd_json_array_close();1497 1498 sharkd_json_value_anyf("num", "%u", pi->num);1499 1500 /*1501 * Get the block for this record, if it has one.1502 */1503 pkt_block = sharkd_get_packet_block(fdata);1504 1505 /*1506 * Does this record have any comments?1507 */1508 if (pkt_block != NULL((void*)0) &&1509 WTAP_OPTTYPE_SUCCESS == wtap_block_get_nth_string_option_value(pkt_block, OPT_COMMENT1, 0, &comment))1510 {1511 sharkd_json_value_anyf("ct", "true");1512 1513 sharkd_json_array_open("comments");1514 for (i = 0; wtap_block_get_nth_string_option_value(pkt_block, OPT_COMMENT1, i, &comment) == WTAP_OPTTYPE_SUCCESS; i++) {1515 sharkd_json_value_string(NULL((void*)0), comment);1516 }1517 sharkd_json_array_close();1518 }1519 1520 if (fdata->ignored)1521 sharkd_json_value_anyf("i", "true");1522 1523 if (fdata->marked)1524 sharkd_json_value_anyf("m", "true");1525 1526 if (fdata->color_filter)1527 {1528 sharkd_json_value_stringf("bg", "%06x", color_t_to_rgb(&fdata->color_filter->bg_color));1529 sharkd_json_value_stringf("fg", "%06x", color_t_to_rgb(&fdata->color_filter->fg_color));1530 }1531 1532 wtap_block_unref(pkt_block);1533 json_dumper_end_object(&dumper);1534}1535 1536/**1537 * sharkd_session_process_frames()1538 *1539 * Process frames request1540 *1541 * Input:1542 * (o) column0...columnXX - requested columns either number in range [0..NUM_COL_FMTS), or custom (syntax <dfilter>:<occurrence>).1543 * If column0 is not specified default column set will be used.1544 * (o) filter - filter to be used1545 * (o) skip=N - skip N frames1546 * (o) limit=N - show only N frames1547 * (o) refs - list (comma separated) with sorted time reference frame numbers.1548 *1549 * Output array of frames with attributes:1550 * (m) c - array of column data1551 * (m) num - frame number1552 * (o) i - if frame is ignored1553 * (o) m - if frame is marked1554 * (o) ct - if frame is commented1555 * (o) comments - array of comment strings1556 * (o) bg - color filter - background color in hex1557 * (o) fg - color filter - foreground color in hex1558 */1559static void1560sharkd_session_process_frames(const char *buf, const jsmntok_t *tokens, int count)1561{1562 const char *tok_filter = json_find_attr(buf, tokens, count, "filter");1563 const char *tok_column = json_find_attr(buf, tokens, count, "column0");1564 const char *tok_skip = json_find_attr(buf, tokens, count, "skip");1565 const char *tok_limit = json_find_attr(buf, tokens, count, "limit");1566 const char *tok_refs = json_find_attr(buf, tokens, count, "refs");1567 1568 const uint8_t *filter_data = NULL((void*)0);1569 1570 uint32_t prev_dis_num = 0;1571 uint32_t current_ref_frame = 0, next_ref_frame = UINT32_MAX(4294967295U);1572 uint32_t skip;1573 uint32_t limit;1574 1575 wtap_rec rec; /* Record metadata */1576 Buffer rec_buf; /* Record data */1577 column_info *cinfo = &cfile.cinfo;1578 column_info user_cinfo;1579 1580 if (tok_column)1581 {1582 memset(&user_cinfo, 0, sizeof(user_cinfo));1583 cinfo = sharkd_session_create_columns(&user_cinfo, buf, tokens, count);1584 if (!cinfo)1585 {1586 sharkd_json_error(1587 rpcid, -13001, NULL((void*)0),1588 "Column definition invalid - note column 6 requires a custom definition"1589 );1590 return;1591 }1592 }1593 1594 if (tok_filter)1595 {1596 const struct sharkd_filter_item *filter_item;1597 1598 filter_item = sharkd_session_filter_data(tok_filter);1599 if (!filter_item)1600 {1601 sharkd_json_error(1602 rpcid, -13002, NULL((void*)0),1603 "Filter expression invalid"1604 );1605 return;1606 }1607 1608 filter_data = filter_item->filtered;1609 }1610 1611 skip = 0;1612 if (tok_skip)1613 {1614 if (!ws_strtou32(tok_skip, NULL((void*)0), &skip))1615 return;1616 }1617 1618 limit = 0;1619 if (tok_limit)1620 {1621 if (!ws_strtou32(tok_limit, NULL((void*)0), &limit))1622 return;1623 }1624 1625 if (tok_refs)1626 {1627 if (!ws_strtou32(tok_refs, &tok_refs, &next_ref_frame))1628 return;1629 }1630 1631 sharkd_json_result_array_prologue(rpcid);1632 1633 wtap_rec_init(&rec);1634 ws_buffer_init(&rec_buf, 1514);1635 1636 for (uint32_t framenum = 1; framenum <= cfile.count; framenum++)1637 {1638 frame_data *fdata;1639 uint32_t ref_frame = (framenum != 1) ? 1 : 0;1640 enum dissect_request_status status;1641 int err;1642 char *err_info;1643 1644 if (filter_data && !(filter_data[framenum / 8] & (1 << (framenum % 8))))1645 continue;1646 1647 if (skip)1648 {1649 skip--;1650 prev_dis_num = framenum;1651 continue;1652 }1653 1654 if (tok_refs)1655 {1656 if (framenum >= next_ref_frame)1657 {1658 current_ref_frame = next_ref_frame;1659 1660 if (*tok_refs != ',')1661 next_ref_frame = UINT32_MAX(4294967295U);1662 1663 while (*tok_refs == ',' && framenum >= next_ref_frame)1664 {1665 current_ref_frame = next_ref_frame;1666 1667 if (!ws_strtou32(tok_refs + 1, &tok_refs, &next_ref_frame))1668 {1669 fprintf(stderrstderr, "sharkd_session_process_frames() wrong format for refs: %s\n", tok_refs);1670 break;1671 }1672 }1673 1674 if (*tok_refs == '\0' && framenum >= next_ref_frame)1675 {1676 current_ref_frame = next_ref_frame;1677 next_ref_frame = UINT32_MAX(4294967295U);1678 }1679 }1680 1681 if (current_ref_frame)1682 ref_frame = current_ref_frame;1683 }1684 1685 fdata = sharkd_get_frame(framenum);1686 status = sharkd_dissect_request(framenum,1687 ref_frame, prev_dis_num,1688 &rec, &rec_buf, cinfo,1689 (fdata->color_filter == NULL((void*)0)) ? SHARKD_DISSECT_FLAG_COLOR0x08u : SHARKD_DISSECT_FLAG_NULL0x00u,1690 &sharkd_session_process_frames_cb, NULL((void*)0),1691 &err, &err_info);1692 switch (status) {1693 1694 case DISSECT_REQUEST_SUCCESS:1695 break;1696 1697 case DISSECT_REQUEST_NO_SUCH_FRAME:1698 /* XXX - report the error. */1699 break;1700 1701 case DISSECT_REQUEST_READ_ERROR:1702 /*1703 * Free up the error string.1704 * XXX - report the error.1705 */1706 g_free(err_info);1707 break;1708 }1709 1710 prev_dis_num = framenum;1711 1712 if (limit && --limit == 0)1713 break;1714 }1715 sharkd_json_result_array_epilogue();1716 1717 if (cinfo != &cfile.cinfo)1718 col_cleanup(cinfo);1719 1720 wtap_rec_cleanup(&rec);1721 ws_buffer_free(&rec_buf);1722}1723 1724static void1725sharkd_session_process_tap_stats_node_cb(const char *key, const stat_node *n)1726{1727 stat_node *node;1728 1729 sharkd_json_array_open(key);1730 for (node = n->children; node; node = node->next)1731 {1732 json_dumper_begin_object(&dumper);1733 1734 /* code based on stats_tree_get_values_from_node() */1735 sharkd_json_value_string("name", node->name);1736 sharkd_json_value_anyf("count", "%d", node->counter);1737 if (node->counter && ((node->st_flags & ST_FLG_AVERAGE0x10000000) || node->rng))1738 {1739 switch(node->datatype)1740 {1741 case STAT_DT_INT:1742 sharkd_json_value_anyf("avg", "%.2f", ((float)node->total.int_total) / node->counter);1743 sharkd_json_value_anyf("min", "%d", node->minvalue.int_min);1744 sharkd_json_value_anyf("max", "%d", node->maxvalue.int_max);1745 break;1746 case STAT_DT_FLOAT:1747 sharkd_json_value_anyf("avg", "%.2f", node->total.float_total / node->counter);1748 sharkd_json_value_anyf("min", "%f", node->minvalue.float_min);1749 sharkd_json_value_anyf("max", "%f", node->maxvalue.float_max);1750 break;1751 }1752 }1753 1754 if (node->st->elapsed)1755 sharkd_json_value_anyf("rate", "%.4f", ((float)node->counter) / node->st->elapsed);1756 1757 if (node->parent && node->parent->counter)1758 sharkd_json_value_anyf("perc", "%.2f", (node->counter * 100.0) / node->parent->counter);1759 else if (node->parent == &(node->st->root))1760 sharkd_json_value_anyf("perc", "100");1761 1762 if (prefs.st_enable_burstinfo && node->max_burst)1763 {1764 if (prefs.st_burst_showcount)1765 sharkd_json_value_anyf("burstcount", "%d", node->max_burst);1766 else1767 sharkd_json_value_anyf("burstrate", "%.4f", ((double)node->max_burst) / prefs.st_burst_windowlen);1768 1769 sharkd_json_value_anyf("bursttime", "%.3f", (node->burst_time / 1000.0));1770 }1771 1772 if (node->children)1773 {1774 sharkd_session_process_tap_stats_node_cb("sub", node);1775 }1776 json_dumper_end_object(&dumper);1777 }1778 sharkd_json_array_close();1779}1780 1781/**1782 * sharkd_session_process_tap_stats_cb()1783 *1784 * Output stats tap:1785 *1786 * (m) tap - tap name1787 * (m) type:stats - tap output type1788 * (m) name - stat name1789 * (m) stats - array of object with attributes:1790 * (m) name - stat item name1791 * (m) count - stat item counter1792 * (o) avg - stat item averange value1793 * (o) min - stat item min value1794 * (o) max - stat item max value1795 * (o) rate - stat item rate value (ms)1796 * (o) perc - stat item percentage1797 * (o) burstrate - stat item burst rate1798 * (o) burstcount - stat item burst count1799 * (o) burstttme - stat item burst start1800 * (o) sub - array of object with attributes like in stats node.1801 */1802static void1803sharkd_session_process_tap_stats_cb(void *psp)1804{1805 stats_tree *st = (stats_tree *) psp;1806 1807 json_dumper_begin_object(&dumper);1808 1809 sharkd_json_value_stringf("tap", "stats:%s", st->cfg->abbr);1810 sharkd_json_value_string("type", "stats");1811 sharkd_json_value_string("name", st->cfg->path);1812 1813 sharkd_session_process_tap_stats_node_cb("stats", &st->root);1814 1815 json_dumper_end_object(&dumper);1816}1817 1818static void1819sharkd_session_free_tap_stats_cb(void *psp)1820{1821 stats_tree *st = (stats_tree *) psp;1822 1823 stats_tree_free(st);1824}1825 1826struct sharkd_expert_tap1827{1828 GSList *details;1829 GStringChunk *text;1830};1831 1832/**1833 * sharkd_session_process_tap_expert_cb()1834 *1835 * Output expert tap:1836 *1837 * (m) tap - tap name1838 * (m) type:expert - tap output type1839 * (m) details - array of object with attributes:1840 * (m) f - frame number, which generated expert information1841 * (o) s - severity1842 * (o) g - group1843 * (m) m - expert message1844 * (o) p - protocol1845 */1846static void1847sharkd_session_process_tap_expert_cb(void *tapdata)1848{1849 struct sharkd_expert_tap *etd = (struct sharkd_expert_tap *) tapdata;1850 GSList *list;1851 1852 json_dumper_begin_object(&dumper);1853 1854 sharkd_json_value_string("tap", "expert");1855 sharkd_json_value_string("type", "expert");1856 1857 sharkd_json_array_open("details");1858 for (list = etd->details; list; list = list->next)1859 {1860 expert_info_t *ei = (expert_info_t *) list->data;1861 const char *tmp;1862 1863 json_dumper_begin_object(&dumper);1864 1865 sharkd_json_value_anyf("f", "%u", ei->packet_num);1866 1867 tmp = try_val_to_str(ei->severity, expert_severity_vals);1868 if (tmp)1869 sharkd_json_value_string("s", tmp);1870 1871 tmp = try_val_to_str(ei->group, expert_group_vals);1872 if (tmp)1873 sharkd_json_value_string("g", tmp);1874 1875 sharkd_json_value_string("m", ei->summary);1876 1877 if (ei->protocol)1878 sharkd_json_value_string("p", ei->protocol);1879 1880 json_dumper_end_object(&dumper);1881 }1882 sharkd_json_array_close();1883 1884 json_dumper_end_object(&dumper);1885}1886 1887static tap_packet_status1888sharkd_session_packet_tap_expert_cb(void *tapdata, packet_info *pinfo _U___attribute__((unused)), epan_dissect_t *edt _U___attribute__((unused)), const void *pointer, tap_flags_t flags _U___attribute__((unused)))1889{1890 struct sharkd_expert_tap *etd = (struct sharkd_expert_tap *) tapdata;1891 const expert_info_t *ei = (const expert_info_t *) pointer;1892 expert_info_t *ei_copy;1893 1894 if (ei == NULL((void*)0))1895 return TAP_PACKET_DONT_REDRAW;1896 1897 ei_copy = g_new(expert_info_t, 1)((expert_info_t *) g_malloc_n ((1), sizeof (expert_info_t)));1898 /* Note: this is a shallow copy */1899 *ei_copy = *ei;1900 1901 /* ei->protocol, ei->summary might be allocated in packet scope, make a copy. */1902 ei_copy->protocol = g_string_chunk_insert_const(etd->text, ei_copy->protocol);1903 ei_copy->summary = g_string_chunk_insert_const(etd->text, ei_copy->summary);1904 1905 etd->details = g_slist_prepend(etd->details, ei_copy);1906 1907 return TAP_PACKET_REDRAW;1908}1909 1910static void1911sharkd_session_free_tap_expert_cb(void *tapdata)1912{1913 struct sharkd_expert_tap *etd = (struct sharkd_expert_tap *) tapdata;1914 1915 g_slist_free_full(etd->details, g_free);1916 g_string_chunk_free(etd->text);1917 g_free(etd);1918}1919 1920/**1921 * sharkd_session_process_tap_flow_cb()1922 *1923 * Output flow tap:1924 * (m) tap - tap name1925 * (m) type:flow - tap output type1926 * (m) nodes - array of strings with node address1927 * (m) flows - array of object with attributes:1928 * (m) t - frame time string1929 * (m) n - array of two numbers with source node index and destination node index1930 * (m) pn - array of two numbers with source and destination port1931 * (o) c - comment1932 */1933static void1934sharkd_session_process_tap_flow_cb(void *tapdata)1935{1936 seq_analysis_info_t *graph_analysis = (seq_analysis_info_t *) tapdata;1937 GList *flow_list;1938 unsigned i;1939 1940 sequence_analysis_get_nodes(graph_analysis);1941 1942 json_dumper_begin_object(&dumper);1943 sharkd_json_value_stringf("tap", "seqa:%s", graph_analysis->name);1944 sharkd_json_value_string("type", "flow");1945 1946 sharkd_json_array_open("nodes");1947 for (i = 0; i < graph_analysis->num_nodes; i++)1948 {1949 char *addr_str;1950 1951 addr_str = address_to_display(NULL((void*)0), &(graph_analysis->nodes[i]));1952 sharkd_json_value_string(NULL((void*)0), addr_str);1953 wmem_free(NULL((void*)0), addr_str);1954 }1955 sharkd_json_array_close();1956 1957 sharkd_json_array_open("flows");1958 flow_list = g_queue_peek_nth_link(graph_analysis->items, 0);1959 while (flow_list)1960 {1961 seq_analysis_item_t *sai = (seq_analysis_item_t *) flow_list->data;1962 1963 flow_list = g_list_next(flow_list)((flow_list) ? (((GList *)(flow_list))->next) : ((void*)0)
)
;1964 1965 if (!sai->display)1966 continue;1967 1968 json_dumper_begin_object(&dumper);1969 1970 sharkd_json_value_string("t", sai->time_str);1971 sharkd_json_value_anyf("n", "[%u,%u]", sai->src_node, sai->dst_node);1972 sharkd_json_value_anyf("pn", "[%u,%u]", sai->port_src, sai->port_dst);1973 1974 if (sai->comment)1975 sharkd_json_value_string("c", sai->comment);1976 1977 json_dumper_end_object(&dumper);1978 }1979 sharkd_json_array_close();1980 1981 json_dumper_end_object(&dumper);1982}1983 1984static void1985sharkd_session_free_tap_flow_cb(void *tapdata)1986{1987 seq_analysis_info_t *graph_analysis = (seq_analysis_info_t *) tapdata;1988 1989 sequence_analysis_info_free(graph_analysis);1990}1991 1992struct sharkd_conv_tap_data1993{1994 const char *type;1995 conv_hash_t hash;1996 bool_Bool resolve_name;1997 bool_Bool resolve_port;1998};1999 2000static bool_Bool2001sharkd_session_geoip_addr(address *addr, const char *suffix)2002{2003 const mmdb_lookup_t *lookup = NULL((void*)0);2004 bool_Bool with_geoip = false0;2005 char json_key[64];2006 2007 if (addr->type == AT_IPv4)2008 {2009 const ws_in4_addr *ip4 = (const ws_in4_addr *) addr->data;2010 2011 lookup = maxmind_db_lookup_ipv4(ip4);2012 }2013 else if (addr->type == AT_IPv6)2014 {2015 const ws_in6_addr *ip6 = (const ws_in6_addr *) addr->data;2016 2017 lookup = maxmind_db_lookup_ipv6(ip6);2018 }2019 2020 if (!lookup || !lookup->found)2021 return false0;2022 2023 if (lookup->country)2024 {2025 snprintf(json_key, sizeof(json_key), "geoip_country%s", suffix);2026 sharkd_json_value_string(json_key, lookup->country);2027 with_geoip = true1;2028 }2029 2030 if (lookup->country_iso)2031 {2032 snprintf(json_key, sizeof(json_key), "geoip_country_iso%s", suffix);2033 sharkd_json_value_string(json_key, lookup->country_iso);2034 with_geoip = true1;2035 }2036 2037 if (lookup->city)2038 {2039 snprintf(json_key, sizeof(json_key), "geoip_city%s", suffix);2040 sharkd_json_value_string(json_key, lookup->city);2041 with_geoip = true1;2042 }2043 2044 if (lookup->as_org)2045 {2046 snprintf(json_key, sizeof(json_key), "geoip_as_org%s", suffix);2047 sharkd_json_value_string(json_key, lookup->as_org);2048 with_geoip = true1;2049 }2050 2051 if (lookup->as_number > 0)2052 {2053 snprintf(json_key, sizeof(json_key), "geoip_as%s", suffix);2054 sharkd_json_value_anyf(json_key, "%u", lookup->as_number);2055 with_geoip = true1;2056 }2057 2058 if (lookup->latitude >= -90.0 && lookup->latitude <= 90.0)2059 {2060 snprintf(json_key, sizeof(json_key), "geoip_lat%s", suffix);2061 sharkd_json_value_anyf(json_key, "%f", lookup->latitude);2062 with_geoip = true1;2063 }2064 2065 if (lookup->longitude >= -180.0 && lookup->longitude <= 180.0)2066 {2067 snprintf(json_key, sizeof(json_key), "geoip_lon%s", suffix);2068 sharkd_json_value_anyf(json_key, "%f", lookup->longitude);2069 with_geoip = true1;2070 }2071 2072 return with_geoip;2073}2074 2075struct sharkd_analyse_rtp_items2076{2077 uint32_t frame_num;2078 uint32_t sequence_num;2079 2080 double delta;2081 double jitter;2082 double skew;2083 double bandwidth;2084 bool_Bool marker;2085 2086 double arrive_offset;2087 2088 /* from tap_rtp_stat_t */2089 uint32_t flags;2090 uint16_t pt;2091};2092 2093struct sharkd_analyse_rtp2094{2095 const char *tap_name;2096 rtpstream_id_t id;2097 2098 GSList *packets;2099 double start_time;2100 tap_rtp_stat_t statinfo;2101};2102 2103static void2104sharkd_session_process_tap_rtp_free_cb(void *tapdata)2105{2106 struct sharkd_analyse_rtp *rtp_req = (struct sharkd_analyse_rtp *) tapdata;2107 2108 g_slist_free_full(rtp_req->packets, g_free);2109 g_free(rtp_req);2110}2111 2112static tap_packet_status2113sharkd_session_packet_tap_rtp_analyse_cb(void *tapdata, packet_info *pinfo, epan_dissect_t *edt _U___attribute__((unused)), const void *pointer, tap_flags_t flags _U___attribute__((unused)))2114{2115 struct sharkd_analyse_rtp *rtp_req = (struct sharkd_analyse_rtp *) tapdata;2116 const struct _rtp_info *rtp_info = (const struct _rtp_info *) pointer;2117 2118 if (rtpstream_id_equal_pinfo_rtp_info(&rtp_req->id, pinfo, rtp_info))2119 {2120 tap_rtp_stat_t *statinfo = &(rtp_req->statinfo);2121 struct sharkd_analyse_rtp_items *item;2122 2123 rtppacket_analyse(statinfo, pinfo, rtp_info);2124 2125 item = g_new(struct sharkd_analyse_rtp_items, 1)((struct sharkd_analyse_rtp_items *) g_malloc_n ((1), sizeof (
struct sharkd_analyse_rtp_items)))
;2126 2127 if (!rtp_req->packets)2128 rtp_req->start_time = nstime_to_sec(&pinfo->abs_ts);2129 2130 item->frame_num = pinfo->num;2131 item->sequence_num = rtp_info->info_seq_num;2132 item->delta = (statinfo->flags & STAT_FLAG_FIRST0x001) ? 0.0 : statinfo->delta;2133 item->jitter = (statinfo->flags & STAT_FLAG_FIRST0x001) ? 0.0 : statinfo->jitter;2134 item->skew = (statinfo->flags & STAT_FLAG_FIRST0x001) ? 0.0 : statinfo->skew;2135 item->bandwidth = statinfo->bandwidth;2136 item->marker = rtp_info->info_marker_set ? true1 : false0;2137 item->arrive_offset= nstime_to_sec(&pinfo->abs_ts) - rtp_req->start_time;2138 2139 item->flags = statinfo->flags;2140 item->pt = statinfo->pt;2141 2142 /* XXX, O(n) optimize */2143 rtp_req->packets = g_slist_append(rtp_req->packets, item);2144 }2145 2146 return TAP_PACKET_REDRAW;2147}2148 2149/**2150 * sharkd_session_process_tap_rtp_analyse_cb()2151 *2152 * Output rtp analyse tap:2153 * (m) tap - tap name2154 * (m) type - tap output type2155 * (m) ssrc - RTP SSRC2156 * (m) max_delta - Max delta (ms)2157 * (m) max_delta_nr - Max delta packet #2158 * (m) max_jitter - Max jitter (ms)2159 * (m) mean_jitter - Mean jitter (ms)2160 * (m) max_skew - Max skew (ms)2161 * (m) total_nr - Total number of RTP packets2162 * (m) seq_err - Number of sequence errors2163 * (m) duration - Duration (ms)2164 * (m) items - array of object with attributes:2165 * (m) f - frame number2166 * (m) o - arrive offset2167 * (m) sn - sequence number2168 * (m) d - delta2169 * (m) j - jitter2170 * (m) sk - skew2171 * (m) bw - bandwidth2172 * (o) s - status string2173 * (o) t - status type2174 * (o) mark - rtp mark2175 */2176static void2177sharkd_session_process_tap_rtp_analyse_cb(void *tapdata)2178{2179 const int RTP_TYPE_CN = 1;2180 const int RTP_TYPE_ERROR = 2;2181 const int RTP_TYPE_WARN = 3;2182 const int RTP_TYPE_PT_EVENT = 4;2183 2184 const struct sharkd_analyse_rtp *rtp_req = (struct sharkd_analyse_rtp *) tapdata;2185 const tap_rtp_stat_t *statinfo = &rtp_req->statinfo;2186 2187 GSList *l;2188 2189 json_dumper_begin_object(&dumper);2190 2191 sharkd_json_value_string("tap", rtp_req->tap_name);2192 sharkd_json_value_string("type", "rtp-analyse");2193 sharkd_json_value_stringf("ssrc", "0x%x", rtp_req->id.ssrc);2194 2195 sharkd_json_value_anyf("max_delta", "%f", statinfo->max_delta);2196 sharkd_json_value_anyf("max_delta_nr", "%u", statinfo->max_nr);2197 sharkd_json_value_anyf("max_jitter", "%f", statinfo->max_jitter);2198 sharkd_json_value_anyf("mean_jitter", "%f", statinfo->mean_jitter);2199 sharkd_json_value_anyf("max_skew", "%f", statinfo->max_skew);2200 sharkd_json_value_anyf("total_nr", "%u", statinfo->total_nr);2201 sharkd_json_value_anyf("seq_err", "%u", statinfo->sequence);2202 sharkd_json_value_anyf("duration", "%f", statinfo->time - statinfo->start_time);2203 2204 sharkd_json_array_open("items");2205 for (l = rtp_req->packets; l; l = l->next)2206 {2207 struct sharkd_analyse_rtp_items *item = (struct sharkd_analyse_rtp_items *) l->data;2208 2209 json_dumper_begin_object(&dumper);2210 2211 sharkd_json_value_anyf("f", "%u", item->frame_num);2212 sharkd_json_value_anyf("o", "%.9f", item->arrive_offset);2213 sharkd_json_value_anyf("sn", "%u", item->sequence_num);2214 sharkd_json_value_anyf("d", "%.2f", item->delta);2215 sharkd_json_value_anyf("j", "%.2f", item->jitter);2216 sharkd_json_value_anyf("sk", "%.2f", item->skew);2217 sharkd_json_value_anyf("bw", "%.2f", item->bandwidth);2218 2219 if (item->pt == PT_CN13)2220 {2221 sharkd_json_value_string("s", "Comfort noise (PT=13, RFC 3389)");2222 sharkd_json_value_anyf("t", "%d", RTP_TYPE_CN);2223 }2224 else if (item->pt == PT_CN_OLD19)2225 {2226 sharkd_json_value_string("s", "Comfort noise (PT=19, reserved)");2227 sharkd_json_value_anyf("t", "%d", RTP_TYPE_CN);2228 }2229 else if (item->flags & STAT_FLAG_WRONG_SEQ0x004)2230 {2231 sharkd_json_value_string("s", "Wrong sequence number");2232 sharkd_json_value_anyf("t", "%d", RTP_TYPE_ERROR);2233 }2234 else if (item->flags & STAT_FLAG_DUP_PKT0x200)2235 {2236 sharkd_json_value_string("s", "Suspected duplicate (MAC address) only delta time calculated");2237 sharkd_json_value_anyf("t", "%d", RTP_TYPE_WARN);2238 }2239 else if (item->flags & STAT_FLAG_REG_PT_CHANGE0x040)2240 {2241 sharkd_json_value_stringf("s", "Payload changed to PT=%u%s",2242 item->pt,2243 (item->flags & STAT_FLAG_PT_T_EVENT0x100) ? " telephone/event" : "");2244 sharkd_json_value_anyf("t", "%d", RTP_TYPE_WARN);2245 }2246 else if (item->flags & STAT_FLAG_WRONG_TIMESTAMP0x080)2247 {2248 sharkd_json_value_string("s", "Incorrect timestamp");2249 sharkd_json_value_anyf("t", "%d", RTP_TYPE_WARN);2250 }2251 else if ((item->flags & STAT_FLAG_PT_CHANGE0x008)2252 && !(item->flags & STAT_FLAG_FIRST0x001)2253 && !(item->flags & STAT_FLAG_PT_CN0x010)2254 && (item->flags & STAT_FLAG_FOLLOW_PT_CN0x020)2255 && !(item->flags & STAT_FLAG_MARKER0x002))2256 {2257 sharkd_json_value_string("s", "Marker missing?");2258 sharkd_json_value_anyf("t", "%d", RTP_TYPE_WARN);2259 }2260 else if (item->flags & STAT_FLAG_PT_T_EVENT0x100)2261 {2262 sharkd_json_value_stringf("s", "PT=%u telephone/event", item->pt);2263 sharkd_json_value_anyf("t", "%d", RTP_TYPE_PT_EVENT);2264 }2265 else if (item->flags & STAT_FLAG_MARKER0x002)2266 {2267 sharkd_json_value_anyf("t", "%d", RTP_TYPE_WARN);2268 }2269 2270 if (item->marker)2271 sharkd_json_value_anyf("mark", "1");2272 2273 json_dumper_end_object(&dumper);2274 }2275 sharkd_json_array_close();2276 2277 json_dumper_end_object(&dumper);2278}2279 2280/**2281 * sharkd_session_process_tap_conv_cb()2282 *2283 * Output conv tap:2284 * (m) tap - tap name2285 * (m) type - tap output type2286 * (m) proto - protocol short name2287 * (o) filter - filter string2288 * (o) geoip - whether GeoIP information is available, boolean2289 *2290 * (o) convs - array of object with attributes:2291 * (m) saddr - source address2292 * (m) daddr - destination address2293 * (o) sport - source port2294 * (o) dport - destination port2295 * (m) txf - TX frame count2296 * (m) txb - TX bytes2297 * (m) rxf - RX frame count2298 * (m) rxb - RX bytes2299 * (m) start - (relative) first packet time2300 * (m) stop - (relative) last packet time2301 * (o) filter - conversation filter2302 *2303 * (o) hosts - array of object with attributes:2304 * (m) host - host address2305 * (o) port - host port2306 * (m) txf - TX frame count2307 * (m) txb - TX bytes2308 * (m) rxf - RX frame count2309 * (m) rxb - RX bytes2310 */2311static void2312sharkd_session_process_tap_conv_cb(void *arg)2313{2314 conv_hash_t *hash = (conv_hash_t *) arg;2315 const struct sharkd_conv_tap_data *iu = (struct sharkd_conv_tap_data *) hash->user_data;2316 const char *proto;2317 int proto_with_port;2318 unsigned i;2319 2320 int with_geoip = 0;2321 2322 json_dumper_begin_object(&dumper);2323 sharkd_json_value_string("tap", iu->type);2324 2325 if (!strncmp(iu->type, "conv:", 5))2326 {2327 sharkd_json_value_string("type", "conv");2328 sharkd_json_array_open("convs");2329 proto = iu->type + 5;2330 }2331 else if (!strncmp(iu->type, "endpt:", 6))2332 {2333 sharkd_json_value_string("type", "host");2334 sharkd_json_array_open("hosts");2335 proto = iu->type + 6;2336 }2337 else2338 {2339 sharkd_json_value_string("type", "err");2340 proto = "";2341 }2342 2343 proto_with_port = (!strcmp(proto, "TCP") || !strcmp(proto, "UDP") || !strcmp(proto, "SCTP"));2344 2345 if (iu->hash.conv_array != NULL((void*)0) && !strncmp(iu->type, "conv:", 5))2346 {2347 for (i = 0; i < iu->hash.conv_array->len; i++)2348 {2349 conv_item_t *iui = &g_array_index(iu->hash.conv_array, conv_item_t, i)(((conv_item_t*) (void *) (iu->hash.conv_array)->data) [
(i)])
;2350 char *src_addr, *dst_addr;2351 char *src_port, *dst_port;2352 char *filter_str;2353 2354 json_dumper_begin_object(&dumper);2355 2356 sharkd_json_value_string("saddr", (src_addr = get_conversation_address(NULL((void*)0), &iui->src_address, iu->resolve_name)));2357 sharkd_json_value_string("daddr", (dst_addr = get_conversation_address(NULL((void*)0), &iui->dst_address, iu->resolve_name)));2358 2359 if (proto_with_port)2360 {2361 sharkd_json_value_string("sport", (src_port = get_conversation_port(NULL((void*)0), iui->src_port, iui->ctype, iu->resolve_port)));2362 sharkd_json_value_string("dport", (dst_port = get_conversation_port(NULL((void*)0), iui->dst_port, iui->ctype, iu->resolve_port)));2363 2364 wmem_free(NULL((void*)0), src_port);2365 wmem_free(NULL((void*)0), dst_port);2366 }2367 2368 sharkd_json_value_anyf("rxf", "%" PRIu64"l" "u", iui->rx_frames);2369 sharkd_json_value_anyf("rxb", "%" PRIu64"l" "u", iui->rx_bytes);2370 2371 sharkd_json_value_anyf("txf", "%" PRIu64"l" "u", iui->tx_frames);2372 sharkd_json_value_anyf("txb", "%" PRIu64"l" "u", iui->tx_bytes);2373 2374 sharkd_json_value_anyf("start", "%.9f", nstime_to_sec(&iui->start_time));2375 sharkd_json_value_anyf("stop", "%.9f", nstime_to_sec(&iui->stop_time));2376 2377 filter_str = get_conversation_filter(iui, CONV_DIR_A_TO_FROM_B);2378 if (filter_str)2379 {2380 sharkd_json_value_string("filter", filter_str);2381 g_free(filter_str);2382 }2383 2384 wmem_free(NULL((void*)0), src_addr);2385 wmem_free(NULL((void*)0), dst_addr);2386 2387 if (sharkd_session_geoip_addr(&(iui->src_address), "1"))2388 with_geoip = 1;2389 if (sharkd_session_geoip_addr(&(iui->dst_address), "2"))2390 with_geoip = 1;2391 2392 json_dumper_end_object(&dumper);2393 }2394 }2395 else if (iu->hash.conv_array != NULL((void*)0) && !strncmp(iu->type, "endpt:", 6))2396 {2397 for (i = 0; i < iu->hash.conv_array->len; i++)2398 {2399 endpoint_item_t *endpoint = &g_array_index(iu->hash.conv_array, endpoint_item_t, i)(((endpoint_item_t*) (void *) (iu->hash.conv_array)->data
) [(i)])
;2400 char *host_str, *port_str;2401 char *filter_str;2402 2403 json_dumper_begin_object(&dumper);2404 2405 sharkd_json_value_string("host", (host_str = get_conversation_address(NULL((void*)0), &endpoint->myaddress, iu->resolve_name)));2406 2407 if (proto_with_port)2408 {2409 sharkd_json_value_string("port", (port_str = get_endpoint_port(NULL((void*)0), endpoint, iu->resolve_port)));2410 2411 wmem_free(NULL((void*)0), port_str);2412 }2413 2414 sharkd_json_value_anyf("rxf", "%" PRIu64"l" "u", endpoint->rx_frames);2415 sharkd_json_value_anyf("rxb", "%" PRIu64"l" "u", endpoint->rx_bytes);2416 2417 sharkd_json_value_anyf("txf", "%" PRIu64"l" "u", endpoint->tx_frames);2418 sharkd_json_value_anyf("txb", "%" PRIu64"l" "u", endpoint->tx_bytes);2419 2420 filter_str = get_endpoint_filter(endpoint);2421 if (filter_str)2422 {2423 sharkd_json_value_string("filter", filter_str);2424 g_free(filter_str);2425 }2426 2427 wmem_free(NULL((void*)0), host_str);2428 2429 if (sharkd_session_geoip_addr(&(endpoint->myaddress), ""))2430 with_geoip = 1;2431 json_dumper_end_object(&dumper);2432 }2433 }2434 sharkd_json_array_close();2435 2436 sharkd_json_value_string("proto", proto);2437 sharkd_json_value_anyf("geoip", with_geoip ? "true" : "false");2438 2439 json_dumper_end_object(&dumper);2440}2441 2442static void2443sharkd_session_free_tap_conv_cb(void *arg)2444{2445 conv_hash_t *hash = (conv_hash_t *) arg;2446 struct sharkd_conv_tap_data *iu = (struct sharkd_conv_tap_data *) hash->user_data;2447 2448 if (!strncmp(iu->type, "conv:", 5))2449 {2450 reset_conversation_table_data(hash);2451 }2452 else if (!strncmp(iu->type, "endpt:", 6))2453 {2454 reset_endpoint_table_data(hash);2455 }2456 2457 g_free(iu);2458}2459 2460/**2461 * sharkd_session_process_tap_nstat_cb()2462 *2463 * Output nstat tap:2464 * (m) tap - tap name2465 * (m) type - tap output type2466 * (m) fields: array of objects with attributes:2467 * (m) c - name2468 *2469 * (m) tables: array of object with attributes:2470 * (m) t - table title2471 * (m) i - array of items2472 */2473static void2474sharkd_session_process_tap_nstat_cb(void *arg)2475{2476 stat_data_t *stat_data = (stat_data_t *) arg;2477 unsigned i, j, k;2478 2479 json_dumper_begin_object(&dumper);2480 sharkd_json_value_stringf("tap", "nstat:%s", stat_data->stat_tap_data->cli_string);2481 sharkd_json_value_string("type", "nstat");2482 2483 sharkd_json_array_open("fields");2484 for (i = 0; i < stat_data->stat_tap_data->nfields; i++)2485 {2486 stat_tap_table_item *field = &(stat_data->stat_tap_data->fields[i]);2487 2488 json_dumper_begin_object(&dumper);2489 sharkd_json_value_string("c", field->column_name);2490 json_dumper_end_object(&dumper);2491 }2492 sharkd_json_array_close();2493 2494 sharkd_json_array_open("tables");2495 for (i = 0; i < stat_data->stat_tap_data->tables->len; i++)2496 {2497 stat_tap_table *table = g_array_index(stat_data->stat_tap_data->tables, stat_tap_table *, i)(((stat_tap_table **) (void *) (stat_data->stat_tap_data->
tables)->data) [(i)])
;2498 2499 json_dumper_begin_object(&dumper);2500 2501 sharkd_json_value_string("t", table->title);2502 2503 sharkd_json_array_open("i");2504 for (j = 0; j < table->num_elements; j++)2505 {2506 stat_tap_table_item_type *field_data;2507 2508 field_data = stat_tap_get_field_data(table, j, 0);2509 if (field_data == NULL((void*)0) || field_data->type == TABLE_ITEM_NONE) /* Nothing for us here */2510 continue;2511 2512 sharkd_json_array_open(NULL((void*)0));2513 for (k = 0; k < table->num_fields; k++)2514 {2515 field_data = stat_tap_get_field_data(table, j, k);2516 2517 switch (field_data->type)2518 {2519 case TABLE_ITEM_UINT:2520 sharkd_json_value_anyf(NULL((void*)0), "%u", field_data->value.uint_value);2521 break;2522 2523 case TABLE_ITEM_INT:2524 sharkd_json_value_anyf(NULL((void*)0), "%d", field_data->value.int_value);2525 break;2526 2527 case TABLE_ITEM_STRING:2528 sharkd_json_value_string(NULL((void*)0), field_data->value.string_value);2529 break;2530 2531 case TABLE_ITEM_FLOAT:2532 sharkd_json_value_anyf(NULL((void*)0), "%f", field_data->value.float_value);2533 break;2534 2535 case TABLE_ITEM_ENUM:2536 sharkd_json_value_anyf(NULL((void*)0), "%d", field_data->value.enum_value);2537 break;2538 2539 case TABLE_ITEM_NONE:2540 sharkd_json_value_anyf(NULL((void*)0), "null");2541 break;2542 }2543 }2544 2545 sharkd_json_array_close();2546 }2547 sharkd_json_array_close();2548 json_dumper_end_object(&dumper);2549 }2550 sharkd_json_array_close();2551 2552 json_dumper_end_object(&dumper);2553}2554 2555static void2556sharkd_session_free_tap_nstat_cb(void *arg)2557{2558 stat_data_t *stat_data = (stat_data_t *) arg;2559 2560 free_stat_tables(stat_data->stat_tap_data);2561}2562 2563/**2564 * sharkd_session_process_tap_rtd_cb()2565 *2566 * Output rtd tap:2567 * (m) tap - tap name2568 * (m) type - tap output type2569 * (m) stats - statistics rows - array object with attributes:2570 * (m) type - statistic name2571 * (m) num - number of messages2572 * (m) min - minimum SRT time2573 * (m) max - maximum SRT time2574 * (m) tot - total SRT time2575 * (m) min_frame - minimal SRT2576 * (m) max_frame - maximum SRT2577 * (o) open_req - Open Requests2578 * (o) disc_rsp - Discarded Responses2579 * (o) req_dup - Duplicated Requests2580 * (o) rsp_dup - Duplicated Responses2581 * (o) open_req - Open Requests2582 * (o) disc_rsp - Discarded Responses2583 * (o) req_dup - Duplicated Requests2584 * (o) rsp_dup - Duplicated Responses2585 */2586static void2587sharkd_session_process_tap_rtd_cb(void *arg)2588{2589 rtd_data_t *rtd_data = (rtd_data_t *) arg;2590 register_rtd_t *rtd = (register_rtd_t *) rtd_data->user_data;2591 2592 unsigned i, j;2593 2594 const char *filter = proto_get_protocol_filter_name(get_rtd_proto_id(rtd));2595 2596 /* XXX, some dissectors are having single table and multiple timestats (mgcp, megaco),2597 * some multiple table and single timestat (radius, h225)2598 * and it seems that value_string is used one for timestamp-ID, other one for table-ID2599 * I wonder how it will gonna work with multiple timestats and multiple tables...2600 * (for usage grep for: register_rtd_table)2601 */2602 const value_string *vs = get_rtd_value_string(rtd);2603 2604 json_dumper_begin_object(&dumper);2605 sharkd_json_value_stringf("tap", "rtd:%s", filter);2606 sharkd_json_value_string("type", "rtd");2607 2608 if (rtd_data->stat_table.num_rtds == 1)2609 {2610 const rtd_timestat *ms = &rtd_data->stat_table.time_stats[0];2611 2612 sharkd_json_value_anyf("open_req", "%u", ms->open_req_num);2613 sharkd_json_value_anyf("disc_rsp", "%u", ms->disc_rsp_num);2614 sharkd_json_value_anyf("req_dup", "%u", ms->req_dup_num);2615 sharkd_json_value_anyf("rsp_dup", "%u", ms->rsp_dup_num);2616 }2617 2618 sharkd_json_array_open("stats");2619 for (i = 0; i < rtd_data->stat_table.num_rtds; i++)2620 {2621 const rtd_timestat *ms = &rtd_data->stat_table.time_stats[i];2622 2623 for (j = 0; j < ms->num_timestat; j++)2624 {2625 const char *type_str;2626 2627 if (ms->rtd[j].num == 0)2628 continue;2629 2630 json_dumper_begin_object(&dumper);2631 2632 if (rtd_data->stat_table.num_rtds == 1)2633 type_str = val_to_str_const(j, vs, "Other"); /* 1 table - description per row */2634 else2635 type_str = val_to_str_const(i, vs, "Other"); /* multiple table - description per table */2636 sharkd_json_value_string("type", type_str);2637 2638 sharkd_json_value_anyf("num", "%u", ms->rtd[j].num);2639 sharkd_json_value_anyf("min", "%.9f", nstime_to_sec(&(ms->rtd[j].min)));2640 sharkd_json_value_anyf("max", "%.9f", nstime_to_sec(&(ms->rtd[j].max)));2641 sharkd_json_value_anyf("tot", "%.9f", nstime_to_sec(&(ms->rtd[j].tot)));2642 sharkd_json_value_anyf("min_frame", "%u", ms->rtd[j].min_num);2643 sharkd_json_value_anyf("max_frame", "%u", ms->rtd[j].max_num);2644 2645 if (rtd_data->stat_table.num_rtds != 1)2646 {2647 /* like in tshark, display it on every row */2648 sharkd_json_value_anyf("open_req", "%u", ms->open_req_num);2649 sharkd_json_value_anyf("disc_rsp", "%u", ms->disc_rsp_num);2650 sharkd_json_value_anyf("req_dup", "%u", ms->req_dup_num);2651 sharkd_json_value_anyf("rsp_dup", "%u", ms->rsp_dup_num);2652 }2653 2654 json_dumper_end_object(&dumper);2655 }2656 }2657 sharkd_json_array_close();2658 2659 json_dumper_end_object(&dumper);2660}2661 2662static void2663sharkd_session_free_tap_rtd_cb(void *arg)2664{2665 rtd_data_t *rtd_data = (rtd_data_t *) arg;2666 2667 free_rtd_table(&rtd_data->stat_table);2668 g_free(rtd_data);2669}2670 2671/**2672 * sharkd_session_process_tap_srt_cb()2673 *2674 * Output srt tap:2675 * (m) tap - tap name2676 * (m) type - tap output type2677 *2678 * (m) tables - array of object with attributes:2679 * (m) n - table name2680 * (m) f - table filter2681 * (o) c - table column name2682 * (m) r - table rows - array object with attributes:2683 * (m) n - row name2684 * (m) idx - procedure index2685 * (m) num - number of events2686 * (m) min - minimum SRT time2687 * (m) max - maximum SRT time2688 * (m) tot - total SRT time2689 */2690static void2691sharkd_session_process_tap_srt_cb(void *arg)2692{2693 srt_data_t *srt_data = (srt_data_t *) arg;2694 register_srt_t *srt = (register_srt_t *) srt_data->user_data;2695 2696 const char *filter = proto_get_protocol_filter_name(get_srt_proto_id(srt));2697 2698 unsigned i;2699 2700 json_dumper_begin_object(&dumper);2701 sharkd_json_value_stringf("tap", "srt:%s", filter);2702 sharkd_json_value_string("type", "srt");2703 2704 sharkd_json_array_open("tables");2705 for (i = 0; i < srt_data->srt_array->len; i++)2706 {2707 /* SRT table */2708 srt_stat_table *rst = g_array_index(srt_data->srt_array, srt_stat_table *, i)(((srt_stat_table **) (void *) (srt_data->srt_array)->data
) [(i)])
;2709 2710 int j;2711 2712 json_dumper_begin_object(&dumper);2713 2714 if (rst->name)2715 sharkd_json_value_string("n", rst->name);2716 else if (rst->short_name)2717 sharkd_json_value_string("n", rst->short_name);2718 else2719 sharkd_json_value_stringf("n", "table%u", i);2720 2721 if (rst->filter_string)2722 sharkd_json_value_string("f", rst->filter_string);2723 2724 if (rst->proc_column_name)2725 sharkd_json_value_string("c", rst->proc_column_name);2726 2727 sharkd_json_array_open("r");2728 for (j = 0; j < rst->num_procs; j++)2729 {2730 /* SRT row */2731 srt_procedure_t *proc = &rst->procedures[j];2732 2733 if (proc->stats.num == 0)2734 continue;2735 2736 json_dumper_begin_object(&dumper);2737 2738 sharkd_json_value_string("n", proc->procedure);2739 2740 if (rst->filter_string)2741 sharkd_json_value_anyf("idx", "%d", proc->proc_index);2742 2743 sharkd_json_value_anyf("num", "%u", proc->stats.num);2744 2745 sharkd_json_value_anyf("min", "%.9f", nstime_to_sec(&proc->stats.min));2746 sharkd_json_value_anyf("max", "%.9f", nstime_to_sec(&proc->stats.max));2747 sharkd_json_value_anyf("tot", "%.9f", nstime_to_sec(&proc->stats.tot));2748 2749 json_dumper_end_object(&dumper);2750 }2751 sharkd_json_array_close();2752 2753 json_dumper_end_object(&dumper);2754 }2755 sharkd_json_array_close();2756 2757 json_dumper_end_object(&dumper);2758}2759 2760static void2761sharkd_session_free_tap_srt_cb(void *arg)2762{2763 srt_data_t *srt_data = (srt_data_t *) arg;2764 register_srt_t *srt = (register_srt_t *) srt_data->user_data;2765 2766 free_srt_table(srt, srt_data->srt_array);2767 g_array_free(srt_data->srt_array, TRUE(!(0)));2768 g_free(srt_data);2769}2770 2771static void2772sharkd_session_process_tap_phs_cb_aux(phs_t *rs)2773{2774 for (; rs; rs = rs->sibling) {2775 if (rs->protocol == -1) {2776 return;2777 }2778 sharkd_json_object_open(NULL((void*)0));2779 sharkd_json_value_string("proto", rs->proto_name);2780 sharkd_json_value_anyf("frames", "%"PRIu32"u", rs->frames);2781 sharkd_json_value_anyf("bytes", "%"PRIu64"l" "u", rs->bytes);2782 if (rs->child != NULL((void*)0) && rs->child->protocol != -1) {2783 sharkd_json_array_open("protos");2784 sharkd_session_process_tap_phs_cb_aux(rs->child);2785 sharkd_json_array_close();2786 }2787 sharkd_json_object_close();2788 }2789}2790 2791/**2792 * sharkd_session_process_tap_phs_cb()2793 *2794 * Output phs tap:2795 * (m) tap - tap name2796 * (m) type - tap output type2797 * (m) filter - tap filter argument2798 * (m) protos - array of proto objects2799 *2800 * proto object:2801 * (m) proto - protocol name2802 * (m) frames - frame count2803 * (m) bytes - bytes count2804 * (o) protos - array of proto objects2805 */2806static void2807sharkd_session_process_tap_phs_cb(void *arg)2808{2809 phs_t *rs = (phs_t *)arg;2810 sharkd_json_object_open(NULL((void*)0));2811 sharkd_json_value_string("tap", "phs");2812 sharkd_json_value_string("type", "phs");2813 sharkd_json_value_string("filter", rs->filter ? rs->filter : "");2814 sharkd_json_array_open("protos");2815 sharkd_session_process_tap_phs_cb_aux(rs);2816 sharkd_json_array_close();2817 sharkd_json_object_close();2818}2819 2820static void2821sharkd_session_free_tap_phs_cb(void *arg)2822{2823 phs_t *rs = (phs_t *)arg;2824 free_phs(rs);2825}2826 2827struct sharkd_export_object_list2828{2829 struct sharkd_export_object_list *next;2830 2831 char *type;2832 const char *proto;2833 GSList *entries;2834};2835 2836static struct sharkd_export_object_list *sharkd_eo_list;2837 2838/**2839 * sharkd_session_process_tap_eo_cb()2840 *2841 * Output eo tap:2842 * (m) tap - tap name2843 * (m) type - tap output type2844 * (m) proto - protocol short name2845 * (m) objects - array of object with attributes:2846 * (m) pkt - packet number2847 * (o) hostname - hostname2848 * (o) type - content type2849 * (o) filename - filename2850 * (m) len - object length2851 * (m) sha1 - object's sha1 sum2852 */2853static void2854sharkd_session_process_tap_eo_cb(void *tapdata)2855{2856 export_object_list_t *tap_object = (export_object_list_t *) tapdata;2857 struct sharkd_export_object_list *object_list = (struct sharkd_export_object_list *) tap_object->gui_data;2858 GSList *slist;2859 int i = 0;2860 char sha1sum_bytes[HASH_SHA1_LENGTH20], *sha1sum_str;2861 2862 json_dumper_begin_object(&dumper);2863 sharkd_json_value_string("tap", object_list->type);2864 sharkd_json_value_string("type", "eo");2865 2866 sharkd_json_value_string("proto", object_list->proto);2867 2868 sharkd_json_array_open("objects");2869 for (slist = object_list->entries; slist; slist = slist->next)2870 {2871 const export_object_entry_t *eo_entry = (export_object_entry_t *) slist->data;2872 2873 json_dumper_begin_object(&dumper);2874 2875 sharkd_json_value_anyf("pkt", "%u", eo_entry->pkt_num);2876 2877 if (eo_entry->hostname)2878 sharkd_json_value_string("hostname", eo_entry->hostname);2879 2880 if (eo_entry->content_type)2881 sharkd_json_value_string("type", eo_entry->content_type);2882 2883 if (eo_entry->filename)2884 sharkd_json_value_string("filename", eo_entry->filename);2885 2886 sharkd_json_value_stringf("_download", "%s_%d", object_list->type, i);2887 2888 sharkd_json_value_anyf("len", "%zu", eo_entry->payload_len);2889 2890 gcry_md_hash_buffer(GCRY_MD_SHA1, sha1sum_bytes, eo_entry->payload_data, eo_entry->payload_len);2891 sha1sum_str = bytes_to_str(NULL, sha1sum_bytes, HASH_SHA1_LENGTH)bytes_to_str_maxlen(((void*)0), sha1sum_bytes, 20, 36);2892 sharkd_json_value_string("sha1", sha1sum_str);2893 g_free(sha1sum_str);2894 2895 json_dumper_end_object(&dumper);2896 2897 i++;2898 }2899 sharkd_json_array_close();2900 2901 json_dumper_end_object(&dumper);2902}2903 2904static void2905sharkd_eo_object_list_add_entry(void *gui_data, export_object_entry_t *entry)2906{2907 struct sharkd_export_object_list *object_list = (struct sharkd_export_object_list *) gui_data;2908 2909 object_list->entries = g_slist_append(object_list->entries, entry);2910}2911 2912static export_object_entry_t *2913sharkd_eo_object_list_get_entry(void *gui_data, int row)2914{2915 struct sharkd_export_object_list *object_list = (struct sharkd_export_object_list *) gui_data;2916 2917 return (export_object_entry_t *) g_slist_nth_data(object_list->entries, row);2918}2919 2920static struct sharkd_export_object_list *2921sharkd_eo_object_list_get_entry_by_type(void *gui_data, const char *tap_type)2922{2923 struct sharkd_export_object_list *object_list = (struct sharkd_export_object_list *) gui_data;2924 for (; object_list; object_list = object_list->next)2925 {2926 if (!strcmp(object_list->type, tap_type))2927 return object_list;2928 }2929 return NULL((void*)0);2930}2931 2932 2933/**2934 * sharkd_session_process_tap_rtp_cb()2935 *2936 * Output RTP streams tap:2937 * (m) tap - tap name2938 * (m) type - tap output type2939 * (m) streams - array of object with attributes:2940 * (m) ssrc - RTP synchronization source identifier2941 * (m) payload - stream payload2942 * (m) saddr - source address2943 * (m) sport - source port2944 * (m) daddr - destination address2945 * (m) dport - destination port2946 * (m) pkts - packets count2947 * (m) max_delta - max delta (ms)2948 * (m) max_jitter - max jitter (ms)2949 * (m) mean_jitter - mean jitter (ms)2950 * (m) expectednr -2951 * (m) totalnr -2952 * (m) problem - if analyser found the problem2953 * (m) ipver - address IP version (4 or 6)2954 */2955static void2956sharkd_session_process_tap_rtp_cb(void *arg)2957{2958 rtpstream_tapinfo_t *rtp_tapinfo = (rtpstream_tapinfo_t *) arg;2959 2960 GList *listx;2961 2962 json_dumper_begin_object(&dumper);2963 sharkd_json_value_string("tap", "rtp-streams");2964 sharkd_json_value_string("type", "rtp-streams");2965 2966 sharkd_json_array_open("streams");2967 for (listx = g_list_first(rtp_tapinfo->strinfo_list); listx; listx = listx->next)2968 {2969 rtpstream_info_t *streaminfo = (rtpstream_info_t *) listx->data;2970 rtpstream_info_calc_t calc;2971 2972 rtpstream_info_calculate(streaminfo, &calc);2973 2974 json_dumper_begin_object(&dumper);2975 2976 sharkd_json_value_stringf("ssrc", "0x%x", calc.ssrc);2977 sharkd_json_value_string("payload", calc.all_payload_type_names);2978 2979 sharkd_json_value_string("saddr", calc.src_addr_str);2980 sharkd_json_value_anyf("sport", "%u", calc.src_port);2981 sharkd_json_value_string("daddr", calc.dst_addr_str);2982 sharkd_json_value_anyf("dport", "%u", calc.dst_port);2983 2984 sharkd_json_value_anyf("start_time", "%f", calc.start_time_ms);2985 sharkd_json_value_anyf("duration", "%f", calc.duration_ms);2986 2987 sharkd_json_value_anyf("pkts", "%u", calc.packet_count);2988 sharkd_json_value_anyf("lost", "%u", calc.lost_num);2989 sharkd_json_value_anyf("lost_percent", "%f", calc.lost_perc);2990 2991 sharkd_json_value_anyf("max_delta", "%f",calc.max_delta);2992 sharkd_json_value_anyf("min_delta", "%f",calc.min_delta);2993 sharkd_json_value_anyf("mean_delta", "%f",calc.mean_delta);2994 sharkd_json_value_anyf("min_jitter", "%f", calc.min_jitter);2995 sharkd_json_value_anyf("max_jitter", "%f", calc.max_jitter);2996 sharkd_json_value_anyf("mean_jitter", "%f", calc.mean_jitter);2997 2998 sharkd_json_value_anyf("expectednr", "%u", calc.packet_expected);2999 sharkd_json_value_anyf("totalnr", "%u", calc.total_nr);3000 3001 sharkd_json_value_anyf("problem", calc.problem ? "true" : "false");3002 3003 /* for filter */3004 sharkd_json_value_anyf("ipver", "%d", (streaminfo->id.src_addr.type == AT_IPv6) ? 6 : 4);3005 3006 rtpstream_info_calc_free(&calc);3007 3008 json_dumper_end_object(&dumper);3009 }3010 sharkd_json_array_close();3011 3012 json_dumper_end_object(&dumper);3013}3014 3015/**3016* sharkd_session_process_tap_multicast_cb()3017*3018* Output UDP Multicast streams tap:3019* (m) tap - tap name3020* (m) type - tap output type3021* (m) bufferThresholdBytes - byte count for a stream where a buffer alarm should be reported3022* (m) burstIntervalMs - analysis interval in milliseconds3023* (m) burstThresholdPackets - count of packets in an interval that should trigger an alarm3024* (m) streams - array of streams with metrics:3025* (m) saddr - source address3026* (m) sport - source port3027* (m) daddr - destination address3028* (m) dport - destination port3029* (m) packets - object group for packet metrics with attributes:3030* (m) number - count of packets in the stream3031* (m) perSecond - average number of packets per seconds in the stream3032* (m) bandwidth - object group for bandwidth metrics with attributes:3033* (m) average - average measured bitrate in the stream3034* (m) max - max measured bitrate in the stream3035* (m) buffer - object group for buffer metrics with attributes:3036* (m) alarms - number of times the stream exceeded the buffer threshold3037* (m) max - highest stream buffer utilization3038* (m) burst - object group for burst metrics with attributes:3039* (m) alarms - number of times the stream exceeded the burst threshold3040* (m) max - most stream packets measured in a burst interval3041*/3042static void3043sharkd_session_process_tap_multicast_cb(void *arg)3044{3045 mcaststream_tapinfo_t *tapinfo = (mcaststream_tapinfo_t *)arg;3046 GList *list_item;3047 char *addr_str;3048 3049 json_dumper_begin_object(&dumper);3050 3051 sharkd_json_value_string("tap", "multicast");3052 sharkd_json_value_string("type", "multicast");3053 3054 sharkd_json_value_anyf("bufferThresholdBytes", "%u", mcast_stream_bufferalarm);3055 sharkd_json_value_anyf("burstIntervalMs", "%u", mcast_stream_burstint);3056 sharkd_json_value_anyf("burstThresholdPackets", "%u", mcast_stream_trigger);3057 3058 sharkd_json_array_open("streams");3059 for (list_item = g_list_first(tapinfo->strinfo_list); list_item; list_item = list_item->next) {3060 mcast_stream_info_t *stream_info = (mcast_stream_info_t *) list_item->data;3061 sharkd_json_object_open(NULL((void*)0));3062 {3063 addr_str = address_to_display(NULL((void*)0), &stream_info->src_addr);3064 sharkd_json_value_string("saddr", addr_str);3065 wmem_free(NULL((void*)0), addr_str);3066 sharkd_json_value_anyf("sport", "%u", stream_info->src_port);3067 addr_str = address_to_display(NULL((void*)0), &stream_info->dest_addr);3068 sharkd_json_value_string("daddr", addr_str);3069 wmem_free(NULL((void*)0), addr_str);3070 sharkd_json_value_anyf("dport", "%u", stream_info->dest_port);3071 sharkd_json_object_open("packets");3072 {3073 sharkd_json_value_anyf("number", "%u", stream_info->npackets);3074 sharkd_json_value_anyf("perSecond", "%f", stream_info->apackets);3075 }3076 sharkd_json_object_close();3077 sharkd_json_object_open("bandwidth");3078 {3079 sharkd_json_value_anyf("average", "%f", stream_info->average_bw);3080 sharkd_json_value_anyf("max", "%f", stream_info->element.maxbw);3081 }3082 sharkd_json_object_close();3083 sharkd_json_object_open("buffer");3084 {3085 sharkd_json_value_anyf("alarms", "%u", stream_info->element.numbuffalarms);3086 sharkd_json_value_anyf("max", "%u", stream_info->element.topbuffusage);3087 }3088 sharkd_json_object_close();3089 sharkd_json_object_open("burst");3090 {3091 sharkd_json_value_anyf("alarms", "%u", stream_info->element.numbursts);3092 sharkd_json_value_anyf("max", "%u", stream_info->element.topburstsize);3093 }3094 sharkd_json_object_close();3095 }3096 sharkd_json_object_close();3097 }3098 sharkd_json_array_close();3099 3100 json_dumper_end_object(&dumper);3101}3102 3103static void3104sharkd_session_process_free_tap_multicast_cb(void *tapdata)3105{3106 mcaststream_tapinfo_t *tapinfo = (mcaststream_tapinfo_t *)tapdata;3107 3108 mcaststream_reset(tapinfo);3109 3110 g_free(tapinfo);3111}3112 3113/**3114 * sharkd_session_process_tap_voip_calls_cb()3115 *3116 * Output VoIP Calls tap:3117 * (m) tap - tap name3118 * (m) type - tap output type3119 * (m) calls - array of objects with attributes:3120 * (m) call - call number3121 * (m) start_time - start timestamp3122 * (m) stop_time - stop timestamp3123 * (m) initial_speaker - address of initial speaker3124 * (m) from - from address3125 * (m) to - to address3126 * (m) protocol - protocol name3127 * (m) packets - packet count3128 * (m) state - state string3129 * (m) comment - comment string3130 */3131static void3132sharkd_session_process_tap_voip_calls_cb(void *arg)3133{3134 voip_calls_tapinfo_t *tapinfo = (voip_calls_tapinfo_t *)arg;3135 char *addr_str;3136 GList *cur_call = g_queue_peek_nth_link(tapinfo->callsinfos, 0);3137 sharkd_json_object_open(NULL((void*)0));3138 sharkd_json_value_string("tap", "voip-calls");3139 sharkd_json_value_string("type", "voip-calls");3140 sharkd_json_array_open("calls");3141 while (cur_call && cur_call->data) {3142 voip_calls_info_t *call_info_ = (voip_calls_info_t*) cur_call->data;3143 sharkd_json_object_open(NULL((void*)0));3144 sharkd_json_value_anyf("call", "%hu", call_info_->call_num);3145 sharkd_json_value_anyf("start_time", "%.6f", nstime_to_sec(&(call_info_->start_rel_ts)));3146 sharkd_json_value_anyf("stop_time", "%.6f", nstime_to_sec(&(call_info_->stop_rel_ts)));3147 addr_str = address_to_display(NULL((void*)0), &(call_info_->initial_speaker));3148 sharkd_json_value_string("initial_speaker", addr_str);3149 wmem_free(NULL((void*)0), addr_str);3150 sharkd_json_value_string("from", call_info_->from_identity);3151 sharkd_json_value_string("to", call_info_->to_identity);3152 sharkd_json_value_string("protocol", ((call_info_->protocol == VOIP_COMMON) && call_info_->protocol_name) ?3153 call_info_->protocol_name : voip_protocol_name[call_info_->protocol]);3154 sharkd_json_value_anyf("packets", "%u", call_info_->npackets);3155 sharkd_json_value_string("state", voip_call_state_name[call_info_->call_state]);3156 sharkd_json_value_string("comment", call_info_->call_comment);3157 sharkd_json_object_close();3158 cur_call = g_list_next(cur_call)((cur_call) ? (((GList *)(cur_call))->next) : ((void*)0));3159 }3160 sharkd_json_array_close();3161 sharkd_json_object_close();3162}3163 3164static void3165sharkd_session_free_tap_voip_calls_cb(void *tapdata)3166{3167 voip_calls_tapinfo_t *tapinfo = (voip_calls_tapinfo_t *)tapdata;3168 voip_calls_remove_all_tap_listeners(tapinfo);3169 if (tapinfo->callsinfos != NULL((void*)0)) {3170 g_queue_free(tapinfo->callsinfos);3171 }3172 if (tapinfo->graph_analysis != NULL((void*)0)) {3173 sequence_analysis_info_free(tapinfo->graph_analysis);3174 }3175 memset(tapinfo, 0, sizeof(*tapinfo));3176}3177 3178 3179struct sharkd_voip_convs_req {3180 voip_calls_tapinfo_t *tapinfo;3181 const char *tap_name;3182};3183 3184/**3185 * sharkd_session_process_tap_voip_convs_cb()3186 *3187 * Output VoIP Conversations tap:3188 * (m) tap - tap name3189 * (m) type - tap output type3190 * (m) convs - array of objects with attributes:3191 * (m) frame - frame number3192 * (m) call - call number3193 * (m) time - timestamp3194 * (m) dst_addr - destination address3195 * (m) dst_port - destination port3196 * (m) src_addr - source address3197 * (m) src_port - source port3198 * (m) label - label string3199 * (m) comment - comment string3200 */3201static void3202sharkd_session_process_tap_voip_convs_cb(void *arg)3203{3204 struct sharkd_voip_convs_req *voip_convs_req = (struct sharkd_voip_convs_req *)arg;3205 voip_calls_tapinfo_t *tapinfo = voip_convs_req->tapinfo;3206 seq_analysis_info_t *sainfo = tapinfo->graph_analysis;3207 char *addr_str;3208 sequence_analysis_list_sort(sainfo);3209 sharkd_json_object_open(NULL((void*)0));3210 sharkd_json_value_string("tap", voip_convs_req->tap_name);3211 sharkd_json_value_string("type", "voip-convs");3212 sharkd_json_array_open("convs");3213 for (GList *cur = g_queue_peek_nth_link(sainfo->items, 0); cur; cur = g_list_next(cur)((cur) ? (((GList *)(cur))->next) : ((void*)0))) {3214 seq_analysis_item_t *sai = (seq_analysis_item_t *) cur->data;3215 if ((voip_conv_sel[sai->conv_num / VOIP_CONV_BITS(sizeof(int) * 8)] & (1 << (sai->conv_num % VOIP_CONV_BITS(sizeof(int) * 8)))) == 0)3216 continue;3217 sharkd_json_object_open(NULL((void*)0));3218 sharkd_json_value_anyf("frame", "%d", sai->frame_number);3219 sharkd_json_value_anyf("call", "%d", sai->conv_num);3220 sharkd_json_value_string("time", sai->time_str);3221 addr_str = address_to_display(NULL((void*)0), &(sai->dst_addr));3222 sharkd_json_value_string("dst_addr", addr_str);3223 wmem_free(NULL((void*)0), addr_str);3224 sharkd_json_value_anyf("dst_port", "%d", sai->port_dst);3225 addr_str = address_to_display(NULL((void*)0), &(sai->src_addr));3226 sharkd_json_value_string("src_addr", addr_str);3227 wmem_free(NULL((void*)0), addr_str);3228 sharkd_json_value_anyf("src_port", "%d", sai->port_src);3229 sharkd_json_value_string("label", sai->frame_label);3230 sharkd_json_value_string("comment", sai->comment);3231 sharkd_json_object_close();3232 }3233 sharkd_json_array_close();3234 sharkd_json_object_close();3235}3236 3237static void3238sharkd_session_free_tap_voip_convs_cb(void *tapdata)3239{3240 struct sharkd_voip_convs_req *voip_convs_req = (struct sharkd_voip_convs_req *)tapdata;3241 voip_calls_tapinfo_t *tapinfo = voip_convs_req->tapinfo;3242 voip_calls_remove_all_tap_listeners(tapinfo);3243 if (tapinfo->callsinfos != NULL((void*)0)) {3244 g_queue_free(tapinfo->callsinfos);3245 }3246 if (tapinfo->graph_analysis != NULL((void*)0)) {3247 sequence_analysis_info_free(tapinfo->graph_analysis);3248 }3249 memset(tapinfo, 0, sizeof(*tapinfo));3250 g_free(voip_convs_req);3251}3252 3253struct sharkd_hosts_req {3254 const char *tap_name;3255 bool_Bool dump_v4;3256 bool_Bool dump_v6;3257};3258 3259static int3260sharkd_session_tap_ipv4_host_compare(const void *a, const void *b)3261{3262 return ws_ascii_strnatcmp(((const hashipv4_t *)a)->name,3263 ((const hashipv4_t *)b)->name);3264}3265 3266static int3267sharkd_session_tap_ipv6_host_compare(const void *a, const void *b)3268{3269 return ws_ascii_strnatcmp(((const hashipv6_t *)a)->name,3270 ((const hashipv6_t *)b)->name);3271}3272 3273static void3274sharkd_session_tap_ipv4_host_print(void *data, void *user_data _U___attribute__((unused)))3275{3276 hashipv4_t *ipv4_hash_table_entry = (hashipv4_t *)data;3277 sharkd_json_object_open(NULL((void*)0));3278 sharkd_json_value_string("name", ipv4_hash_table_entry->name);3279 sharkd_json_value_string("addr", ipv4_hash_table_entry->ip);3280 sharkd_json_object_close();3281}3282 3283static void3284sharkd_session_tap_ipv6_host_print(void *data, void *user_data _U___attribute__((unused)))3285{3286 hashipv6_t *ipv6_hash_table_entry = (hashipv6_t *)data;3287 sharkd_json_object_open(NULL((void*)0));3288 sharkd_json_value_string("name", ipv6_hash_table_entry->name);3289 sharkd_json_value_string("addr", ipv6_hash_table_entry->ip6);3290 sharkd_json_object_close();3291}3292 3293static void3294sharkd_session_tap_ipv4_host_insert_sorted(void *key _U___attribute__((unused)), void *value, void *user_data)3295{3296 hashipv4_t *ipv4_hash_table_entry = (hashipv4_t *)value;3297 GSList **list = (GSList **)user_data;3298 if ((ipv4_hash_table_entry->flags & NAME_RESOLVED(1U<<1))) {3299 *list = g_slist_insert_sorted(*list, ipv4_hash_table_entry, sharkd_session_tap_ipv4_host_compare);3300 }3301}3302 3303static void3304sharkd_session_tap_ipv6_host_insert_sorted(void *key _U___attribute__((unused)), void *value, void *user_data)3305{3306 hashipv6_t *ipv6_hash_table_entry = (hashipv6_t *)value;3307 GSList **list = (GSList **) user_data;3308 if ((ipv6_hash_table_entry->flags & NAME_RESOLVED(1U<<1))) {3309 *list = g_slist_insert_sorted(*list, ipv6_hash_table_entry, sharkd_session_tap_ipv6_host_compare);3310 }3311}3312 3313static void3314sharkd_session_tap_ipv4_hosts_print(void)3315{3316 wmem_map_t *ipv4_hash_table = get_ipv4_hash_table();3317 if (!ipv4_hash_table)3318 return;3319 GSList *list = NULL((void*)0);3320 wmem_map_foreach(ipv4_hash_table, sharkd_session_tap_ipv4_host_insert_sorted, &list);3321 g_slist_foreach(list, sharkd_session_tap_ipv4_host_print, NULL((void*)0));3322 g_slist_free(list);3323}3324 3325static void3326sharkd_session_tap_ipv6_hosts_print(void)3327{3328 wmem_map_t *ipv6_hash_table = get_ipv6_hash_table();3329 if (!ipv6_hash_table)3330 return;3331 GSList *list = NULL((void*)0);3332 wmem_map_foreach(ipv6_hash_table, sharkd_session_tap_ipv6_host_insert_sorted, &list);3333 g_slist_foreach(list, sharkd_session_tap_ipv6_host_print, NULL((void*)0));3334 g_slist_free(list);3335}3336 3337/**3338 * sharkd_session_process_tap_hosts_cb()3339 *3340 * Output Hosts tap:3341 * (m) tap - tap name3342 * (m) type - tap output type3343 * (o) ipv4_hosts - array of objects with attributes:3344 * (m) addr - ipv4 address3345 * (m) name - resolved name of address3346 * (o) ipv6_hosts - array of objects with attributes:3347 * (m) addr - ipv6 address3348 * (m) name - resolved name of address3349 */3350static void3351sharkd_session_process_tap_hosts_cb(void *arg)3352{3353 struct sharkd_hosts_req *hosts_req = (struct sharkd_hosts_req *)arg;3354 sharkd_json_object_open(NULL((void*)0));3355 sharkd_json_value_string("tap", hosts_req->tap_name);3356 sharkd_json_value_string("type", "hosts");3357 if (hosts_req->dump_v4) {3358 sharkd_json_array_open("ipv4_hosts");3359 sharkd_session_tap_ipv4_hosts_print();3360 sharkd_json_array_close();3361 }3362 if (hosts_req->dump_v6) {3363 sharkd_json_array_open("ipv6_hosts");3364 sharkd_session_tap_ipv6_hosts_print();3365 sharkd_json_array_close();3366 }3367 sharkd_json_object_close();3368}3369 3370static void3371sharkd_session_free_tap_hosts_cb(void *tapdata)3372{3373 struct sharkd_hosts_req *hosts_req = (struct sharkd_hosts_req *)tapdata;3374 g_free(hosts_req);3375}3376 3377static GString*3378sharkd_session_eo_register_tap_listener(register_eo_t *eo, const char *tap_type, const char *tap_filter, tap_draw_cb tap_draw, void **ptap_data, GFreeFunc* ptap_free)3379{3380 export_object_list_t *eo_object;3381 struct sharkd_export_object_list *object_list;3382 3383 object_list = sharkd_eo_object_list_get_entry_by_type(sharkd_eo_list, tap_type);3384 if (object_list)3385 {3386 g_slist_free_full(object_list->entries, (GDestroyNotify) eo_free_entry);3387 object_list->entries = NULL((void*)0);3388 }3389 else3390 {3391 object_list = g_new(struct sharkd_export_object_list, 1)((struct sharkd_export_object_list *) g_malloc_n ((1), sizeof
(struct sharkd_export_object_list)))
;3392 object_list->type = g_strdup(tap_type)g_strdup_inline (tap_type);3393 object_list->proto = proto_get_protocol_short_name(find_protocol_by_id(get_eo_proto_id(eo)));3394 object_list->entries = NULL((void*)0);3395 object_list->next = sharkd_eo_list;3396 sharkd_eo_list = object_list;3397 }3398 3399 eo_object = g_new0(export_object_list_t, 1)((export_object_list_t *) g_malloc0_n ((1), sizeof (export_object_list_t
)))
;3400 eo_object->add_entry = sharkd_eo_object_list_add_entry;3401 eo_object->get_entry = sharkd_eo_object_list_get_entry;3402 eo_object->gui_data = (void *) object_list;3403 3404 *ptap_data = eo_object;3405 *ptap_free = g_free; /* need to free only eo_object, object_list need to be kept for potential download */3406 3407 return register_tap_listener(get_eo_tap_listener_name(eo), eo_object, tap_filter, 0, NULL((void*)0), get_eo_packet_func(eo), tap_draw, NULL((void*)0));3408}3409 3410/**3411 * sharkd_session_process_tap()3412 *3413 * Process tap request3414 *3415 * Input:3416 * (m) tap0 - First tap request3417 * (o) tap1...tap15 - Other tap requests3418 *3419 * Output object with attributes:3420 * (m) taps - array of object with attributes:3421 * (m) tap - tap name3422 * (m) type - tap output type3423 * ...3424 * for type:stats see sharkd_session_process_tap_stats_cb()3425 * for type:nstat see sharkd_session_process_tap_nstat_cb()3426 * for type:conv see sharkd_session_process_tap_conv_cb()3427 * for type:host see sharkd_session_process_tap_conv_cb()3428 * for type:rtp-streams see sharkd_session_process_tap_rtp_cb()3429 * for type:rtp-analyse see sharkd_session_process_tap_rtp_analyse_cb()3430 * for type:eo see sharkd_session_process_tap_eo_cb()3431 * for type:expert see sharkd_session_process_tap_expert_cb()3432 * for type:rtd see sharkd_session_process_tap_rtd_cb()3433 * for type:srt see sharkd_session_process_tap_srt_cb()3434 * for type:flow see sharkd_session_process_tap_flow_cb()3435 *3436 * (m) err - error code3437 */3438static void3439sharkd_session_process_tap(char *buf, const jsmntok_t *tokens, int count)3440{3441 void *taps_data[16];3442 GFreeFunc taps_free[16];3443 int taps_count = 0;3444 int i;3445 const char *tap_filter = json_find_attr(buf, tokens, count, "filter");3446 3447 rtpstream_tapinfo_t rtp_tapinfo =3448 { NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0), 0, NULL((void*)0), NULL((void*)0), 0, TAP_ANALYSE, NULL((void*)0), NULL((void*)0), NULL((void*)0), false0, false0};3449 3450 for (i = 0; i < 16; i++)3451 {3452 char tapbuf[32];3453 const char *tok_tap;3454 3455 void *tap_data = NULL((void*)0);3456 GFreeFunc tap_free = NULL((void*)0);3457 GString *tap_error = NULL((void*)0);3458 3459 snprintf(tapbuf, sizeof(tapbuf), "tap%d", i);3460 tok_tap = json_find_attr(buf, tokens, count, tapbuf);3461 if (!tok_tap)3462 break;3463 3464 if (!strncmp(tok_tap, "stat:", 5))3465 {3466 stats_tree_cfg *cfg = stats_tree_get_cfg_by_abbr(tok_tap + 5);3467 stats_tree *st;3468 3469 if (!cfg)3470 {3471 sharkd_json_error(3472 rpcid, -11001, NULL((void*)0),3473 "sharkd_session_process_tap() stat %s not found", tok_tap + 53474 );3475 return;3476 }3477 3478 st = stats_tree_new(cfg, NULL((void*)0), tap_filter);3479 3480 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((void*)0));3481 3482 if (!tap_error && cfg->init)3483 cfg->init(st);3484 3485 tap_data = st;3486 tap_free = sharkd_session_free_tap_stats_cb;3487 }3488 else if (!strcmp(tok_tap, "expert"))3489 {3490 struct sharkd_expert_tap *expert_tap;3491 3492 expert_tap = g_new0(struct sharkd_expert_tap, 1)((struct sharkd_expert_tap *) g_malloc0_n ((1), sizeof (struct
sharkd_expert_tap)))
;3493 expert_tap->text = g_string_chunk_new(100);3494 3495 tap_error = register_tap_listener("expert", expert_tap, tap_filter, 0, NULL((void*)0), sharkd_session_packet_tap_expert_cb, sharkd_session_process_tap_expert_cb, NULL((void*)0));3496 3497 tap_data = expert_tap;3498 tap_free = sharkd_session_free_tap_expert_cb;3499 }3500 else if (!strncmp(tok_tap, "seqa:", 5))3501 {3502 seq_analysis_info_t *graph_analysis;3503 register_analysis_t *analysis;3504 const char *tap_name;3505 tap_packet_cb tap_func;3506 unsigned tap_flags;3507 3508 analysis = sequence_analysis_find_by_name(tok_tap + 5);3509 if (!analysis)3510 {3511 sharkd_json_error(3512 rpcid, -11002, NULL((void*)0),3513 "sharkd_session_process_tap() seq analysis %s not found", tok_tap + 53514 );3515 return;3516 }3517 3518 graph_analysis = sequence_analysis_info_new();3519 graph_analysis->name = tok_tap + 5;3520 /* TODO, make configurable */3521 graph_analysis->any_addr = false0;3522 3523 tap_name = sequence_analysis_get_tap_listener_name(analysis);3524 tap_flags = sequence_analysis_get_tap_flags(analysis);3525 tap_func = sequence_analysis_get_packet_func(analysis);3526 3527 tap_error = register_tap_listener(tap_name, graph_analysis, tap_filter, tap_flags, NULL((void*)0), tap_func, sharkd_session_process_tap_flow_cb, NULL((void*)0));3528 3529 tap_data = graph_analysis;3530 tap_free = sharkd_session_free_tap_flow_cb;3531 }3532 else if (!strncmp(tok_tap, "conv:", 5) || !strncmp(tok_tap, "endpt:", 6))3533 {3534 struct register_ct *ct = NULL((void*)0);3535 const char *ct_tapname;3536 struct sharkd_conv_tap_data *ct_data;3537 tap_packet_cb tap_func = NULL((void*)0);3538 3539 if (!strncmp(tok_tap, "conv:", 5))3540 {3541 ct = get_conversation_by_proto_id(proto_get_id_by_short_name(tok_tap + 5));3542 3543 if (!ct || !(tap_func = get_conversation_packet_func(ct)))3544 {3545 sharkd_json_error(3546 rpcid, -11003, NULL((void*)0),3547 "sharkd_session_process_tap() conv %s not found", tok_tap + 53548 );3549 return;3550 }3551 }3552 else if (!strncmp(tok_tap, "endpt:", 6))3553 {3554 ct = get_conversation_by_proto_id(proto_get_id_by_short_name(tok_tap + 6));3555 3556 if (!ct || !(tap_func = get_endpoint_packet_func(ct)))3557 {3558 sharkd_json_error(3559 rpcid, -11004, NULL((void*)0),3560 "sharkd_session_process_tap() endpt %s not found", tok_tap + 63561 );3562 return;3563 }3564 }3565 else3566 {3567 sharkd_json_error(3568 rpcid, -11005, NULL((void*)0),3569 "sharkd_session_process_tap() conv/endpt(?): %s not found", tok_tap3570 );3571 return;3572 }3573 3574 ct_tapname = proto_get_protocol_filter_name(get_conversation_proto_id(ct));3575 3576 ct_data = g_new0(struct sharkd_conv_tap_data, 1)((struct sharkd_conv_tap_data *) g_malloc0_n ((1), sizeof (struct
sharkd_conv_tap_data)))
;3577 ct_data->type = tok_tap;3578 ct_data->hash.user_data = ct_data;3579 3580 /* XXX: make configurable */3581 ct_data->resolve_name = true1;3582 ct_data->resolve_port = true1;3583 3584 tap_error = register_tap_listener(ct_tapname, &ct_data->hash, tap_filter, 0, NULL((void*)0), tap_func, sharkd_session_process_tap_conv_cb, NULL((void*)0));3585 3586 tap_data = &ct_data->hash;3587 tap_free = sharkd_session_free_tap_conv_cb;3588 }3589 else if (!strncmp(tok_tap, "nstat:", 6))3590 {3591 stat_tap_table_ui *stat_tap = stat_tap_by_name(tok_tap + 6);3592 stat_data_t *stat_data;3593 3594 if (!stat_tap)3595 {3596 sharkd_json_error(3597 rpcid, -11006, NULL((void*)0),3598 "sharkd_session_process_tap() nstat=%s not found", tok_tap + 63599 );3600 return;3601 }3602 3603 stat_tap->stat_tap_init_cb(stat_tap);3604 3605 stat_data = g_new0(stat_data_t, 1)((stat_data_t *) g_malloc0_n ((1), sizeof (stat_data_t)));3606 stat_data->stat_tap_data = stat_tap;3607 stat_data->user_data = NULL((void*)0);3608 3609 tap_error = register_tap_listener(stat_tap->tap_name, stat_data, tap_filter, 0, NULL((void*)0), stat_tap->packet_func, sharkd_session_process_tap_nstat_cb, NULL((void*)0));3610 3611 tap_data = stat_data;3612 tap_free = sharkd_session_free_tap_nstat_cb;3613 }3614 else if (!strncmp(tok_tap, "rtd:", 4))3615 {3616 register_rtd_t *rtd = get_rtd_table_by_name(tok_tap + 4);3617 rtd_data_t *rtd_data;3618 char *err;3619 3620 if (!rtd)3621 {3622 sharkd_json_error(3623 rpcid, -11007, NULL((void*)0),3624 "sharkd_session_process_tap() rtd=%s not found", tok_tap + 43625 );3626 return;3627 }3628 3629 rtd_table_get_filter(rtd, "", &tap_filter, &err);3630 if (err != NULL((void*)0))3631 {3632 sharkd_json_error(3633 rpcid, -11008, NULL((void*)0),3634 "sharkd_session_process_tap() rtd=%s err=%s", tok_tap + 4, err3635 );3636 g_free(err);3637 return;3638 }3639 3640 rtd_data = g_new0(rtd_data_t, 1)((rtd_data_t *) g_malloc0_n ((1), sizeof (rtd_data_t)));3641 rtd_data->user_data = rtd;3642 rtd_table_dissector_init(rtd, &rtd_data->stat_table, NULL((void*)0), NULL((void*)0));3643 3644 tap_error = register_tap_listener(get_rtd_tap_listener_name(rtd), rtd_data, tap_filter, 0, NULL((void*)0), get_rtd_packet_func(rtd), sharkd_session_process_tap_rtd_cb, NULL((void*)0));3645 3646 tap_data = rtd_data;3647 tap_free = sharkd_session_free_tap_rtd_cb;3648 }3649 else if (!strncmp(tok_tap, "srt:", 4))3650 {3651 register_srt_t *srt = get_srt_table_by_name(tok_tap + 4);3652 srt_data_t *srt_data;3653 char *err;3654 3655 if (!srt)3656 {3657 sharkd_json_error(3658 rpcid, -11009, NULL((void*)0),3659 "sharkd_session_process_tap() srt=%s not found", tok_tap + 43660 );3661 return;3662 }3663 3664 srt_table_get_filter(srt, "", &tap_filter, &err);3665 if (err != NULL((void*)0))3666 {3667 sharkd_json_error(3668 rpcid, -11010, NULL((void*)0),3669 "sharkd_session_process_tap() srt=%s err=%s", tok_tap + 4, err3670 );3671 g_free(err);3672 return;3673 }3674 3675 srt_data = g_new0(srt_data_t, 1)((srt_data_t *) g_malloc0_n ((1), sizeof (srt_data_t)));3676 srt_data->srt_array = g_array_new(FALSE(0), TRUE(!(0)), sizeof(srt_stat_table *));3677 srt_data->user_data = srt;3678 srt_table_dissector_init(srt, srt_data->srt_array);3679 3680 tap_error = register_tap_listener(get_srt_tap_listener_name(srt), srt_data, tap_filter, 0, NULL((void*)0), get_srt_packet_func(srt), sharkd_session_process_tap_srt_cb, NULL((void*)0));3681 3682 tap_data = srt_data;3683 tap_free = sharkd_session_free_tap_srt_cb;3684 }3685 else if (!strncmp(tok_tap, "eo:", 3))3686 {3687 register_eo_t *eo = get_eo_by_name(tok_tap + 3);3688 3689 if (!eo)3690 {3691 sharkd_json_error(3692 rpcid, -11011, NULL((void*)0),3693 "sharkd_session_process_tap() eo=%s not found", tok_tap + 33694 );3695 return;3696 }3697 3698 tap_error = sharkd_session_eo_register_tap_listener(eo, tok_tap, tap_filter, sharkd_session_process_tap_eo_cb, &tap_data, &tap_free);3699 3700 /* tap_data & tap_free assigned by sharkd_session_eo_register_tap_listener */3701 }3702 else if (!strcmp(tok_tap, "rtp-streams"))3703 {3704 tap_error = register_tap_listener("rtp", &rtp_tapinfo, tap_filter, 0, rtpstream_reset_cb, rtpstream_packet_cb, sharkd_session_process_tap_rtp_cb, NULL((void*)0));3705 3706 tap_data = &rtp_tapinfo;3707 tap_free = rtpstream_reset_cb;3708 }3709 else if (!strncmp(tok_tap, "rtp-analyse:", 12))3710 {3711 struct sharkd_analyse_rtp *rtp_req;3712 3713 rtp_req = (struct sharkd_analyse_rtp *) g_malloc0(sizeof(*rtp_req));3714 if (!sharkd_rtp_match_init(&rtp_req->id, tok_tap + 12))3715 {3716 rtpstream_id_free(&rtp_req->id);3717 g_free(rtp_req);3718 continue;3719 }3720 3721 rtp_req->tap_name = tok_tap;3722 rtp_req->statinfo.first_packet = true1;3723 rtp_req->statinfo.reg_pt = PT_UNDEFINED-1;3724 3725 tap_error = register_tap_listener("rtp", rtp_req, tap_filter, 0, NULL((void*)0), sharkd_session_packet_tap_rtp_analyse_cb, sharkd_session_process_tap_rtp_analyse_cb, NULL((void*)0));3726 3727 tap_data = rtp_req;3728 tap_free = sharkd_session_process_tap_rtp_free_cb;3729 }3730 else if (!strcmp(tok_tap, "multicast"))3731 {3732 mcaststream_tapinfo_t *mcaststream_tapinfo;3733 mcaststream_tapinfo = (mcaststream_tapinfo_t *) g_malloc0(sizeof(*mcaststream_tapinfo));3734 3735 tap_error = register_tap_listener("udp", mcaststream_tapinfo, tap_filter, 0, NULL((void*)0), mcaststream_packet, sharkd_session_process_tap_multicast_cb, NULL((void*)0));3736 tap_data = mcaststream_tapinfo;3737 tap_free = sharkd_session_process_free_tap_multicast_cb;3738 }3739 else if (!strcmp(tok_tap, "phs"))3740 {3741 phs_t *rs;3742 3743 pc_proto_id = proto_registrar_get_id_byname("pkt_comment");3744 3745 rs = new_phs_t(NULL((void*)0), tap_filter);3746 3747 tap_error = register_tap_listener("frame", rs, tap_filter, TL_REQUIRES_PROTO_TREE0x00000001, NULL((void*)0),3748 protohierstat_packet,3749 sharkd_session_process_tap_phs_cb, NULL((void*)0));3750 3751 tap_data = rs;3752 tap_free = sharkd_session_free_tap_phs_cb;3753 }3754 else if (!strcmp(tok_tap, "voip-calls"))3755 {3756 voip_stat_init_tapinfo();3757 3758 tap_error = register_tap_listener("frame", &tapinfo_, tap_filter, 0, NULL((void*)0), NULL((void*)0), sharkd_session_process_tap_voip_calls_cb, NULL((void*)0));3759 3760 tapinfo_.session = cfile.epan;3761 voip_calls_init_all_taps(&tapinfo_);3762 3763 tap_data = &tapinfo_;3764 tap_free = sharkd_session_free_tap_voip_calls_cb;3765 }3766 else if (!strncmp(tok_tap, "voip-convs:", 11))3767 {3768 int len;3769 unsigned int min, max;3770 struct sharkd_voip_convs_req *voip_convs_req;3771 const char *conv_arg = tok_tap + 11;3772 3773 // parse tok_tap to get which call we are asking for3774 if (*conv_arg == 0) {3775 // set all bits of voip_conv_sel (-1 in binary is all 1's)3776 memset(voip_conv_sel, -1, sizeof(voip_conv_sel));3777 } else {3778 memset(voip_conv_sel, 0, sizeof(voip_conv_sel));3779 3780 while (*conv_arg != 0) {3781 if (*conv_arg == ',') {3782 conv_arg++;3783 }3784 if (sscanf(conv_arg, "%u-%u%n", &min, &max, &len) == 2) {3785 conv_arg += len;3786 } else if (sscanf(conv_arg, "%u%n", &min, &len) == 1) {3787 max = min;3788 conv_arg += len;3789 } else {3790 sharkd_json_error(3791 rpcid, -11014, NULL((void*)0),3792 "sharkd_session_process_tap() voip-convs=%s invalid 'convs' parameter", tok_tap3793 );3794 return;3795 }3796 if (min > max || min >= VOIP_CONV_MAX((sizeof(int) * 8) * ((1<<(sizeof(uint16_t) * 8))/(sizeof
(int) * 8)))
|| max >= VOIP_CONV_MAX((sizeof(int) * 8) * ((1<<(sizeof(uint16_t) * 8))/(sizeof
(int) * 8)))
) {3797 sharkd_json_error(3798 rpcid, -11012, NULL((void*)0),3799 "sharkd_session_process_tap() voip-convs=%s invalid 'convs' number range", tok_tap3800 );3801 return;3802 }3803 for(; min <= max; min++) {3804 voip_conv_sel[min / VOIP_CONV_BITS(sizeof(int) * 8)] |= 1 << (min % VOIP_CONV_BITS(sizeof(int) * 8));3805 }3806 }3807 }3808 3809 voip_stat_init_tapinfo();3810 3811 voip_convs_req = (struct sharkd_voip_convs_req *) g_malloc0(sizeof(*voip_convs_req));3812 voip_convs_req->tapinfo = &tapinfo_;3813 voip_convs_req->tap_name = tok_tap;3814 3815 tap_error = register_tap_listener("frame", voip_convs_req, tap_filter, 0, NULL((void*)0), NULL((void*)0), sharkd_session_process_tap_voip_convs_cb, NULL((void*)0));3816 3817 tapinfo_.session = cfile.epan;3818 voip_calls_init_all_taps(&tapinfo_);3819 3820 tap_data = voip_convs_req;3821 tap_free = sharkd_session_free_tap_voip_convs_cb;3822 }3823 else if (!strncmp(tok_tap, "hosts:", 6))3824 {3825 bool_Bool dump_v4;3826 bool_Bool dump_v6;3827 struct sharkd_hosts_req *hosts_req;3828 const char *proto_arg;3829 char **proto_tokens;3830 int proto_count;3831 3832 proto_arg = tok_tap + 6;3833 3834 if (strlen(proto_arg) == 0) {3835 dump_v4 = true1;3836 dump_v6 = true1;3837 } else {3838 dump_v4 = false0;3839 dump_v6 = false0;3840 3841 proto_tokens = g_strsplit(proto_arg, ",", 0);3842 proto_count = 0;3843 while (proto_tokens[proto_count]) {3844 if (!strcmp("ip", proto_tokens[proto_count]) ||3845 !strcmp("ipv4", proto_tokens[proto_count])) {3846 dump_v4 = true1;3847 } else if (!strcmp("ipv6", proto_tokens[proto_count])) {3848 dump_v6 = true1;3849 } else {3850 g_strfreev(proto_tokens);3851 sharkd_json_error(3852 rpcid, -11015, NULL((void*)0),3853 "sharkd_session_process_tap() hosts=%s invalid 'protos' parameter", tok_tap3854 );3855 return;3856 }3857 proto_count++;3858 }3859 g_strfreev(proto_tokens);3860 }3861 3862 hosts_req = (struct sharkd_hosts_req *)g_malloc0(sizeof(*hosts_req));3863 hosts_req->dump_v4 = dump_v4;3864 hosts_req->dump_v6 = dump_v6;3865 hosts_req->tap_name = tok_tap;3866 3867 tap_error = register_tap_listener("frame", hosts_req, tap_filter, TL_REQUIRES_PROTO_TREE0x00000001, NULL((void*)0), NULL((void*)0), sharkd_session_process_tap_hosts_cb, NULL((void*)0));3868 3869 tap_data = hosts_req;3870 tap_free = sharkd_session_free_tap_hosts_cb;3871 }3872 else3873 {3874 sharkd_json_error(3875 rpcid, -11012, NULL((void*)0),3876 "sharkd_session_process_tap() %s not recognized", tok_tap3877 );3878 return;3879 }3880 3881 if (tap_error)3882 {3883 sharkd_json_error(3884 rpcid, -11013, NULL((void*)0),3885 "sharkd_session_process_tap() name=%s error=%s", tok_tap, tap_error->str3886 );3887 g_string_free(tap_error, TRUE)(__builtin_constant_p ((!(0))) ? (((!(0))) ? (g_string_free) (
(tap_error), ((!(0)))) : g_string_free_and_steal (tap_error))
: (g_string_free) ((tap_error), ((!(0)))))
;3888 if (tap_free)3889 tap_free(tap_data);3890 return;3891 }3892 3893 taps_data[taps_count] = tap_data;3894 taps_free[taps_count] = tap_free;3895 taps_count++;3896 }3897 3898 fprintf(stderrstderr, "sharkd_session_process_tap() count=%d\n", taps_count);3899 if (taps_count == 0)3900 {3901 sharkd_json_result_prologue(rpcid);3902 sharkd_json_array_open("taps");3903 sharkd_json_array_close();3904 sharkd_json_result_epilogue();3905 return;3906 }3907 3908 sharkd_json_result_prologue(rpcid);3909 sharkd_json_array_open("taps");3910 sharkd_retap();3911 sharkd_json_array_close();3912 sharkd_json_result_epilogue();3913 3914 for (i = 0; i < taps_count; i++)3915 {3916 if (taps_data[i])3917 remove_tap_listener(taps_data[i]);3918 3919 if (taps_free[i])3920 taps_free[i](taps_data[i]);3921 }3922}3923 3924/**3925 * sharkd_session_process_follow()3926 *3927 * Process follow request3928 *3929 * Input:3930 * (m) follow - follow protocol request (e.g. HTTP)3931 * (m) filter - filter request (e.g. tcp.stream == 1)3932 * (m) stream - stream index number3933 * (o) sub_stream - follow sub-stream index number (e.g. for HTTP/2 and QUIC streams)3934 *3935 * Output object with attributes:3936 *3937 * (m) err - error code3938 * (m) shost - server host3939 * (m) sport - server port3940 * (m) sbytes - server send bytes count3941 * (m) chost - client host3942 * (m) cport - client port3943 * (m) cbytes - client send bytes count3944 * (o) payloads - array of object with attributes:3945 * (o) s - set if server sent, else client3946 * (m) n - packet number3947 * (m) d - data base64 encoded3948 */3949static void3950sharkd_session_process_follow(char *buf, const jsmntok_t *tokens, int count)3951{3952 const char *tok_follow = json_find_attr(buf, tokens, count, "follow");3953 const char *tok_filter = json_find_attr(buf, tokens, count, "filter");3954 const char *tok_sub_stream = json_find_attr(buf, tokens, count, "sub_stream");3955 3956 register_follow_t *follower;3957 GString *tap_error;3958 3959 follow_info_t *follow_info;3960 const char *host;3961 char *port;3962 3963 follower = get_follow_by_name(tok_follow);3964 if (!follower)3965 {3966 sharkd_json_error(3967 rpcid, -12001, NULL((void*)0),3968 "sharkd_session_process_follow() follower=%s not found", tok_follow3969 );3970 return;3971 }3972 3973 uint64_t substream_id = SUBSTREAM_UNUSED0xFFFFFFFFFFFFFFFFUL;3974 if (tok_sub_stream)3975 {3976 ws_strtou64(tok_sub_stream, NULL((void*)0), &substream_id);3977 }3978 3979 /* follow_reset_stream ? */3980 follow_info = g_new0(follow_info_t, 1)((follow_info_t *) g_malloc0_n ((1), sizeof (follow_info_t)));3981 follow_info->substream_id = substream_id;3982 /* gui_data, filter_out_filter not set, but not used by dissector */3983 3984 tap_error = register_tap_listener(get_follow_tap_string(follower), follow_info, tok_filter, 0, NULL((void*)0), get_follow_tap_handler(follower), NULL((void*)0), NULL((void*)0));3985 if (tap_error)3986 {3987 sharkd_json_error(3988 rpcid, -12002, NULL((void*)0),3989 "sharkd_session_process_follow() name=%s error=%s", tok_follow, tap_error->str3990 );3991 g_string_free(tap_error, TRUE)(__builtin_constant_p ((!(0))) ? (((!(0))) ? (g_string_free) (
(tap_error), ((!(0)))) : g_string_free_and_steal (tap_error))
: (g_string_free) ((tap_error), ((!(0)))))
;3992 g_free(follow_info);3993 return;3994 }3995 3996 sharkd_retap();3997 3998 sharkd_json_result_prologue(rpcid);3999 4000 /* Server information: hostname, port, bytes sent */4001 host = address_to_name(&follow_info->server_ip);4002 sharkd_json_value_string("shost", host);4003 4004 port = get_follow_port_to_display(follower)(NULL((void*)0), follow_info->server_port);4005 sharkd_json_value_string("sport", port);4006 wmem_free(NULL((void*)0), port);4007 4008 sharkd_json_value_anyf("sbytes", "%u", follow_info->bytes_written[0]);4009 4010 /* Client information: hostname, port, bytes sent */4011 host = address_to_name(&follow_info->client_ip);4012 sharkd_json_value_string("chost", host);4013 4014 port = get_follow_port_to_display(follower)(NULL((void*)0), follow_info->client_port);4015 sharkd_json_value_string("cport", port);4016 wmem_free(NULL((void*)0), port);4017 4018 sharkd_json_value_anyf("cbytes", "%u", follow_info->bytes_written[1]);4019 4020 if (follow_info->payload)4021 {4022 follow_record_t *follow_record;4023 GList *cur;4024 4025 sharkd_json_array_open("payloads");4026 for (cur = g_list_last(follow_info->payload); cur; cur = g_list_previous(cur)((cur) ? (((GList *)(cur))->prev) : ((void*)0)))4027 {4028 follow_record = (follow_record_t *) cur->data;4029 4030 json_dumper_begin_object(&dumper);4031 4032 sharkd_json_value_anyf("n", "%u", follow_record->packet_num);4033 sharkd_json_value_base64("d", follow_record->data->data, follow_record->data->len);4034 4035 if (follow_record->is_server)4036 sharkd_json_value_anyf("s", "%d", 1);4037 4038 json_dumper_end_object(&dumper);4039 }4040 sharkd_json_array_close();4041 }4042 4043 sharkd_json_result_epilogue();4044 4045 remove_tap_listener(follow_info);4046 follow_info_free(follow_info);4047}4048 4049static void4050sharkd_session_process_frame_cb_tree(const char *key, epan_dissect_t *edt, proto_tree *tree, tvbuff_t **tvbs, bool_Bool display_hidden)4051{4052 proto_node *node;4053 4054 sharkd_json_array_open(key);4055 for (node = tree->first_child; node; node = node->next)4056 {4057 field_info *finfo = PNODE_FINFO(node)((node)->finfo);4058 4059 if (!finfo)4060 continue;4061 4062 if (!display_hidden && FI_GET_FLAG(finfo, FI_HIDDEN)((finfo) ? ((finfo)->flags & (0x00000001)) : 0))4063 continue;4064 4065 json_dumper_begin_object(&dumper);4066 4067 if (!finfo->rep)4068 {4069 char label_str[ITEM_LABEL_LENGTH240];4070 4071 label_str[0] = '\0';4072 proto_item_fill_label(finfo, label_str);4073 sharkd_json_value_string("l", label_str);4074 }4075 else4076 {4077 sharkd_json_value_string("l", finfo->rep->representation);4078 }4079 4080 if (finfo->ds_tvb && tvbs && tvbs[0] != finfo->ds_tvb)4081 {4082 int idx;4083 4084 for (idx = 1; tvbs[idx]; idx++)4085 {4086 if (tvbs[idx] == finfo->ds_tvb)4087 {4088 sharkd_json_value_anyf("ds", "%d", idx);4089 break;4090 }4091 }4092 }4093 4094 if (finfo->start >= 0 && finfo->length > 0)4095 sharkd_json_value_anyf("h", "[%d,%d]", finfo->start, finfo->length);4096 4097 if (finfo->appendix_start >= 0 && finfo->appendix_length > 0)4098 sharkd_json_value_anyf("i", "[%d,%d]", finfo->appendix_start, finfo->appendix_length);4099 4100 4101 if (finfo->hfinfo)4102 {4103 char *filter;4104 4105 if (finfo->hfinfo->type == FT_PROTOCOL)4106 {4107 sharkd_json_value_string("t", "proto");4108 }4109 else if (finfo->hfinfo->type == FT_FRAMENUM)4110 {4111 sharkd_json_value_string("t", "framenum");4112 sharkd_json_value_anyf("fnum", "%u", fvalue_get_uinteger(finfo->value));4113 }4114 else if (FI_GET_FLAG(finfo, FI_URL)((finfo) ? ((finfo)->flags & (0x00000004)) : 0) && FT_IS_STRING(finfo->hfinfo->type)((finfo->hfinfo->type) == FT_STRING || (finfo->hfinfo
->type) == FT_STRINGZ || (finfo->hfinfo->type) == FT_STRINGZPAD
|| (finfo->hfinfo->type) == FT_STRINGZTRUNC || (finfo->
hfinfo->type) == FT_UINT_STRING || (finfo->hfinfo->type
) == FT_AX25)
)4115 {4116 char *url = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DISPLAY, finfo->hfinfo->display);4117 4118 sharkd_json_value_string("t", "url");4119 sharkd_json_value_string("url", url);4120 wmem_free(NULL((void*)0), url);4121 }4122 4123 filter = proto_construct_match_selected_string(finfo, edt);4124 if (filter)4125 {4126 sharkd_json_value_string("f", filter);4127 wmem_free(NULL((void*)0), filter);4128 }4129 4130 if (finfo->hfinfo->abbrev)4131 sharkd_json_value_string("fn", finfo->hfinfo->abbrev);4132 }4133 4134 if (FI_GET_FLAG(finfo, FI_GENERATED)((finfo) ? ((finfo)->flags & (0x00000002)) : 0))4135 sharkd_json_value_anyf("g", "true");4136 4137 if (FI_GET_FLAG(finfo, FI_HIDDEN)((finfo) ? ((finfo)->flags & (0x00000001)) : 0))4138 sharkd_json_value_anyf("v", "true");4139 4140 if (FI_GET_FLAG(finfo, PI_SEVERITY_MASK)((finfo) ? ((finfo)->flags & (0x00F00000)) : 0))4141 {4142 const char *severity = try_val_to_str(FI_GET_FLAG(finfo, PI_SEVERITY_MASK)((finfo) ? ((finfo)->flags & (0x00F00000)) : 0), expert_severity_vals);4143 4144 ws_assert(severity != NULL)do { if ((1) && !(severity != ((void*)0))) ws_log_fatal_full
("", LOG_LEVEL_ERROR, "sharkd_session.c", 4144, __func__, "assertion failed: %s"
, "severity != ((void*)0)"); } while (0)
;4145 4146 sharkd_json_value_string("s", severity);4147 }4148 4149 if (((proto_tree *) node)->first_child)4150 {4151 if (finfo->tree_type != -1)4152 sharkd_json_value_anyf("e", "%d", finfo->tree_type);4153 4154 sharkd_session_process_frame_cb_tree("n", edt, (proto_tree *) node, tvbs, display_hidden);4155 }4156 4157 json_dumper_end_object(&dumper);4158 }4159 sharkd_json_array_close();4160}4161 4162static bool_Bool4163sharkd_follower_visit_layers_cb(const void *key _U___attribute__((unused)), void *value, void *user_data)4164{4165 register_follow_t *follower = (register_follow_t *) value;4166 epan_dissect_t *edt = (epan_dissect_t *) user_data;4167 packet_info *pi = &edt->pi;4168 4169 const int proto_id = get_follow_proto_id(follower);4170 4171 uint32_t ignore_stream;4172 uint32_t ignore_sub_stream;4173 4174 if (proto_is_frame_protocol(pi->layers, proto_get_protocol_filter_name(proto_id)))4175 {4176 const char *layer_proto = proto_get_protocol_short_name(find_protocol_by_id(proto_id));4177 char *follow_filter;4178 4179 follow_filter = get_follow_conv_func(follower)(edt, pi, &ignore_stream, &ignore_sub_stream);4180 4181 json_dumper_begin_array(&dumper);4182 json_dumper_value_string(&dumper, layer_proto);4183 json_dumper_value_string(&dumper, follow_filter);4184 json_dumper_end_array(&dumper);4185 4186 g_free(follow_filter);4187 }4188 4189 return false0;4190}4191 4192static bool_Bool4193sharkd_followers_visit_layers_cb(const void *key _U___attribute__((unused)), void *value, void *user_data)4194{4195 register_follow_t *follower = (register_follow_t *) value;4196 epan_dissect_t *edt = (epan_dissect_t *) user_data;4197 packet_info *pi = &edt->pi;4198 4199 const int proto_id = get_follow_proto_id(follower);4200 4201 unsigned stream;4202 unsigned sub_stream;4203 4204 if (proto_is_frame_protocol(pi->layers, proto_get_protocol_filter_name(proto_id)))4205 {4206 const char *layer_proto = proto_get_protocol_short_name(find_protocol_by_id(proto_id));4207 char *follow_filter;4208 4209 follow_filter = get_follow_conv_func(follower)(edt, pi, &stream, &sub_stream);4210 4211 sharkd_json_object_open(NULL((void*)0));4212 sharkd_json_value_string("protocol", layer_proto);4213 sharkd_json_value_string("filter", follow_filter);4214 if (get_follow_stream_count_func(follower) != NULL((void*)0))4215 {4216 sharkd_json_value_anyf("stream", "%u", stream);4217 }4218 if (get_follow_sub_stream_id_func(follower) != NULL((void*)0))4219 {4220 sharkd_json_value_anyf("sub_stream", "%u", sub_stream);4221 }4222 sharkd_json_object_close();4223 4224 g_free(follow_filter);4225 }4226 4227 return false0;4228}4229 4230struct sharkd_frame_request_data4231{4232 bool_Bool display_hidden;4233};4234 4235static void4236sharkd_session_process_frame_cb(epan_dissect_t *edt, proto_tree *tree, struct epan_column_info *cinfo, const GSList *data_src, void *data)4237{4238 packet_info *pi = &edt->pi;4239 frame_data *fdata = pi->fd;4240 wtap_block_t pkt_block = NULL((void*)0);4241 4242 const struct sharkd_frame_request_data * const req_data = (const struct sharkd_frame_request_data * const) data;4243 const bool_Bool display_hidden = (req_data) ? req_data->display_hidden : false0;4244 4245 sharkd_json_result_prologue(rpcid);4246 4247 if (fdata->has_modified_block)4248 pkt_block = sharkd_get_modified_block(fdata);4249 else4250 pkt_block = pi->rec->block;4251 4252 if (pkt_block)4253 {4254 unsigned i;4255 unsigned n;4256 char *comment;4257 4258 n = wtap_block_count_option(pkt_block, OPT_COMMENT1);4259 4260 sharkd_json_array_open("comment");4261 for (i = 0; i < n; i++) {4262 if (WTAP_OPTTYPE_SUCCESS == wtap_block_get_nth_string_option_value(pkt_block, OPT_COMMENT1, i, &comment)) {4263 sharkd_json_value_string(NULL((void*)0), comment);4264 }4265 }4266 sharkd_json_array_close();4267 }4268 4269 if (tree)4270 {4271 tvbuff_t **tvbs = NULL((void*)0);4272 4273 /* arrayize data src, to speedup searching for ds_tvb index */4274 if (data_src && data_src->next /* only needed if there are more than one data source */)4275 {4276 unsigned count = g_slist_length((GSList *) data_src);4277 unsigned i;4278 4279 tvbs = (tvbuff_t **) g_malloc0((count + 1) * sizeof(*tvbs));4280 4281 for (i = 0; i < count; i++)4282 {4283 const struct data_source *src = (const struct data_source *) g_slist_nth_data((GSList *) data_src, i);4284 4285 tvbs[i] = get_data_source_tvb(src);4286 }4287 4288 tvbs[count] = NULL((void*)0);4289 }4290 4291 sharkd_session_process_frame_cb_tree("tree", edt, tree, tvbs, display_hidden);4292 4293 g_free(tvbs);4294 }4295 4296 if (cinfo)4297 {4298 int col;4299 4300 sharkd_json_array_open("col");4301 for (col = 0; col < cinfo->num_cols; ++col)4302 {4303 sharkd_json_value_string(NULL((void*)0), get_column_text(cinfo, col));4304 }4305 sharkd_json_array_close();4306 }4307 4308 if (fdata->ignored)4309 sharkd_json_value_anyf("i", "true");4310 4311 if (fdata->marked)4312 sharkd_json_value_anyf("m", "true");4313 4314 if (fdata->color_filter)4315 {4316 sharkd_json_value_stringf("bg", "%06x", color_t_to_rgb(&fdata->color_filter->bg_color));4317 sharkd_json_value_stringf("fg", "%06x", color_t_to_rgb(&fdata->color_filter->fg_color));4318 }4319 4320 if (data_src)4321 {4322 struct data_source *src = (struct data_source *) data_src->data;4323 bool_Bool ds_open = false0;4324 4325 tvbuff_t *tvb;4326 unsigned length;4327 4328 tvb = get_data_source_tvb(src);4329 length = tvb_captured_length(tvb);4330 4331 if (length != 0)4332 {4333 const unsigned char *cp = tvb_get_ptr(tvb, 0, length);4334 4335 /* XXX pi.fd->encoding */4336 sharkd_json_value_base64("bytes", cp, length);4337 }4338 else4339 {4340 sharkd_json_value_base64("bytes", "", 0);4341 }4342 4343 data_src = data_src->next;4344 if (data_src)4345 {4346 sharkd_json_array_open("ds");4347 ds_open = true1;4348 }4349 4350 while (data_src)4351 {4352 src = (struct data_source *) data_src->data;4353 4354 json_dumper_begin_object(&dumper);4355 4356 {4357 char *src_name = get_data_source_name(src);4358 4359 sharkd_json_value_string("name", src_name);4360 wmem_free(NULL((void*)0), src_name);4361 }4362 4363 tvb = get_data_source_tvb(src);4364 length = tvb_captured_length(tvb);4365 4366 if (length != 0)4367 {4368 const unsigned char *cp = tvb_get_ptr(tvb, 0, length);4369 4370 /* XXX pi.fd->encoding */4371 sharkd_json_value_base64("bytes", cp, length);4372 }4373 else4374 {4375 sharkd_json_value_base64("bytes", "", 0);4376 }4377 4378 json_dumper_end_object(&dumper);4379 4380 data_src = data_src->next;4381 }4382 4383 /* close ds, only if was opened */4384 if (ds_open)4385 sharkd_json_array_close();4386 }4387 4388 sharkd_json_array_open("fol");4389 follow_iterate_followers(sharkd_follower_visit_layers_cb, edt);4390 sharkd_json_array_close();4391 4392 sharkd_json_array_open("followers");4393 follow_iterate_followers(sharkd_followers_visit_layers_cb, edt);4394 sharkd_json_array_close();4395 4396 sharkd_json_result_epilogue();4397}4398 4399#define SHARKD_IOGRAPH_MAX_ITEMS1 << 25 1 << 25 /* 33,554,432 limit of items, same as max_io_items_ in ui/qt/io_graph_dialog.h */4400 4401struct sharkd_iograph4402{4403 /* config */4404 int hf_index;4405 io_graph_item_unit_t calc_type;4406 uint32_t interval;4407 4408 /* result */4409 int space_items;4410 int num_items;4411 io_graph_item_t *items;4412 GString *error;4413};4414 4415static tap_packet_status4416sharkd_iograph_packet(void *g, packet_info *pinfo, epan_dissect_t *edt, const void *dummy _U___attribute__((unused)), tap_flags_t flags _U___attribute__((unused)))4417{4418 struct sharkd_iograph *graph = (struct sharkd_iograph *) g;4419 int idx;4420 bool_Bool update_succeeded;4421 4422 int64_t tmp_idx = get_io_graph_index(pinfo, graph->interval);4423 if (tmp_idx < 0 || tmp_idx >= SHARKD_IOGRAPH_MAX_ITEMS1 << 25)

1

Assuming 'tmp_idx' is >= 0

2

Assuming the condition is false

4424 return TAP_PACKET_DONT_REDRAW;4425 4426 idx = (int)tmp_idx;4427 4428 if (idx + 1 > graph->num_items)

4

Assuming the condition is true

5

Taking true branch

4429 {4430 if (idx + 1 > graph->space_items)

6

Assuming the condition is false

7

Taking false branch

4431 {4432 int new_size = idx + 1024;4433 4434 graph->items = (io_graph_item_t *) g_realloc(graph->items, sizeof(io_graph_item_t) * new_size);4435 reset_io_graph_items(&graph->items[graph->space_items], new_size - graph->space_items, graph->hf_index);4436 4437 graph->space_items = new_size;4438 }4439 else if (graph->items == NULL((void*)0))

8

Assuming field 'items' is equal to NULL

9

Taking true branch

4440 {4441 graph->items = g_new(io_graph_item_t, graph->space_items)((io_graph_item_t *) g_malloc_n ((graph->space_items), sizeof
(io_graph_item_t)))
;

10

Uninitialized value stored to field 'first_frame_in_invl'

4442 reset_io_graph_items(graph->items, graph->space_items, graph->hf_index);

11

Calling 'reset_io_graph_items'

14

Returning from 'reset_io_graph_items'

4443 }4444 4445 graph->num_items = idx + 1;4446 }4447 4448 update_succeeded = update_io_graph_item(graph->items, idx, pinfo, edt, graph->hf_index, graph->calc_type, graph->interval);

15

Calling 'update_io_graph_item'

4449 /* XXX - TAP_PACKET_FAILED if the item couldn't be updated, with an error message? */4450 return update_succeeded ? TAP_PACKET_REDRAW : TAP_PACKET_DONT_REDRAW;4451}4452 4453/**4454 * sharkd_session_process_iograph()4455 *4456 * Process iograph request4457 *4458 * Input:4459 * (o) interval - interval time, if not specified: 10004460 * (o) interval_units - units for interval time, must be 's', 'ms' or 'us', if not specified: ms4461 * (m) graph0 - First graph request4462 * (o) graph1...graph9 - Other graph requests4463 * (o) filter0 - First graph filter4464 * (o) filter1...filter9 - Other graph filters4465 *4466 * Graph requests can be one of: "packets", "bytes", "bits", "sum:<field>", "frames:<field>", "max:<field>", "min:<field>", "avg:<field>", "load:<field>",4467 * if you use variant with <field>, you need to pass field name in filter request.4468 *4469 * Output object with attributes:4470 * (m) iograph - array of graph results with attributes:4471 * errmsg - graph cannot be constructed4472 * items - graph values, zeros are skipped, if value is not a number it's next index encoded as hex string4473 */4474static void4475sharkd_session_process_iograph(char *buf, const jsmntok_t *tokens, int count)4476{4477 const char *tok_interval = json_find_attr(buf, tokens, count, "interval");4478 const char *tok_interval_units = json_find_attr(buf, tokens, count, "interval_units");4479 struct sharkd_iograph graphs[10];4480 bool_Bool is_any_ok = false0;4481 int graph_count;4482 4483 int i;4484 4485 /* default: 1000ms = one per second */4486 uint32_t interval = 1000;4487 const char *interval_units = "ms";4488 4489 if (tok_interval)4490 ws_strtou32(tok_interval, NULL((void*)0), &interval);4491 4492 if (tok_interval_units)4493 {4494 if (strcmp(tok_interval_units, "us") != 0 &&4495 strcmp(tok_interval_units, "ms") != 0 &&4496 strcmp(tok_interval_units, "s") != 0)4497 {4498 sharkd_json_error(4499 rpcid, -7003, NULL((void*)0),4500 "Invalid interval_units parameter: '%s', must be 's', 'ms' or 'us'", tok_interval_units4501 );4502 return;4503 }4504 interval_units = tok_interval_units;4505 }4506 4507 uint32_t interval_us = 0;4508 if (strcmp(interval_units, "us") == 0)4509 {4510 interval_us = interval;4511 }4512 else if (strcmp(interval_units, "ms") == 0)4513 {4514 interval_us = 1000 * interval;4515 }4516 else if (strcmp(interval_units, "s") == 0)4517 {4518 interval_us = 1000000 * interval;4519 }4520 4521 for (i = graph_count = 0; i < (int) G_N_ELEMENTS(graphs)(sizeof (graphs) / sizeof ((graphs)[0])); i++)4522 {4523 struct sharkd_iograph *graph = &graphs[graph_count];4524 4525 const char *tok_graph;4526 const char *tok_filter;4527 char tok_format_buf[32];4528 const char *field_name;4529 4530 snprintf(tok_format_buf, sizeof(tok_format_buf), "graph%d", i);4531 tok_graph = json_find_attr(buf, tokens, count, tok_format_buf);4532 if (!tok_graph)4533 break;4534 4535 snprintf(tok_format_buf, sizeof(tok_format_buf), "filter%d", i);4536 tok_filter = json_find_attr(buf, tokens, count, tok_format_buf);4537 4538 if (!strcmp(tok_graph, "packets"))4539 graph->calc_type = IOG_ITEM_UNIT_PACKETS;4540 else if (!strcmp(tok_graph, "bytes"))4541 graph->calc_type = IOG_ITEM_UNIT_BYTES;4542 else if (!strcmp(tok_graph, "bits"))4543 graph->calc_type = IOG_ITEM_UNIT_BITS;4544 else if (g_str_has_prefix(tok_graph, "sum:")(__builtin_constant_p ("sum:")? __extension__ ({ const char *
const __str = (tok_graph); const char * const __prefix = ("sum:"
); gboolean __result = (0); if (__str == ((void*)0) || __prefix
== ((void*)0)) __result = (g_str_has_prefix) (__str, __prefix
); else { const size_t __str_len = strlen (((__str) + !(__str
))); const size_t __prefix_len = strlen (((__prefix) + !(__prefix
))); if (__str_len >= __prefix_len) __result = memcmp (((__str
) + !(__str)), ((__prefix) + !(__prefix)), __prefix_len) == 0
; } __result; }) : (g_str_has_prefix) (tok_graph, "sum:") )
)4545 graph->calc_type = IOG_ITEM_UNIT_CALC_SUM;4546 else if (g_str_has_prefix(tok_graph, "frames:")(__builtin_constant_p ("frames:")? __extension__ ({ const char
* const __str = (tok_graph); const char * const __prefix = (
"frames:"); gboolean __result = (0); if (__str == ((void*)0) ||
__prefix == ((void*)0)) __result = (g_str_has_prefix) (__str
, __prefix); else { const size_t __str_len = strlen (((__str)
+ !(__str))); const size_t __prefix_len = strlen (((__prefix
) + !(__prefix))); if (__str_len >= __prefix_len) __result
= memcmp (((__str) + !(__str)), ((__prefix) + !(__prefix)), __prefix_len
) == 0; } __result; }) : (g_str_has_prefix) (tok_graph, "frames:"
) )
)4547 graph->calc_type = IOG_ITEM_UNIT_CALC_FRAMES;4548 else if (g_str_has_prefix(tok_graph, "fields:")(__builtin_constant_p ("fields:")? __extension__ ({ const char
* const __str = (tok_graph); const char * const __prefix = (
"fields:"); gboolean __result = (0); if (__str == ((void*)0) ||
__prefix == ((void*)0)) __result = (g_str_has_prefix) (__str
, __prefix); else { const size_t __str_len = strlen (((__str)
+ !(__str))); const size_t __prefix_len = strlen (((__prefix
) + !(__prefix))); if (__str_len >= __prefix_len) __result
= memcmp (((__str) + !(__str)), ((__prefix) + !(__prefix)), __prefix_len
) == 0; } __result; }) : (g_str_has_prefix) (tok_graph, "fields:"
) )
)4549 graph->calc_type = IOG_ITEM_UNIT_CALC_FIELDS;4550 else if (g_str_has_prefix(tok_graph, "max:")(__builtin_constant_p ("max:")? __extension__ ({ const char *
const __str = (tok_graph); const char * const __prefix = ("max:"
); gboolean __result = (0); if (__str == ((void*)0) || __prefix
== ((void*)0)) __result = (g_str_has_prefix) (__str, __prefix
); else { const size_t __str_len = strlen (((__str) + !(__str
))); const size_t __prefix_len = strlen (((__prefix) + !(__prefix
))); if (__str_len >= __prefix_len) __result = memcmp (((__str
) + !(__str)), ((__prefix) + !(__prefix)), __prefix_len) == 0
; } __result; }) : (g_str_has_prefix) (tok_graph, "max:") )
)4551 graph->calc_type = IOG_ITEM_UNIT_CALC_MAX;4552 else if (g_str_has_prefix(tok_graph, "min:")(__builtin_constant_p ("min:")? __extension__ ({ const char *
const __str = (tok_graph); const char * const __prefix = ("min:"
); gboolean __result = (0); if (__str == ((void*)0) || __prefix
== ((void*)0)) __result = (g_str_has_prefix) (__str, __prefix
); else { const size_t __str_len = strlen (((__str) + !(__str
))); const size_t __prefix_len = strlen (((__prefix) + !(__prefix
))); if (__str_len >= __prefix_len) __result = memcmp (((__str
) + !(__str)), ((__prefix) + !(__prefix)), __prefix_len) == 0
; } __result; }) : (g_str_has_prefix) (tok_graph, "min:") )
)4553 graph->calc_type = IOG_ITEM_UNIT_CALC_MIN;4554 else if (g_str_has_prefix(tok_graph, "avg:")(__builtin_constant_p ("avg:")? __extension__ ({ const char *
const __str = (tok_graph); const char * const __prefix = ("avg:"
); gboolean __result = (0); if (__str == ((void*)0) || __prefix
== ((void*)0)) __result = (g_str_has_prefix) (__str, __prefix
); else { const size_t __str_len = strlen (((__str) + !(__str
))); const size_t __prefix_len = strlen (((__prefix) + !(__prefix
))); if (__str_len >= __prefix_len) __result = memcmp (((__str
) + !(__str)), ((__prefix) + !(__prefix)), __prefix_len) == 0
; } __result; }) : (g_str_has_prefix) (tok_graph, "avg:") )
)4555 graph->calc_type = IOG_ITEM_UNIT_CALC_AVERAGE;4556 else if (g_str_has_prefix(tok_graph, "load:")(__builtin_constant_p ("load:")? __extension__ ({ const char *
const __str = (tok_graph); const char * const __prefix = ("load:"
); gboolean __result = (0); if (__str == ((void*)0) || __prefix
== ((void*)0)) __result = (g_str_has_prefix) (__str, __prefix
); else { const size_t __str_len = strlen (((__str) + !(__str
))); const size_t __prefix_len = strlen (((__prefix) + !(__prefix
))); if (__str_len >= __prefix_len) __result = memcmp (((__str
) + !(__str)), ((__prefix) + !(__prefix)), __prefix_len) == 0
; } __result; }) : (g_str_has_prefix) (tok_graph, "load:") )
)4557 graph->calc_type = IOG_ITEM_UNIT_CALC_LOAD;4558 else4559 break;4560 4561 field_name = strchr(tok_graph, ':');4562 if (field_name)4563 field_name = field_name + 1;4564 4565 /* io_graph_item now supports microseconds (and this parameter4566 * is expected to be in microseconds.) */4567 graph->interval = interval_us;4568 4569 graph->hf_index = -1;4570 graph->error = check_field_unit(field_name, &graph->hf_index, graph->calc_type);4571 4572 graph->space_items = 0; /* TODO, can avoid realloc()s in sharkd_iograph_packet() by calculating: capture_time / interval */4573 graph->num_items = 0;4574 graph->items = NULL((void*)0);4575 4576 if (!graph->error)4577 graph->error = register_tap_listener("frame", graph, tok_filter, TL_REQUIRES_PROTO_TREE0x00000001, NULL((void*)0), sharkd_iograph_packet, NULL((void*)0), NULL((void*)0));4578 4579 graph_count++;4580 4581 if (graph->error)4582 {4583 sharkd_json_error(4584 rpcid, -6001, NULL((void*)0),4585 "%s", graph->error->str4586 );4587 g_string_free(graph->error, TRUE)(__builtin_constant_p ((!(0))) ? (((!(0))) ? (g_string_free) (
(graph->error), ((!(0)))) : g_string_free_and_steal (graph
->error)) : (g_string_free) ((graph->error), ((!(0)))))
;4588 return;4589 }4590 4591 if (graph->error == NULL((void*)0))4592 is_any_ok = true1;4593 }4594 4595 /* retap only if we have at least one ok */4596 if (is_any_ok)4597 sharkd_retap();4598 4599 sharkd_json_result_prologue(rpcid);4600 4601 sharkd_json_array_open("iograph");4602 for (i = 0; i < graph_count; i++)4603 {4604 struct sharkd_iograph *graph = &graphs[i];4605 4606 json_dumper_begin_object(&dumper);4607 4608 if (graph->error)4609 {4610 fprintf(stderrstderr, "SNAP 6002 - we should never get to here.\n");4611 g_string_free(graph->error, TRUE)(__builtin_constant_p ((!(0))) ? (((!(0))) ? (g_string_free) (
(graph->error), ((!(0)))) : g_string_free_and_steal (graph
->error)) : (g_string_free) ((graph->error), ((!(0)))))
;4612 exit(-1);4613 }4614 else4615 {4616 int idx;4617 int next_idx = 0;4618 4619 sharkd_json_array_open("items");4620 for (idx = 0; idx < graph->num_items; idx++)4621 {4622 double val;4623 4624 val = get_io_graph_item(graph->items, graph->calc_type, idx, graph->hf_index, &cfile, graph->interval, graph->num_items);4625 4626 /* if it's zero, don't display */4627 if (val == 0.0)4628 continue;4629 4630 /* cause zeros are not printed, need to output index */4631 if (next_idx != idx)4632 sharkd_json_value_stringf(NULL((void*)0), "%x", idx);4633 4634 sharkd_json_value_anyf(NULL((void*)0), "%f", val);4635 next_idx = idx + 1;4636 }4637 sharkd_json_array_close();4638 }4639 json_dumper_end_object(&dumper);4640 4641 remove_tap_listener(graph);4642 g_free(graph->items);4643 }4644 sharkd_json_array_close();4645 4646 sharkd_json_result_epilogue();4647}4648 4649/**4650 * sharkd_session_process_intervals()4651 *4652 * Process intervals request - generate basic capture file statistics per requested interval.4653 *4654 * Input:4655 * (o) interval - interval time in ms, if not specified: 1000ms4656 * (o) filter - filter for generating interval request4657 *4658 * Output object with attributes:4659 * (m) intervals - array of intervals, with indexes:4660 * [0] - index of interval,4661 * [1] - number of frames during interval,4662 * [2] - number of bytes during interval.4663 *4664 * (m) last - last interval number.4665 * (m) frames - total number of frames4666 * (m) bytes - total number of bytes4667 *4668 * NOTE: If frames are not in order, there might be items with same interval index, or even negative one.4669 */4670static void4671sharkd_session_process_intervals(char *buf, const jsmntok_t *tokens, int count)4672{4673 const char *tok_interval = json_find_attr(buf, tokens, count, "interval");4674 const char *tok_filter = json_find_attr(buf, tokens, count, "filter");4675 4676 const uint8_t *filter_data = NULL((void*)0);4677 4678 struct4679 {4680 unsigned int frames;4681 uint64_t bytes;4682 } st, st_total;4683 4684 nstime_t *start_ts;4685 4686 uint32_t interval_ms = 1000; /* default: one per second */4687 4688 int64_t idx;4689 int64_t max_idx = 0;4690 4691 if (tok_interval)4692 ws_strtou32(tok_interval, NULL((void*)0), &interval_ms); // already validated4693 4694 if (tok_filter)4695 {4696 const struct sharkd_filter_item *filter_item;4697 4698 filter_item = sharkd_session_filter_data(tok_filter);4699 if (!filter_item)4700 {4701 sharkd_json_error(4702 rpcid, -7001, NULL((void*)0),4703 "Invalid filter parameter: %s", tok_filter4704 );4705 return;4706 }4707 filter_data = filter_item->filtered;4708 }4709 4710 st_total.frames = 0;4711 st_total.bytes = 0;4712 4713 st.frames = 0;4714 st.bytes = 0;4715 4716 idx = 0;4717 4718 sharkd_json_result_prologue(rpcid);4719 sharkd_json_array_open("intervals");4720 4721 start_ts = (cfile.count >= 1) ? &(sharkd_get_frame(1)->abs_ts) : NULL((void*)0);4722 4723 for (uint32_t framenum = 1; framenum <= cfile.count; framenum++)4724 {4725 frame_data *fdata;4726 int64_t msec_rel;4727 int64_t new_idx;4728 4729 if (filter_data && !(filter_data[framenum / 8] & (1 << (framenum % 8))))4730 continue;4731 4732 fdata = sharkd_get_frame(framenum);4733 4734 msec_rel = (fdata->abs_ts.secs - start_ts->secs) * (int64_t) 1000 + (fdata->abs_ts.nsecs - start_ts->nsecs) / 1000000;4735 new_idx = msec_rel / interval_ms;4736 4737 if (idx != new_idx)4738 {4739 if (st.frames != 0)4740 {4741 sharkd_json_value_anyf(NULL((void*)0), "[%" PRId64"l" "d" ",%u,%" PRIu64"l" "u" "]", idx, st.frames, st.bytes);4742 }4743 4744 idx = new_idx;4745 if (idx > max_idx)4746 max_idx = idx;4747 4748 st.frames = 0;4749 st.bytes = 0;4750 }4751 4752 st.frames += 1;4753 st.bytes += fdata->pkt_len;4754 4755 st_total.frames += 1;4756 st_total.bytes += fdata->pkt_len;4757 }4758 4759 if (st.frames != 0)4760 {4761 sharkd_json_value_anyf(NULL((void*)0), "[%" PRId64"l" "d" ",%u,%" PRIu64"l" "u" "]", idx, st.frames, st.bytes);4762 }4763 sharkd_json_array_close();4764 4765 sharkd_json_value_anyf("last", "%" PRId64"l" "d", max_idx);4766 sharkd_json_value_anyf("frames", "%u", st_total.frames);4767 sharkd_json_value_anyf("bytes", "%" PRIu64"l" "u", st_total.bytes);4768 4769 sharkd_json_result_epilogue();4770}4771 4772/**4773 * sharkd_session_process_frame()4774 *4775 * Process frame request4776 *4777 * Input:4778 * (m) frame - requested frame number4779 * (o) ref_frame - time reference frame number4780 * (o) prev_frame - previously displayed frame number4781 * (o) proto - set if output frame tree4782 * (o) columns - set if output frame columns4783 * (o) color - set if output color-filter bg/fg4784 * (o) bytes - set if output frame bytes4785 * (o) hidden - set if output hidden tree fields4786 *4787 * Output object with attributes:4788 * (m) err - 0 if succeed4789 * (o) tree - array of frame nodes with attributes:4790 * l - label4791 * t: 'proto', 'framenum', 'url' - type of node4792 * f - filter string4793 * fn - field name4794 * s - severity4795 * e - subtree ett index4796 * n - array of subtree nodes4797 * h - two item array: (item start, item length)4798 * i - two item array: (appendix start, appendix length)4799 * p - [RESERVED] two item array: (protocol start, protocol length)4800 * ds- data src index4801 * url - only for t:'url', url4802 * fnum - only for t:'framenum', frame number4803 * g - if field is generated by Wireshark4804 * v - if field is hidden4805 *4806 * (o) col - array of column data4807 * (o) bytes - base64 of frame bytes4808 * (o) ds - array of other data srcs4809 * (o) comment - frame comment4810 * (o) fol - array of follow filters:4811 * [0] - protocol4812 * [1] - filter string4813 * (o) followers - array of followers with attributes:4814 * protocol - protocol string4815 * filter - filter string4816 * stream - stream index number4817 * sub_stream - sub-stream index number (optional, e.g. for HTTP/2 and QUIC streams)4818 * (o) i - if frame is ignored4819 * (o) m - if frame is marked4820 * (o) bg - color filter - background color in hex4821 * (o) fg - color filter - foreground color in hex4822 */4823static void4824sharkd_session_process_frame(char *buf, const jsmntok_t *tokens, int count)4825{4826 const char *tok_frame = json_find_attr(buf, tokens, count, "frame");4827 const char *tok_ref_frame = json_find_attr(buf, tokens, count, "ref_frame");4828 const char *tok_prev_frame = json_find_attr(buf, tokens, count, "prev_frame");4829 column_info *cinfo = NULL((void*)0);4830 4831 uint32_t framenum, ref_frame_num, prev_dis_num;4832 uint32_t dissect_flags = SHARKD_DISSECT_FLAG_NULL0x00u;4833 struct sharkd_frame_request_data req_data;4834 wtap_rec rec; /* Record metadata */4835 Buffer rec_buf; /* Record data */4836 enum dissect_request_status status;4837 int err;4838 char *err_info;4839 4840 ws_strtou32(tok_frame, NULL((void*)0), &framenum); // we have already validated this4841 4842 ref_frame_num = (framenum != 1) ? 1 : 0;4843 if (tok_ref_frame)4844 {4845 ws_strtou32(tok_ref_frame, NULL((void*)0), &ref_frame_num);4846 if (ref_frame_num > framenum)4847 {4848 sharkd_json_error(4849 rpcid, -8001, NULL((void*)0),4850 "Invalid ref_frame - The ref_frame occurs after the frame specified"4851 );4852 return;4853 }4854 }4855 4856 prev_dis_num = framenum - 1;4857 if (tok_prev_frame)4858 {4859 ws_strtou32(tok_prev_frame, NULL((void*)0), &prev_dis_num);4860 if (prev_dis_num >= framenum)4861 {4862 sharkd_json_error(4863 rpcid, -8002, NULL((void*)0),4864 "Invalid prev_frame - The prev_frame occurs on or after the frame specified"4865 );4866 return;4867 }4868 }4869 4870 if (json_find_attr(buf, tokens, count, "proto") != NULL((void*)0))4871 dissect_flags |= SHARKD_DISSECT_FLAG_PROTO_TREE0x04u;4872 if (json_find_attr(buf, tokens, count, "bytes") != NULL((void*)0))4873 dissect_flags |= SHARKD_DISSECT_FLAG_BYTES0x01u;4874 if (json_find_attr(buf, tokens, count, "columns") != NULL((void*)0)) {4875 dissect_flags |= SHARKD_DISSECT_FLAG_COLUMNS0x02u;4876 cinfo = &cfile.cinfo;4877 }4878 if (json_find_attr(buf, tokens, count, "color") != NULL((void*)0))4879 dissect_flags |= SHARKD_DISSECT_FLAG_COLOR0x08u;4880 4881 req_data.display_hidden = (json_find_attr(buf, tokens, count, "v") != NULL((void*)0));4882 4883 wtap_rec_init(&rec);4884 ws_buffer_init(&rec_buf, 1514);4885 4886 status = sharkd_dissect_request(framenum, ref_frame_num, prev_dis_num,4887 &rec, &rec_buf, cinfo, dissect_flags,4888 &sharkd_session_process_frame_cb, &req_data, &err, &err_info);4889 switch (status) {4890 4891 case DISSECT_REQUEST_SUCCESS:4892 /* success */4893 break;4894 4895 case DISSECT_REQUEST_NO_SUCH_FRAME:4896 sharkd_json_error(4897 rpcid, -8003, NULL((void*)0),4898 "Invalid frame - The frame number requested is out of range"4899 );4900 break;4901 4902 case DISSECT_REQUEST_READ_ERROR:4903 sharkd_json_error(4904 rpcid, -8003, NULL((void*)0),4905 /* XXX - show the error details */4906 "Read error - The frame could not be read from the file"4907 );4908 g_free(err_info);4909 break;4910 }4911 4912 wtap_rec_cleanup(&rec);4913 ws_buffer_free(&rec_buf);4914}4915 4916/**4917 * sharkd_session_process_check()4918 *4919 * Process check request.4920 *4921 * Input:4922 * (o) filter - filter to be checked4923 * (o) field - field to be checked4924 *4925 * Output object with attributes:4926 * (m) err - always 04927 * (o) filter - 'ok', 'warn' or error message4928 * (o) field - 'ok', or 'notfound'4929 */4930static int4931sharkd_session_process_check(char *buf, const jsmntok_t *tokens, int count)4932{4933 const char *tok_filter = json_find_attr(buf, tokens, count, "filter");4934 const char *tok_field = json_find_attr(buf, tokens, count, "field");4935 4936 if (tok_filter != NULL((void*)0))4937 {4938 dfilter_t *dfp;4939 df_error_t *df_err = NULL((void*)0);4940 4941 if (dfilter_compile(tok_filter, &dfp, &df_err)dfilter_compile_full(tok_filter, &dfp, &df_err, (1U <<
1)|(1U << 2), __func__)
)4942 {4943 if (dfp && dfilter_deprecated_tokens(dfp))4944 sharkd_json_warning(rpcid, "Filter contains deprecated tokens");4945 else4946 sharkd_json_simple_ok(rpcid);4947 4948 dfilter_free(dfp);4949 df_error_free(&df_err);4950 return 0;4951 }4952 else4953 {4954 sharkd_json_error(4955 rpcid, -5001, NULL((void*)0),4956 "Filter invalid - %s", df_err->msg4957 );4958 df_error_free(&df_err);4959 return -5001;4960 }4961 }4962 4963 if (tok_field != NULL((void*)0))4964 {4965 header_field_info *hfi = proto_registrar_get_byname(tok_field);4966 4967 if (!hfi)4968 {4969 sharkd_json_error(4970 rpcid, -5002, NULL((void*)0),4971 "Field %s not found", tok_field4972 );4973 return -5002;4974 }4975 else4976 {4977 sharkd_json_simple_ok(rpcid);4978 return 0;4979 }4980 }4981 4982 sharkd_json_simple_ok(rpcid);4983 return 0;4984}4985 4986struct sharkd_session_process_complete_pref_data4987{4988 const char *module;4989 const char *pref;4990};4991 4992static unsigned4993sharkd_session_process_complete_pref_cb(module_t *module, void *d)4994{4995 struct sharkd_session_process_complete_pref_data *data = (struct sharkd_session_process_complete_pref_data *) d;4996 4997 if (strncmp(data->pref, module->name, strlen(data->pref)) != 0)4998 return 0;4999 5000 json_dumper_begin_object(&dumper);5001 sharkd_json_value_string("f", module->name);5002 sharkd_json_value_string("d", module->title);5003 json_dumper_end_object(&dumper);5004 5005 return 0;5006}5007 5008static unsigned5009sharkd_session_process_complete_pref_option_cb(pref_t *pref, void *d)5010{5011 struct sharkd_session_process_complete_pref_data *data = (struct sharkd_session_process_complete_pref_data *) d;5012 const char *pref_name = prefs_get_name(pref);5013 const char *pref_title = prefs_get_title(pref);5014 5015 if (strncmp(data->pref, pref_name, strlen(data->pref)) != 0)5016 return 0;5017 5018 json_dumper_begin_object(&dumper);5019 sharkd_json_value_stringf("f", "%s.%s", data->module, pref_name);5020 sharkd_json_value_string("d", pref_title);5021 json_dumper_end_object(&dumper);5022 5023 return 0; /* continue */5024}5025 5026/**5027 * sharkd_session_process_complete()5028 *5029 * Process complete request5030 *5031 * Input:5032 * (o) field - field to be completed5033 * (o) pref - preference to be completed5034 *5035 * Output object with attributes:5036 * (m) err - always 05037 * (o) field - array of object with attributes:5038 * (m) f - field text5039 * (o) t - field type (FT_ number)5040 * (o) n - field name5041 * (o) pref - array of object with attributes:5042 * (m) f - pref name5043 * (o) d - pref description5044 */5045static int5046sharkd_session_process_complete(char *buf, const jsmntok_t *tokens, int count)5047{5048 const char *tok_field = json_find_attr(buf, tokens, count, "field");5049 const char *tok_pref = json_find_attr(buf, tokens, count, "pref");5050 5051 sharkd_json_result_prologue(rpcid);5052 5053 if (tok_field != NULL((void*)0) && tok_field[0])5054 {5055 const size_t filter_length = strlen(tok_field);5056 const int filter_with_dot = !!strchr(tok_field, '.');5057 5058 void *proto_cookie;5059 void *field_cookie;5060 int proto_id;5061 5062 sharkd_json_array_open("field");5063 5064 for (proto_id = proto_get_first_protocol(&proto_cookie); proto_id != -1; proto_id = proto_get_next_protocol(&proto_cookie))5065 {5066 protocol_t *protocol = find_protocol_by_id(proto_id);5067 const char *protocol_filter;5068 const char *protocol_name;5069 header_field_info *hfinfo;5070 5071 if (!proto_is_protocol_enabled(protocol))5072 continue;5073 5074 protocol_name = proto_get_protocol_long_name(protocol);5075 protocol_filter = proto_get_protocol_filter_name(proto_id);5076 5077 if (strlen(protocol_filter) >= filter_length && !g_ascii_strncasecmp(tok_field, protocol_filter, filter_length))5078 {5079 json_dumper_begin_object(&dumper);5080 {5081 sharkd_json_value_string("f", protocol_filter);5082 sharkd_json_value_anyf("t", "%d", FT_PROTOCOL);5083 sharkd_json_value_string("n", protocol_name);5084 }5085 json_dumper_end_object(&dumper);5086 }5087 5088 if (!filter_with_dot)5089 continue;5090 5091 for (hfinfo = proto_get_first_protocol_field(proto_id, &field_cookie); hfinfo != NULL((void*)0); hfinfo = proto_get_next_protocol_field(proto_id, &field_cookie))5092 {5093 if (hfinfo->same_name_prev_id != -1) /* ignore duplicate names */5094 continue;5095 5096 if (strlen(hfinfo->abbrev) >= filter_length && !g_ascii_strncasecmp(tok_field, hfinfo->abbrev, filter_length))5097 {5098 json_dumper_begin_object(&dumper);5099 {5100 sharkd_json_value_string("f", hfinfo->abbrev);5101 5102 /* XXX, skip displaying name, if there are multiple (to not confuse user) */5103 if (hfinfo->same_name_next == NULL((void*)0))5104 {5105 sharkd_json_value_anyf("t", "%d", hfinfo->type);5106 sharkd_json_value_string("n", hfinfo->name);5107 }5108 }5109 json_dumper_end_object(&dumper);5110 }5111 }5112 }5113 5114 sharkd_json_array_close();5115 }5116 5117 if (tok_pref != NULL((void*)0) && tok_pref[0])5118 {5119 struct sharkd_session_process_complete_pref_data data;5120 char *dot_sepa;5121 5122 data.module = tok_pref;5123 data.pref = tok_pref;5124 5125 sharkd_json_array_open("pref");5126 if ((dot_sepa = strchr(tok_pref, '.')))5127 {5128 module_t *pref_mod;5129 5130 *dot_sepa = '\0'; /* XXX, C abuse: discarding-const */5131 data.pref = dot_sepa + 1;5132 5133 pref_mod = prefs_find_module(data.module);5134 if (pref_mod)5135 prefs_pref_foreach(pref_mod, sharkd_session_process_complete_pref_option_cb, &data);5136 5137 *dot_sepa = '.';5138 }5139 else5140 {5141 prefs_modules_foreach(sharkd_session_process_complete_pref_cb, &data);5142 }5143 sharkd_json_array_close();5144 }5145 5146 sharkd_json_result_epilogue();5147 5148 return 0;5149}5150 5151/**5152 * sharkd_session_process_setcomment()5153 *5154 * Process setcomment request5155 *5156 * Input:5157 * (m) frame - frame number5158 * (o) comment - user comment5159 *5160 * Output object with attributes:5161 * (m) err - error code: 0 succeed5162 *5163 * Note:5164 * For now, adds comments, doesn't remove or replace them.5165 */5166static void5167sharkd_session_process_setcomment(char *buf, const jsmntok_t *tokens, int count)5168{5169 const char *tok_frame = json_find_attr(buf, tokens, count, "frame");5170 const char *tok_comment = json_find_attr(buf, tokens, count, "comment");5171 5172 uint32_t framenum;5173 frame_data *fdata;5174 wtap_opttype_return_val ret;5175 wtap_block_t pkt_block = NULL((void*)0);5176 5177 if (!tok_frame || !ws_strtou32(tok_frame, NULL((void*)0), &framenum) || framenum == 0)5178 {5179 sharkd_json_error(5180 rpcid, -3001, NULL((void*)0),5181 "Frame number must be a positive integer"5182 );5183 return;5184 }5185 5186 fdata = sharkd_get_frame(framenum); // BUG HERE - If no file loaded you get a crash5187 if (!fdata)5188 {5189 sharkd_json_error(5190 rpcid, -3002, NULL((void*)0),5191 "Frame number is out of range"5192 );5193 return;5194 }5195 5196 pkt_block = sharkd_get_packet_block(fdata);5197 5198 ret = wtap_block_add_string_option(pkt_block, OPT_COMMENT1, tok_comment, strlen(tok_comment));5199 5200 if (ret != WTAP_OPTTYPE_SUCCESS)5201 {5202 sharkd_json_error(5203 rpcid, -3003, NULL((void*)0),5204 "Unable to set the comment"5205 );5206 }5207 else5208 {5209 sharkd_set_modified_block(fdata, pkt_block);5210 sharkd_json_simple_ok(rpcid);5211 }5212}5213 5214/**5215 * sharkd_session_process_setconf()5216 *5217 * Process setconf request5218 *5219 * Input:5220 * (m) name - preference name5221 * (m) value - preference value5222 *5223 * Output object with attributes:5224 * (m) err - error code: 0 succeed5225 */5226static void5227sharkd_session_process_setconf(char *buf, const jsmntok_t *tokens, int count)5228{5229 const char *tok_name = json_find_attr(buf, tokens, count, "name");5230 const char *tok_value = json_find_attr(buf, tokens, count, "value");5231 char pref[4096];5232 char *errmsg = NULL((void*)0);5233 5234 prefs_set_pref_e ret;5235 5236 if (!tok_name || tok_name[0] == '\0')5237 {5238 sharkd_json_error(5239 rpcid, -4001, NULL((void*)0),5240 "Preference name missing"5241 );5242 return;5243 }5244 5245 if (!tok_value)5246 {5247 sharkd_json_error(5248 rpcid, -4002, NULL((void*)0),5249 "Preference value missing"5250 );5251 return;5252 }5253 5254 snprintf(pref, sizeof(pref), "%s:%s", tok_name, tok_value);5255 5256 ret = prefs_set_pref(pref, &errmsg);5257 5258 switch (ret)5259 {5260 case PREFS_SET_OK:5261 sharkd_json_simple_ok(rpcid);5262 break;5263 5264 case PREFS_SET_OBSOLETE:5265 sharkd_json_error(5266 rpcid, -4003, NULL((void*)0),5267 "The preference specified is obsolete"5268 );5269 break;5270 5271 case PREFS_SET_NO_SUCH_PREF:5272 sharkd_json_error(5273 rpcid, -4004, NULL((void*)0),5274 "No such preference exists"5275 );5276 break;5277 5278 default:5279 sharkd_json_error(5280 rpcid, -4005, NULL((void*)0),5281 "Unable to set the preference"5282 );5283 }5284 5285 g_free(errmsg);5286}5287 5288struct sharkd_session_process_dumpconf_data5289{5290 module_t *module;5291};5292 5293static unsigned5294sharkd_session_process_dumpconf_cb(pref_t *pref, void *d)5295{5296 struct sharkd_session_process_dumpconf_data *data = (struct sharkd_session_process_dumpconf_data *) d;5297 const char *pref_name = prefs_get_name(pref);5298 5299 char json_pref_key[512];5300 5301 snprintf(json_pref_key, sizeof(json_pref_key), "%s.%s", data->module->name, pref_name);5302 sharkd_json_object_open(json_pref_key);5303 5304 switch (prefs_get_type(pref))5305 {5306 case PREF_UINT(1u << 0):5307 sharkd_json_value_anyf("u", "%u", prefs_get_uint_value_real(pref, pref_current));5308 if (prefs_get_uint_base(pref) != 10)5309 sharkd_json_value_anyf("ub", "%u", prefs_get_uint_base(pref));5310 break;5311 5312 case PREF_BOOL(1u << 1):5313 sharkd_json_value_anyf("b", prefs_get_bool_value(pref, pref_current) ? "1" : "0");5314 break;5315 5316 case PREF_STRING(1u << 3):5317 case PREF_SAVE_FILENAME(1u << 7):5318 case PREF_OPEN_FILENAME(1u << 14):5319 case PREF_DIRNAME(1u << 11):5320 case PREF_PASSWORD(1u << 15):5321 case PREF_DISSECTOR(1u << 17):5322 sharkd_json_value_string("s", prefs_get_string_value(pref, pref_current));5323 break;5324 5325 case PREF_ENUM(1u << 2):5326 {5327 const enum_val_t *enums;5328 5329 sharkd_json_array_open("e");5330 for (enums = prefs_get_enumvals(pref); enums->name; enums++)5331 {5332 json_dumper_begin_object(&dumper);5333 5334 sharkd_json_value_anyf("v", "%d", enums->value);5335 5336 if (enums->value == prefs_get_enum_value(pref, pref_current))5337 sharkd_json_value_anyf("s", "1");5338 5339 sharkd_json_value_string("d", enums->description);5340 5341 json_dumper_end_object(&dumper);5342 }5343 sharkd_json_array_close();5344 break;5345 }5346 5347 case PREF_RANGE(1u << 4):5348 case PREF_DECODE_AS_RANGE(1u << 13):5349 {5350 char *range_str = range_convert_range(NULL((void*)0), prefs_get_range_value_real(pref, pref_current));5351 sharkd_json_value_string("r", range_str);5352 wmem_free(NULL((void*)0), range_str);5353 break;5354 }5355 5356 case PREF_UAT(1u << 6):5357 {5358 uat_t *uat = prefs_get_uat_value(pref);5359 unsigned idx;5360 5361 sharkd_json_array_open("t");5362 for (idx = 0; idx < uat->raw_data->len; idx++)5363 {5364 void *rec = UAT_INDEX_PTR(uat, idx)(uat->raw_data->data + (uat->record_size * (idx)));5365 unsigned colnum;5366 5367 sharkd_json_array_open(NULL((void*)0));5368 for (colnum = 0; colnum < uat->ncols; colnum++)5369 {5370 char *str = uat_fld_tostr(rec, &(uat->fields[colnum]));5371 5372 sharkd_json_value_string(NULL((void*)0), str);5373 g_free(str);5374 }5375 5376 sharkd_json_array_close();5377 }5378 5379 sharkd_json_array_close();5380 break;5381 }5382 5383 case PREF_COLOR(1u << 8):5384 case PREF_CUSTOM(1u << 9):5385 case PREF_STATIC_TEXT(1u << 5):5386 case PREF_OBSOLETE(1u << 10):5387 /* TODO */5388 break;5389 }5390 5391#if 05392 sharkd_json_value_string("t", prefs_get_title(pref));5393#endif5394 5395 sharkd_json_object_close();5396 5397 return 0; /* continue */5398}5399 5400static unsigned5401sharkd_session_process_dumpconf_mod_cb(module_t *module, void *d)5402{5403 struct sharkd_session_process_dumpconf_data *data = (struct sharkd_session_process_dumpconf_data *) d;5404 5405 data->module = module;5406 prefs_pref_foreach(module, sharkd_session_process_dumpconf_cb, data);5407 5408 return 0;5409}5410 5411/**5412 * sharkd_session_process_dumpconf()5413 *5414 * Process dumpconf request5415 *5416 * Input:5417 * (o) pref - module, or preference, NULL for all5418 *5419 * Output object with attributes:5420 * (o) prefs - object with module preferences5421 * (m) [KEY] - preference name5422 * (o) u - preference value (for PREF_UINT)5423 * (o) ub - preference value suggested base for display (for PREF_UINT) and if different than 105424 * (o) b - preference value (only for PREF_BOOL) (1 true, 0 false)5425 * (o) s - preference value (for PREF_STRING, PREF_SAVE_FILENAME, PREF_OPEN_FILENAME, PREF_DIRNAME, PREF_PASSWORD, PREF_DISSECTOR)5426 * (o) e - preference possible values (only for PREF_ENUM)5427 * (o) r - preference value (for PREF_RANGE, PREF_DECODE_AS_RANGE)5428 * (o) t - preference value (only for PREF_UAT)5429 */5430static void5431sharkd_session_process_dumpconf(char *buf, const jsmntok_t *tokens, int count)5432{5433 const char *tok_pref = json_find_attr(buf, tokens, count, "pref");5434 module_t *pref_mod;5435 char *dot_sepa;5436 5437 if (!tok_pref)5438 {5439 struct sharkd_session_process_dumpconf_data data;5440 5441 data.module = NULL((void*)0);5442 5443 sharkd_json_result_prologue(rpcid);5444 5445 sharkd_json_object_open("prefs");5446 prefs_modules_foreach(sharkd_session_process_dumpconf_mod_cb, &data);5447 sharkd_json_object_close();5448 5449 sharkd_json_result_epilogue();5450 return;5451 }5452 5453 if ((dot_sepa = strchr(tok_pref, '.')))5454 {5455 pref_t *pref = NULL((void*)0);5456 5457 *dot_sepa = '\0'; /* XXX, C abuse: discarding-const */5458 pref_mod = prefs_find_module(tok_pref);5459 if (pref_mod)5460 pref = prefs_find_preference(pref_mod, dot_sepa + 1);5461 *dot_sepa = '.';5462 5463 if (pref)5464 {5465 struct sharkd_session_process_dumpconf_data data;5466 5467 data.module = pref_mod;5468 5469 sharkd_json_result_prologue(rpcid);5470 5471 sharkd_json_object_open("prefs");5472 sharkd_session_process_dumpconf_cb(pref, &data);5473 sharkd_json_object_close();5474 5475 sharkd_json_result_epilogue();5476 return;5477 }5478 else5479 {5480 sharkd_json_error(5481 rpcid, -9001, NULL((void*)0),5482 "Invalid pref %s.", tok_pref5483 );5484 return;5485 }5486 5487 }5488 5489 pref_mod = prefs_find_module(tok_pref);5490 if (pref_mod)5491 {5492 struct sharkd_session_process_dumpconf_data data;5493 5494 data.module = pref_mod;5495 5496 sharkd_json_result_prologue(rpcid);5497 5498 sharkd_json_object_open("prefs");5499 prefs_pref_foreach(pref_mod, sharkd_session_process_dumpconf_cb, &data);5500 sharkd_json_object_close();5501 5502 sharkd_json_result_epilogue();5503 }5504 else5505 {5506 sharkd_json_error(5507 rpcid, -9002, NULL((void*)0),5508 "Invalid pref %s.", tok_pref5509 );5510 }5511}5512 5513struct sharkd_download_rtp5514{5515 rtpstream_id_t id;5516 GSList *packets;5517 double start_time;5518};5519 5520static void5521sharkd_rtp_download_free_items(void *ptr)5522{5523 rtp_packet_t *rtp_packet = (rtp_packet_t *) ptr;5524 5525 g_free(rtp_packet->info);5526 g_free(rtp_packet->payload_data);5527 g_free(rtp_packet);5528}5529 5530static void5531sharkd_rtp_download_decode(struct sharkd_download_rtp *req)5532{5533 /* based on RtpAudioStream::decode() 6e29d874f8b5e6ebc59f661a0bb0dab8e56f122a */5534 /* TODO, for now only without silence (timing_mode_ = Uninterrupted) */5535 5536 static const int sample_bytes_ = sizeof(SAMPLE) / sizeof(char);5537 5538 uint32_t audio_out_rate_ = 0;5539 struct _GHashTable *decoders_hash_ = rtp_decoder_hash_table_new();5540 struct SpeexResamplerState_ *audio_resampler_ = NULL((void*)0);5541 5542 size_t resample_buff_len = 0x1000;5543 SAMPLE *resample_buff = (SAMPLE *) g_malloc(resample_buff_len);5544 spx_uint32_t cur_in_rate = 0;5545 char *write_buff = NULL((void*)0);5546 size_t write_bytes = 0;5547 unsigned channels = 0;5548 unsigned sample_rate = 0;5549 5550 GSList *l;5551 5552 for (l = req->packets; l; l = l->next)5553 {5554 rtp_packet_t *rtp_packet = (rtp_packet_t *) l->data;5555 5556 SAMPLE *decode_buff = NULL((void*)0);5557 size_t decoded_bytes;5558 5559 decoded_bytes = decode_rtp_packet(rtp_packet, &decode_buff, decoders_hash_, &channels, &sample_rate);5560 if (decoded_bytes == 0 || sample_rate == 0)5561 {5562 /* We didn't decode anything. Clean up and prep for the next packet. */5563 g_free(decode_buff);5564 continue;5565 }5566 5567 if (audio_out_rate_ == 0)5568 {5569 uint32_t tmp32;5570 uint16_t tmp16;5571 char wav_hdr[44];5572 5573 /* First non-zero wins */5574 audio_out_rate_ = sample_rate;5575 5576 RTP_STREAM_DEBUG("Audio sample rate is %u", audio_out_rate_);5577 5578 /* write WAVE header */5579 memset(&wav_hdr, 0, sizeof(wav_hdr));5580 memcpy(&wav_hdr[0], "RIFF", 4);5581 memcpy(&wav_hdr[4], "\xFF\xFF\xFF\xFF", 4); /* XXX, unknown */5582 memcpy(&wav_hdr[8], "WAVE", 4);5583 5584 memcpy(&wav_hdr[12], "fmt ", 4);5585 memcpy(&wav_hdr[16], "\x10\x00\x00\x00", 4); /* PCM */5586 memcpy(&wav_hdr[20], "\x01\x00", 2); /* PCM */5587 /* # channels */5588 tmp16 = channels;5589 memcpy(&wav_hdr[22], &tmp16, 2);5590 /* sample rate */5591 tmp32 = sample_rate;5592 memcpy(&wav_hdr[24], &tmp32, 4);5593 /* byte rate */5594 tmp32 = sample_rate * channels * sample_bytes_;5595 memcpy(&wav_hdr[28], &tmp32, 4);5596 /* block align */5597 tmp16 = channels * sample_bytes_;5598 memcpy(&wav_hdr[32], &tmp16, 2);5599 /* bits per sample */5600 tmp16 = 8 * sample_bytes_;5601 memcpy(&wav_hdr[34], &tmp16, 2);5602 5603 memcpy(&wav_hdr[36], "data", 4);5604 memcpy(&wav_hdr[40], "\xFF\xFF\xFF\xFF", 4); /* XXX, unknown */5605 5606 json_dumper_write_base64(&dumper, wav_hdr, sizeof(wav_hdr));5607 }5608 5609 // Write samples to our file.5610 write_buff = (char *) decode_buff;5611 write_bytes = decoded_bytes;5612 5613 if (audio_out_rate_ != sample_rate)5614 {5615 spx_uint32_t in_len, out_len;5616 5617 /* Resample the audio to match our previous output rate. */5618 if (!audio_resampler_)5619 {5620 audio_resampler_ = speex_resampler_init(1, sample_rate, audio_out_rate_, 10, NULL((void*)0));5621 speex_resampler_skip_zeros(audio_resampler_);5622 RTP_STREAM_DEBUG("Started resampling from %u to (out) %u Hz.", sample_rate, audio_out_rate_);5623 }5624 else5625 {5626 spx_uint32_t audio_out_rate;5627 speex_resampler_get_rate(audio_resampler_, &cur_in_rate, &audio_out_rate);5628 5629 if (sample_rate != cur_in_rate)5630 {5631 speex_resampler_set_rate(audio_resampler_, sample_rate, audio_out_rate);5632 RTP_STREAM_DEBUG("Changed input rate from %u to %u Hz. Out is %u.", cur_in_rate, sample_rate, audio_out_rate_);5633 }5634 }5635 in_len = (spx_uint32_t)rtp_packet->info->info_payload_len;5636 out_len = (audio_out_rate_ * (spx_uint32_t)rtp_packet->info->info_payload_len / sample_rate) + (audio_out_rate_ % sample_rate != 0);5637 if (out_len * sample_bytes_ > resample_buff_len)5638 {5639 while ((out_len * sample_bytes_ > resample_buff_len))5640 resample_buff_len *= 2;5641 resample_buff = (SAMPLE *) g_realloc(resample_buff, resample_buff_len);5642 }5643 5644 speex_resampler_process_int(audio_resampler_, 0, decode_buff, &in_len, resample_buff, &out_len);5645 write_buff = (char *) resample_buff;5646 write_bytes = out_len * sample_bytes_;5647 }5648 5649 /* Write the decoded, possibly-resampled audio */5650 json_dumper_write_base64(&dumper, write_buff, write_bytes);5651 5652 g_free(decode_buff);5653 }5654 5655 g_free(resample_buff);5656 g_hash_table_destroy(decoders_hash_);5657}5658 5659static tap_packet_status5660sharkd_session_packet_download_tap_rtp_cb(void *tapdata, packet_info *pinfo, epan_dissect_t *edt _U___attribute__((unused)), const void *data, tap_flags_t flags _U___attribute__((unused)))5661{5662 const struct _rtp_info *rtp_info = (const struct _rtp_info *) data;5663 struct sharkd_download_rtp *req_rtp = (struct sharkd_download_rtp *) tapdata;5664 5665 /* do not consider RTP packets without a setup frame */5666 if (rtp_info->info_setup_frame_num == 0)5667 return TAP_PACKET_DONT_REDRAW;5668 5669 if (rtpstream_id_equal_pinfo_rtp_info(&req_rtp->id, pinfo, rtp_info))5670 {5671 rtp_packet_t *rtp_packet;5672 5673 rtp_packet = g_new0(rtp_packet_t, 1)((rtp_packet_t *) g_malloc0_n ((1), sizeof (rtp_packet_t)));5674 rtp_packet->info = (struct _rtp_info *) g_memdup2(rtp_info, sizeof(struct _rtp_info));5675 5676 if (rtp_info->info_all_data_present && rtp_info->info_payload_len != 0)5677 rtp_packet->payload_data = (uint8_t *) g_memdup2(&(rtp_info->info_data[rtp_info->info_payload_offset]), rtp_info->info_payload_len);5678 5679 if (!req_rtp->packets)5680 req_rtp->start_time = nstime_to_sec(&pinfo->abs_ts);5681 5682 rtp_packet->frame_num = pinfo->num;5683 rtp_packet->arrive_offset = nstime_to_sec(&pinfo->abs_ts) - req_rtp->start_time;5684 5685 /* XXX, O(n) optimize */5686 req_rtp->packets = g_slist_append(req_rtp->packets, rtp_packet);5687 }5688 5689 return TAP_PACKET_DONT_REDRAW;5690}5691 5692static bool_Bool5693sharkd_session_eo_retap_listener(const char *tap_type) {5694 bool_Bool ok = true1;5695 register_eo_t *eo = NULL((void*)0);5696 GString *tap_error = NULL((void*)0);5697 void *tap_data = NULL((void*)0);5698 GFreeFunc tap_free = NULL((void*)0);5699 5700 // get <name> from eo:<name>, get_eo_by_name only needs the name (http etc.)5701 eo = get_eo_by_name(tap_type + 3);5702 if (!eo)5703 {5704 ok = false0;5705 sharkd_json_error(5706 rpcid, -11011, NULL((void*)0),5707 "sharkd_session_eo_retap_listener() eo=%s not found", tap_type + 35708 );5709 }5710 5711 if (ok)5712 {5713 tap_error = sharkd_session_eo_register_tap_listener(eo, tap_type, NULL((void*)0), NULL((void*)0), &tap_data, &tap_free);5714 if (tap_error)5715 {5716 ok = false0;5717 sharkd_json_error(5718 rpcid, -10002, NULL((void*)0),5719 "sharkd_session_eo_retap_listener() sharkd_session_eo_register_tap_listener error %s",5720 tap_error->str);5721 g_string_free(tap_error, TRUE)(__builtin_constant_p ((!(0))) ? (((!(0))) ? (g_string_free) (
(tap_error), ((!(0)))) : g_string_free_and_steal (tap_error))
: (g_string_free) ((tap_error), ((!(0)))))
;5722 }5723 }5724 5725 if (ok)5726 sharkd_retap();5727 5728 if (!tap_error)5729 remove_tap_listener(tap_data);5730 5731 if (tap_free)5732 tap_free(tap_data);5733 5734 return ok;5735}5736 5737/**5738 * sharkd_session_process_download()5739 *5740 * Process download request5741 *5742 * Input:5743 * (m) token - token to download5744 *5745 * Output object with attributes:5746 * (o) file - suggested name of file5747 * (o) mime - suggested content type5748 * (o) data - payload base64 encoded5749 */5750static void5751sharkd_session_process_download(char *buf, const jsmntok_t *tokens, int count)5752{5753 const char *tok_token = json_find_attr(buf, tokens, count, "token");5754 5755 if (!tok_token)5756 {5757 sharkd_json_error(5758 rpcid, -10005, NULL((void*)0),5759 "missing token"5760 );5761 return;5762 }5763 5764 if (!strncmp(tok_token, "eo:", 3))5765 {5766 // get eo:<name> from eo:<name>_<row>5767 char *tap_type = g_strdup(tok_token)g_strdup_inline (tok_token);5768 char *tmp = strrchr(tap_type, '_');5769 if (tmp)5770 *tmp = '\0';5771 5772 // if eo:<name> not in sharkd_eo_list, retap5773 if (!sharkd_eo_object_list_get_entry_by_type(sharkd_eo_list, tap_type) &&5774 !sharkd_session_eo_retap_listener(tap_type))5775 {5776 g_free(tap_type);5777 // sharkd_json_error called in sharkd_session_eo_retap_listener5778 return;5779 }5780 5781 g_free(tap_type);5782 5783 struct sharkd_export_object_list *object_list;5784 const export_object_entry_t *eo_entry = NULL((void*)0);5785 5786 for (object_list = sharkd_eo_list; object_list; object_list = object_list->next)5787 {5788 size_t eo_type_len = strlen(object_list->type);5789 5790 if (!strncmp(tok_token, object_list->type, eo_type_len) && tok_token[eo_type_len] == '_')5791 {5792 int row;5793 5794 if (sscanf(&tok_token[eo_type_len + 1], "%d", &row) != 1)5795 break;5796 5797 eo_entry = (export_object_entry_t *) g_slist_nth_data(object_list->entries, row);5798 break;5799 }5800 }5801 5802 if (eo_entry)5803 {5804 const char *mime = (eo_entry->content_type) ? eo_entry->content_type : "application/octet-stream";5805 const char *filename = (eo_entry->filename) ? eo_entry->filename : tok_token;5806 5807 sharkd_json_result_prologue(rpcid);5808 sharkd_json_value_string("file", filename);5809 sharkd_json_value_string("mime", mime);5810 sharkd_json_value_base64("data", eo_entry->payload_data, eo_entry->payload_len);5811 sharkd_json_result_epilogue();5812 }5813 else5814 {5815 sharkd_json_result_prologue(rpcid);5816 sharkd_json_result_epilogue();5817 }5818 }5819 else if (!strcmp(tok_token, "ssl-secrets"))5820 {5821 size_t str_len;5822 char *str = ssl_export_sessions(&str_len);5823 5824 if (str)5825 {5826 const char *mime = "text/plain";5827 const char *filename = "keylog.txt";5828 5829 sharkd_json_result_prologue(rpcid);5830 sharkd_json_value_string("file", filename);5831 sharkd_json_value_string("mime", mime);5832 sharkd_json_value_base64("data", str, str_len);5833 sharkd_json_result_epilogue();5834 }5835 g_free(str);5836 }5837 else if (!strncmp(tok_token, "rtp:", 4))5838 {5839 struct sharkd_download_rtp rtp_req;5840 GString *tap_error;5841 5842 memset(&rtp_req, 0, sizeof(rtp_req));5843 if (!sharkd_rtp_match_init(&rtp_req.id, tok_token + 4))5844 {5845 sharkd_json_error(5846 rpcid, -10001, NULL((void*)0),5847 "sharkd_session_process_download() rtp tokenizing error %s", tok_token5848 );5849 return;5850 }5851 5852 tap_error = register_tap_listener("rtp", &rtp_req, NULL((void*)0), 0, NULL((void*)0), sharkd_session_packet_download_tap_rtp_cb, NULL((void*)0), NULL((void*)0));5853 if (tap_error)5854 {5855 sharkd_json_error(5856 rpcid, -10002, NULL((void*)0),5857 "sharkd_session_process_download() rtp error %s", tap_error->str5858 );5859 g_string_free(tap_error, TRUE)(__builtin_constant_p ((!(0))) ? (((!(0))) ? (g_string_free) (
(tap_error), ((!(0)))) : g_string_free_and_steal (tap_error))
: (g_string_free) ((tap_error), ((!(0)))))
;5860 return;5861 }5862 5863 sharkd_retap();5864 remove_tap_listener(&rtp_req);5865 5866 if (rtp_req.packets)5867 {5868 const char *mime = "audio/x-wav";5869 const char *filename = tok_token;5870 5871 sharkd_json_result_prologue(rpcid);5872 sharkd_json_value_string("file", filename);5873 sharkd_json_value_string("mime", mime);5874 5875 json_dumper_set_member_name(&dumper, "data");5876 json_dumper_begin_base64(&dumper);5877 sharkd_rtp_download_decode(&rtp_req);5878 json_dumper_end_base64(&dumper);5879 5880 sharkd_json_result_epilogue();5881 5882 g_slist_free_full(rtp_req.packets, sharkd_rtp_download_free_items);5883 }5884 else5885 {5886 sharkd_json_error(5887 rpcid, -10003, NULL((void*)0),5888 "no rtp data available"5889 );5890 }5891 }5892 else5893 {5894 sharkd_json_error(5895 rpcid, -10004, NULL((void*)0),5896 "unrecognized token"5897 );5898 }5899}5900 5901static void5902sharkd_session_process(char *buf, const jsmntok_t *tokens, int count)5903{5904 if (json_prep(buf, tokens, count))5905 {5906 /* don't need [0] token */5907 tokens++;5908 count--;5909 5910 const char* tok_method = json_find_attr(buf, tokens, count, "method");5911 5912 if (!tok_method) {5913 sharkd_json_error(5914 rpcid, -32601, NULL((void*)0),5915 "No method found");5916 return;5917 }5918 if (!strcmp(tok_method, "load"))5919 sharkd_session_process_load(buf, tokens, count);5920 else if (!strcmp(tok_method, "status"))5921 sharkd_session_process_status();5922 else if (!strcmp(tok_method, "analyse"))5923 sharkd_session_process_analyse();5924 else if (!strcmp(tok_method, "info"))5925 sharkd_session_process_info();5926 else if (!strcmp(tok_method, "check"))5927 sharkd_session_process_check(buf, tokens, count);5928 else if (!strcmp(tok_method, "complete"))5929 sharkd_session_process_complete(buf, tokens, count);5930 else if (!strcmp(tok_method, "frames"))5931 sharkd_session_process_frames(buf, tokens, count);5932 else if (!strcmp(tok_method, "tap"))5933 sharkd_session_process_tap(buf, tokens, count);5934 else if (!strcmp(tok_method, "follow"))5935 sharkd_session_process_follow(buf, tokens, count);5936 else if (!strcmp(tok_method, "iograph"))5937 sharkd_session_process_iograph(buf, tokens, count);5938 else if (!strcmp(tok_method, "intervals"))5939 sharkd_session_process_intervals(buf, tokens, count);5940 else if (!strcmp(tok_method, "frame"))5941 sharkd_session_process_frame(buf, tokens, count);5942 else if (!strcmp(tok_method, "setcomment"))5943 sharkd_session_process_setcomment(buf, tokens, count);5944 else if (!strcmp(tok_method, "setconf"))5945 sharkd_session_process_setconf(buf, tokens, count);5946 else if (!strcmp(tok_method, "dumpconf"))5947 sharkd_session_process_dumpconf(buf, tokens, count);5948 else if (!strcmp(tok_method, "download"))5949 sharkd_session_process_download(buf, tokens, count);5950 else if (!strcmp(tok_method, "bye"))5951 {5952 sharkd_json_simple_ok(rpcid);5953 exit(0);5954 }5955 else5956 {5957 sharkd_json_error(5958 rpcid, -32601, NULL((void*)0),5959 "The method \"%s\" is unknown", tok_method5960 );5961 }5962 }5963}5964 5965int5966sharkd_session_main(int mode_setting)5967{5968 char buf[8 * 1024];5969 jsmntok_t *tokens = NULL((void*)0);5970 int tokens_max = -1;5971 5972 mode = mode_setting;5973 5974 fprintf(stderrstderr, "Hello in child.\n");5975 5976 dumper.output_file = stdoutstdout;5977 5978 filter_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, sharkd_session_filter_free);5979 5980#ifdef HAVE_MAXMINDDB15981 /* mmdbresolve was stopped before fork(), force starting it */5982 uat_get_table_by_name("MaxMind Database Paths")->post_update_cb();5983#endif5984 5985 set_resolution_synchrony(true1);5986 5987 while (fgets(buf, sizeof(buf), stdinstdin))5988 {5989 /* every command is line separated JSON */5990 int ret;5991 5992 ret = json_parse(buf, NULL((void*)0), 0);5993 if (ret <= 0)5994 {5995 sharkd_json_error(5996 rpcid, -32600, NULL((void*)0),5997 "Invalid JSON(1)"5998 );5999 continue;6000 }6001 6002 /* fprintf(stderr, "JSON: %d tokens\n", ret); */6003 ret += 1;6004 6005 if (tokens == NULL((void*)0) || tokens_max < ret)6006 {6007 tokens_max = ret;6008 tokens = (jsmntok_t *) g_realloc(tokens, sizeof(jsmntok_t) * tokens_max);6009 }6010 6011 memset(tokens, 0, ret * sizeof(jsmntok_t));6012 6013 ret = json_parse(buf, tokens, ret);6014 if (ret <= 0)6015 {6016 sharkd_json_error(6017 rpcid, -32600, NULL((void*)0),6018 "Invalid JSON(2)"6019 );6020 continue;6021 }6022 6023 host_name_lookup_process();6024 6025 sharkd_session_process(buf, tokens, ret);6026 }6027 6028 g_hash_table_destroy(filter_table);6029 g_free(tokens);6030 6031 return 0;6032}
1/** @file2 *3 * Definitions and functions for I/O graph items4 *5 * Copied from gtk/io_stat.c, (c) 2002 Ronnie Sahlberg6 *7 * Wireshark - Network traffic analyzer8 * By Gerald Combs <[emailprotected]>9 * Copyright 1998 Gerald Combs10 *11 * SPDX-License-Identifier: GPL-2.0-or-later12 */13 14#ifndef __IO_GRAPH_ITEM_H__15#define __IO_GRAPH_ITEM_H__16 17#include "cfile.h"18#include <wsutil/ws_assert.h>19 20#include <epan/epan_dissect.h>21 22#ifdef __cplusplus23extern "C" {24#endif /* __cplusplus */25 26typedef enum {27 IOG_ITEM_UNIT_FIRST,28 IOG_ITEM_UNIT_PACKETS = IOG_ITEM_UNIT_FIRST,29 IOG_ITEM_UNIT_BYTES,30 IOG_ITEM_UNIT_BITS,31 IOG_ITEM_UNIT_CALC_SUM,32 IOG_ITEM_UNIT_CALC_FRAMES,33 IOG_ITEM_UNIT_CALC_FIELDS,34 IOG_ITEM_UNIT_CALC_MAX,35 IOG_ITEM_UNIT_CALC_MIN,36 IOG_ITEM_UNIT_CALC_AVERAGE,37 IOG_ITEM_UNIT_CALC_THROUGHPUT,38 IOG_ITEM_UNIT_CALC_LOAD,39 IOG_ITEM_UNIT_LAST = IOG_ITEM_UNIT_CALC_LOAD,40 NUM_IOG_ITEM_UNITS41} io_graph_item_unit_t;42 43typedef struct _io_graph_item_t {44 uint32_t frames; /* always calculated, will hold number of frames*/45 uint64_t bytes; /* always calculated, will hold number of bytes*/46 uint64_t fields;47 /* We use a double for totals because of overflow. For min and max,48 * unsigned 64 bit integers larger than 2^53 cannot all be represented49 * in a double, and this is useful for determining the frame with the50 * min or max value, even though for plotting it will be converted to a51 * double.52 */53 union {54 nstime_t time_max;55 double double_max;56 int64_t int_max;57 uint64_t uint_max;58 };59 union {60 nstime_t time_min;61 double double_min;62 int64_t int_min;63 uint64_t uint_min;64 };65 union {66 nstime_t time_tot;67 double double_tot;68 };69 uint32_t first_frame_in_invl;70 uint32_t min_frame_in_invl;71 uint32_t max_frame_in_invl;72 uint32_t last_frame_in_invl;73} io_graph_item_t;74 75/** Reset (zero) an io_graph_item_t.76 *77 * @param items [in,out] Array containing the items to reset.78 * @param count [in] The number of items in the array.79 */80static inline void81reset_io_graph_items(io_graph_item_t *items, size_t count, int hf_index _U___attribute__((unused))) {82 io_graph_item_t *item;83 size_t i;84 85 for (i = 0; i < count; i++) {

12

Assuming 'i' is >= 'count'

13

Loop condition is false. Execution continues on line 85

86 item = &items[i];87 88 item->frames = 0;89 item->bytes = 0;90 item->fields = 0;91 item->first_frame_in_invl = 0;92 item->min_frame_in_invl = 0;93 item->max_frame_in_invl = 0;94 item->last_frame_in_invl = 0;95 96 nstime_set_zero(&item->time_max);97 nstime_set_zero(&item->time_min);98 nstime_set_zero(&item->time_tot);99 100#if 0101 /* XXX - On C, type punning is explicitly allowed since C99 so102 * setting the nstime_t values to 0 is always sufficient.103 * On C++ that appears technically to be undefined behavior (though104 * I don't know of any compilers for which it doesn't work and I105 * can't get UBSAN to complain about it) and this would be safer.106 */107 if (hf_index > 0) {108 109 switch (proto_registrar_get_ftype(hf_index)) {110 111 case FT_INT8:112 case FT_INT16:113 case FT_INT24:114 case FT_INT32:115 case FT_INT40:116 case FT_INT48:117 case FT_INT56:118 case FT_INT64:119 item->int_max = 0;120 item->int_min = 0;121 item->double_tot = 0;122 break;123 124 case FT_UINT8:125 case FT_UINT16:126 case FT_UINT24:127 case FT_UINT32:128 case FT_UINT40:129 case FT_UINT48:130 case FT_UINT56:131 case FT_UINT64:132 item->uint_max = 0;133 item->uint_min = 0;134 item->double_tot = 0;135 break;136 137 case FT_DOUBLE:138 case FT_FLOAT:139 item->double_max = 0;140 item->double_min = 0;141 item->double_tot = 0;142 break;143 144 case FT_RELATIVE_TIME:145 nstime_set_zero(&item->time_max);146 nstime_set_zero(&item->time_min);147 nstime_set_zero(&item->time_tot);148 break;149 150 default:151 break;152 }153 }154#endif155 }156}157 158/** Get the interval (array index) for a packet159 *160 * It is up to the caller to determine if the return value is valid.161 *162 * @param [in] pinfo Packet of interest.163 * @param [in] interval Time interval in microseconds164 * @return Array index on success, -1 on failure.165 *166 * @note pinfo->rel_ts, and hence the index, is not affected by ignoring167 * frames, but is affected by time references. (Ignoring frames before168 * a time reference can be useful, though.)169 */170int64_t get_io_graph_index(packet_info *pinfo, int interval);171 172/** Check field and item unit compatibility173 *174 * @param field_name [in] Header field name to check175 * @param hf_index [out] Assigned the header field index corresponding to field_name if valid.176 * Can be NULL.177 * @param item_unit [in] The type of unit to calculate. From IOG_ITEM_UNITS.178 * @return NULL if compatible, otherwise an error string. The string must179 * be freed by the caller.180 */181GString *check_field_unit(const char *field_name, int *hf_index, io_graph_item_unit_t item_unit);182 183/** Get the value at the given interval (idx) for the current value unit.184 *185 * @param items [in] Array containing the item to get.186 * @param val_units [in] The type of unit to calculate. From IOG_ITEM_UNITS.187 * @param idx [in] Index of the item to get.188 * @param hf_index [in] Header field index for advanced statistics.189 * @param cap_file [in] Capture file.190 * @param interval [in] Timing interval in ms.191 * @param cur_idx [in] Current index.192 */193double get_io_graph_item(const io_graph_item_t *items, io_graph_item_unit_t val_units, int idx, int hf_index, const capture_file *cap_file, int interval, int cur_idx);194 195/** Update the values of an io_graph_item_t.196 *197 * Frame and byte counts are always calculated. If edt is non-NULL advanced198 * statistics are calculated using hfindex.199 *200 * @param items [in,out] Array containing the item to update.201 * @param idx [in] Index of the item to update.202 * @param pinfo [in] Packet containing update information.203 * @param edt [in] Dissection information for advanced statistics. May be NULL.204 * @param hf_index [in] Header field index for advanced statistics.205 * @param item_unit [in] The type of unit to calculate. From IOG_ITEM_UNITS.206 * @param interval [in] Timing interval in μs.207 * @return true if the update was successful, otherwise false.208 */209static inline bool_Bool210update_io_graph_item(io_graph_item_t *items, int idx, packet_info *pinfo, epan_dissect_t *edt, int hf_index, int item_unit, uint32_t interval) {211 io_graph_item_t *item = &items[idx];212 213 /* Set the first and last frame num in current interval matching the target field+filter */214 if (item->first_frame_in_invl == 0) {

16

The left operand of '==' is a garbage value
215 item->first_frame_in_invl = pinfo->num;216 }217 item->last_frame_in_invl = pinfo->num;218 219 if (edt && hf_index >= 0) {220 GPtrArray *gp;221 unsigned i;222 223 gp = proto_get_finfo_ptr_array(edt->tree, hf_index);224 if (!gp) {225 return false0;226 }227 228 /* Update the appropriate counters. If fields == 0, this is the first seen229 * value so set any min/max values accordingly. */230 for (i=0; i < gp->len; i++) {231 int64_t new_int64;232 uint64_t new_uint64;233 float new_float;234 double new_double;235 const nstime_t *new_time;236 237 switch (proto_registrar_get_ftype(hf_index)) {238 case FT_UINT8:239 case FT_UINT16:240 case FT_UINT24:241 case FT_UINT32:242 new_uint64 = fvalue_get_uinteger(((field_info *)gp->pdata[i])->value);243 244 if ((new_uint64 > item->uint_max) || (item->fields == 0)) {245 item->uint_max = new_uint64;246 item->max_frame_in_invl = pinfo->num;247 }248 if ((new_uint64 < item->uint_min) || (item->fields == 0)) {249 item->uint_min = new_uint64;250 item->min_frame_in_invl = pinfo->num;251 }252 item->double_tot += (double)new_uint64;253 item->fields++;254 break;255 case FT_INT8:256 case FT_INT16:257 case FT_INT24:258 case FT_INT32:259 new_int64 = fvalue_get_sinteger(((field_info *)gp->pdata[i])->value);260 if ((new_int64 > item->int_max) || (item->fields == 0)) {261 item->int_max = new_int64;262 item->max_frame_in_invl = pinfo->num;263 }264 if ((new_int64 < item->int_min) || (item->fields == 0)) {265 item->int_min = new_int64;266 item->min_frame_in_invl = pinfo->num;267 }268 item->double_tot += (double)new_int64;269 item->fields++;270 break;271 case FT_UINT40:272 case FT_UINT48:273 case FT_UINT56:274 case FT_UINT64:275 new_uint64 = fvalue_get_uinteger64(((field_info *)gp->pdata[i])->value);276 if ((new_uint64 > item->uint_max) || (item->fields == 0)) {277 item->uint_max = new_uint64;278 item->max_frame_in_invl = pinfo->num;279 }280 if ((new_uint64 < item->uint_min) || (item->fields == 0)) {281 item->uint_min = new_uint64;282 item->min_frame_in_invl = pinfo->num;283 }284 item->double_tot += (double)new_uint64;285 item->fields++;286 break;287 case FT_INT40:288 case FT_INT48:289 case FT_INT56:290 case FT_INT64:291 new_int64 = fvalue_get_sinteger64(((field_info *)gp->pdata[i])->value);292 if ((new_int64 > item->int_max) || (item->fields == 0)) {293 item->int_max = new_int64;294 item->max_frame_in_invl = pinfo->num;295 }296 if ((new_int64 < item->int_min) || (item->fields == 0)) {297 item->int_min = new_int64;298 item->min_frame_in_invl = pinfo->num;299 }300 item->double_tot += (double)new_int64;301 item->fields++;302 break;303 case FT_FLOAT:304 new_float = (float)fvalue_get_floating(((field_info *)gp->pdata[i])->value);305 if ((new_float > item->double_max) || (item->fields == 0)) {306 item->double_max = new_float;307 item->max_frame_in_invl = pinfo->num;308 }309 if ((new_float < item->double_min) || (item->fields == 0)) {310 item->double_min = new_float;311 item->min_frame_in_invl = pinfo->num;312 }313 item->double_tot += new_float;314 item->fields++;315 break;316 case FT_DOUBLE:317 new_double = fvalue_get_floating(((field_info *)gp->pdata[i])->value);318 if ((new_double > item->double_max) || (item->fields == 0)) {319 item->double_max = new_double;320 item->max_frame_in_invl = pinfo->num;321 }322 if ((new_double < item->double_min) || (item->fields == 0)) {323 item->double_min = new_double;324 item->min_frame_in_invl = pinfo->num;325 }326 item->double_tot += new_double;327 item->fields++;328 break;329 case FT_RELATIVE_TIME:330 new_time = fvalue_get_time(((field_info *)gp->pdata[i])->value);331 332 switch (item_unit) {333 case IOG_ITEM_UNIT_CALC_LOAD:334 {335 uint64_t t, pt; /* time in us */336 int j;337 /*338 * Add the time this call spanned each interval according to339 * its contribution to that interval.340 * If the call time is negative (unlikely, requires both an341 * out of order capture file plus retransmission), ignore.342 */343 const nstime_t time_zero = NSTIME_INIT_ZERO{0, 0};344 if (nstime_cmp(new_time, &time_zero) < 0) {345 break;346 }347 t = new_time->secs;348 t = t * 1000000 + new_time->nsecs / 1000;349 j = idx;350 /*351 * Handle current interval352 * This cannot be negative, because get_io_graph_index353 * returns an invalid interval if so.354 */355 pt = pinfo->rel_ts.secs * 1000000 + pinfo->rel_ts.nsecs / 1000;356 pt = pt % interval;357 if (pt > t) {358 pt = t;359 }360 while (t) {361 io_graph_item_t *load_item;362 363 load_item = &items[j];364 load_item->time_tot.nsecs += (int) (pt * 1000);365 if (load_item->time_tot.nsecs > 1000000000) {366 load_item->time_tot.secs++;367 load_item->time_tot.nsecs -= 1000000000;368 }369 load_item->fields++;370 371 if (j == 0) {372 break;373 }374 j--;375 t -= pt;376 if (t > (uint64_t) interval) {377 pt = (uint64_t) interval;378 } else {379 pt = t;380 }381 }382 break;383 }384 default:385 if ( (nstime_cmp(new_time, &item->time_max) > 0)386 || (item->fields == 0)) {387 item->time_max = *new_time;388 item->max_frame_in_invl = pinfo->num;389 }390 if ( (nstime_cmp(new_time, &item->time_min) < 0)391 || (item->fields == 0)) {392 item->time_min = *new_time;393 item->min_frame_in_invl = pinfo->num;394 }395 nstime_add(&item->time_tot, new_time)nstime_sum(&item->time_tot, &item->time_tot, new_time
)
;396 item->fields++;397 }398 break;399 default:400 if ((item_unit == IOG_ITEM_UNIT_CALC_FRAMES) ||401 (item_unit == IOG_ITEM_UNIT_CALC_FIELDS)) {402 /*403 * It's not an integeresque type, but404 * all we want to do is count it, so405 * that's all right.406 */407 item->fields++;408 }409 else {410 /*411 * "Can't happen"; see the "check that the412 * type is compatible" check in413 * filter_callback().414 */415 ws_assert_not_reached()ws_log_fatal_full("", LOG_LEVEL_ERROR, "ui/io_graph_item.h", 415
, __func__, "assertion \"not reached\" failed")
;416 }417 break;418 }419 }420 }421 422 item->frames++;423 item->bytes += pinfo->fd->pkt_len;424 425 return true1;426}427 428 429#ifdef __cplusplus430}431#endif /* __cplusplus */432 433#endif /* __IO_GRAPH_ITEM_H__ */
/builds/wireshark/wireshark/ui/io_graph_item.h (2024)

References

Top Articles
54 Old-School Recipes That Deserve a Comeback
Samosa Chaatdish Recipe (Indian Tater Tot Hotdish) — Worthy Pause
Steve Bannon Issues Warning To Donald Trump
Aged Grimm Character Nyt Crossword
Craigslist The Big Island
Tripadvisor London Forum
NO CLUE: deutsche Übersetzung von NCT 127
Subfinder Online
Www.citizen-Times.com Obituaries
People Helping Others Property
Yasmin Boland Daily Horoscope
Wlds Obits
10000 Divided By 5
Mychart.solutionhealth.org/Mychartprd/Billing/Summary
Espn Masters Leaderboard
Inloggen bij AH Sam - E-Overheid
Sauce 423405
Wvtm 13 Schedule
Keci News
Mifflin County 24 Hour Auction
Spirited Showtimes Near Gqt Kalamazoo 10
American Eagle Store Locator
Ratchet And Clank Tools Of Destruction Rpcs3 Freeze
Meridamoonbeams
Truist Business Checking: 2024 Review
Emma D'arcy Deepfake
Gary Keesee Kingdom Principles Pdf
Chris Bailey Weather Forecast
4201 Crossroads Wy, Rancho Cordova, CA 95742 - MLS 224103058 - Coldwell Banker
San Bernardino Pick A Part Inventory
Craigslist Used Motorhomes For Sale By Owner
Snowy Hydro Truck Jobs in All Sydney NSW - Sep 2024 | SEEK
Most Popular Pub food in Lipetsk, Lipetsk Oblast, Russia
Cooktopcove Com
Rule 34 Supreme Court: Key Insights and Implications
Alexis Drake Donation Request
Psalm 136 Nkjv
Lockstraps Net Worth
eCare: Nutzung am PC | BARMER
Giant Egg Classic Wow
Fineassarri
Dimensional Doors Mod (1.20.1, 1.19.4) - Pocket Dimensions
Hocus Pocus Showtimes Near Harkins Theatres Yuma Palms 14
Tillamook Headlight Herald Obituaries
Grizzly Expiration Date 2023
Can You Change Your Breathing Style In Demonfall
Love In Orbit Manga Buddy
Immobiliare di Felice| Appartamento | Appartamento in vendita Porto San
Rexford Tucker Pritchett
Konami announces TGS 2024 lineup, schedule
Only Partly Forgotten Wotlk
Texas State Final Grades
Latest Posts
Article information

Author: Sen. Emmett Berge

Last Updated:

Views: 5989

Rating: 5 / 5 (60 voted)

Reviews: 91% of readers found this page helpful

Author information

Name: Sen. Emmett Berge

Birthday: 1993-06-17

Address: 787 Elvis Divide, Port Brice, OH 24507-6802

Phone: +9779049645255

Job: Senior Healthcare Specialist

Hobby: Cycling, Model building, Kitesurfing, Origami, Lapidary, Dance, Basketball

Introduction: My name is Sen. Emmett Berge, I am a funny, vast, charming, courageous, enthusiastic, jolly, famous person who loves writing and wants to share my knowledge and understanding with you.