forked from osmocom/wireshark
Add initial support for BBLog files
This commit is contained in:
parent
8c4543373a
commit
b17f354304
|
@ -28,6 +28,7 @@ libwiretap.so.0 libwiretap0 #MINVER#
|
|||
wtap_block_add_if_filter_option@Base 3.5.0
|
||||
wtap_block_add_ipv4_option@Base 2.1.2
|
||||
wtap_block_add_ipv6_option@Base 2.1.2
|
||||
wtap_block_add_nflx_custom_option@Base 3.5.0
|
||||
wtap_block_add_string_option@Base 2.1.2
|
||||
wtap_block_add_string_option_format@Base 2.1.2
|
||||
wtap_block_add_uint32_option@Base 3.5.0
|
||||
|
@ -43,6 +44,7 @@ libwiretap.so.0 libwiretap0 #MINVER#
|
|||
wtap_block_get_ipv4_option_value@Base 2.1.2
|
||||
wtap_block_get_ipv6_option_value@Base 2.1.2
|
||||
wtap_block_get_mandatory_data@Base 2.1.2
|
||||
wtap_block_get_nflx_custom_option@Base 3.5.0
|
||||
wtap_block_get_nth_bytes_option_value@Base 3.5.0
|
||||
wtap_block_get_nth_string_option_value@Base 2.1.2
|
||||
wtap_block_get_options_size_padded@Base 3.5.0
|
||||
|
|
|
@ -734,6 +734,7 @@ set(DISSECTOR_SRC
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/packet-banana.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/packet-bat.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/packet-batadv.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/packet-bblog.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/packet-bctp.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/packet-beep.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/packet-bencode.c
|
||||
|
|
|
@ -0,0 +1,419 @@
|
|||
/* packet-bblog.c
|
||||
* Routines for Black Box Log dissection
|
||||
* Copyright 2021 Michael Tuexen <tuexen [AT] wireshark.org>
|
||||
*
|
||||
* Wireshark - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@wireshark.org>
|
||||
* Copyright 1998 Gerald Combs
|
||||
*
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <epan/packet.h>
|
||||
|
||||
void proto_register_bblog_event(void);
|
||||
void proto_reg_handoff_bblog(void);
|
||||
|
||||
static int proto_bblog = -1;
|
||||
|
||||
static int hf_ticks = -1;
|
||||
static int hf_serial_nr = -1;
|
||||
static int hf_stack_id = -1;
|
||||
static int hf_event_id = -1;
|
||||
static int hf_event_flags = -1;
|
||||
static int hf_event_flags_rxbuf = -1;
|
||||
static int hf_event_flags_txbuf = -1;
|
||||
static int hf_event_flags_hdr = -1;
|
||||
static int hf_event_flags_verbose = -1;
|
||||
static int hf_event_flags_stack = -1;
|
||||
static int hf_errno = -1;
|
||||
static int hf_rxb_acc = -1;
|
||||
static int hf_rxb_ccc = -1;
|
||||
static int hf_rxb_spare = -1;
|
||||
static int hf_txb_acc = -1;
|
||||
static int hf_txb_ccc = -1;
|
||||
static int hf_txb_spare = -1;
|
||||
static int hf_state = -1;
|
||||
static int hf_starttime = -1;
|
||||
static int hf_iss = -1;
|
||||
static int hf_flags = -1;
|
||||
static int hf_snd_una = -1;
|
||||
static int hf_snd_max = -1;
|
||||
static int hf_snd_cwnd = -1;
|
||||
static int hf_snd_nxt = -1;
|
||||
static int hf_snd_recover = -1;
|
||||
static int hf_snd_wnd = -1;
|
||||
static int hf_snd_ssthresh = -1;
|
||||
static int hf_srtt = -1;
|
||||
static int hf_rttvar = -1;
|
||||
static int hf_rcv_up = -1;
|
||||
static int hf_rcv_adv = -1;
|
||||
static int hf_flags2 = -1;
|
||||
static int hf_rcv_nxt = -1;
|
||||
static int hf_rcv_wnd = -1;
|
||||
static int hf_dupacks = -1;
|
||||
static int hf_seg_qlen = -1;
|
||||
static int hf_snd_num_holes = -1;
|
||||
static int hf_flex_1 = -1;
|
||||
static int hf_flex_2 = -1;
|
||||
static int hf_first_byte_in = -1;
|
||||
static int hf_first_byte_out = -1;
|
||||
static int hf_snd_scale = -1;
|
||||
static int hf_rcv_scale = -1;
|
||||
static int hf_pad_1 = -1;
|
||||
static int hf_pad_2 = -1;
|
||||
static int hf_pad_3 = -1;
|
||||
static int hf_payload_len = -1;
|
||||
|
||||
static gint ett_bblog = -1;
|
||||
static gint ett_bblog_flags = -1;
|
||||
|
||||
#define TCP_LOG_IN 1
|
||||
#define TCP_LOG_OUT 2
|
||||
#define TCP_LOG_RTO 3
|
||||
#define TCP_LOG_SB_WAKE 4
|
||||
#define TCP_LOG_BAD_RETRAN 5
|
||||
#define TCP_LOG_PRR 6
|
||||
#define TCP_LOG_REORDER 7
|
||||
#define TCP_LOG_HPTS 8
|
||||
#define BBR_LOG_BBRUPD 9
|
||||
#define BBR_LOG_BBRSND 10
|
||||
#define BBR_LOG_ACKCLEAR 11
|
||||
#define BBR_LOG_INQUEUE 12
|
||||
#define BBR_LOG_TIMERSTAR 13
|
||||
#define BBR_LOG_TIMERCANC 14
|
||||
#define BBR_LOG_ENTREC 15
|
||||
#define BBR_LOG_EXITREC 16
|
||||
#define BBR_LOG_CWND 17
|
||||
#define BBR_LOG_BWSAMP 18
|
||||
#define BBR_LOG_MSGSIZE 19
|
||||
#define BBR_LOG_BBRRTT 20
|
||||
#define BBR_LOG_JUSTRET 21
|
||||
#define BBR_LOG_STATE 22
|
||||
#define BBR_LOG_PKT_EPOCH 23
|
||||
#define BBR_LOG_PERSIST 24
|
||||
#define TCP_LOG_FLOWEND 25
|
||||
#define BBR_LOG_RTO 26
|
||||
#define BBR_LOG_DOSEG_DONE 27
|
||||
#define BBR_LOG_EXIT_GAIN 28
|
||||
#define BBR_LOG_THRESH_CALC 29
|
||||
#define TCP_LOG_MAPCHG 30
|
||||
#define TCP_LOG_USERSEND 31
|
||||
#define BBR_RSM_CLEARED 32
|
||||
#define BBR_LOG_STATE_TARGET 33
|
||||
#define BBR_LOG_TIME_EPOCH 34
|
||||
#define BBR_LOG_TO_PROCESS 35
|
||||
#define BBR_LOG_BBRTSO 36
|
||||
#define BBR_LOG_HPTSDIAG 37
|
||||
#define BBR_LOG_LOWGAIN 38
|
||||
#define BBR_LOG_PROGRESS 39
|
||||
#define TCP_LOG_SOCKET_OPT 40
|
||||
#define BBR_LOG_TIMERPREP 41
|
||||
#define BBR_LOG_ENOBUF_JMP 42
|
||||
#define BBR_LOG_HPTSI_CALC 43
|
||||
#define BBR_LOG_RTT_SHRINKS 44
|
||||
#define BBR_LOG_BW_RED_EV 45
|
||||
#define BBR_LOG_REDUCE 46
|
||||
#define TCP_LOG_RTT 47
|
||||
#define BBR_LOG_SETTINGS_CHG 48
|
||||
#define BBR_LOG_SRTT_GAIN_EVENT 49
|
||||
#define TCP_LOG_REASS 50
|
||||
#define TCP_HDWR_TLS 51
|
||||
#define BBR_LOG_HDWR_PACE 52
|
||||
#define BBR_LOG_TSTMP_VAL 53
|
||||
#define TCP_LOG_CONNEND 54
|
||||
#define TCP_LOG_LRO 55
|
||||
#define TCP_SACK_FILTER_RES 56
|
||||
#define TCP_SAD_DETECTION 57
|
||||
#define TCP_TIMELY_WORK 58
|
||||
#define TCP_LOG_USER_EVENT 59
|
||||
#define TCP_LOG_SENDFILE 60
|
||||
#define TCP_LOG_HTTP_T 61
|
||||
#define TCP_LOG_ACCOUNTING 62
|
||||
#define TCP_LOG_FSB 63
|
||||
|
||||
|
||||
static const value_string event_identifier_values[] = {
|
||||
{ TCP_LOG_IN, "Incoming packet" },
|
||||
{ TCP_LOG_OUT, "Transmit (without other event)" },
|
||||
{ TCP_LOG_RTO, "Retransmit timeout" },
|
||||
{ TCP_LOG_SB_WAKE, "Awaken socket buffer" },
|
||||
{ TCP_LOG_BAD_RETRAN, "Detected bad retransmission" },
|
||||
{ TCP_LOG_PRR, "Doing PRR" },
|
||||
{ TCP_LOG_REORDER, "Detected reorder" },
|
||||
{ TCP_LOG_HPTS, "Hpts sending a packet" },
|
||||
{ BBR_LOG_BBRUPD, "We updated BBR info" },
|
||||
{ BBR_LOG_BBRSND, "We did a slot calculation and sending is done" },
|
||||
{ BBR_LOG_ACKCLEAR, "A ack clears all outstanding" },
|
||||
{ BBR_LOG_INQUEUE, "The tcb had a packet input to it" },
|
||||
{ BBR_LOG_TIMERSTAR, "Start a timer" },
|
||||
{ BBR_LOG_TIMERCANC, "Cancel a timer" },
|
||||
{ BBR_LOG_ENTREC, "Entered recovery" },
|
||||
{ BBR_LOG_EXITREC, "Exited recovery" },
|
||||
{ BBR_LOG_CWND, "Cwnd change" },
|
||||
{ BBR_LOG_BWSAMP, "LT B/W sample has been made" },
|
||||
{ BBR_LOG_MSGSIZE, "We received a EMSGSIZE error" },
|
||||
{ BBR_LOG_BBRRTT, "BBR RTT is updated" },
|
||||
{ BBR_LOG_JUSTRET, "We just returned out of output" },
|
||||
{ BBR_LOG_STATE, "A BBR state change occured" },
|
||||
{ BBR_LOG_PKT_EPOCH, "A BBR packet epoch occured" },
|
||||
{ BBR_LOG_PERSIST, "BBR changed to/from a persists" },
|
||||
{ TCP_LOG_FLOWEND, "End of a flow" },
|
||||
{ BBR_LOG_RTO, "BBR's timeout includes BBR info" },
|
||||
{ BBR_LOG_DOSEG_DONE, "hpts do_segment completes" },
|
||||
{ BBR_LOG_EXIT_GAIN, "hpts do_segment completes" },
|
||||
{ BBR_LOG_THRESH_CALC, "Doing threshold calculation" },
|
||||
{ TCP_LOG_MAPCHG, "Map Changes to the sendmap" },
|
||||
{ TCP_LOG_USERSEND, "User level sends data" },
|
||||
{ BBR_RSM_CLEARED, "RSM cleared of ACK flags" },
|
||||
{ BBR_LOG_STATE_TARGET, "Log of target at state" },
|
||||
{ BBR_LOG_TIME_EPOCH, "A timed based Epoch occured" },
|
||||
{ BBR_LOG_TO_PROCESS, "A to was processed" },
|
||||
{ BBR_LOG_BBRTSO, "TSO update" },
|
||||
{ BBR_LOG_HPTSDIAG, "Hpts diag insert" },
|
||||
{ BBR_LOG_LOWGAIN, "Low gain accounting" },
|
||||
{ BBR_LOG_PROGRESS, "Progress timer event" },
|
||||
{ TCP_LOG_SOCKET_OPT, "A socket option is set" },
|
||||
{ BBR_LOG_TIMERPREP, "A BBR var to debug out TLP issues" },
|
||||
{ BBR_LOG_ENOBUF_JMP, "We had a enobuf jump" },
|
||||
{ BBR_LOG_HPTSI_CALC, "calc the hptsi time" },
|
||||
{ BBR_LOG_RTT_SHRINKS, "We had a log reduction of rttProp" },
|
||||
{ BBR_LOG_BW_RED_EV, "B/W reduction events" },
|
||||
{ BBR_LOG_REDUCE, "old bbr log reduce for 4.1 and earlier" },
|
||||
{ TCP_LOG_RTT, "A rtt (in useconds) is being sampled and applied to the srtt algo" },
|
||||
{ BBR_LOG_SETTINGS_CHG, "Settings changed for loss response 48" },
|
||||
{ BBR_LOG_SRTT_GAIN_EVENT, "SRTT gaining -- now not used" },
|
||||
{ TCP_LOG_REASS, "Reassembly buffer logging" },
|
||||
{ TCP_HDWR_TLS, "TCP Hardware TLS logs" },
|
||||
{ BBR_LOG_HDWR_PACE, "TCP Hardware pacing log" },
|
||||
{ BBR_LOG_TSTMP_VAL, "Temp debug timestamp validation" },
|
||||
{ TCP_LOG_CONNEND, "End of connection" },
|
||||
{ TCP_LOG_LRO, "LRO entry" },
|
||||
{ TCP_SACK_FILTER_RES, "Results of SACK Filter" },
|
||||
{ TCP_SAD_DETECTION, "Sack Attack Detection" },
|
||||
{ TCP_TIMELY_WORK, "Logs regarding Timely CC tweaks" },
|
||||
{ TCP_LOG_USER_EVENT, "User space event data" },
|
||||
{ TCP_LOG_SENDFILE, "sendfile() logging for TCP connections" },
|
||||
{ TCP_LOG_HTTP_T, "logging of http request tracking" },
|
||||
{ TCP_LOG_ACCOUNTING, "Log of TCP Accounting data" },
|
||||
{ TCP_LOG_FSB, "FSB information 63" },
|
||||
{ 0, NULL } };
|
||||
|
||||
static const value_string tcp_state_values[] = {
|
||||
{ 0, "CLOSED" },
|
||||
{ 1, "LISTEN" },
|
||||
{ 2, "SYN SENT" },
|
||||
{ 3, "SYN RECEIVED" },
|
||||
{ 4, "ESTABLISHED" },
|
||||
{ 5, "CLOSE WAIT" },
|
||||
{ 6, "FIN WAIT 1" },
|
||||
{ 7, "CLOSING" },
|
||||
{ 8, "LAST ACK" },
|
||||
{ 9, "FIN WAIT 2" },
|
||||
{ 10, "TIME WAIT" },
|
||||
{ 0, NULL } };
|
||||
|
||||
#define EVENT_FLAG_RXBUF 0x0001
|
||||
#define EVENT_FLAG_TXBUF 0x0002
|
||||
#define EVENT_FLAG_HDR 0x0004
|
||||
#define EVENT_FLAG_VERBOSE 0x0008
|
||||
#define EVENT_FLAG_STACKINFO 0x0010
|
||||
|
||||
static const true_false_string event_flags_rxbuf = {
|
||||
"Receive buffer information available",
|
||||
"Receive buffer information not available"
|
||||
};
|
||||
|
||||
static const true_false_string event_flags_txbuf = {
|
||||
"Send buffer information available",
|
||||
"Send buffer information not available"
|
||||
};
|
||||
|
||||
static const true_false_string event_flags_hdr = {
|
||||
"TCP header available",
|
||||
"TCP header not available"
|
||||
};
|
||||
|
||||
static const true_false_string event_flags_verbose = {
|
||||
"Additional information available",
|
||||
"Additional information not available"
|
||||
};
|
||||
|
||||
static const true_false_string event_flags_stack = {
|
||||
"Stack specific information available",
|
||||
"Stack specific information not available"
|
||||
};
|
||||
|
||||
#define SND_SCALE_MASK 0xf0
|
||||
#define RCV_SCALE_MASK 0x0f
|
||||
|
||||
/*
|
||||
* The structures used here are defined in
|
||||
* https://cgit.freebsd.org/src/tree/sys/netinet/tcp_log_buf.h
|
||||
*/
|
||||
|
||||
static int
|
||||
dissect_bblog(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
|
||||
{
|
||||
proto_item *bblog_item, *event_flags_item;
|
||||
proto_tree *bblog_tree, *event_flags_tree;
|
||||
guint16 event_flags;
|
||||
|
||||
col_set_str(pinfo->cinfo, COL_PROTOCOL, "BBLog");
|
||||
col_append_fstr(pinfo->cinfo, COL_INFO, "%s", val_to_str_const(tvb_get_guint8(tvb, 25), event_identifier_values, "Unknown"));
|
||||
|
||||
bblog_item = proto_tree_add_item(tree, proto_bblog, tvb, 0, -1, ENC_NA);
|
||||
bblog_tree = proto_item_add_subtree(bblog_item, ett_bblog);
|
||||
|
||||
proto_tree_add_item(bblog_tree, hf_ticks, tvb, 16, 4, ENC_LITTLE_ENDIAN);
|
||||
proto_tree_add_item(bblog_tree, hf_serial_nr, tvb, 20, 4, ENC_LITTLE_ENDIAN);
|
||||
proto_tree_add_item(bblog_tree, hf_stack_id, tvb, 24, 1, ENC_LITTLE_ENDIAN);
|
||||
proto_tree_add_item(bblog_tree, hf_event_id, tvb, 25, 1, ENC_LITTLE_ENDIAN);
|
||||
|
||||
event_flags = tvb_get_letohs(tvb, 26);
|
||||
event_flags_item = proto_tree_add_item(bblog_tree, hf_event_flags, tvb, 26, 2, ENC_LITTLE_ENDIAN);
|
||||
event_flags_tree = proto_item_add_subtree(event_flags_item, ett_bblog_flags);
|
||||
proto_tree_add_item(event_flags_tree, hf_event_flags_rxbuf, tvb, 26, 2, ENC_LITTLE_ENDIAN);
|
||||
proto_tree_add_item(event_flags_tree, hf_event_flags_txbuf, tvb, 26, 2, ENC_LITTLE_ENDIAN);
|
||||
proto_tree_add_item(event_flags_tree, hf_event_flags_hdr, tvb, 26, 2, ENC_LITTLE_ENDIAN);
|
||||
proto_tree_add_item(event_flags_tree, hf_event_flags_verbose, tvb, 26, 2, ENC_LITTLE_ENDIAN);
|
||||
proto_tree_add_item(event_flags_tree, hf_event_flags_stack, tvb, 26, 2, ENC_LITTLE_ENDIAN);
|
||||
proto_tree_add_item(bblog_tree, hf_errno, tvb, 28, 4, ENC_LITTLE_ENDIAN);
|
||||
if (event_flags & EVENT_FLAG_RXBUF) {
|
||||
proto_tree_add_item(bblog_tree, hf_rxb_acc, tvb, 32, 4, ENC_LITTLE_ENDIAN);
|
||||
proto_tree_add_item(bblog_tree, hf_rxb_ccc, tvb, 36, 4, ENC_LITTLE_ENDIAN);
|
||||
proto_tree_add_item(bblog_tree, hf_rxb_spare, tvb, 40, 4, ENC_LITTLE_ENDIAN);
|
||||
}
|
||||
if (event_flags & EVENT_FLAG_TXBUF) {
|
||||
proto_tree_add_item(bblog_tree, hf_txb_acc, tvb, 44, 4, ENC_LITTLE_ENDIAN);
|
||||
proto_tree_add_item(bblog_tree, hf_txb_ccc, tvb, 48, 4, ENC_LITTLE_ENDIAN);
|
||||
proto_tree_add_item(bblog_tree, hf_txb_spare, tvb, 52, 4, ENC_LITTLE_ENDIAN);
|
||||
}
|
||||
proto_tree_add_item(bblog_tree, hf_state, tvb, 56, 4, ENC_LITTLE_ENDIAN);
|
||||
proto_tree_add_item(bblog_tree, hf_starttime, tvb, 60, 4, ENC_LITTLE_ENDIAN);
|
||||
proto_tree_add_item(bblog_tree, hf_iss, tvb, 64, 4, ENC_LITTLE_ENDIAN);
|
||||
proto_tree_add_item(bblog_tree, hf_flags, tvb, 68, 4, ENC_LITTLE_ENDIAN);
|
||||
proto_tree_add_item(bblog_tree, hf_snd_una, tvb, 72, 4, ENC_LITTLE_ENDIAN);
|
||||
proto_tree_add_item(bblog_tree, hf_snd_max, tvb, 76, 4, ENC_LITTLE_ENDIAN);
|
||||
proto_tree_add_item(bblog_tree, hf_snd_cwnd, tvb, 80, 4, ENC_LITTLE_ENDIAN);
|
||||
proto_tree_add_item(bblog_tree, hf_snd_nxt, tvb, 84, 4, ENC_LITTLE_ENDIAN);
|
||||
proto_tree_add_item(bblog_tree, hf_snd_recover, tvb, 88, 4, ENC_LITTLE_ENDIAN);
|
||||
proto_tree_add_item(bblog_tree, hf_snd_wnd, tvb, 92, 4, ENC_LITTLE_ENDIAN);
|
||||
proto_tree_add_item(bblog_tree, hf_snd_ssthresh, tvb, 96, 4, ENC_LITTLE_ENDIAN);
|
||||
proto_tree_add_item(bblog_tree, hf_srtt, tvb, 100, 4, ENC_LITTLE_ENDIAN);
|
||||
proto_tree_add_item(bblog_tree, hf_rttvar, tvb, 104, 4, ENC_LITTLE_ENDIAN);
|
||||
proto_tree_add_item(bblog_tree, hf_rcv_up, tvb, 108, 4, ENC_LITTLE_ENDIAN);
|
||||
proto_tree_add_item(bblog_tree, hf_rcv_adv, tvb, 112, 4, ENC_LITTLE_ENDIAN);
|
||||
proto_tree_add_item(bblog_tree, hf_flags2, tvb, 116, 4, ENC_LITTLE_ENDIAN);
|
||||
proto_tree_add_item(bblog_tree, hf_rcv_nxt, tvb, 120, 4, ENC_LITTLE_ENDIAN);
|
||||
proto_tree_add_item(bblog_tree, hf_rcv_wnd, tvb, 124, 4, ENC_LITTLE_ENDIAN);
|
||||
proto_tree_add_item(bblog_tree, hf_dupacks, tvb, 128, 4, ENC_LITTLE_ENDIAN);
|
||||
proto_tree_add_item(bblog_tree, hf_seg_qlen, tvb, 132, 4, ENC_LITTLE_ENDIAN);
|
||||
proto_tree_add_item(bblog_tree, hf_snd_num_holes, tvb, 136, 4, ENC_LITTLE_ENDIAN);
|
||||
proto_tree_add_item(bblog_tree, hf_flex_1, tvb, 140, 4, ENC_LITTLE_ENDIAN);
|
||||
proto_tree_add_item(bblog_tree, hf_flex_2, tvb, 144, 4, ENC_LITTLE_ENDIAN);
|
||||
proto_tree_add_item(bblog_tree, hf_first_byte_in, tvb, 148, 4, ENC_LITTLE_ENDIAN);
|
||||
proto_tree_add_item(bblog_tree, hf_first_byte_out, tvb, 152, 4, ENC_LITTLE_ENDIAN);
|
||||
proto_tree_add_item(bblog_tree, hf_snd_scale, tvb, 156, 1, ENC_LITTLE_ENDIAN);
|
||||
proto_tree_add_item(bblog_tree, hf_rcv_scale, tvb, 156, 1, ENC_LITTLE_ENDIAN);
|
||||
proto_tree_add_item(bblog_tree, hf_pad_1, tvb, 157, 1, ENC_LITTLE_ENDIAN);
|
||||
proto_tree_add_item(bblog_tree, hf_pad_2, tvb, 158, 1, ENC_LITTLE_ENDIAN);
|
||||
proto_tree_add_item(bblog_tree, hf_pad_3, tvb, 159, 1, ENC_LITTLE_ENDIAN);
|
||||
if (event_flags & EVENT_FLAG_STACKINFO) {
|
||||
/* stack specific data */
|
||||
}
|
||||
proto_tree_add_item(bblog_tree, hf_payload_len, tvb, 264, 4, ENC_LITTLE_ENDIAN);
|
||||
return tvb_captured_length(tvb);
|
||||
}
|
||||
|
||||
void
|
||||
proto_register_bblog(void)
|
||||
{
|
||||
static hf_register_info hf[] = {
|
||||
{ &hf_ticks, { "Ticks", "bblog.ticks", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL} },
|
||||
{ &hf_serial_nr, { "Serial Number", "bblog.serial_nr", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL} },
|
||||
{ &hf_stack_id, { "Stack Identifier", "bblog.stack_id", FT_UINT8, BASE_DEC, NULL , 0x0, NULL, HFILL} },
|
||||
{ &hf_event_id, { "Event Identifier", "bblog.event_id", FT_UINT8, BASE_DEC, VALS(event_identifier_values), 0x0, NULL, HFILL} },
|
||||
{ &hf_event_flags, { "Event Flags", "bblog.event_flags", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL} },
|
||||
{ &hf_event_flags_rxbuf, { "Bit", "bblog.event_flags_rxbuf", FT_BOOLEAN, 8, TFS(&event_flags_rxbuf), EVENT_FLAG_RXBUF, NULL, HFILL} },
|
||||
{ &hf_event_flags_txbuf, { "Bit", "bblog.event_flags_txbuf", FT_BOOLEAN, 8, TFS(&event_flags_txbuf), EVENT_FLAG_TXBUF, NULL, HFILL} },
|
||||
{ &hf_event_flags_hdr, { "Bit", "bblog.event_flags_hdr", FT_BOOLEAN, 8, TFS(&event_flags_hdr), EVENT_FLAG_HDR, NULL, HFILL} },
|
||||
{ &hf_event_flags_verbose, { "Bit", "bblog.event_flags_verbose", FT_BOOLEAN, 8, TFS(&event_flags_verbose), EVENT_FLAG_VERBOSE, NULL, HFILL} },
|
||||
{ &hf_event_flags_stack, { "Bit", "bblog.event_flags_stack", FT_BOOLEAN, 8, TFS(&event_flags_stack), EVENT_FLAG_STACKINFO, NULL, HFILL} },
|
||||
{ &hf_errno, { "Error Number", "bblog.errno", FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL} },
|
||||
{ &hf_rxb_acc, { "Receive Buffer ACC", "bblog.rxb_acc", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL} },
|
||||
{ &hf_rxb_ccc, { "Receive Buffer CCC", "bblog.rxb_ccc", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL} },
|
||||
{ &hf_rxb_spare, { "Receive Buffer Spare", "bblog.rxb_spare", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL} },
|
||||
{ &hf_txb_acc, { "Send Buffer ACC", "bblog.txb_acc", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL} },
|
||||
{ &hf_txb_ccc, { "Send Buffer CCC", "bblog.txb_accs", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL} },
|
||||
{ &hf_txb_spare, { "Send Buffer Spare", "bblog.txb_spare", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL} },
|
||||
{ &hf_state, { "TCP State", "bblog.state", FT_UINT32, BASE_DEC, VALS(tcp_state_values), 0x0, NULL, HFILL} },
|
||||
{ &hf_starttime, { "Starttime", "bblog.starttime", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL} },
|
||||
{ &hf_iss, { "Initial Sending Sequence Number (ISS)", "bblog.iss", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL} },
|
||||
{ &hf_flags, { "TCB Flags", "bblog.flags", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL} },
|
||||
{ &hf_snd_una, { "Oldest Unacknowledged Sequence Number (SND.UNA)", "bblog.snd_una", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL} },
|
||||
{ &hf_snd_max, { "Newest Sequence Number Sent (SND.MAX)", "bblog.snd_max", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL} },
|
||||
{ &hf_snd_cwnd, { "Congestion Window", "bblog.snd_cwnd", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL} },
|
||||
{ &hf_snd_nxt, { "Next Sequence Number (SND.NXT)", "bblog.snd_nxt", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL} },
|
||||
{ &hf_snd_recover, { "Recovery Sequence Number (SND.RECOVER)", "bblog.snd_recover", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL} },
|
||||
{ &hf_snd_wnd, { "Send Window (SND.WND)", "bblog.snd_wnd", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL} },
|
||||
{ &hf_snd_ssthresh, { "Slowstart Threshold (SSTHREASH)", "bblog.snd_ssthresh", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL} },
|
||||
{ &hf_srtt, { "Smoothed Round Trip Time (SRTT)", "bblog.srtt", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL} },
|
||||
{ &hf_rttvar, { "Round Trip Timer Variance (RTTVAR)", "bblog.rttvar", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL} },
|
||||
{ &hf_rcv_up, { "Receive Urgent Pointer (RCV.UP)", "bblog.rcv_up", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL} },
|
||||
{ &hf_rcv_adv, { "Receive Advanced (RCV.ADV)", "bblog.rcv_adv", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL} },
|
||||
{ &hf_flags2, { "TCB Flags2", "bblog.flags2", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL} },
|
||||
{ &hf_rcv_nxt, { "Receive Next (RCV.NXT)", "bblog.rcv_nxt", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL} },
|
||||
{ &hf_rcv_wnd, { "Receive Window (RCV.WND)", "bblog.rcv_wnd", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL} },
|
||||
{ &hf_dupacks, { "Duplicate Acknowledgements", "bblog.dupacks", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL} },
|
||||
{ &hf_seg_qlen, { "Segment Queue Length", "bblog.seg_qlen", FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL} },
|
||||
{ &hf_snd_num_holes, { "Number of Holes", "bblog.snd_num_holes", FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL} },
|
||||
{ &hf_flex_1, { "Flex 1", "bblog.flex_1", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL} },
|
||||
{ &hf_flex_2, { "Flex 2", "bblog.flex_2", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL} },
|
||||
{ &hf_first_byte_in, { "Time of First Byte In", "bblog.first_byte_in", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL} },
|
||||
{ &hf_first_byte_out, { "Time of First Byte Out", "bblog.first_byte_out", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL} },
|
||||
{ &hf_snd_scale, { "Shift Count for Send Window", "bblog.snd_shift", FT_UINT8, BASE_DEC, NULL, SND_SCALE_MASK, NULL, HFILL} },
|
||||
{ &hf_rcv_scale, { "Shift Count for Receive Window", "bblog.rcv_shift", FT_UINT8, BASE_DEC, NULL, RCV_SCALE_MASK, NULL, HFILL} },
|
||||
{ &hf_pad_1, { "Padding", "bblog.pad_1", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL} },
|
||||
{ &hf_pad_2, { "Padding", "bblog.pad_2", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL} },
|
||||
{ &hf_pad_3, { "Padding", "bblog.pad_3", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL} },
|
||||
{ &hf_payload_len, { "TCP Payload Length", "bblog.payload_length", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL} },
|
||||
};
|
||||
|
||||
/* Setup protocol subtree array */
|
||||
static gint *ett[] = {
|
||||
&ett_bblog,
|
||||
&ett_bblog_flags
|
||||
};
|
||||
|
||||
/* Register the protocol name and description */
|
||||
proto_bblog = proto_register_protocol("Black Box Log", "BBLog", "bblog");
|
||||
|
||||
/* Required function calls to register the header fields and subtrees */
|
||||
proto_register_field_array(proto_bblog, hf, array_length(hf));
|
||||
proto_register_subtree_array(ett, array_length(ett));
|
||||
|
||||
register_dissector("bblog", dissect_bblog, proto_bblog);
|
||||
}
|
||||
|
||||
void
|
||||
proto_reg_handoff_bblog(void)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Editor modelines - https://www.wireshark.org/tools/modelines.html
|
||||
*
|
||||
* Local variables:
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 8
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*
|
||||
* vi: set shiftwidth=4 tabstop=8 expandtab:
|
||||
* :indentSize=4:tabSize=8:noTabs=true:
|
||||
*/
|
|
@ -47,6 +47,7 @@ void proto_reg_handoff_frame(void);
|
|||
static int proto_frame = -1;
|
||||
static int proto_pkt_comment = -1;
|
||||
static int proto_syscall = -1;
|
||||
static int proto_bblog = -1;
|
||||
|
||||
static int hf_frame_arrival_time = -1;
|
||||
static int hf_frame_shift_offset = -1;
|
||||
|
@ -94,6 +95,9 @@ static int hf_frame_pack_symbol_error = -1;
|
|||
static int hf_frame_wtap_encap = -1;
|
||||
static int hf_frame_cb_pen = -1;
|
||||
static int hf_frame_cb_copy_allowed = -1;
|
||||
static int hf_frame_bblog = -1;
|
||||
static int hf_frame_bblog_ticks = -1;
|
||||
static int hf_frame_bblog_serial_nr = -1;
|
||||
static int hf_comments_text = -1;
|
||||
|
||||
static gint ett_frame = -1;
|
||||
|
@ -101,6 +105,7 @@ static gint ett_ifname = -1;
|
|||
static gint ett_flags = -1;
|
||||
static gint ett_comments = -1;
|
||||
static gint ett_verdict = -1;
|
||||
static gint ett_bblog = -1;
|
||||
|
||||
static expert_field ei_comments_text = EI_INIT;
|
||||
static expert_field ei_arrive_time_out_of_range = EI_INIT;
|
||||
|
@ -111,6 +116,7 @@ static int frame_tap = -1;
|
|||
static dissector_handle_t docsis_handle;
|
||||
static dissector_handle_t sysdig_handle;
|
||||
static dissector_handle_t systemd_journal_handle;
|
||||
static dissector_handle_t bblog_handle;
|
||||
|
||||
/* Preferences */
|
||||
static gboolean show_file_off = FALSE;
|
||||
|
@ -350,6 +356,7 @@ dissect_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void*
|
|||
const color_filter_t *color_filter;
|
||||
dissector_handle_t dissector_handle;
|
||||
fr_foreach_t fr_user_data;
|
||||
struct nflx_tcpinfo tcpinfo;
|
||||
|
||||
tree=parent_tree;
|
||||
|
||||
|
@ -451,7 +458,14 @@ dissect_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void*
|
|||
break;
|
||||
|
||||
case REC_TYPE_CUSTOM_BLOCK:
|
||||
pinfo->current_proto = "PCAPNG Custom Block";
|
||||
switch (pinfo->rec->rec_header.custom_block_header.pen) {
|
||||
case PEN_NFLX:
|
||||
pinfo->current_proto = "Black Box Log";
|
||||
break;
|
||||
default:
|
||||
pinfo->current_proto = "PCAPNG Custom Block";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -581,18 +595,28 @@ dissect_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void*
|
|||
break;
|
||||
|
||||
case REC_TYPE_CUSTOM_BLOCK:
|
||||
ti = proto_tree_add_protocol_format(tree, proto_frame, tvb, 0, tvb_captured_length(tvb),
|
||||
"PCAPNG Custom Block %u: %u byte%s",
|
||||
pinfo->num, frame_len, frame_plurality);
|
||||
if (generate_bits_field) {
|
||||
proto_item_append_text(ti, " (%u bits)", frame_len * 8);
|
||||
switch (pinfo->rec->rec_header.custom_block_header.pen) {
|
||||
case PEN_NFLX:
|
||||
ti = proto_tree_add_protocol_format(tree, proto_bblog, tvb, 0, tvb_captured_length(tvb),
|
||||
"Black Box Log %u: %u byte%s",
|
||||
pinfo->num, frame_len, frame_plurality);
|
||||
break;
|
||||
default:
|
||||
ti = proto_tree_add_protocol_format(tree, proto_frame, tvb, 0, tvb_captured_length(tvb),
|
||||
"PCAPNG Custom Block %u: %u byte%s",
|
||||
pinfo->num, frame_len, frame_plurality);
|
||||
if (generate_bits_field) {
|
||||
proto_item_append_text(ti, " (%u bits)", frame_len * 8);
|
||||
}
|
||||
proto_item_append_text(ti, " of custom data and options, PEN %s (%u)",
|
||||
enterprises_lookup(pinfo->rec->rec_header.custom_block_header.pen, "Unknown"),
|
||||
pinfo->rec->rec_header.custom_block_header.pen);
|
||||
proto_item_append_text(ti, ", copying%s allowed",
|
||||
pinfo->rec->rec_header.custom_block_header.copy_allowed ? "" : " not");
|
||||
break;
|
||||
}
|
||||
proto_item_append_text(ti, " of custom data and options, PEN %s (%u)",
|
||||
enterprises_lookup(pinfo->rec->rec_header.custom_block_header.pen, "Unknown"),
|
||||
pinfo->rec->rec_header.custom_block_header.pen);
|
||||
proto_item_append_text(ti, ", copying%s allowed",
|
||||
pinfo->rec->rec_header.custom_block_header.copy_allowed ? "" : " not");
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
fh_tree = proto_item_add_subtree(ti, ett_frame);
|
||||
|
@ -763,6 +787,15 @@ dissect_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void*
|
|||
proto_tree_add_uint(fh_tree, hf_link_number, tvb,
|
||||
0, 0, pinfo->link_number);
|
||||
}
|
||||
if (WTAP_OPTTYPE_SUCCESS == wtap_block_get_nflx_custom_option(fr_data->pkt_block, NFLX_OPT_TYPE_TCPINFO, (char *)&tcpinfo, sizeof(struct nflx_tcpinfo))) {
|
||||
proto_tree *bblog_tree;
|
||||
proto_item *bblog_item;
|
||||
|
||||
bblog_item = proto_tree_add_string(fh_tree, hf_frame_bblog, tvb, 0, 0, "");
|
||||
bblog_tree = proto_item_add_subtree(bblog_item, ett_bblog);
|
||||
proto_tree_add_uint(bblog_tree, hf_frame_bblog_ticks, tvb, 0, 0, tcpinfo.tlb_ticks);
|
||||
proto_tree_add_uint(bblog_tree, hf_frame_bblog_serial_nr, tvb, 0, 0, tcpinfo.tlb_sn);
|
||||
}
|
||||
}
|
||||
|
||||
if (show_file_off) {
|
||||
|
@ -874,19 +907,29 @@ dissect_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void*
|
|||
break;
|
||||
|
||||
case REC_TYPE_CUSTOM_BLOCK:
|
||||
col_set_str(pinfo->cinfo, COL_PROTOCOL, "PCAPNG");
|
||||
proto_tree_add_uint_format_value(fh_tree, hf_frame_cb_pen, tvb, 0, 0,
|
||||
pinfo->rec->rec_header.custom_block_header.pen,
|
||||
"%s (%u)",
|
||||
enterprises_lookup(pinfo->rec->rec_header.custom_block_header.pen, "Unknown"),
|
||||
pinfo->rec->rec_header.custom_block_header.pen);
|
||||
proto_tree_add_boolean(fh_tree, hf_frame_cb_copy_allowed, tvb, 0, 0, pinfo->rec->rec_header.custom_block_header.copy_allowed);
|
||||
col_add_fstr(pinfo->cinfo, COL_INFO, "Custom Block: PEN = %s (%d), will%s be copied",
|
||||
enterprises_lookup(pinfo->rec->rec_header.custom_block_header.pen, "Unknown"),
|
||||
pinfo->rec->rec_header.custom_block_header.pen,
|
||||
pinfo->rec->rec_header.custom_block_header.copy_allowed ? "" : " not");
|
||||
call_data_dissector(tvb, pinfo, parent_tree);
|
||||
switch (pinfo->rec->rec_header.custom_block_header.pen) {
|
||||
case PEN_NFLX:
|
||||
call_dissector_with_data(bblog_handle,
|
||||
tvb, pinfo, parent_tree,
|
||||
(void *)pinfo->pseudo_header);
|
||||
break;
|
||||
default:
|
||||
col_set_str(pinfo->cinfo, COL_PROTOCOL, "PCAPNG");
|
||||
proto_tree_add_uint_format_value(fh_tree, hf_frame_cb_pen, tvb, 0, 0,
|
||||
pinfo->rec->rec_header.custom_block_header.pen,
|
||||
"%s (%u)",
|
||||
enterprises_lookup(pinfo->rec->rec_header.custom_block_header.pen, "Unknown"),
|
||||
pinfo->rec->rec_header.custom_block_header.pen);
|
||||
proto_tree_add_boolean(fh_tree, hf_frame_cb_copy_allowed, tvb, 0, 0, pinfo->rec->rec_header.custom_block_header.copy_allowed);
|
||||
col_add_fstr(pinfo->cinfo, COL_INFO, "Custom Block: PEN = %s (%d), will%s be copied",
|
||||
enterprises_lookup(pinfo->rec->rec_header.custom_block_header.pen, "Unknown"),
|
||||
pinfo->rec->rec_header.custom_block_header.pen,
|
||||
pinfo->rec->rec_header.custom_block_header.copy_allowed ? "" : " not");
|
||||
call_data_dissector(tvb, pinfo, parent_tree);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
#ifdef _MSC_VER
|
||||
} __except(EXCEPTION_EXECUTE_HANDLER /* handle all exceptions */) {
|
||||
|
@ -1283,6 +1326,22 @@ proto_register_frame(void)
|
|||
{ "Copying", "frame.cb_copy",
|
||||
FT_BOOLEAN, BASE_DEC, TFS(&tfs_allowed_not_allowed), 0x0,
|
||||
"Whether the custom block will be written or not", HFILL }},
|
||||
|
||||
{ &hf_frame_bblog,
|
||||
{ "Black Box Log", "frame.bblog",
|
||||
FT_STRING, BASE_NONE, NULL, 0x0,
|
||||
NULL, HFILL }},
|
||||
|
||||
{ &hf_frame_bblog_ticks,
|
||||
{ "Ticks", "frame.bblog.ticks",
|
||||
FT_UINT32, BASE_DEC, NULL, 0x0,
|
||||
NULL, HFILL}},
|
||||
|
||||
{ &hf_frame_bblog_serial_nr,
|
||||
{ "Serial Number", "frame.bblog.serial_nr",
|
||||
FT_UINT32, BASE_DEC, NULL, 0x0,
|
||||
NULL, HFILL}},
|
||||
|
||||
};
|
||||
|
||||
static hf_register_info hf_encap =
|
||||
|
@ -1297,6 +1356,7 @@ proto_register_frame(void)
|
|||
&ett_flags,
|
||||
&ett_comments,
|
||||
&ett_verdict,
|
||||
&ett_bblog
|
||||
};
|
||||
|
||||
static ei_register_info ei[] = {
|
||||
|
@ -1326,6 +1386,7 @@ proto_register_frame(void)
|
|||
proto_frame = proto_register_protocol("Frame", "Frame", "frame");
|
||||
proto_pkt_comment = proto_register_protocol_in_name_only("Packet comments", "Pkt_Comment", "pkt_comment", proto_frame, FT_PROTOCOL);
|
||||
proto_syscall = proto_register_protocol("System Call", "Syscall", "syscall");
|
||||
proto_bblog = proto_get_id_by_filter_name("bblog");
|
||||
|
||||
proto_register_field_array(proto_frame, hf, array_length(hf));
|
||||
proto_register_field_array(proto_frame, &hf_encap, 1);
|
||||
|
@ -1378,6 +1439,7 @@ proto_reg_handoff_frame(void)
|
|||
docsis_handle = find_dissector_add_dependency("docsis", proto_frame);
|
||||
sysdig_handle = find_dissector_add_dependency("sysdig", proto_frame);
|
||||
systemd_journal_handle = find_dissector_add_dependency("systemd_journal", proto_frame);
|
||||
bblog_handle = find_dissector_add_dependency("bblog", proto_frame);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -207,9 +207,18 @@ frame_data_init(frame_data *fdata, guint32 num, const wtap_rec *rec,
|
|||
/*
|
||||
* XXX - is cum_bytes supposed to count non-packet bytes?
|
||||
*/
|
||||
fdata->pkt_len = rec->rec_header.custom_block_header.length;
|
||||
fdata->cum_bytes = cum_bytes + rec->rec_header.custom_block_header.length;
|
||||
fdata->cap_len = rec->rec_header.custom_block_header.length;
|
||||
switch (rec->rec_header.custom_block_header.pen) {
|
||||
case PEN_NFLX:
|
||||
fdata->pkt_len = rec->rec_header.custom_block_header.length - 4;
|
||||
fdata->cum_bytes = cum_bytes + rec->rec_header.custom_block_header.length - 4;
|
||||
fdata->cap_len = rec->rec_header.custom_block_header.length - 4;
|
||||
break;
|
||||
default:
|
||||
fdata->pkt_len = rec->rec_header.custom_block_header.length;
|
||||
fdata->cum_bytes = cum_bytes + rec->rec_header.custom_block_header.length;
|
||||
fdata->cap_len = rec->rec_header.custom_block_header.length;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
|
|
@ -508,7 +508,14 @@ dissect_record(epan_dissect_t *edt, int file_type_subtype,
|
|||
break;
|
||||
|
||||
case REC_TYPE_CUSTOM_BLOCK:
|
||||
record_type = "PCAPNG Custom Block";
|
||||
switch (rec->rec_header.custom_block_header.pen) {
|
||||
case PEN_NFLX:
|
||||
record_type = "Black Box Log Block";
|
||||
break;
|
||||
default:
|
||||
record_type = "PCAPNG Custom Block";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -560,8 +567,16 @@ dissect_record(epan_dissect_t *edt, int file_type_subtype,
|
|||
break;
|
||||
|
||||
case REC_TYPE_CUSTOM_BLOCK:
|
||||
edt->pi.pseudo_header = NULL;
|
||||
switch (rec->rec_header.custom_block_header.pen) {
|
||||
case PEN_NFLX:
|
||||
edt->pi.pseudo_header = NULL;
|
||||
break;
|
||||
default:
|
||||
edt->pi.pseudo_header = NULL;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
edt->pi.fd = fd;
|
||||
|
|
391
wiretap/pcapng.c
391
wiretap/pcapng.c
|
@ -233,11 +233,14 @@ typedef struct wtapng_simple_packet_s {
|
|||
|
||||
/* Section data in private struct */
|
||||
typedef struct section_info_t {
|
||||
gboolean byte_swapped; /**< TRUE if this section is not in our byte order */
|
||||
guint16 version_major; /**< Major version number of this section */
|
||||
guint16 version_minor; /**< Minor version number of this section */
|
||||
GArray *interfaces; /**< Interfaces found in this section */
|
||||
gint64 shb_off; /**< File offset of the SHB for this section */
|
||||
gboolean byte_swapped; /**< TRUE if this section is not in our byte order */
|
||||
guint16 version_major; /**< Major version number of this section */
|
||||
guint16 version_minor; /**< Minor version number of this section */
|
||||
GArray *interfaces; /**< Interfaces found in this section */
|
||||
gint64 shb_off; /**< File offset of the SHB for this section */
|
||||
guint32 bblog_version; /**< BBLog: version used */
|
||||
guint64 bblog_offset_tv_sec; /**< BBLog: UTC offset */
|
||||
guint64 bblog_offset_tv_usec;
|
||||
} section_info_t;
|
||||
|
||||
/* Interface data in private struct */
|
||||
|
@ -612,14 +615,98 @@ pcapng_process_bytes_option(wtapng_block_t *wblock, guint16 option_code,
|
|||
wtap_block_add_bytes_option(wblock->block, option_code, (const char *)option_content, option_length);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
pcapng_process_nflx_custom_option(wtapng_block_t *wblock,
|
||||
section_info_t *section_info,
|
||||
const guint8 *value, guint16 length)
|
||||
{
|
||||
struct nflx_dumpinfo dumpinfo;
|
||||
guint32 type, version;
|
||||
gint64 dumptime, temp;
|
||||
|
||||
if (length < 4) {
|
||||
ws_debug("Length = %u too small", length);
|
||||
return FALSE;
|
||||
}
|
||||
memcpy(&type, value, sizeof(guint32));
|
||||
type = GUINT32_FROM_LE(type);
|
||||
value += 4;
|
||||
length -= 4;
|
||||
ws_debug("Handling type = %u, payload of length = %u", type, length);
|
||||
switch (type) {
|
||||
case NFLX_OPT_TYPE_VERSION:
|
||||
if (length == sizeof(guint32)) {
|
||||
memcpy(&version, value, sizeof(guint32));
|
||||
version = GUINT32_FROM_LE(version);
|
||||
ws_debug("BBLog version: %u", version);
|
||||
section_info->bblog_version = version;
|
||||
} else {
|
||||
ws_debug("BBLog version parameter has strange length: %u", length);
|
||||
}
|
||||
break;
|
||||
case NFLX_OPT_TYPE_TCPINFO:
|
||||
ws_debug("BBLog tcpinfo of length: %u", length);
|
||||
if (wblock->type == BLOCK_TYPE_CB_COPY) {
|
||||
ws_buffer_assure_space(wblock->frame_buffer, length);
|
||||
wblock->rec->rec_header.custom_block_header.length = length + 4;
|
||||
memcpy(ws_buffer_start_ptr(wblock->frame_buffer), value, length);
|
||||
memcpy(&temp, value, sizeof(guint64));
|
||||
temp = GUINT64_FROM_LE(temp);
|
||||
wblock->rec->ts.secs = section_info->bblog_offset_tv_sec + temp;
|
||||
memcpy(&temp, value + sizeof(guint64), sizeof(guint64));
|
||||
temp = GUINT64_FROM_LE(temp);
|
||||
wblock->rec->ts.nsecs = (guint32)(section_info->bblog_offset_tv_usec + temp) * 1000;
|
||||
if (wblock->rec->ts.nsecs >= 1000000000) {
|
||||
wblock->rec->ts.secs += 1;
|
||||
wblock->rec->ts.nsecs -= 1000000000;
|
||||
}
|
||||
wblock->rec->presence_flags = WTAP_HAS_TS;
|
||||
wblock->internal = FALSE;
|
||||
}
|
||||
break;
|
||||
case NFLX_OPT_TYPE_DUMPINFO:
|
||||
if (length == sizeof(struct nflx_dumpinfo)) {
|
||||
memcpy(&dumpinfo, value, sizeof(struct nflx_dumpinfo));
|
||||
section_info->bblog_offset_tv_sec = GUINT64_FROM_LE(dumpinfo.tlh_offset_tv_sec);
|
||||
section_info->bblog_offset_tv_usec = GUINT64_FROM_LE(dumpinfo.tlh_offset_tv_usec);
|
||||
ws_debug("BBLog dumpinfo time offset: %" G_GUINT64_FORMAT, section_info->bblog_offset_tv_sec);
|
||||
} else {
|
||||
ws_debug("BBLog dumpinfo parameter has strange length: %u", length);
|
||||
}
|
||||
break;
|
||||
case NFLX_OPT_TYPE_DUMPTIME:
|
||||
if (length == sizeof(gint64)) {
|
||||
memcpy(&dumptime, value, sizeof(gint64));
|
||||
dumptime = GINT64_FROM_LE(dumptime);
|
||||
ws_debug("BBLog dumpinfo time offset: %" G_GUINT64_FORMAT, dumptime);
|
||||
} else {
|
||||
ws_debug("BBLog dumptime parameter has strange length: %u", length);
|
||||
}
|
||||
break;
|
||||
case NFLX_OPT_TYPE_STACKNAME:
|
||||
if (length >= 2) {
|
||||
ws_debug("BBLog stack name: %.*s(%u)", length - 1, value + 1, *(guint8 *)value);
|
||||
} else {
|
||||
ws_debug("BBLog stack name has strange length: %u)", length);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ws_debug("Unknown type: %u, length: %u", type, length);
|
||||
break;
|
||||
}
|
||||
return wtap_block_add_nflx_custom_option(wblock->block, type, value, length) == WTAP_OPTTYPE_SUCCESS;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
pcapng_process_custom_option(wtapng_block_t *wblock,
|
||||
const section_info_t *section_info,
|
||||
section_info_t *section_info,
|
||||
guint16 option_code, guint16 option_length,
|
||||
const guint8 *option_content,
|
||||
gboolean little_endian,
|
||||
int *err, gchar **err_info)
|
||||
{
|
||||
guint32 pen;
|
||||
gboolean ret;
|
||||
|
||||
if (option_length < 4) {
|
||||
*err = WTAP_ERR_BAD_FILE;
|
||||
|
@ -628,18 +715,22 @@ pcapng_process_custom_option(wtapng_block_t *wblock,
|
|||
return FALSE;
|
||||
}
|
||||
memcpy(&pen, option_content, sizeof(guint32));
|
||||
if (section_info->byte_swapped) {
|
||||
if (little_endian) {
|
||||
pen = GUINT32_FROM_LE(pen);
|
||||
} else if (section_info->byte_swapped) {
|
||||
pen = GUINT32_SWAP_LE_BE(pen);
|
||||
}
|
||||
switch (pen) {
|
||||
case PEN_NFLX:
|
||||
ret = pcapng_process_nflx_custom_option(wblock, section_info, option_content + 4, option_length - 4);
|
||||
break;
|
||||
default:
|
||||
ret = wtap_block_add_custom_option(wblock->block, option_code, pen, option_content + 4, option_length - 4) == WTAP_OPTTYPE_SUCCESS;
|
||||
ws_debug("Custom option type 0x%04x with unknown pen %u with custom data of length %u", option_code, pen, option_length - 4);
|
||||
if (wtap_block_add_custom_option(wblock->block, option_code, pen, option_content + 4, option_length - 4) != WTAP_OPTTYPE_SUCCESS) {
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
ws_debug("returning %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef HAVE_PLUGINS
|
||||
|
@ -682,13 +773,14 @@ pcapng_process_unhandled_option(wtapng_block_t *wblock _U_,
|
|||
|
||||
static gboolean
|
||||
pcapng_process_options(FILE_T fh, wtapng_block_t *wblock,
|
||||
const section_info_t *section_info,
|
||||
section_info_t *section_info,
|
||||
guint opt_cont_buf_len,
|
||||
gboolean (*process_option)(wtapng_block_t *,
|
||||
const section_info_t *,
|
||||
guint16, guint16,
|
||||
const guint8 *,
|
||||
int *, gchar **),
|
||||
gboolean little_endian,
|
||||
int *err, gchar **err_info)
|
||||
{
|
||||
guint8 *option_content; /* Allocate as large as the options block */
|
||||
|
@ -738,7 +830,10 @@ pcapng_process_options(FILE_T fh, wtapng_block_t *wblock,
|
|||
}
|
||||
option_code = oh->option_code;
|
||||
option_length = oh->option_length;
|
||||
if (section_info->byte_swapped) {
|
||||
if (little_endian) {
|
||||
option_code = GUINT16_FROM_LE(option_code);
|
||||
option_length = GUINT16_FROM_LE(option_length);
|
||||
} else if (section_info->byte_swapped) {
|
||||
option_code = GUINT16_SWAP_LE_BE(option_code);
|
||||
option_length = GUINT16_SWAP_LE_BE(option_length);
|
||||
}
|
||||
|
@ -776,6 +871,7 @@ pcapng_process_options(FILE_T fh, wtapng_block_t *wblock,
|
|||
if (!pcapng_process_custom_option(wblock, section_info,
|
||||
option_code, option_length,
|
||||
option_ptr,
|
||||
little_endian,
|
||||
err, err_info)) {
|
||||
g_free(option_content);
|
||||
return FALSE;
|
||||
|
@ -783,7 +879,8 @@ pcapng_process_options(FILE_T fh, wtapng_block_t *wblock,
|
|||
break;
|
||||
|
||||
default:
|
||||
if (!(*process_option)(wblock, section_info, option_code,
|
||||
if (process_option == NULL ||
|
||||
!(*process_option)(wblock, (const section_info_t *)section_info, option_code,
|
||||
option_length, option_ptr,
|
||||
err, err_info)) {
|
||||
g_free(option_content);
|
||||
|
@ -995,7 +1092,7 @@ pcapng_read_section_header_block(FILE_T fh, pcapng_block_header_t *bh,
|
|||
opt_cont_buf_len = bh->block_total_length - MIN_SHB_SIZE;
|
||||
if (!pcapng_process_options(fh, wblock, section_info, opt_cont_buf_len,
|
||||
pcapng_process_section_header_block_option,
|
||||
err, err_info))
|
||||
FALSE, err, err_info))
|
||||
return PCAPNG_BLOCK_ERROR;
|
||||
|
||||
/*
|
||||
|
@ -1190,7 +1287,7 @@ pcapng_process_if_descr_block_option(wtapng_block_t *wblock,
|
|||
/* "Interface Description Block" */
|
||||
static gboolean
|
||||
pcapng_read_if_descr_block(wtap *wth, FILE_T fh, pcapng_block_header_t *bh,
|
||||
const section_info_t *section_info,
|
||||
section_info_t *section_info,
|
||||
wtapng_block_t *wblock, int *err, gchar **err_info)
|
||||
{
|
||||
guint64 time_units_per_second = 1000000; /* default = 10^6 */
|
||||
|
@ -1258,7 +1355,7 @@ pcapng_read_if_descr_block(wtap *wth, FILE_T fh, pcapng_block_header_t *bh,
|
|||
opt_cont_buf_len = bh->block_total_length - MIN_IDB_SIZE;
|
||||
if (!pcapng_process_options(fh, wblock, section_info, opt_cont_buf_len,
|
||||
pcapng_process_if_descr_block_option,
|
||||
err, err_info))
|
||||
FALSE, err, err_info))
|
||||
return FALSE;
|
||||
|
||||
/*
|
||||
|
@ -1557,7 +1654,7 @@ pcapng_process_packet_block_option(wtapng_block_t *wblock,
|
|||
|
||||
static gboolean
|
||||
pcapng_read_packet_block(FILE_T fh, pcapng_block_header_t *bh,
|
||||
const section_info_t *section_info,
|
||||
section_info_t *section_info,
|
||||
wtapng_block_t *wblock,
|
||||
int *err, gchar **err_info, gboolean enhanced)
|
||||
{
|
||||
|
@ -1763,7 +1860,7 @@ pcapng_read_packet_block(FILE_T fh, pcapng_block_header_t *bh,
|
|||
(int)sizeof(bh->block_total_length);
|
||||
if (!pcapng_process_options(fh, wblock, section_info, opt_cont_buf_len,
|
||||
pcapng_process_packet_block_option,
|
||||
err, err_info))
|
||||
FALSE, err, err_info))
|
||||
return FALSE;
|
||||
|
||||
/*
|
||||
|
@ -2033,7 +2130,7 @@ pcapng_process_name_resolution_block_option(wtapng_block_t *wblock,
|
|||
static gboolean
|
||||
pcapng_read_name_resolution_block(FILE_T fh, pcapng_block_header_t *bh,
|
||||
pcapng_t *pn,
|
||||
const section_info_t *section_info,
|
||||
section_info_t *section_info,
|
||||
wtapng_block_t *wblock,
|
||||
int *err, gchar **err_info)
|
||||
{
|
||||
|
@ -2254,7 +2351,7 @@ read_options:
|
|||
opt_cont_buf_len = to_read;
|
||||
if (!pcapng_process_options(fh, wblock, section_info, opt_cont_buf_len,
|
||||
pcapng_process_name_resolution_block_option,
|
||||
err, err_info))
|
||||
FALSE, err, err_info))
|
||||
return FALSE;
|
||||
|
||||
ws_buffer_free(&nrb_rec);
|
||||
|
@ -2334,7 +2431,7 @@ pcapng_process_interface_statistics_block_option(wtapng_block_t *wblock,
|
|||
|
||||
static gboolean
|
||||
pcapng_read_interface_statistics_block(FILE_T fh, pcapng_block_header_t *bh,
|
||||
const section_info_t *section_info,
|
||||
section_info_t *section_info,
|
||||
wtapng_block_t *wblock,
|
||||
int *err, gchar **err_info)
|
||||
{
|
||||
|
@ -2386,7 +2483,7 @@ pcapng_read_interface_statistics_block(FILE_T fh, pcapng_block_header_t *bh,
|
|||
(MIN_BLOCK_SIZE + (guint)sizeof isb); /* fixed and variable part, including padding */
|
||||
if (!pcapng_process_options(fh, wblock, section_info, opt_cont_buf_len,
|
||||
pcapng_process_interface_statistics_block_option,
|
||||
err, err_info))
|
||||
FALSE, err, err_info))
|
||||
return FALSE;
|
||||
|
||||
/*
|
||||
|
@ -2397,6 +2494,71 @@ pcapng_read_interface_statistics_block(FILE_T fh, pcapng_block_header_t *bh,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
#define NFLX_BLOCK_TYPE_EVENT 1
|
||||
#define NFLX_BLOCK_TYPE_SKIP 2
|
||||
|
||||
typedef struct pcapng_nflx_custom_block_s {
|
||||
guint32 nflx_type;
|
||||
} pcapng_nflx_custom_block_t;
|
||||
|
||||
#define MIN_NFLX_CB_SIZE ((guint32)(MIN_CB_SIZE + sizeof(pcapng_nflx_custom_block_t)))
|
||||
|
||||
static gboolean
|
||||
pcapng_read_nflx_custom_block(FILE_T fh, pcapng_block_header_t *bh,
|
||||
section_info_t *section_info,
|
||||
wtapng_block_t *wblock,
|
||||
int *err, gchar **err_info)
|
||||
{
|
||||
pcapng_nflx_custom_block_t nflx_cb;
|
||||
guint opt_cont_buf_len;
|
||||
guint32 type, skipped;
|
||||
|
||||
if (bh->block_total_length < MIN_NFLX_CB_SIZE) {
|
||||
*err = WTAP_ERR_BAD_FILE;
|
||||
*err_info = g_strdup_printf("pcapng_read_nflx_custom_block: total block length %u is too small (< %u)",
|
||||
bh->block_total_length, MIN_NFLX_CB_SIZE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
opt_cont_buf_len = bh->block_total_length - MIN_NFLX_CB_SIZE;
|
||||
wblock->rec->rec_type = REC_TYPE_CUSTOM_BLOCK;
|
||||
wblock->rec->rec_header.custom_block_header.pen = PEN_NFLX;
|
||||
/* "NFLX Custom Block" read fixed part */
|
||||
if (!wtap_read_bytes(fh, &nflx_cb, sizeof nflx_cb, err, err_info)) {
|
||||
ws_debug("Failed to read nflx type");
|
||||
return FALSE;
|
||||
}
|
||||
type = GUINT32_FROM_LE(nflx_cb.nflx_type);
|
||||
ws_debug("BBLog type: %u", type);
|
||||
switch (type) {
|
||||
case NFLX_BLOCK_TYPE_EVENT:
|
||||
wblock->rec->rec_header.custom_block_header.custom_data_header.nflx_custom_data_header.type = BBLOG_TYPE_EVENT_BLOCK;
|
||||
opt_cont_buf_len = bh->block_total_length - MIN_NFLX_CB_SIZE;
|
||||
ws_debug("event");
|
||||
break;
|
||||
case NFLX_BLOCK_TYPE_SKIP:
|
||||
wblock->rec->rec_header.custom_block_header.custom_data_header.nflx_custom_data_header.type = BBLOG_TYPE_SKIPPED_BLOCK;
|
||||
if (!wtap_read_bytes(fh, &skipped, sizeof(guint32), err, err_info)) {
|
||||
ws_debug("Failed to read skipped");
|
||||
return FALSE;
|
||||
}
|
||||
wblock->rec->rec_header.custom_block_header.custom_data_header.nflx_custom_data_header.skipped = GUINT32_FROM_LE(skipped);
|
||||
ws_debug("skipped: %u", wblock->rec->rec_header.custom_block_header.custom_data_header.nflx_custom_data_header.skipped);
|
||||
opt_cont_buf_len = bh->block_total_length - MIN_NFLX_CB_SIZE - sizeof(guint32);
|
||||
break;
|
||||
default:
|
||||
ws_debug("Unknown type %u", type);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Options */
|
||||
if (!pcapng_process_options(fh, wblock, section_info, opt_cont_buf_len,
|
||||
NULL, TRUE, err, err_info))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
pcapng_handle_generic_custom_block(FILE_T fh, pcapng_block_header_t *bh,
|
||||
guint32 pen, wtapng_block_t *wblock,
|
||||
|
@ -2425,9 +2587,10 @@ pcapng_handle_generic_custom_block(FILE_T fh, pcapng_block_header_t *bh,
|
|||
wblock->internal = FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
pcapng_read_custom_block(FILE_T fh, pcapng_block_header_t *bh,
|
||||
const section_info_t *section_info,
|
||||
section_info_t *section_info,
|
||||
wtapng_block_t *wblock,
|
||||
int *err, gchar **err_info)
|
||||
{
|
||||
|
@ -2445,6 +2608,8 @@ pcapng_read_custom_block(FILE_T fh, pcapng_block_header_t *bh,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
wblock->block = wtap_block_create(WTAP_BLOCK_CUSTOM);
|
||||
|
||||
/* Custom block read fixed part */
|
||||
if (!wtap_read_bytes(fh, &cb, sizeof cb, err, err_info)) {
|
||||
ws_debug("failed to read pen");
|
||||
|
@ -2458,6 +2623,10 @@ pcapng_read_custom_block(FILE_T fh, pcapng_block_header_t *bh,
|
|||
ws_debug("pen %u, custom data and option length %u", pen, bh->block_total_length - MIN_CB_SIZE);
|
||||
|
||||
switch (pen) {
|
||||
case PEN_NFLX:
|
||||
if (!pcapng_read_nflx_custom_block(fh, bh, section_info, wblock, err, err_info))
|
||||
return FALSE;
|
||||
break;
|
||||
default:
|
||||
if (!pcapng_handle_generic_custom_block(fh, bh, pen, wblock, err, err_info)) {
|
||||
return FALSE;
|
||||
|
@ -2465,6 +2634,9 @@ pcapng_read_custom_block(FILE_T fh, pcapng_block_header_t *bh,
|
|||
break;
|
||||
}
|
||||
|
||||
wblock->rec->block = wblock->block;
|
||||
wblock->block = NULL;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -3521,7 +3693,18 @@ static guint32 pcapng_compute_custom_option_size(wtap_optval_t *optval)
|
|||
{
|
||||
size_t size, pad;
|
||||
|
||||
size = optval->custom_opt.custom_data_len + sizeof(guint32);
|
||||
/* PEN */
|
||||
size = sizeof(guint32);
|
||||
switch (optval->custom_opt.pen) {
|
||||
case PEN_NFLX:
|
||||
/* PEN */
|
||||
size += sizeof(guint32);
|
||||
size += optval->custom_opt.data.nflx_data.custom_data_len;
|
||||
break;
|
||||
default:
|
||||
size += optval->custom_opt.data.generic_data.custom_data_len;
|
||||
break;
|
||||
}
|
||||
if (size > 65535) {
|
||||
size = 65535;
|
||||
}
|
||||
|
@ -3957,13 +4140,28 @@ static gboolean pcapng_write_if_filter_option(wtap_dumper *wdh, guint option_id,
|
|||
static gboolean pcapng_write_custom_option(wtap_dumper *wdh, guint option_id, wtap_optval_t *optval, int *err)
|
||||
{
|
||||
struct pcapng_option_header option_hdr;
|
||||
gsize pad;
|
||||
gsize size;
|
||||
const guint32 zero_pad = 0;
|
||||
size_t pad;
|
||||
guint32 pen, type;
|
||||
gboolean use_little_endian;
|
||||
|
||||
if ((option_id == OPT_CUSTOM_STR_NO_COPY) ||
|
||||
(option_id == OPT_CUSTOM_BIN_NO_COPY))
|
||||
return TRUE;
|
||||
if (optval->custom_opt.custom_data_len + sizeof(guint32) > 65535) {
|
||||
ws_debug("PEN %d", optval->custom_opt.pen);
|
||||
switch (optval->custom_opt.pen) {
|
||||
case PEN_NFLX:
|
||||
size = sizeof(guint32) + sizeof(guint32) + optval->custom_opt.data.nflx_data.custom_data_len;
|
||||
use_little_endian = optval->custom_opt.data.nflx_data.use_little_endian;
|
||||
break;
|
||||
default:
|
||||
size = sizeof(guint32) + optval->custom_opt.data.generic_data.custom_data_len;
|
||||
use_little_endian = false;
|
||||
break;
|
||||
}
|
||||
ws_debug("use_little_endian %d", use_little_endian);
|
||||
if (size > 65535) {
|
||||
/*
|
||||
* Too big to fit in the option.
|
||||
* Don't write anything.
|
||||
|
@ -3975,30 +4173,57 @@ static gboolean pcapng_write_custom_option(wtap_dumper *wdh, guint option_id, wt
|
|||
|
||||
/* write option header */
|
||||
option_hdr.type = (guint16)option_id;
|
||||
option_hdr.value_length = (guint16)(optval->custom_opt.custom_data_len + sizeof(guint32));
|
||||
option_hdr.value_length = (guint16)size;
|
||||
if (use_little_endian) {
|
||||
option_hdr.type = GUINT16_TO_LE(option_hdr.type);
|
||||
option_hdr.value_length = GUINT16_TO_LE(option_hdr.value_length);
|
||||
}
|
||||
if (!wtap_dump_file_write(wdh, &option_hdr, sizeof(struct pcapng_option_header), err))
|
||||
return FALSE;
|
||||
wdh->bytes_dumped += sizeof(struct pcapng_option_header);
|
||||
|
||||
/* write PEN */
|
||||
if (!wtap_dump_file_write(wdh, &optval->custom_opt.pen, sizeof(guint32), err))
|
||||
pen = optval->custom_opt.pen;
|
||||
if (use_little_endian) {
|
||||
pen = GUINT32_TO_LE(pen);
|
||||
}
|
||||
if (!wtap_dump_file_write(wdh, &pen, sizeof(guint32), err))
|
||||
return FALSE;
|
||||
wdh->bytes_dumped += sizeof(guint32);
|
||||
|
||||
/* write custom data */
|
||||
if (!wtap_dump_file_write(wdh, optval->custom_opt.custom_data, optval->custom_opt.custom_data_len, err))
|
||||
return FALSE;
|
||||
wdh->bytes_dumped += optval->custom_opt.custom_data_len;
|
||||
switch (optval->custom_opt.pen) {
|
||||
case PEN_NFLX:
|
||||
/* write NFLX type */
|
||||
type = GUINT32_TO_LE(optval->custom_opt.data.nflx_data.type);
|
||||
ws_debug("type=%d", type);
|
||||
if (!wtap_dump_file_write(wdh, &type, sizeof(guint32), err))
|
||||
return FALSE;
|
||||
wdh->bytes_dumped += sizeof(guint32);
|
||||
/* write custom data */
|
||||
if (!wtap_dump_file_write(wdh, optval->custom_opt.data.nflx_data.custom_data, optval->custom_opt.data.nflx_data.custom_data_len, err)) {
|
||||
return FALSE;
|
||||
}
|
||||
wdh->bytes_dumped += optval->custom_opt.data.nflx_data.custom_data_len;
|
||||
break;
|
||||
default:
|
||||
/* write custom data */
|
||||
if (!wtap_dump_file_write(wdh, optval->custom_opt.data.generic_data.custom_data, optval->custom_opt.data.generic_data.custom_data_len, err)) {
|
||||
return FALSE;
|
||||
}
|
||||
wdh->bytes_dumped += optval->custom_opt.data.generic_data.custom_data_len;
|
||||
break;
|
||||
}
|
||||
|
||||
/* write padding (if any) */
|
||||
if ((optval->custom_opt.custom_data_len % 4)) {
|
||||
pad = 4 - (optval->custom_opt.custom_data_len % 4);
|
||||
if (size % 4 != 0) {
|
||||
pad = 4 - (size % 4);
|
||||
} else {
|
||||
pad = 0;
|
||||
}
|
||||
if (pad != 0) {
|
||||
if (!wtap_dump_file_write(wdh, &zero_pad, pad, err))
|
||||
if (!wtap_dump_file_write(wdh, &zero_pad, pad, err)) {
|
||||
return FALSE;
|
||||
}
|
||||
wdh->bytes_dumped += pad;
|
||||
}
|
||||
ws_debug("Wrote custom option: type %u, length %u", option_hdr.type, option_hdr.value_length);
|
||||
|
@ -4591,9 +4816,9 @@ pcapng_write_custom_block(wtap_dumper *wdh, const wtap_rec *rec,
|
|||
/* write block header */
|
||||
bh.block_type = BLOCK_TYPE_CB_COPY;
|
||||
bh.block_total_length = (guint32)sizeof(bh) + (guint32)sizeof(cb) + rec->rec_header.custom_block_header.length + pad_len + 4;
|
||||
ws_debug("writing %u bytes, %u padded",
|
||||
ws_debug("writing %u bytes, %u padded, PEN %u",
|
||||
rec->rec_header.custom_block_header.length,
|
||||
bh.block_total_length);
|
||||
bh.block_total_length, rec->rec_header.custom_block_header.pen);
|
||||
if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -4605,6 +4830,7 @@ pcapng_write_custom_block(wtap_dumper *wdh, const wtap_rec *rec,
|
|||
return FALSE;
|
||||
}
|
||||
wdh->bytes_dumped += sizeof cb;
|
||||
ws_debug("wrote PEN = %u", cb.pen);
|
||||
|
||||
/* write custom data */
|
||||
if (!wtap_dump_file_write(wdh, pd, rec->rec_header.custom_block_header.length, err)) {
|
||||
|
@ -4625,6 +4851,76 @@ pcapng_write_custom_block(wtap_dumper *wdh, const wtap_rec *rec,
|
|||
sizeof bh.block_total_length, err)) {
|
||||
return FALSE;
|
||||
}
|
||||
wdh->bytes_dumped += sizeof bh.block_total_length;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
pcapng_write_bblog_block(wtap_dumper *wdh, const wtap_rec *rec,
|
||||
const guint8 *pd _U_, int *err)
|
||||
{
|
||||
pcapng_block_header_t bh;
|
||||
pcapng_write_block_t block_data;
|
||||
gsize options_len;
|
||||
guint32 pen, skipped, type;
|
||||
|
||||
options_len = wtap_block_get_options_size_padded(rec->block) + 4;
|
||||
|
||||
/* write block header */
|
||||
bh.block_type = BLOCK_TYPE_CB_COPY;
|
||||
bh.block_total_length = (guint32)(sizeof(bh) + sizeof(guint32) + sizeof(guint32) + options_len + 4);
|
||||
if (rec->rec_header.custom_block_header.custom_data_header.nflx_custom_data_header.type == BBLOG_TYPE_SKIPPED_BLOCK) {
|
||||
bh.block_total_length += (guint32)sizeof(guint32);
|
||||
}
|
||||
ws_debug("writing %u bytes, type %u",
|
||||
bh.block_total_length, rec->rec_header.custom_block_header.custom_data_header.nflx_custom_data_header.type);
|
||||
if (!wtap_dump_file_write(wdh, &bh, sizeof(bh), err)) {
|
||||
return FALSE;
|
||||
}
|
||||
wdh->bytes_dumped += sizeof bh;
|
||||
|
||||
/* write PEN */
|
||||
pen = PEN_NFLX;
|
||||
if (!wtap_dump_file_write(wdh, &pen, sizeof(guint32), err)) {
|
||||
return FALSE;
|
||||
}
|
||||
wdh->bytes_dumped += sizeof(guint32);
|
||||
ws_debug("wrote PEN = %u", pen);
|
||||
|
||||
/* write type */
|
||||
type = GUINT32_TO_LE(rec->rec_header.custom_block_header.custom_data_header.nflx_custom_data_header.type);
|
||||
if (!wtap_dump_file_write(wdh, &type, sizeof(guint32), err)) {
|
||||
return FALSE;
|
||||
}
|
||||
wdh->bytes_dumped += sizeof(guint32);
|
||||
ws_debug("wrote type = %u", rec->rec_header.custom_block_header.custom_data_header.nflx_custom_data_header.type);
|
||||
|
||||
if (rec->rec_header.custom_block_header.custom_data_header.nflx_custom_data_header.type == BBLOG_TYPE_SKIPPED_BLOCK) {
|
||||
skipped = GUINT32_TO_LE(rec->rec_header.custom_block_header.custom_data_header.nflx_custom_data_header.skipped);
|
||||
if (!wtap_dump_file_write(wdh, &skipped, sizeof(guint32), err)) {
|
||||
return FALSE;
|
||||
}
|
||||
wdh->bytes_dumped += sizeof(guint32);
|
||||
ws_debug("wrote skipped = %u", rec->rec_header.custom_block_header.custom_data_header.nflx_custom_data_header.skipped);
|
||||
}
|
||||
|
||||
block_data.wdh = wdh;
|
||||
block_data.err = err;
|
||||
if (!wtap_block_foreach_option(rec->block, pcapng_write_option_cb, &block_data)) {
|
||||
return FALSE;
|
||||
}
|
||||
/* Write end of options if we have options */
|
||||
if (!pcapng_write_option_eofopt(wdh, err)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* write block footer */
|
||||
if (!wtap_dump_file_write(wdh, &bh.block_total_length,
|
||||
sizeof bh.block_total_length, err)) {
|
||||
return FALSE;
|
||||
}
|
||||
wdh->bytes_dumped += sizeof bh.block_total_length;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -4752,7 +5048,7 @@ put_nrb_option(wtap_block_t block _U_, guint option_id, wtap_opttype_e option_ty
|
|||
case OPT_CUSTOM_STR_COPY:
|
||||
case OPT_CUSTOM_BIN_COPY:
|
||||
/* Custom options don't consider pad bytes part of the length */
|
||||
size = (guint32)(optval->custom_opt.custom_data_len + sizeof(guint32)) & 0xffff;
|
||||
size = (guint32)(optval->custom_opt.data.generic_data.custom_data_len + sizeof(guint32)) & 0xffff;
|
||||
option_hdr.type = (guint16)option_id;
|
||||
option_hdr.value_length = (guint16)size;
|
||||
memcpy(*opt_ptrp, &option_hdr, 4);
|
||||
|
@ -4761,8 +5057,8 @@ put_nrb_option(wtap_block_t block _U_, guint option_id, wtap_opttype_e option_ty
|
|||
memcpy(*opt_ptrp, &optval->custom_opt.pen, sizeof(guint32));
|
||||
*opt_ptrp += sizeof(guint32);
|
||||
|
||||
memcpy(*opt_ptrp, optval->custom_opt.custom_data, size);
|
||||
*opt_ptrp += size;
|
||||
memcpy(*opt_ptrp, optval->custom_opt.data.generic_data.custom_data, optval->custom_opt.data.generic_data.custom_data_len);
|
||||
*opt_ptrp += optval->custom_opt.data.generic_data.custom_data_len;
|
||||
|
||||
if ((size % 4)) {
|
||||
pad = 4 - (size % 4);
|
||||
|
@ -5398,8 +5694,17 @@ static gboolean pcapng_dump(wtap_dumper *wdh,
|
|||
break;
|
||||
|
||||
case REC_TYPE_CUSTOM_BLOCK:
|
||||
if (!pcapng_write_custom_block(wdh, rec, pd, err)) {
|
||||
return FALSE;
|
||||
switch (rec->rec_header.custom_block_header.pen) {
|
||||
case PEN_NFLX:
|
||||
if (!pcapng_write_bblog_block(wdh, rec, pd, err)) {
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (!pcapng_write_custom_block(wdh, rec, pd, err)) {
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -1323,8 +1323,17 @@ typedef struct {
|
|||
guint32 length; /* length of the record */
|
||||
guint32 pen; /* private enterprise number */
|
||||
gboolean copy_allowed; /* CB can be written */
|
||||
union {
|
||||
struct nflx {
|
||||
guint32 type; /* block type */
|
||||
guint32 skipped; /* Used if type == BBLOG_TYPE_SKIPPED_BLOCK */
|
||||
} nflx_custom_data_header;
|
||||
} custom_data_header;
|
||||
} wtap_custom_block_header;
|
||||
|
||||
#define BBLOG_TYPE_EVENT_BLOCK 1
|
||||
#define BBLOG_TYPE_SKIPPED_BLOCK 2
|
||||
|
||||
typedef struct {
|
||||
guint rec_type; /* what type of record is this? */
|
||||
guint32 presence_flags; /* what stuff do we have? */
|
||||
|
|
|
@ -299,7 +299,14 @@ static void wtap_block_free_option(wtap_block_t block, wtap_option_t *opt)
|
|||
break;
|
||||
|
||||
case WTAP_OPTTYPE_CUSTOM:
|
||||
g_free(opt->value.custom_opt.custom_data);
|
||||
switch (opt->value.custom_opt.pen) {
|
||||
case PEN_NFLX:
|
||||
g_free(opt->value.custom_opt.data.nflx_data.custom_data);
|
||||
break;
|
||||
default:
|
||||
g_free(opt->value.custom_opt.data.generic_data.custom_data);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -433,7 +440,14 @@ wtap_block_copy(wtap_block_t dest_block, wtap_block_t src_block)
|
|||
break;
|
||||
|
||||
case WTAP_OPTTYPE_CUSTOM:
|
||||
wtap_block_add_custom_option(dest_block, src_opt->option_id, src_opt->value.custom_opt.pen, src_opt->value.custom_opt.custom_data, src_opt->value.custom_opt.custom_data_len);
|
||||
switch (src_opt->value.custom_opt.pen) {
|
||||
case PEN_NFLX:
|
||||
wtap_block_add_nflx_custom_option(dest_block, src_opt->value.custom_opt.data.nflx_data.type, src_opt->value.custom_opt.data.nflx_data.custom_data, src_opt->value.custom_opt.data.nflx_data.custom_data_len);
|
||||
break;
|
||||
default:
|
||||
wtap_block_add_custom_option(dest_block, src_opt->option_id, src_opt->value.custom_opt.pen, src_opt->value.custom_opt.data.generic_data.custom_data, src_opt->value.custom_opt.data.generic_data.custom_data_len);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -500,7 +514,18 @@ wtap_block_option_get_value_size(wtap_opttype_e option_type, wtap_optval_t *opti
|
|||
break;
|
||||
|
||||
case WTAP_OPTTYPE_CUSTOM:
|
||||
ret_val += sizeof(guint32) + option->custom_opt.custom_data_len;
|
||||
/* PEN */
|
||||
ret_val += sizeof(guint32);
|
||||
switch (option->custom_opt.pen) {
|
||||
case PEN_NFLX:
|
||||
/* NFLX type */
|
||||
ret_val += sizeof(guint32);
|
||||
ret_val += option->custom_opt.data.nflx_data.custom_data_len;
|
||||
break;
|
||||
default:
|
||||
ret_val += option->custom_opt.data.generic_data.custom_data_len;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return ret_val;
|
||||
|
@ -1204,6 +1229,190 @@ wtap_block_get_if_filter_option_value(wtap_block_t block, guint option_id, if_fi
|
|||
return WTAP_OPTTYPE_SUCCESS;
|
||||
}
|
||||
|
||||
wtap_opttype_return_val
|
||||
wtap_block_add_nflx_custom_option(wtap_block_t block, guint32 type, const char *custom_data, gsize custom_data_len)
|
||||
{
|
||||
wtap_opttype_return_val ret;
|
||||
wtap_option_t *opt;
|
||||
|
||||
ret = wtap_block_add_option_common(block, OPT_CUSTOM_BIN_COPY, WTAP_OPTTYPE_CUSTOM, &opt);
|
||||
if (ret != WTAP_OPTTYPE_SUCCESS)
|
||||
return ret;
|
||||
opt->value.custom_opt.pen = PEN_NFLX;
|
||||
opt->value.custom_opt.data.nflx_data.type = type;
|
||||
opt->value.custom_opt.data.nflx_data.custom_data_len = custom_data_len;
|
||||
opt->value.custom_opt.data.nflx_data.custom_data = g_memdup2(custom_data, custom_data_len);
|
||||
opt->value.custom_opt.data.nflx_data.use_little_endian = (block->info->block_type == WTAP_BLOCK_CUSTOM);
|
||||
return WTAP_OPTTYPE_SUCCESS;
|
||||
}
|
||||
|
||||
wtap_opttype_return_val
|
||||
wtap_block_get_nflx_custom_option(wtap_block_t block, guint32 nflx_type, char *nflx_custom_data _U_, gsize nflx_custom_data_len)
|
||||
{
|
||||
const wtap_opttype_t *opttype;
|
||||
wtap_option_t *opt;
|
||||
guint i;
|
||||
|
||||
if (block == NULL) {
|
||||
return WTAP_OPTTYPE_BAD_BLOCK;
|
||||
}
|
||||
opttype = GET_OPTION_TYPE(block->info->options, OPT_CUSTOM_BIN_COPY);
|
||||
if (opttype == NULL) {
|
||||
return WTAP_OPTTYPE_NO_SUCH_OPTION;
|
||||
}
|
||||
if (opttype->data_type != WTAP_OPTTYPE_CUSTOM) {
|
||||
return WTAP_OPTTYPE_TYPE_MISMATCH;
|
||||
}
|
||||
|
||||
for (i = 0; i < block->options->len; i++) {
|
||||
opt = &g_array_index(block->options, wtap_option_t, i);
|
||||
if ((opt->option_id == OPT_CUSTOM_BIN_COPY) &&
|
||||
(opt->value.custom_opt.pen == PEN_NFLX) &&
|
||||
(opt->value.custom_opt.data.nflx_data.type == nflx_type)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == block->options->len) {
|
||||
return WTAP_OPTTYPE_NOT_FOUND;
|
||||
}
|
||||
if (nflx_custom_data_len < opt->value.custom_opt.data.nflx_data.custom_data_len) {
|
||||
return WTAP_OPTTYPE_TYPE_MISMATCH;
|
||||
}
|
||||
switch (nflx_type) {
|
||||
case NFLX_OPT_TYPE_VERSION: {
|
||||
guint32 *src, *dst;
|
||||
|
||||
ws_assert(nflx_custom_data_len == sizeof(guint32));
|
||||
src = (guint32 *)opt->value.custom_opt.data.nflx_data.custom_data;
|
||||
dst = (guint32 *)nflx_custom_data;
|
||||
*dst = GUINT32_FROM_LE(*src);
|
||||
break;
|
||||
}
|
||||
case NFLX_OPT_TYPE_TCPINFO: {
|
||||
struct nflx_tcpinfo *src, *dst;
|
||||
|
||||
ws_assert(nflx_custom_data_len == sizeof(struct nflx_tcpinfo));
|
||||
src = (struct nflx_tcpinfo *)opt->value.custom_opt.data.nflx_data.custom_data;
|
||||
dst = (struct nflx_tcpinfo *)nflx_custom_data;
|
||||
dst->tlb_tv_sec = GUINT64_FROM_LE(src->tlb_tv_sec);
|
||||
dst->tlb_tv_usec = GUINT64_FROM_LE(src->tlb_tv_usec);
|
||||
dst->tlb_ticks = GUINT32_FROM_LE(src->tlb_ticks);
|
||||
dst->tlb_sn = GUINT32_FROM_LE(src->tlb_sn);
|
||||
dst->tlb_stackid = src->tlb_stackid;
|
||||
dst->tlb_eventid = src->tlb_eventid;
|
||||
dst->tlb_eventflags = GUINT16_FROM_LE(src->tlb_eventflags);
|
||||
dst->tlb_errno = GINT32_FROM_LE(src->tlb_errno);
|
||||
dst->tlb_rxbuf_tls_sb_acc = GUINT32_FROM_LE(src->tlb_rxbuf_tls_sb_acc);
|
||||
dst->tlb_rxbuf_tls_sb_ccc = GUINT32_FROM_LE(src->tlb_rxbuf_tls_sb_ccc);
|
||||
dst->tlb_rxbuf_tls_sb_spare = GUINT32_FROM_LE(src->tlb_rxbuf_tls_sb_spare);
|
||||
dst->tlb_txbuf_tls_sb_acc = GUINT32_FROM_LE(src->tlb_txbuf_tls_sb_acc);
|
||||
dst->tlb_txbuf_tls_sb_ccc = GUINT32_FROM_LE(src->tlb_txbuf_tls_sb_ccc);
|
||||
dst->tlb_txbuf_tls_sb_spare = GUINT32_FROM_LE(src->tlb_txbuf_tls_sb_spare);
|
||||
dst->tlb_state = GINT32_FROM_LE(src->tlb_state);
|
||||
dst->tlb_starttime = GUINT32_FROM_LE(src->tlb_starttime);
|
||||
dst->tlb_iss = GUINT32_FROM_LE(src->tlb_iss);
|
||||
dst->tlb_flags = GUINT32_FROM_LE(src->tlb_flags);
|
||||
dst->tlb_snd_una = GUINT32_FROM_LE(src->tlb_snd_una);
|
||||
dst->tlb_snd_max = GUINT32_FROM_LE(src->tlb_snd_max);
|
||||
dst->tlb_snd_cwnd = GUINT32_FROM_LE(src->tlb_snd_cwnd);
|
||||
dst->tlb_snd_nxt = GUINT32_FROM_LE(src->tlb_snd_nxt);
|
||||
dst->tlb_snd_recover = GUINT32_FROM_LE(src->tlb_snd_recover);
|
||||
dst->tlb_snd_wnd = GUINT32_FROM_LE(src->tlb_snd_wnd);
|
||||
dst->tlb_snd_ssthresh = GUINT32_FROM_LE(src->tlb_snd_ssthresh);
|
||||
dst->tlb_srtt = GUINT32_FROM_LE(src->tlb_srtt);
|
||||
dst->tlb_rttvar = GUINT32_FROM_LE(src->tlb_rttvar);
|
||||
dst->tlb_rcv_up = GUINT32_FROM_LE(src->tlb_rcv_up);
|
||||
dst->tlb_rcv_adv = GUINT32_FROM_LE(src->tlb_rcv_adv);
|
||||
dst->tlb_flags2 = GUINT32_FROM_LE(src->tlb_flags2);
|
||||
dst->tlb_rcv_nxt = GUINT32_FROM_LE(src->tlb_rcv_nxt);
|
||||
dst->tlb_rcv_wnd = GUINT32_FROM_LE(src->tlb_rcv_wnd);
|
||||
dst->tlb_dupacks = GUINT32_FROM_LE(src->tlb_dupacks);
|
||||
dst->tlb_segqlen = GINT32_FROM_LE(src->tlb_segqlen);
|
||||
dst->tlb_snd_numholes = GINT32_FROM_LE(src->tlb_snd_numholes);
|
||||
dst->tlb_flex1 = GUINT32_FROM_LE(src->tlb_flex1);
|
||||
dst->tlb_flex2 = GUINT32_FROM_LE(src->tlb_flex2);
|
||||
dst->tlb_fbyte_in = GUINT32_FROM_LE(src->tlb_fbyte_in);
|
||||
dst->tlb_fbyte_out = GUINT32_FROM_LE(src->tlb_fbyte_out);
|
||||
dst->tlb_snd_scale = src->tlb_snd_scale;
|
||||
dst->tlb_rcv_scale = src->tlb_rcv_scale;
|
||||
for (i = 0; i < 3; i++) {
|
||||
dst->_pad[i] = src->_pad[i];
|
||||
}
|
||||
dst->tlb_stackinfo_bbr_cur_del_rate = GUINT64_FROM_LE(src->tlb_stackinfo_bbr_cur_del_rate);
|
||||
dst->tlb_stackinfo_bbr_delRate = GUINT64_FROM_LE(src->tlb_stackinfo_bbr_delRate);
|
||||
dst->tlb_stackinfo_bbr_rttProp = GUINT64_FROM_LE(src->tlb_stackinfo_bbr_rttProp);
|
||||
dst->tlb_stackinfo_bbr_bw_inuse = GUINT64_FROM_LE(src->tlb_stackinfo_bbr_bw_inuse);
|
||||
dst->tlb_stackinfo_bbr_inflight = GUINT32_FROM_LE(src->tlb_stackinfo_bbr_inflight);
|
||||
dst->tlb_stackinfo_bbr_applimited = GUINT32_FROM_LE(src->tlb_stackinfo_bbr_applimited);
|
||||
dst->tlb_stackinfo_bbr_delivered = GUINT32_FROM_LE(src->tlb_stackinfo_bbr_delivered);
|
||||
dst->tlb_stackinfo_bbr_timeStamp = GUINT32_FROM_LE(src->tlb_stackinfo_bbr_timeStamp);
|
||||
dst->tlb_stackinfo_bbr_epoch = GUINT32_FROM_LE(src->tlb_stackinfo_bbr_epoch);
|
||||
dst->tlb_stackinfo_bbr_lt_epoch = GUINT32_FROM_LE(src->tlb_stackinfo_bbr_lt_epoch);
|
||||
dst->tlb_stackinfo_bbr_pkts_out = GUINT32_FROM_LE(src->tlb_stackinfo_bbr_pkts_out);
|
||||
dst->tlb_stackinfo_bbr_flex1 = GUINT32_FROM_LE(src->tlb_stackinfo_bbr_flex1);
|
||||
dst->tlb_stackinfo_bbr_flex2 = GUINT32_FROM_LE(src->tlb_stackinfo_bbr_flex2);
|
||||
dst->tlb_stackinfo_bbr_flex3 = GUINT32_FROM_LE(src->tlb_stackinfo_bbr_flex3);
|
||||
dst->tlb_stackinfo_bbr_flex4 = GUINT32_FROM_LE(src->tlb_stackinfo_bbr_flex4);
|
||||
dst->tlb_stackinfo_bbr_flex5 = GUINT32_FROM_LE(src->tlb_stackinfo_bbr_flex5);
|
||||
dst->tlb_stackinfo_bbr_flex6 = GUINT32_FROM_LE(src->tlb_stackinfo_bbr_flex6);
|
||||
dst->tlb_stackinfo_bbr_lost = GUINT32_FROM_LE(src->tlb_stackinfo_bbr_lost);
|
||||
dst->tlb_stackinfo_bbr_pacing_gain = GUINT16_FROM_LE(src->tlb_stackinfo_bbr_lost);
|
||||
dst->tlb_stackinfo_bbr_cwnd_gain = GUINT16_FROM_LE(src->tlb_stackinfo_bbr_lost);
|
||||
dst->tlb_stackinfo_bbr_flex7 = GUINT16_FROM_LE(src->tlb_stackinfo_bbr_flex7);
|
||||
dst->tlb_stackinfo_bbr_bbr_state = src->tlb_stackinfo_bbr_bbr_state;
|
||||
dst->tlb_stackinfo_bbr_bbr_substate = src->tlb_stackinfo_bbr_bbr_substate;
|
||||
dst->tlb_stackinfo_bbr_inhpts = src->tlb_stackinfo_bbr_inhpts;
|
||||
dst->tlb_stackinfo_bbr_ininput = src->tlb_stackinfo_bbr_ininput;
|
||||
dst->tlb_stackinfo_bbr_use_lt_bw = src->tlb_stackinfo_bbr_use_lt_bw;
|
||||
dst->tlb_stackinfo_bbr_flex8 = src->tlb_stackinfo_bbr_flex8;
|
||||
dst->tlb_stackinfo_bbr_pkt_epoch = GUINT32_FROM_LE(src->tlb_stackinfo_bbr_pkt_epoch);
|
||||
dst->tlb_len = GUINT32_FROM_LE(src->tlb_len);
|
||||
break;
|
||||
}
|
||||
case NFLX_OPT_TYPE_DUMPINFO: {
|
||||
struct nflx_dumpinfo *src, *dst;
|
||||
|
||||
ws_assert(nflx_custom_data_len == sizeof(struct nflx_dumpinfo));
|
||||
src = (struct nflx_dumpinfo *)opt->value.custom_opt.data.nflx_data.custom_data;
|
||||
dst = (struct nflx_dumpinfo *)nflx_custom_data;
|
||||
dst->tlh_version = GUINT32_FROM_LE(src->tlh_version);
|
||||
dst->tlh_type = GUINT32_FROM_LE(src->tlh_type);
|
||||
dst->tlh_length = GUINT64_FROM_LE(src->tlh_length);
|
||||
dst->tlh_ie_fport = src->tlh_ie_fport;
|
||||
dst->tlh_ie_lport = src->tlh_ie_lport;
|
||||
for (i = 0; i < 4; i++) {
|
||||
dst->tlh_ie_faddr_addr32[i] = src->tlh_ie_faddr_addr32[i];
|
||||
dst->tlh_ie_laddr_addr32[i] = src->tlh_ie_laddr_addr32[i];
|
||||
}
|
||||
dst->tlh_ie_zoneid = src->tlh_ie_zoneid;
|
||||
dst->tlh_offset_tv_sec = GUINT64_FROM_LE(src->tlh_offset_tv_sec);
|
||||
dst->tlh_offset_tv_usec = GUINT64_FROM_LE(src->tlh_offset_tv_usec);
|
||||
memcpy(dst->tlh_id, src->tlh_id, 64);
|
||||
memcpy(dst->tlh_reason, src->tlh_reason, 32);
|
||||
memcpy(dst->tlh_tag, src->tlh_tag, 32);
|
||||
dst->tlh_af = src->tlh_af;
|
||||
memcpy(dst->_pad, src->_pad, 7);
|
||||
break;
|
||||
}
|
||||
case NFLX_OPT_TYPE_DUMPTIME: {
|
||||
guint64 *src, *dst;
|
||||
|
||||
ws_assert(nflx_custom_data_len == sizeof(guint64));
|
||||
src = (guint64 *)opt->value.custom_opt.data.nflx_data.custom_data;
|
||||
dst = (guint64 *)nflx_custom_data;
|
||||
*dst = GUINT64_FROM_LE(*src);
|
||||
break;
|
||||
}
|
||||
case NFLX_OPT_TYPE_STACKNAME:
|
||||
ws_assert(nflx_custom_data_len >= 2);
|
||||
memcpy(nflx_custom_data, opt->value.custom_opt.data.nflx_data.custom_data, nflx_custom_data_len);
|
||||
break;
|
||||
default:
|
||||
return WTAP_OPTTYPE_NOT_FOUND;
|
||||
}
|
||||
return WTAP_OPTTYPE_SUCCESS;
|
||||
}
|
||||
|
||||
wtap_opttype_return_val
|
||||
wtap_block_add_custom_option(wtap_block_t block, guint option_id, guint32 pen, const char *custom_data, gsize custom_data_len)
|
||||
{
|
||||
|
@ -1214,8 +1423,8 @@ wtap_block_add_custom_option(wtap_block_t block, guint option_id, guint32 pen, c
|
|||
if (ret != WTAP_OPTTYPE_SUCCESS)
|
||||
return ret;
|
||||
opt->value.custom_opt.pen = pen;
|
||||
opt->value.custom_opt.custom_data_len = custom_data_len;
|
||||
opt->value.custom_opt.custom_data = g_memdup2(custom_data, custom_data_len);
|
||||
opt->value.custom_opt.data.generic_data.custom_data_len = custom_data_len;
|
||||
opt->value.custom_opt.data.generic_data.custom_data = g_memdup2(custom_data, custom_data_len);
|
||||
return WTAP_OPTTYPE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1414,6 +1623,12 @@ static void pkt_create(wtap_block_t block)
|
|||
block->mandatory_data = NULL;
|
||||
}
|
||||
|
||||
static void cb_create(wtap_block_t block)
|
||||
{
|
||||
/* Ensure this is null, so when g_free is called on it, it simply returns */
|
||||
block->mandatory_data = NULL;
|
||||
}
|
||||
|
||||
void wtap_opttypes_initialize(void)
|
||||
{
|
||||
static wtap_blocktype_t shb_block = {
|
||||
|
@ -1639,6 +1854,16 @@ void wtap_opttypes_initialize(void)
|
|||
WTAP_OPTTYPE_FLAG_MULTIPLE_ALLOWED
|
||||
};
|
||||
|
||||
static wtap_blocktype_t cb_block = {
|
||||
WTAP_BLOCK_CUSTOM, /* block_type */
|
||||
"CB", /* name */
|
||||
"Packet Block", /* description */
|
||||
cb_create, /* create */
|
||||
NULL, /* free_mand */
|
||||
NULL, /* copy_mand */
|
||||
NULL /* options */
|
||||
};
|
||||
|
||||
/*
|
||||
* Register the SHB and the options that can appear in it.
|
||||
*/
|
||||
|
@ -1699,6 +1924,11 @@ void wtap_opttypes_initialize(void)
|
|||
wtap_opttype_option_register(&pkt_block, OPT_PKT_HASH, &pkt_hash);
|
||||
wtap_opttype_option_register(&pkt_block, OPT_PKT_VERDICT, &pkt_verdict);
|
||||
|
||||
/*
|
||||
* Register the CB and the options that can appear in it.
|
||||
*/
|
||||
wtap_opttype_block_register(&cb_block);
|
||||
|
||||
#ifdef DEBUG_COUNT_REFS
|
||||
memset(blocks_active, 0, sizeof(blocks_active));
|
||||
#endif
|
||||
|
|
|
@ -323,16 +323,40 @@ typedef struct if_filter_opt_s {
|
|||
} data;
|
||||
} if_filter_opt_t;
|
||||
|
||||
/* https://www.iana.org/assignments/enterprise-numbers/enterprise-numbers */
|
||||
#define PEN_NFLX 10949
|
||||
|
||||
/*
|
||||
* Structure describing a custom option.
|
||||
*/
|
||||
|
||||
typedef struct custom_opt_s {
|
||||
guint32 pen;
|
||||
gsize custom_data_len;
|
||||
gchar *custom_data;
|
||||
union {
|
||||
struct generic_custom_opt_data {
|
||||
gsize custom_data_len;
|
||||
gchar *custom_data;
|
||||
} generic_data;
|
||||
struct nflx_custom_opt_data {
|
||||
guint32 type;
|
||||
gsize custom_data_len;
|
||||
gchar *custom_data;
|
||||
gboolean use_little_endian;
|
||||
} nflx_data;
|
||||
} data;
|
||||
} custom_opt_t;
|
||||
|
||||
/*
|
||||
* Structure describing a NFLX custom option.
|
||||
*/
|
||||
|
||||
typedef struct nflx_custom_opt_s {
|
||||
gboolean nflx_use_little_endian;
|
||||
guint32 nflx_type;
|
||||
gsize nflx_custom_data_len;
|
||||
gchar *nflx_custom_data;
|
||||
} nflx_custom_opt_t;
|
||||
|
||||
/*
|
||||
* Structure describing a value of an option.
|
||||
*/
|
||||
|
@ -356,6 +380,114 @@ typedef struct {
|
|||
wtap_optval_t value; /**< value */
|
||||
} wtap_option_t;
|
||||
|
||||
#define NFLX_OPT_TYPE_VERSION 1
|
||||
#define NFLX_OPT_TYPE_TCPINFO 2
|
||||
#define NFLX_OPT_TYPE_DUMPINFO 4
|
||||
#define NFLX_OPT_TYPE_DUMPTIME 5
|
||||
#define NFLX_OPT_TYPE_STACKNAME 6
|
||||
|
||||
struct nflx_dumpinfo {
|
||||
guint32 tlh_version;
|
||||
guint32 tlh_type;
|
||||
guint64 tlh_length;
|
||||
guint16 tlh_ie_fport;
|
||||
guint16 tlh_ie_lport;
|
||||
guint32 tlh_ie_faddr_addr32[4];
|
||||
guint32 tlh_ie_laddr_addr32[4];
|
||||
guint32 tlh_ie_zoneid;
|
||||
guint64 tlh_offset_tv_sec;
|
||||
guint64 tlh_offset_tv_usec;
|
||||
char tlh_id[64];
|
||||
char tlh_reason[32];
|
||||
char tlh_tag[32];
|
||||
guint8 tlh_af;
|
||||
guint8 _pad[7];
|
||||
};
|
||||
|
||||
/* Flags used in tlb_eventflags */
|
||||
#define NFLX_TLB_FLAG_RXBUF 0x0001 /* Includes receive buffer info */
|
||||
#define NFLX_TLB_FLAG_TXBUF 0x0002 /* Includes send buffer info */
|
||||
#define NFLX_TLB_FLAG_HDR 0x0004 /* Includes a TCP header */
|
||||
#define NFLX_TLB_FLAG_VERBOSE 0x0008 /* Includes function/line numbers */
|
||||
#define NFLX_TLB_FLAG_STACKINFO 0x0010 /* Includes stack-specific info */
|
||||
|
||||
struct nflx_tcpinfo {
|
||||
guint64 tlb_tv_sec;
|
||||
guint64 tlb_tv_usec;
|
||||
guint32 tlb_ticks;
|
||||
guint32 tlb_sn;
|
||||
guint8 tlb_stackid;
|
||||
guint8 tlb_eventid;
|
||||
guint16 tlb_eventflags;
|
||||
gint32 tlb_errno;
|
||||
guint32 tlb_rxbuf_tls_sb_acc;
|
||||
guint32 tlb_rxbuf_tls_sb_ccc;
|
||||
guint32 tlb_rxbuf_tls_sb_spare;
|
||||
guint32 tlb_txbuf_tls_sb_acc;
|
||||
guint32 tlb_txbuf_tls_sb_ccc;
|
||||
guint32 tlb_txbuf_tls_sb_spare;
|
||||
gint32 tlb_state;
|
||||
guint32 tlb_starttime;
|
||||
guint32 tlb_iss;
|
||||
guint32 tlb_flags;
|
||||
guint32 tlb_snd_una;
|
||||
guint32 tlb_snd_max;
|
||||
guint32 tlb_snd_cwnd;
|
||||
guint32 tlb_snd_nxt;
|
||||
guint32 tlb_snd_recover;
|
||||
guint32 tlb_snd_wnd;
|
||||
guint32 tlb_snd_ssthresh;
|
||||
guint32 tlb_srtt;
|
||||
guint32 tlb_rttvar;
|
||||
guint32 tlb_rcv_up;
|
||||
guint32 tlb_rcv_adv;
|
||||
guint32 tlb_flags2;
|
||||
guint32 tlb_rcv_nxt;
|
||||
guint32 tlb_rcv_wnd;
|
||||
guint32 tlb_dupacks;
|
||||
gint32 tlb_segqlen;
|
||||
gint32 tlb_snd_numholes;
|
||||
guint32 tlb_flex1;
|
||||
guint32 tlb_flex2;
|
||||
guint32 tlb_fbyte_in;
|
||||
guint32 tlb_fbyte_out;
|
||||
guint8 tlb_snd_scale:4,
|
||||
tlb_rcv_scale:4;
|
||||
guint8 _pad[3];
|
||||
|
||||
/* The following fields might become part of a union */
|
||||
guint64 tlb_stackinfo_bbr_cur_del_rate;
|
||||
guint64 tlb_stackinfo_bbr_delRate;
|
||||
guint64 tlb_stackinfo_bbr_rttProp;
|
||||
guint64 tlb_stackinfo_bbr_bw_inuse;
|
||||
guint32 tlb_stackinfo_bbr_inflight;
|
||||
guint32 tlb_stackinfo_bbr_applimited;
|
||||
guint32 tlb_stackinfo_bbr_delivered;
|
||||
guint32 tlb_stackinfo_bbr_timeStamp;
|
||||
guint32 tlb_stackinfo_bbr_epoch;
|
||||
guint32 tlb_stackinfo_bbr_lt_epoch;
|
||||
guint32 tlb_stackinfo_bbr_pkts_out;
|
||||
guint32 tlb_stackinfo_bbr_flex1;
|
||||
guint32 tlb_stackinfo_bbr_flex2;
|
||||
guint32 tlb_stackinfo_bbr_flex3;
|
||||
guint32 tlb_stackinfo_bbr_flex4;
|
||||
guint32 tlb_stackinfo_bbr_flex5;
|
||||
guint32 tlb_stackinfo_bbr_flex6;
|
||||
guint32 tlb_stackinfo_bbr_lost;
|
||||
guint16 tlb_stackinfo_bbr_pacing_gain;
|
||||
guint16 tlb_stackinfo_bbr_cwnd_gain;
|
||||
guint16 tlb_stackinfo_bbr_flex7;
|
||||
guint8 tlb_stackinfo_bbr_bbr_state;
|
||||
guint8 tlb_stackinfo_bbr_bbr_substate;
|
||||
guint8 tlb_stackinfo_bbr_inhpts;
|
||||
guint8 tlb_stackinfo_bbr_ininput;
|
||||
guint8 tlb_stackinfo_bbr_use_lt_bw;
|
||||
guint8 tlb_stackinfo_bbr_flex8;
|
||||
guint32 tlb_stackinfo_bbr_pkt_epoch;
|
||||
|
||||
guint32 tlb_len;
|
||||
};
|
||||
|
||||
struct wtap_dumper;
|
||||
|
||||
typedef void (*wtap_block_create_func)(wtap_block_t block);
|
||||
|
@ -808,6 +940,30 @@ wtap_block_set_if_filter_option_value(wtap_block_t block, guint option_id, if_fi
|
|||
WS_DLL_PUBLIC wtap_opttype_return_val
|
||||
wtap_block_get_if_filter_option_value(wtap_block_t block, guint option_id, if_filter_opt_t* value) G_GNUC_WARN_UNUSED_RESULT;
|
||||
|
||||
/** Add an NFLX custom option to a block
|
||||
*
|
||||
* @param[in] block Block to which to add the option
|
||||
* @param[in] nflx_type NFLX option type
|
||||
* @param[in] nflx_custom_data pointer to the data
|
||||
* @param[in] nflx_custom_data_len length of custom_data
|
||||
* @return wtap_opttype_return_val - WTAP_OPTTYPE_SUCCESS if successful,
|
||||
* error code otherwise
|
||||
*/
|
||||
WS_DLL_PUBLIC wtap_opttype_return_val
|
||||
wtap_block_add_nflx_custom_option(wtap_block_t block, guint32 nflx_type, const char *nflx_custom_data, gsize nflx_custom_data_len);
|
||||
|
||||
/** Get an if_filter option value from a block
|
||||
*
|
||||
* @param[in] block Block from which to get the option value
|
||||
* @param[in] nflx_type type of the option
|
||||
* @param[out] nflx_custom_data Returned value of NFLX custom option value
|
||||
* @param[in] nflx_custom_data_len size of buffer provided in nflx_custom_data
|
||||
* @return wtap_opttype_return_val - WTAP_OPTTYPE_SUCCESS if successful,
|
||||
* error code otherwise
|
||||
*/
|
||||
WS_DLL_PUBLIC wtap_opttype_return_val
|
||||
wtap_block_get_nflx_custom_option(wtap_block_t block, guint32 nflx_type, char *nflx_custom_data, gsize nflx_custom_data_len);
|
||||
|
||||
/** Add an custom option to a block
|
||||
*
|
||||
* @param[in] block Block to which to add the option
|
||||
|
|
Loading…
Reference in New Issue